Context
When a local macro reference in a file using do/run has:
- A callee-side definition that's excluded by do/run inheritance, and
- A same-file definition that exists but isn't visible at the reference site (e.g. inside a different program body)
the provider currently preserves the analyzer's generic `Undefined local macro \`foo'` diagnostic. That's accurate but unhelpful — it doesn't tell the user why their same-file definition is invisible, or that a callee-side alternative exists.
We explored emitting OUT_OF_SCOPE_SYMBOL with the existing "local macros are not inherited via do/run (use include or @lsp-include)" message in those cases, but the message is misleading: it points at the callee file and recommends include, even though the user likely intended the same-file definition they wrote. Switching to include wouldn't expose that same-file local anyway.
Commits b852e1c…1e38388 on include-edge-case explored a scope-aware rewrite and were reverted because each iteration compounded the mis-messaging.
Scenarios worth distinguishing
- Reference at top-level, same-file local defined only inside a
program define body.
- Reference inside program body number 1, same-file local defined in program body number 2 (redeclared program).
- Reference inside one program, same-file local defined in a sibling program.
- Reference + `local' redef where the first definition is program-scoped but a later top-level definition exists via
additional_definitions.
Proposed enhancement
Introduce a dedicated diagnostic (separate wording from "not inherited via do/run") for "same-file definition exists but isn't visible in this scope". Ideas:
'foo' is defined in program \my_prog' but program locals aren't visible here`
'foo' is defined later in the same program body; use this name after the definition
- When both a same-file scope-isolated local and a callee-side local exist, emit a combined message or rank them by proximity.
Requirements sketch
- Detect enclosing program for the reference line and for each same-file definition (primary +
additional_definitions), handling first-definition-wins ProgramSymbol.additional_definitions for redeclared programs. Use a body-specific key (e.g. name#startLine) so redeclarations aren't merged.
- Classify: (a) no same-file def, (b) same-file def in-scope, (c) same-file def out-of-scope, (d) both same-file out-of-scope and callee-side. Emit tailored wording per class.
- Keep the "any same-file match preserves generic UNDEFINED_MACRO" default as a safe fallback when the scope-analysis heuristics are uncertain.
Not in scope
- Callee-only references (
OUT_OF_SCOPE_SYMBOL with existing message is correct and unchanged).
- Globals, scalars, matrices, variables — program-body scoping only affects locals.
Related
- Reverted commits on
include-edge-case: b852e1c, 3ac1904, 12dc34c, 1e38388.
- Anchor in source:
src/providers/diagnostics.ts::is_symbol_defined_in_current_document and the forward-call rewrite path near src/providers/diagnostics.ts:332-368.
Context
When a local macro reference in a file using
do/runhas:the provider currently preserves the analyzer's generic
`Undefined local macro \`foo'`diagnostic. That's accurate but unhelpful — it doesn't tell the user why their same-file definition is invisible, or that a callee-side alternative exists.We explored emitting
OUT_OF_SCOPE_SYMBOLwith the existing "local macros are not inherited via do/run (use include or @lsp-include)" message in those cases, but the message is misleading: it points at the callee file and recommendsinclude, even though the user likely intended the same-file definition they wrote. Switching toincludewouldn't expose that same-file local anyway.Commits
b852e1c…1e38388oninclude-edge-caseexplored a scope-aware rewrite and were reverted because each iteration compounded the mis-messaging.Scenarios worth distinguishing
program definebody.additional_definitions.Proposed enhancement
Introduce a dedicated diagnostic (separate wording from "not inherited via do/run") for "same-file definition exists but isn't visible in this scope". Ideas:
'foo' is defined in program \my_prog' but program locals aren't visible here`'foo' is defined later in the same program body; use this name after the definitionRequirements sketch
additional_definitions), handling first-definition-winsProgramSymbol.additional_definitionsfor redeclared programs. Use a body-specific key (e.g.name#startLine) so redeclarations aren't merged.Not in scope
OUT_OF_SCOPE_SYMBOLwith existing message is correct and unchanged).Related
include-edge-case:b852e1c,3ac1904,12dc34c,1e38388.src/providers/diagnostics.ts::is_symbol_defined_in_current_documentand the forward-call rewrite path nearsrc/providers/diagnostics.ts:332-368.