Skip to content

Commit f111c95

Browse files
authored
Fix LSP references for using alias (#78819)
No bug link, just hit error here when I was investigating something else. It was attempting to create a decompiled location for the definition because it had no `DocumentSpan` ``` 2025-06-04 13:00:56.667 [info] [Error - 1:00:56 PM] [textDocument/references] [LSP] System.InvalidOperationException: Unexpected value 'MyType' of type 'Microsoft.CodeAnalysis.CSharp.Symbols.PublicModel.AliasSymbol' at Microsoft.CodeAnalysis.MetadataAsSource.MetadataAsSourceHelpers.GetTopLevelContainingNamedType(ISymbol symbol) in /_/src/Features/Core/Portable/MetadataAsSource/MetadataAsSourceHelpers.cs:line 51 at Microsoft.CodeAnalysis.MetadataAsSource.DecompilationMetadataAsSourceFileProvider.GetGeneratedFileAsync(MetadataAsSourceWorkspace metadataWorkspace, Workspace sourceWorkspace, Project sourceProject, ISymbol symbol, Boolean signaturesOnly, MetadataAsSourceOptions options, String tempPath, TelemetryMessage telemetryMessage, CancellationToken cancellationToken) in /_/src/Features/Core/Portable/MetadataAsSource/DecompilationMetadataAsSourceFileProvider.cs:line 78 at Microsoft.CodeAnalysis.MetadataAsSource.MetadataAsSourceFileService.GetGeneratedFileAsync(Workspace sourceWorkspace, Project sourceProject, ISymbol symbol, Boolean signaturesOnly, MetadataAsSourceOptions options, CancellationToken cancellationToken) in /_/src/Features/Core/Portable/MetadataAsSource/MetadataAsSourceFileService.cs:line 108 at Microsoft.CodeAnalysis.LanguageServer.Handler.FindUsagesLSPContext.ComputeLocationAsync(Nullable`1 documentSpan, CancellationToken cancellationToken) in /_/src/LanguageServer/Protocol/Handler/References/FindUsagesLSPContext.cs:line 265 ```
2 parents a821574 + e31b7b1 commit f111c95

File tree

2 files changed

+31
-1
lines changed

2 files changed

+31
-1
lines changed

src/LanguageServer/Protocol/Handler/References/FindUsagesLSPContext.cs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -253,14 +253,20 @@ public override async ValueTask OnReferencesFoundAsync(IAsyncEnumerable<SourceRe
253253

254254
// If we have no document span, our location may be in metadata or may be a namespace.
255255
var symbol = await SymbolFinder.FindSymbolAtPositionAsync(_document, _position, cancellationToken).ConfigureAwait(false);
256-
if (symbol == null || symbol.Locations.IsEmpty || symbol.Kind == SymbolKind.Namespace)
256+
if (symbol == null || symbol.Locations.IsEmpty || symbol.Kind is SymbolKind.Namespace)
257257
{
258258
// Either:
259259
// (1) We couldn't find the location in metadata and it's not in any of our known documents.
260260
// (2) The symbol is a namespace (and therefore has no location).
261261
return null;
262262
}
263263

264+
if (symbol is IAliasSymbol aliasSymbol)
265+
{
266+
// If the location symbol is an alias symbol, we need to get the target symbol to find the original location in metadata.
267+
symbol = aliasSymbol.Target;
268+
}
269+
264270
var options = _globalOptions.GetMetadataAsSourceOptions();
265271
var declarationFile = await _metadataAsSourceFileService.GetGeneratedFileAsync(
266272
_workspace, _document.Project, symbol, signaturesOnly: true, options: options, cancellationToken: cancellationToken).ConfigureAwait(false);

src/LanguageServer/ProtocolUnitTests/References/FindAllReferencesHandlerTests.cs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,30 @@ class PREPROCESSING_SYMBOL
300300
AssertHighlightCount(results, expectedDefinitionCount: 0, expectedWrittenReferenceCount: 0, expectedReferenceCount: 3);
301301
}
302302

303+
[Theory, CombinatorialData]
304+
public async Task TestFindReferencesAsync_UsingAlias(bool mutatingLspWorkspace)
305+
{
306+
var markup =
307+
"""
308+
using {|caret:MyType|} = System.{|reference:String|};
309+
310+
class SomeClassToExtract
311+
{
312+
void M()
313+
{
314+
{|reference:MyType|} p;
315+
}
316+
}
317+
""";
318+
await using var testLspServer = await CreateTestLspServerAsync(markup, mutatingLspWorkspace, CapabilitiesWithVSExtensions);
319+
320+
var results = await RunFindAllReferencesAsync(testLspServer, testLspServer.GetLocations("caret").First());
321+
Assert.Equal(3, results.Length);
322+
Assert.True(results[0].Location.DocumentUri.ToString().EndsWith("String.cs"));
323+
324+
AssertLocationsEqual(testLspServer.GetLocations("reference"), results.Skip(1).Select(r => r.Location));
325+
}
326+
303327
private static LSP.ReferenceParams CreateReferenceParams(LSP.Location caret, IProgress<object> progress)
304328
=> new LSP.ReferenceParams()
305329
{

0 commit comments

Comments
 (0)