Skip to content

Fix local vars & function calls leaking into the document symbols outline#72

Merged
JesseHerrick merged 2 commits into
mainfrom
fix-outline-depth-tracking
Jun 11, 2026
Merged

Fix local vars & function calls leaking into the document symbols outline#72
JesseHerrick merged 2 commits into
mainfrom
fix-outline-depth-tracking

Conversation

@JesseHerrick

@JesseHerrick JesseHerrick commented Jun 5, 2026

Copy link
Copy Markdown
Member

Closes #69.

Problem

Local variable assignments and ordinary function calls inside a function body were showing up as entries in the document-symbols outline (and in symbol search). For example, a handle_params/3 body containing:

changeset = build_changeset(search_form_data, unsigned_params, scopes, context)

socket =
  case Ecto.Changeset.apply_action(changeset, :update) do
    {:ok, search_form_data} ->
      paginate_async(socket, unsigned_params, [per_page: @per_page], fn page, per_page -> ...

...produced bogus changeset = build_changeset(...) and paginate_async(...) symbols.

Root cause

The outline builder detects ExUnit-style macros (describe / test / setup) by scanning forward from a leading identifier to see if a do block follows. It used ScanForwardToBlockDo, which intentionally does not stop at end-of-line (to allow split-line heads) and only halts at def/end-style keywords. So for a plain assignment, the scan sailed across statement boundaries and latched onto the do of a later case, making the assignment look like a macro-with-do-block.

The reference-collecting parser already had a careful scan that tracks bracket depth and statement boundaries — but the outline code never shared it.

Fix

  • Extract the careful scan into a shared ScanForwardToMacroCallBlockDo helper: a do only counts at bracket depth 0, and once an end-of-line is seen at depth 0, any non-do token ends the statement and stops the scan.
  • Point the document-symbol code at the new helper.
  • Refactor the parser's duplicated inline scan to call the same helper (removes ~30 lines and prevents the two from diverging again).
  • The defmodule/def call sites keep using ScanForwardToBlockDo — there the keyword itself is a statement boundary, so the naive scan is correct.

Bonus: multi-line macro heads now detected

While here, also fixed a pre-existing limitation: an ExUnit macro whose keyword-argument head spans multiple lines was not detected:

test "creates a user",
     tags: [:integration] do

A trailing comma at bracket depth 0 is an unambiguous continuation in Elixir (a statement can't end on a dangling comma), so the scan now continues across it — while = stays a boundary, keeping the #69 fix intact. Multi-line head labels also collapse internal whitespace so they render on a single line in the outline.


Note

Low Risk
Changes are localized to token forward-scanning and document-symbol labeling, with broad unit/LSP tests and no auth or persistence impact.

Overview
Fixes document symbol outline false positives where assignments and plain calls inside a function were treated as ExUnit-style macros because a forward scan crossed statement boundaries and matched a later case … do.

The outline and reference parser now share ScanForwardToMacroCallBlockDo: at bracket depth 0, end-of-line ends the macro head unless the line ends with a trailing comma (multi-line test/describe heads), and do inside nested parens/brackets does not count. defmodule/def still use ScanForwardToBlockDo.

Macro outline labels collapse whitespace between the name and do so split-line keyword args show as one line. Regression tests cover issue #69 and multi-line macro heads.

Reviewed by Cursor Bugbot for commit 3fcd711. Bugbot is set up for automated code reviews on this repo. Configure here.

@JesseHerrick JesseHerrick self-assigned this Jun 5, 2026

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit de7b63f. Configure here.

Comment thread internal/parser/token_walk.go
@JesseHerrick JesseHerrick merged commit d32e2b3 into main Jun 11, 2026
5 checks passed
@JesseHerrick JesseHerrick deleted the fix-outline-depth-tracking branch June 11, 2026 03:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Local vars and function calls in symbols list

1 participant