Fix/enable navigating to SourceLink from Razor - #84834
Merged
Merged
Conversation
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
|
Azure Pipelines: Successfully started running 2 pipeline(s). There may be pipelines that require an authorized user to comment /azp run to run. |
Contributor
There was a problem hiding this comment.
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.CallHtmlrelies on record-struct value equality (and the implicit convention thatStopHandling:false+Result:nullmeans HTML fallback). Other cohost endpoints instead checkresponse.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
marked this pull request as draft
August 11, 2026 22:30
davidwengier
marked this pull request as ready for review
August 22, 2026 03:59
|
Azure Pipelines: Successfully started running 2 pipeline(s). There may be pipelines that require an authorized user to comment /azp run to run. |
Comment on lines
+94
to
+95
| // Any other combination represents a malformed response. | ||
| throw new InvalidOperationException($"Invalid go-to-definition response: {response}"); |
Member
Author
|
Merged in main now that sonic has landed. @chsienki PTAL |
Member
Author
|
@chsienki PTAL, I think this one slipped through the cracks |
chsienki
approved these changes
Aug 27, 2026
This was referenced Aug 28, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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