Skip to content

Tighten import handling and fix SetComprehension typo#9607

Merged
manzt merged 2 commits into
mainfrom
push-xkrmzlkmskmo
Jun 30, 2026
Merged

Tighten import handling and fix SetComprehension typo#9607
manzt merged 2 commits into
mainfrom
push-xkrmzlkmskmo

Conversation

@manzt

@manzt manzt commented May 19, 2026

Copy link
Copy Markdown
Collaborator

Follow up to #9379

ImportStatement was collecting every VariableName direct child as a binding, including the module path in from m import ... and the imported name when shadowed by as.

Also:

  • Removed the dead ImportFromStatement branch — the Lezer Python grammar only emits ImportStatement, so it never matched.
  • Fixed pre-existing SetComprehension typo in reactive-references/analyzer.ts (grammar node is SetComprehensionExpression); set comprehensions now correctly create a scope.

Copilot AI review requested due to automatic review settings May 19, 2026 15:30
@vercel

vercel Bot commented May 19, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
marimo-docs Ready Ready Preview, Comment Jun 29, 2026 8:08pm

Request Review

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR tightens Python import handling in the CodeMirror AST analyzers used for reactive-variable highlighting and go-to-definition, and fixes a grammar-node typo so set comprehensions correctly create a scope.

Changes:

  • Fix set comprehension scoping by using the correct Lezer node name (SetComprehensionExpression).
  • Refine ImportStatement binding collection so from m import x as y doesn’t treat m or x as local bindings (only y binds).
  • Prevent import-statement names from being treated as reactive uses.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
frontend/src/core/codemirror/reactive-references/analyzer.ts Fixes set-comprehension scope creation; improves import binding collection; skips import nodes during reactive-use scan.
frontend/src/core/codemirror/reactive-references/tests/analyzer.test.ts Adds regression tests for set-comprehension scoping and from-import binding/reactive behavior.
frontend/src/core/codemirror/go-to-definition/commands.ts Improves import binding parsing for scoped declaration collection; adjusts fallback behavior when usagePosition is provided.
frontend/src/core/codemirror/go-to-definition/tests/utils.test.ts Adds regression test ensuring cross-cell resolution isn’t blocked by module-path “declarations” in from-imports.
frontend/src/core/codemirror/go-to-definition/tests/commands.test.ts Adds tests covering from-import alias binding semantics and module-path non-binding behavior.

Comment on lines +314 to +321
if (subCursor.name === "VariableName") {
commit();
pending = options.state.doc.sliceString(
subCursor.from,
subCursor.to,
);
// Add to the current innermost scope
const currentScope =
currentScopeStack[currentScopeStack.length - 1] ?? -1;
if (!allDeclarations.has(currentScope)) {
allDeclarations.set(currentScope, new Set());
}
allDeclarations.get(currentScope)?.add(varName);
} else if (subCursor.name === ",") {
commit();
Comment on lines +341 to 352
if (subCursor.name === "VariableName") {
// Flush any previous pending name (no `as` followed it).
commit();
pending = {
from: subCursor.from,
matches:
state.doc.sliceString(subCursor.from, subCursor.to) ===
variableName,
};
} else if (subCursor.name === ",") {
commit();
}
@mscolnick

Copy link
Copy Markdown
Contributor

@cubic-dev-ai

@cubic-dev-ai

cubic-dev-ai Bot commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

@cubic-dev-ai

@mscolnick I have started the AI code review. It will take a few minutes to complete.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 5 files

Architecture diagram
sequenceDiagram
    participant UI as CodeMirror Editor
    participant Commands as go-to-definition commands.ts
    participant Analyzer as reactive-references analyzer.ts
    participant Parser as Lezer Python Grammar
    participant Utils as go-to-definition utils.ts

    Note over UI,Utils: Import Statement Binding Resolution

    UI->>Commands: goToVariableDefinition(view, name, pos)
    Commands->>Commands: findScopedDefinitionPosition(state, name, pos)
    
    Commands->>Commands: collectMatchingDeclarations(tree, name)
    Commands->>Parser: Walk ImportStatement node
    Parser-->>Commands: Direct child VariableName nodes
    
    Note over Commands: NEW: Only names after 'import' keyword qualify
    Commands->>Commands: Set pastImport=false, pending=null
    loop Each child node
        alt child is "import" keyword
            Commands->>Commands: pastImport=true
        else child is "as" keyword
            Commands->>Commands: pending=null (drop pre-alias name)
        else child is VariableName AND pastImport
            alt previous pending exists
                Commands->>Commands: Commit pending name as declaration
            end
            Commands->>Commands: Set pending={from, matches: equals name}
        else child is comma
            Commands->>Commands: Commit pending name as declaration
        end
    end
    Commands->>Commands: Commit final pending if any

    alt Scoped definition found
        Commands-->>UI: Return true + cursor position
    else No scoped definition (module path or unused alias)
        Note over Commands: CHANGED: No fallback to findFirstMatchingVariable
        Commands-->>UI: Return false (let caller try cross-cell)
    end

    Note over UI,Utils: Reactive References Analysis

    UI->>Analyzer: findReactiveVariables(state)
    Analyzer->>Parser: Walk syntax tree for declarations
    
    alt ImportStatement encountered
        Analyzer->>Analyzer: Use same pastImport/pending/commit logic
        Note over Analyzer: CHANGED: Replaces old ImportStatement + ImportFromStatement branches
        Analyzer->>Analyzer: Only add VariableName after 'import' to scope declarations
    else ComprehensionExpression encountered
        alt SetComprehensionExpression (was "SetComprehension")
            Analyzer->>Analyzer: CHANGED: Correct node name creates scope
        end
    end

    Analyzer->>Parser: Walk tree for reactive uses
    alt ImportStatement encountered
        Note over Analyzer: NEW: Skip all content inside ImportStatement (module paths, imported names, aliases are not reactive uses)
        Analyzer-->>Parser: return (no reactive variables)
    end

    Analyzer-->>UI: Return reactive variable ranges with highlights

    Note over UI,Utils: Cross-Cell Resolution (Regression Test)

    Utils->>Commands: goToDefinitionAtCursorPosition(view)
    Commands->>Commands: findScopedDefinitionPosition fails (module path)
    Commands-->>Utils: Return false
    Utils->>Utils: Fall through to cross-cell lookup
    Utils->>Notebook: Find other cells with matching variable
    Notebook-->>Utils: Target cell + position
    Utils->>Target: Set cursor to declaration position
Loading

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread frontend/src/core/codemirror/go-to-definition/commands.ts
manzt and others added 2 commits June 29, 2026 13:54
Follow up to #9379

`ImportStatement` was collecting every `VariableName` direct child as a
binding, including the module path in `from m import ...` and the
imported name when shadowed by `as`.

Also:

- Removed the dead `ImportFromStatement` branch — the Lezer Python grammar
  only emits `ImportStatement`, so it never matched.
- Fixed pre-existing `SetComprehension` typo in reactive-references/analyzer.ts
  (grammar node is `SetComprehensionExpression`); set comprehensions now
  correctly create a scope.
@manzt manzt merged commit ea3c57c into main Jun 30, 2026
31 checks passed
@manzt manzt deleted the push-xkrmzlkmskmo branch June 30, 2026 00:30
@github-actions

Copy link
Copy Markdown
Contributor

🚀 Development release published. You may be able to view the changes at https://marimo.app?v=0.23.12-dev20

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants