Skip to content

lsp selection range#3003

Open
close2 wants to merge 9 commits intomasterfrom
CL/lsp_selectionRange
Open

lsp selection range#3003
close2 wants to merge 9 commits intomasterfrom
CL/lsp_selectionRange

Conversation

@close2
Copy link
Collaborator

@close2 close2 commented Mar 1, 2026

depends on #3002

Add a new REFERENCES mode to the C++ compiler that finds all references
to a symbol by:
1. Resolving the target definition at the cursor position
2. Walking the IR with FindReferencesVisitor to locate all usages
3. Using ir_to_ast_map to emit exact token ranges

Wire this into the Toit LSP server with:
- find-references method in compiler.toit
- textDocument/rename handler in server.toit
- RenameParams and WorkspaceEdit protocol classes
- Rename test infrastructure (runner + test data + CMake)
Bug: prepareRename on a named constructor call site (e.g., cursor on deserialize in IpAddress.deserialize) incorrectly returned the class name IpAddress instead of the constructor name deserialize.

Root cause: In rename.cc:40-52, FindReferencesHandler::call_static unconditionally redirected ALL constructors/factories to their holder class. This was correct for unnamed constructors (where MyObj calls an unnamed constructor — the user wants to rename the class), but wrong for named constructors/factories like constructor.deserialize (where the user wants to rename deserialize).

Fix: Added a guard that only redirects to the holder class when the constructor's name matches the class name or is Symbols::constructor (both indicating unnamed constructors). Named constructors keep their own identity as the rename target.

Test: Created named-ctor-call-prepare-rename-test.toit with two test cases:

Cursor on the named constructor create in MyClass.create 42 → expects create
Cursor on the class name MyClass in MyClass.create 42 → expects MyClass
Test for named contructor rename
Root cause: prepareRename on a named argument like --network at a call site to a cross-module function returned null because ir::Method::parameters() is empty for imported methods at LSP resolution time. The resolver populates parameters for the entry module first; imported module methods only have their ResolutionShape (which includes named parameter names) but not the actual ir::Parameter* nodes.

Fix in rename.h: The call_static_named method now has a two-step lookup:

First tries ir_method->parameters() (works for same-module methods)
Falls back to resolution_shape().names() for cross-module methods where parameters aren't yet populated. When a match is found, creates a temporary ir::Local node with the correct name and call-site range.
Uses some heuristic to improve rename functionality.
@close2 close2 requested a review from floitsch March 1, 2026 10:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant