Skip to content

Use Salsa infrastructure for find-references and rename#1257

Merged
lionel- merged 19 commits into
mainfrom
oak/salsa-19-find-refs-rename-migration
Jun 19, 2026
Merged

Use Salsa infrastructure for find-references and rename#1257
lionel- merged 19 commits into
mainfrom
oak/salsa-19-find-refs-rename-migration

Conversation

@lionel-

@lionel- lionel- commented Jun 5, 2026

Copy link
Copy Markdown
Contributor

Branched from #1254
Progress towards #1212
Closes #1149

This PR moves find-references and rename onto the Salsa infra and deletes the old implementation (the textual workspace walk).

Candidate search: Unlike Rust-Analyzer that does a textual search across the workspace and resolves all occurrences, we're more aligned with ty: we filter files to inspect with a textual search, but then use a post-parse structure to filter occurrences. ty walks the AST, we walk the index instead with a new uses_of() method that is more to the point than the raw AST.

Candidates are then narrowed with File::resolve_at() to check that they match the definition of the symbol at point.

New supporting infra:

  • Salsa-based Identifier::classify()
  • all_files() (Salsa query) that returns all files known to the database
  • root_by_file() that disambiguates to which workspace root a file belong when roots are nested. That is meant to be the one source of truth for root ownership of files.

Removed infra: The Document copies of the Rowan parse tree and semantic index are now removed, in favour of the Salsa DB.

Other fix: Goto-definition now benefits from the new Salsa-based Identifier::classify() which snaps the cursor to the symbol at point. Fixes goto-def when cursor in on RHS boundary.

I recommend testing with #1259 to benefit from bug fixes and improvements in ulterior branches.

@lionel- lionel- force-pushed the oak/salsa-19-find-refs-rename-migration branch from 11d6ce1 to 31b65be Compare June 5, 2026 09:09
@lionel- lionel- force-pushed the oak/salsa-18-goto-def-migration branch from 399f3f3 to ec4c775 Compare June 11, 2026 12:38
@lionel- lionel- force-pushed the oak/salsa-19-find-refs-rename-migration branch from 31b65be to 2fcc1d2 Compare June 11, 2026 12:39
@lionel- lionel- force-pushed the oak/salsa-18-goto-def-migration branch from fa5b1c0 to cacffa1 Compare June 11, 2026 13:14
@lionel- lionel- force-pushed the oak/salsa-19-find-refs-rename-migration branch from 2fcc1d2 to 9b0c99e Compare June 11, 2026 13:15

@DavisVaughan DavisVaughan 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.

Very cool!

Comment thread crates/oak_semantic/src/semantic_index.rs Outdated
Comment on lines +182 to +183
// Cursor on `mutate` in `dplyr::mutate` is a namespace access, returns nothing.
let code = "dplyr::mutate\n";

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.

i guess it could return every time you call dplyr's mutate()?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

yep good catch, now done. Part of the feature needs to be implemented in #1258 (comment)

Location::new(file1_uri, range((1, 2), (1, 3))),
];
assert_eq!(locs, expected);
assert!(locs.is_empty());

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.

did we lose test_function_scope_target_skips_cross_file_walk as a test?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Renamed to test_function_scope_target_stays_in_file and there's a similar test in IDE layer

Comment thread crates/oak_db/src/identifier.rs Outdated
///
/// Returns `None` when the cursor isn't on a variable binding/use or
/// a member name (e.g. cursor is on an operator, a keyword, or a
/// `pkg::sym` namespace access).

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.

I noticed that NamespaceAccess went away as an Identifier type?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I thought I'd leave it off until later, but resurrected it as part of #1257 (comment)

Comment on lines +24 to +26
/// Cursor on the RHS name of a `$` or `@` extract expression. Member
/// names are not tracked by the semantic index.
Member {

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.

does this all work with nested $ calls? like foo$bar$baz regardless of where the cursor is?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yep it does, I added tests for this

Comment thread crates/oak_ide/src/find_references.rs Outdated
Comment thread crates/oak_ide/src/find_references.rs Outdated
Comment thread crates/oak_ide/src/find_references.rs
Comment thread crates/ark/src/lsp/state.rs Outdated
Comment thread crates/oak_ide/src/rename.rs Outdated
offset: TextSize,
new_name: &str,
) -> anyhow::Result<RenameTargets> {
let new_text = to_identifier_text(new_name)?;

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.

I could see this call moving out of rename() up to the lsp level

So then you would not pass new_name through or return it. And RenameTargets could just be Vec<FileRange>

Mostly I was a bit surprised to see it flow through to here since this function is mostly about "find the sites to rename at", only to find that its passed through here just for name normalization.

I guess its a question of who owns the normalization process, oak_ide or the lsp layer?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I think you're right, that's a better separation of concerns

@lionel- lionel- force-pushed the oak/salsa-19-find-refs-rename-migration branch from 9b0c99e to 8363250 Compare June 15, 2026 14:30
@lionel- lionel- force-pushed the oak/salsa-18-goto-def-migration branch from d73c0d5 to 77bd0a4 Compare June 19, 2026 13:52
Base automatically changed from oak/salsa-18-goto-def-migration to main June 19, 2026 13:53
@lionel- lionel- force-pushed the oak/salsa-19-find-refs-rename-migration branch from 1ab24cd to b09b25b Compare June 19, 2026 13:54
@lionel- lionel- merged commit 6f5c12e into main Jun 19, 2026
17 checks passed
@lionel- lionel- deleted the oak/salsa-19-find-refs-rename-migration branch June 19, 2026 13:54
@github-actions github-actions Bot locked and limited conversation to collaborators Jun 19, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Implement goto-definition, find-references, and rename with oak's symbol resolution

2 participants