Skip to content

Fix/enable navigating to SourceLink from Razor - #84834

Merged
davidwengier merged 3 commits into
dotnet:mainfrom
davidwengier:fix-razor-sourcelink-oop
Aug 27, 2026
Merged

davidwengier merged 3 commits into
dotnet:mainfrom
davidwengier:fix-razor-sourcelink-oop

Conversation

@davidwengier

@davidwengier davidwengier commented Aug 11, 2026

Copy link
Copy Markdown
Member

Fixes dotnet/razor#13214

I naively thought SourceLink was working, because metadata as source and decompilation work (and we have tests), but turns out SourceLink was missing MEF components that only exist in the IDE layers. This PR restores SourceLink by doing repeating the GTD calls to Roslyn in the IDE, if the call in OOP didn't work. Source navigation should be therefore unaffected, but unfortunately it does mean MaaS, decompilation and Source Link are a little slower.

Microsoft Reviewers: Open in CodeFlow

davidwengier and others added 2 commits August 10, 2026 18:31
Razor go-to-definition runs Roslyn in OOP. Direct source navigation works there, but metadata-as-source cannot use SourceLink because the RemoteWorkspace does not contain the host SourceLink service. Metadata navigation therefore falls through to decompilation.

Keep direct source lookup in OOP by calling Roslyn without a metadata-as-source service. When the remaining target is a navigable metadata symbol, return the generated C# document and position to the cohost endpoint. The endpoint resolves that document in the host solution and runs the same Roslyn definition path with the host metadata-as-source service, allowing SourceLink before the existing decompilation fallback.

Continue to use RemoteResponse for the existing stop and HTML states, with a small payload for either direct locations or the host C# request.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: a882f23f-220e-454a-8be6-d62eef9f7c26
Verify direct C# definitions still return from Razor OOP, while navigable metadata symbols return a host C# request. Keep the existing end-to-end assertion that the host produces the expected metadata-as-source location.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: a882f23f-220e-454a-8be6-d62eef9f7c26
Copilot AI lite review requested due to automatic review settings August 11, 2026 00:23
@davidwengier
davidwengier requested a review from a team as a code owner August 11, 2026 00:23
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 2 pipeline(s).
There may be pipelines that require an authorized user to comment /azp run to run.

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

Pull request overview

This PR restores reliable SourceLink navigation for Razor go-to-definition by splitting remote (OOP) results into either direct Razor-mapped locations or a host-side C# request that can use IDE-only services (like SourceLink/metadata-as-source). It updates the remote contract accordingly and adds/adjusts tests to validate the new behavior.

Changes:

  • Change the Razor OOP go-to-definition remote contract to return a structured response (GoToDefinitionResponse) that can represent either locations or a host-side C# request.
  • Update the OOP implementation to do source-only lookup first, and when it detects navigable metadata, defer resolution back to the host.
  • Update the cohost endpoint and unit tests to exercise both direct-location and host-resolution paths.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
src/Razor/src/Razor/test/Microsoft.CodeAnalysis.Razor.CohostingShared.UnitTests/Endpoints/CohostGoToDefinitionEndpointTest.cs Extends tests to validate the new remote response shape and host-side metadata resolution flow.
src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/GoToDefinition/RemoteGoToDefinitionService.cs Updates OOP behavior to avoid metadata-as-source in OOP and emit a host-side request for navigable metadata symbols.
src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Remote/IRemoteGoToDefinitionService.cs Updates the remote service contract to return RemoteResponse<GoToDefinitionResponse?>.
src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Remote/GoToDefinitionResponse.cs Adds a DTO for returning either locations or a C# request to resolve in the host.
src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.CohostingShared/Navigation/CohostGoToDefinitionEndpoint.cs Interprets the new remote response and performs host-side metadata-as-source lookup when requested.
Suppressed comments (1)

src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.CohostingShared/Navigation/CohostGoToDefinitionEndpoint.cs:80

  • Using response == Response.CallHtml relies on record-struct value equality (and the implicit convention that StopHandling:false + Result:null means HTML fallback). Other cohost endpoints instead check response.Result is null (see CohostGoToImplementationEndpoint.cs:67-77), which is clearer and avoids coupling to the sentinel instance.
        if (response == Response.CallHtml)
        {
            return await GetHtmlDefinitionsAsync(request, razorDocument, cancellationToken).ConfigureAwait(false);
        }

Comment on lines +72 to +75
if (response == Response.NoFurtherHandling)
{
return null;
}
@davidwengier
davidwengier marked this pull request as draft August 11, 2026 22:30
@davidwengier
davidwengier marked this pull request as ready for review August 22, 2026 03:59
Copilot AI review requested due to automatic review settings August 22, 2026 03:59
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 2 pipeline(s).
There may be pipelines that require an authorized user to comment /azp run to run.

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

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.

Comment on lines +94 to +95
// Any other combination represents a malformed response.
throw new InvalidOperationException($"Invalid go-to-definition response: {response}");
@davidwengier

Copy link
Copy Markdown
Member Author

Merged in main now that sonic has landed. @chsienki PTAL

@davidwengier

Copy link
Copy Markdown
Member Author

@chsienki PTAL, I think this one slipped through the cracks

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Razor editor: Peek/Go to Definition fails to load SourceLink symbol sources

3 participants