Skip to content

Resolve Go To Definition targets through the workspace's current solution - #20462

Open
xperiandri wants to merge 13 commits into
dotnet:mainfrom
xperiandri:fix/gtd-stale-solution
Open

xperiandri wants to merge 13 commits into
dotnet:mainfrom
xperiandri:fix/gtd-stale-solution

Conversation

@xperiandri

@xperiandri xperiandri commented Sep 6, 2026 •

Copy link
Copy Markdown
Contributor

Go To Definition on a symbol in another F# project of the same solution opened a generated signature ("F# Metadata") instead of the source, and Go To Implementation reported nothing, while a large solution was still loading. Reproduced with the in-box tools on Visual Studio 18 Insiders on a solution with 135 project instances.

The navigation service decides a symbol is external by looking up its file in the Solution snapshot it was handed, which can be one taken before every project finished loading. The same stale lookup narrowed Find All References and Rename to the wrong scope, and could miss declaration spans. The lookup now checks the document's own solution first — which keeps unsaved buffer text intact — and falls back to the workspace's current solution, normalising the path and preferring the target-framework instance the origin project depends on.

🤖 Generated with Claude Code

@github-actions

github-actions Bot commented Sep 6, 2026 •

Copy link
Copy Markdown
Contributor

✅ Release notes checked


✅ Found changes and release notes in following paths:

Change path Release notes path Description
`vsintegration/src` docs/release-notes/.VisualStudio/18.vNext.md

xperiandri added a commit to xperiandri/fsharp that referenced this pull request Sep 6, 2026
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@github-actions github-actions Bot added the AI-Tooling-Check-Scanned-Clean Tooling check: diff analyzed, no interesting infrastructure files label Sep 6, 2026
@github-project-automation github-project-automation Bot moved this from New to In Progress in F# Compiler and Tooling Sep 7, 2026
xperiandri added a commit to xperiandri/fsharp that referenced this pull request Sep 11, 2026
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@xperiandri
xperiandri force-pushed the fix/gtd-stale-solution branch from a0e2ac3 to e2cab44 Compare September 11, 2026 16:19
@github-actions github-actions Bot added the ⚠️ Affects-Design-Time Tooling check: PR touches type providers or dependency manager label Sep 11, 2026
@github-actions

This comment has been minimized.

@github-actions

Copy link
Copy Markdown
Contributor

🔍 Tooling Safety Check — Affects-Design-Time
Affects-Design-Time: Changes Visual Studio Go To Definition resolution.

Generated by PR Tooling Safety Check · gpt56 3.1M · ◷

@T-Gro T-Gro left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

🤖🕵️ If this fixes an issue or implements an RFC/suggestion, link it (Fixes #... when applicable). Otherwise, give a short management-level summary in simplified technical English: what user scenario improves and what this achieves.

Please apply this PR-description guidance. Remove the implementation inventory already visible in Files, but keep necessary scope, compatibility, and dependency caveats.

xperiandri added a commit to xperiandri/fsharp that referenced this pull request Sep 14, 2026
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@xperiandri
xperiandri force-pushed the fix/gtd-stale-solution branch from e2cab44 to ef4fe97 Compare September 14, 2026 15:33
@xperiandri
xperiandri requested a review from T-Gro September 14, 2026 15:38
@T-Gro
T-Gro enabled auto-merge (squash) September 16, 2026 11:22
auto-merge was automatically disabled September 16, 2026 13:39

Head branch was pushed to by a user without write access

xperiandri added a commit to xperiandri/fsharp that referenced this pull request Sep 16, 2026
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@xperiandri
xperiandri force-pushed the fix/gtd-stale-solution branch from ef4fe97 to a82e2ec Compare September 16, 2026 13:39
@xperiandri
xperiandri requested a review from T-Gro September 16, 2026 13:42
@xperiandri

Copy link
Copy Markdown
Contributor Author

@T-Gro I rebased and solved conflicts

Comment thread vsintegration/src/FSharp.Editor/LanguageService/Symbols.fs
Comment thread vsintegration/tests/FSharp.Editor.Tests/Helpers/RoslynHelpers.fs Outdated
Comment thread vsintegration/src/FSharp.Editor/Navigation/GoToDefinition.fs Outdated
Comment thread vsintegration/tests/FSharp.Editor.Tests/Helpers/RoslynHelpers.fs Outdated
Comment thread vsintegration/tests/FSharp.Editor.Tests/Helpers/RoslynHelpers.fs Outdated
Comment thread vsintegration/tests/FSharp.Editor.Tests/Helpers/RoslynHelpers.fs
Comment thread vsintegration/tests/FSharp.Editor.Tests/Helpers/RoslynHelpers.fs Outdated
Comment thread vsintegration/tests/FSharp.Editor.Tests/Helpers/RoslynHelpers.fs Outdated
Comment thread vsintegration/tests/FSharp.Editor.Tests/Helpers/RoslynHelpers.fs
@T-Gro T-Gro added the vsintegration-only Changes only Visual Studio integration, plus optional docs, release notes, or tests label Sep 21, 2026
xperiandri added a commit to xperiandri/fsharp that referenced this pull request Sep 22, 2026
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@xperiandri
xperiandri force-pushed the fix/gtd-stale-solution branch from 7db3dd1 to 6ce4cef Compare September 22, 2026 11:34
xperiandri and others added 12 commits September 26, 2026 03:01
…r tests

Test helpers so far put every synthetic file into one Roslyn project. CreateMultiProjectSolution
creates one project per synthetic project with project references, the way VS wires
project-to-project references; CreateMultiTargetSolution creates one project per target
instance sharing the project path and the document paths, the way VS loads a multi-targeted
project.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The document Roslyn hands to Go To Definition can come from a snapshot taken before every
project of the solution finished loading. Deciding that a symbol is external because that
snapshot has no document for its file sent F# to F# navigation into a generated signature,
and the same lookup silently narrowed the scope of Find All References and Rename.

Look the target up in the document's own solution first and in Workspace.CurrentSolution when
it is missing, normalising the path and preferring the target-framework instance the origin
project depends on. The branch of Go To Definition that already sits on the declaration moves
into its own member.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…arget document

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
List.map followed by List.distinctBy allocates the mapped list and then the
distinct one; a Seq pipeline materializes once, at Seq.toList.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
… tuple

CreateMultiProjectSolution and CreateMultiTargetSolution now both return a
struct tuple, so callers destructure with the struct pattern.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Copilot AI lite review requested due to automatic review settings September 26, 2026 01:01
@xperiandri
xperiandri force-pushed the fix/gtd-stale-solution branch from 6ce4cef to 0c7c5c2 Compare September 26, 2026 01:01

Copilot AI 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.

Copilot review overview

🟡 Changes recommended

Unresolved multi-target document selection and stale-solution rename/navigation issues remain.

Review effort: Lite
Findings: 1 Medium severity

Open (1)
What changed in this PR

Updates F# navigation and symbol resolution to use the workspace’s current solution when snapshots are stale.

Changes:

  • Adds workspace-aware document and project resolution.
  • Updates navigation, Find Usages, Rename, and symbol scoping.
  • Adds multi-project regression tests and release notes.
File Summary
vsintegration/​tests/​FSharp.Editor.Tests/​Helpers/​RoslynHelpers.fs Adds multi-project and multi-target test helpers.
vsintegration/​tests/​FSharp.Editor.Tests/​GoToDefinitionServiceTests.fs Tests stale-snapshot navigation and symbol scope.
vsintegration/​src/​FSharp.Editor/​Navigation/​GoToDefinition.fs Resolves navigation targets through current solutions.
vsintegration/​src/​FSharp.Editor/​Navigation/​FindUsagesService.fs Resolves declaration spans across solution documents.
vsintegration/​src/​FSharp.Editor/​LanguageService/​Symbols.fs Uses workspace-aware documents for symbol scope.
vsintegration/​src/​FSharp.Editor/​LanguageService/​SymbolHelpers.fs Resolves signature and implementation counterparts.
vsintegration/​src/​FSharp.Editor/​Common/​CodeAnalysisExtensions.fs Adds document lookup and solution fallback helpers.
docs/​release-notes/​.VisualStudio/​18.vNext.md Documents the navigation fix.

💡 Add a code-review agent skill for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +142 to +143
member document.TryGetSolutionDocumentFromPath(filePath: string) =
document.GetSolutionDocumentsWithFilePath filePath |> Seq.tryHeadV

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.

Fixed in 98a1a20be3, by the route you suggest: TryGetSolutionDocumentFromPath now builds a range over the path and goes through TryGetSolutionDocumentFromFSharpRange, so one rule decides both — the origin's own project first, then a project that depends on the candidate's, then whatever is left.

It matters for exactly the three callers it has, and all three ask for the sibling of the document they start from: the .fs of a signature and the .fsi of an implementation in FindDefinitionAtPosition, and the counterpart file in SymbolHelpers. Each instance of a multi-targeted project holds that sibling and reads it under its own defines, so the answer has to come from the instance the origin belongs to.

Thirteen tests across GoToDefinitionServiceTests, FindReferences and the multi-target classes pass.

A sibling file looked up by path took whichever document came first, while the same
lookup by range prefers the origin's project or one it depends on. The instances of a
multi-targeted project hold the same file and read it under their own defines, so the
path lookup now goes through that rule too.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

This branch has not been deployed

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

Labels

⚠️ Affects-Design-Time Tooling check: PR touches type providers or dependency manager AI-Tooling-Check-Scanned-Clean Tooling check: diff analyzed, no interesting infrastructure files vsintegration-only Changes only Visual Studio integration, plus optional docs, release notes, or tests

Projects

Status: In Progress

Development

Successfully merging this pull request may close these issues.

3 participants