/
githubmirror
/
roslyn
Обзор
Документация
Войти
/
githubmirror
/
roslyn
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
src/EditorFeatures/Test2/FindReferences/FindReferencesTests.vb
586 строк
32 KB
Jason Malinowski
Switch code that was using Assert.True/False as a replacement for .Fail
21 апр 2026, 23:28
21 апр 2026, 23:28
3bf59ba
Код
Авторство
О чём код?
' Licensed to the .NET Foundation under one or more agreements. ' The .NET Foundation licenses this file to you under the MIT license. ' See the LICENSE file in the project root for more information. Imports System.Collections.Immutable Imports System.Threading Imports Microsoft.CodeAnalysis Imports Microsoft.CodeAnalysis.Classification Imports Microsoft.CodeAnalysis.Collections Imports Microsoft.CodeAnalysis.CSharp.Syntax Imports Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces Imports Microsoft.CodeAnalysis.FindSymbols Imports Microsoft.CodeAnalysis.FindUsages Imports Microsoft.CodeAnalysis.Host Imports Microsoft.CodeAnalysis.PooledObjects Imports Microsoft.CodeAnalysis.Remote.Testing Imports Microsoft.CodeAnalysis.Test.Utilities.FindUsages Imports Microsoft.CodeAnalysis.Text Imports Roslyn.Utilities Imports Xunit.Abstractions Namespace Microsoft.CodeAnalysis.Editor.UnitTests.FindReferences <[UseExportProvider]> Partial Public Class FindReferencesTests Private Shared ReadOnly s_composition As TestComposition = EditorTestCompositions.EditorFeatures.AddParts( GetType(NoCompilationContentTypeDefinitions), GetType(NoCompilationContentTypeLanguageService)) Private Const DefinitionKey As String = "Definition" Private Const ValueUsageInfoKey As String = "ValueUsageInfo." Private Const TypeOrNamespaceUsageInfoKey As String = "TypeOrNamespaceUsageInfo." Private Const AdditionalPropertyKey As String = "AdditionalProperty." Private ReadOnly _outputHelper As ITestOutputHelper Public Sub New(outputHelper As ITestOutputHelper) _outputHelper = outputHelper End Sub Public Enum TestKind API StreamingFeature End Enum Private Async Function TestAPIAndFeature(definition As XElement, kind As TestKind, host As TestHost, Optional searchSingleFileOnly As Boolean = False, Optional uiVisibleOnly As Boolean = False) As Task If kind = TestKind.API Then Await TestAPI(definition, host, searchSingleFileOnly, uiVisibleOnly) Else Assert.Equal(TestKind.StreamingFeature, kind) Await TestStreamingFeature(definition, host, searchSingleFileOnly, uiVisibleOnly) End If End Function Private Shared Async Function TestStreamingFeature(element As XElement, host As TestHost, Optional searchSingleFileOnly As Boolean = False, Optional uiVisibleOnly As Boolean = False) As Task Await TestStreamingFeature(element, searchSingleFileOnly, uiVisibleOnly, host) End Function Private Shared Async Function TestStreamingFeature( element As XElement, searchSingleFileOnly As Boolean, uiVisibleOnly As Boolean, host As TestHost) As Task ' We don't support testing features that only expect partial results. If searchSingleFileOnly OrElse uiVisibleOnly Then Return End If Using workspace = EditorTestWorkspace.Create(element, composition:=s_composition.WithTestHostParts(host)) Assert.True(workspace.Documents.Any(Function(d) d.CursorPosition.HasValue)) For Each cursorDocument In workspace.Documents.Where(Function(d) d.CursorPosition.HasValue) Dim cursorPosition = cursorDocument.CursorPosition.Value Dim startDocument = If(workspace.CurrentSolution.GetDocument(cursorDocument.Id), Await workspace.CurrentSolution.GetSourceGeneratedDocumentAsync(cursorDocument.Id, CancellationToken.None)) Assert.NotNull(startDocument) Dim classificationOptions = workspace.GlobalOptions.GetClassificationOptionsProvider() Dim findRefsService = startDocument.GetLanguageService(Of IFindUsagesService) Dim context = New FindUsagesTestContext() Await findRefsService.FindReferencesAsync(context, startDocument, cursorPosition, classificationOptions, CancellationToken.None) Dim expectedDefinitions = workspace.Documents.Where(Function(d) d.AnnotatedSpans.ContainsKey(DefinitionKey) AndAlso d.AnnotatedSpans(DefinitionKey).Any()). OrderBy(Function(d) d.Name). Select(Function(d) New FileNameAndSpans( d.Name, d.AnnotatedSpans(DefinitionKey).ToList())).ToList() Dim actualDefinitions = GetFileNamesAndSpans( context.Definitions.Where(AddressOf context.ShouldShow). SelectMany(Function(d) d.SourceSpans)) Assert.Equal(expectedDefinitions, actualDefinitions) Dim expectedReferences = workspace.Documents.Where(Function(d) d.SelectedSpans.Any()). OrderBy(Function(d) d.Name). Select(Function(d) New FileNameAndSpans( d.Name, d.SelectedSpans.ToList())).ToList() Dim actualReferences = GetFileNamesAndSpans( context.References.Select(Function(r) r.SourceSpan)) Assert.Equal(expectedReferences, actualReferences) Dim valueUsageInfoKeys = workspace.Documents.SelectMany(Function(d) d.AnnotatedSpans.Keys.Where(Function(key) key.StartsWith(ValueUsageInfoKey))) For Each key In valueUsageInfoKeys Dim expected = workspace.Documents.Where(Function(d) d.AnnotatedSpans.ContainsKey(key) AndAlso d.AnnotatedSpans(key).Any()). OrderBy(Function(d) d.Name). Select(Function(d) New FileNameAndSpans( d.Name, d.AnnotatedSpans(key).ToList())).ToList() Dim valueUsageInfoField = key.Substring(ValueUsageInfoKey.Length) Dim actual = GetFileNamesAndSpans( context.References.SelectAsArray(Function(r) r.SymbolUsageInfo.ValueUsageInfoOpt?.ToString() = valueUsageInfoField, Function(r) r.SourceSpan)) Assert.Equal(expected, actual) Next Dim typeOrNamespaceUsageInfoKeys = workspace.Documents.SelectMany(Function(d) d.AnnotatedSpans.Keys.Where(Function(key) key.StartsWith(TypeOrNamespaceUsageInfoKey))) For Each key In typeOrNamespaceUsageInfoKeys Dim expected = workspace.Documents.Where(Function(d) d.AnnotatedSpans.ContainsKey(key) AndAlso d.AnnotatedSpans(key).Any()). OrderBy(Function(d) d.Name). Select(Function(d) New FileNameAndSpans( d.Name, d.AnnotatedSpans(key).ToList())).ToList() Dim typeOrNamespaceUsageInfoFieldNames = key.Substring(TypeOrNamespaceUsageInfoKey.Length).Split(","c).Select(Function(s) s.Trim) Dim actual = GetFileNamesAndSpans( context.References.Where(Function(r) Return r.SymbolUsageInfo.TypeOrNamespaceUsageInfoOpt IsNot Nothing AndAlso r.SymbolUsageInfo.TypeOrNamespaceUsageInfoOpt.ToString().Split(","c).Select(Function(s) s.Trim).SetEquals(typeOrNamespaceUsageInfoFieldNames) End Function).Select(Function(r) r.SourceSpan)) Assert.Equal(expected, actual) Next Dim additionalPropertiesMap = GetExpectedAdditionalPropertiesMap(workspace) For Each kvp In additionalPropertiesMap Dim propertyName = kvp.Key For Each propertyValue In kvp.Value Dim annotationKey = AdditionalPropertyKey + propertyName + "." + propertyValue Dim expected = workspace.Documents.Where(Function(d) d.AnnotatedSpans.ContainsKey(annotationKey) AndAlso d.AnnotatedSpans(annotationKey).Any()). OrderBy(Function(d) d.Name). Select(Function(d) New FileNameAndSpans( d.Name, d.AnnotatedSpans(annotationKey).ToList())).ToList() Dim actual = GetFileNamesAndSpans( context.References.Where(Function(r) For Each tuple In r.AdditionalProperties If tuple.key = propertyName Then Return tuple.value = propertyValue End If Next Return propertyValue.Length = 0 End Function).Select(Function(r) r.SourceSpan)) Assert.Equal(expected, actual) Next Next Next End Using End Function Private Shared Function GetExpectedAdditionalPropertiesMap(workspace As EditorTestWorkspace) As Dictionary(Of String, HashSet(Of String)) Dim additionalPropertyKeys = workspace.Documents.SelectMany(Function(d) d.AnnotatedSpans.Keys.Where(Function(key) key.StartsWith(AdditionalPropertyKey)).Select(Function(key) key.Substring(AdditionalPropertyKey.Length))) Dim additionalPropertiesMap As New Dictionary(Of String, HashSet(Of String)) For Each key In additionalPropertyKeys Dim index = key.IndexOf(".") Assert.True(index > 0) Dim propertyName = key.Substring(0, index) Dim propertyValue = key.Substring(index + 1) Dim propertyValues As HashSet(Of String) = Nothing If Not additionalPropertiesMap.TryGetValue(propertyName, propertyValues) Then propertyValues = New HashSet(Of String)() additionalPropertiesMap.Add(propertyName, propertyValues) End If propertyValues.Add(propertyValue) Next Return additionalPropertiesMap End Function Private Shared Function GetFileNamesAndSpans(items As IEnumerable(Of DocumentSpan)) As List(Of FileNameAndSpans) Return items.Where(Function(i) i.Document IsNot Nothing). GroupBy(Function(i) i.Document). OrderBy(Function(g) g.Key.Name). Select(Function(g) GetFileNameAndSpans(g)).ToList() End Function Private Shared Function GetFileNameAndSpans(g As IGrouping(Of Document, DocumentSpan)) As FileNameAndSpans Return New FileNameAndSpans( g.Key.Name, g.Select(Function(i) i.SourceSpan).OrderBy(Function(s) s.Start). Distinct().ToList()) End Function Private Structure FileNameAndSpans Public ReadOnly FileName As String Public ReadOnly Spans As List(Of TextSpan) Public Sub New(fileName As String, spans As List(Of TextSpan)) Me.FileName = fileName Me.Spans = spans End Sub Public Overrides Function Equals(obj As Object) As Boolean Return Equals(DirectCast(obj, FileNameAndSpans)) End Function Public Overloads Function Equals(f As FileNameAndSpans) As Boolean Assert.Equal(Me.FileName, f.FileName) Assert.Equal(Me.Spans.Count, f.Spans.Count) For i = 0 To Me.Spans.Count - 1 Assert.Equal(Me.Spans(i), f.Spans(i)) Next Return True End Function End Structure Private Async Function TestAPI( definition As XElement, host As TestHost, Optional searchSingleFileOnly As Boolean = False, Optional uiVisibleOnly As Boolean = False) As Task Await TestAPI(definition, host, searchSingleFileOnly, uiVisibleOnly, New FindReferencesSearchOptions(Explicit:=False)) Await TestAPI(definition, host, searchSingleFileOnly, uiVisibleOnly, New FindReferencesSearchOptions(Explicit:=True)) End Function Private Async Function TestAPI( definition As XElement, host As TestHost, searchSingleFileOnly As Boolean, uiVisibleOnly As Boolean, options As FindReferencesSearchOptions) As Task Using workspace = EditorTestWorkspace.Create(definition, composition:=s_composition.WithTestHostParts(host).AddParts(GetType(WorkspaceTestLogger))) workspace.Services.SolutionServices.SetWorkspaceTestOutput(_outputHelper) For Each cursorDocument In workspace.Documents.Where(Function(d) d.CursorPosition.HasValue) Dim cursorPosition = cursorDocument.CursorPosition.Value Dim document = If(workspace.CurrentSolution.GetDocument(cursorDocument.Id), Await workspace.CurrentSolution.GetSourceGeneratedDocumentAsync(cursorDocument.Id, CancellationToken.None)) Assert.NotNull(document) Dim symbol = Await SymbolFinder.FindSymbolAtPositionAsync(document, cursorPosition) Dim result = ImmutableArray(Of ReferencedSymbol).Empty If symbol IsNot Nothing Then Dim scope = If(searchSingleFileOnly, ImmutableHashSet.Create(Of Document)(document), Nothing) Dim project = document.Project result = result.Concat( Await SymbolFinder.FindReferencesAsync( symbol, project.Solution, progress:=DirectCast(Nothing, IFindReferencesProgress), documents:=scope, options, CancellationToken.None)) End If Dim actualDefinitions = result.FilterToItemsToShow(options). Where(Function(s) Not IsImplicitNamespace(s)). SelectMany(Function(r) r.Definition.GetDefinitionLocationsToShow()). Where(Function(loc) IsInSource(loc, uiVisibleOnly)). GroupBy(Function(loc) loc.SourceTree). ToDictionary( Function(g) GetFilePathAndProjectLabel(document.Project.Solution, g.Key), Function(g) g.Select(Function(loc) loc.SourceSpan).Distinct().ToList()) Dim documentsWithAnnotatedSpans = workspace.Documents.Where(Function(d) d.AnnotatedSpans.Any()) Assert.Equal(Of String)(documentsWithAnnotatedSpans.Select(Function(d) GetFilePathAndProjectLabel(d)).Order(), actualDefinitions.Keys.Order()) For Each doc In documentsWithAnnotatedSpans Dim spans As ImmutableArray(Of TextSpan) = Nothing Dim expected = If(doc.AnnotatedSpans.TryGetValue(DefinitionKey, spans), spans, ImmutableArray(Of TextSpan).Empty).Order() Dim actual = actualDefinitions(GetFilePathAndProjectLabel(doc)).Order() If Not TextSpansMatch(expected, actual) Then Assert.Fail(PrintSpans(expected, actual, workspace.CurrentSolution.GetDocument(doc.Id), "{|Definition:", "|}")) End If Next Dim actualReferences = GetActualReferences(result, uiVisibleOnly, options, document) Dim expectedDocuments = workspace.Documents.Where(Function(d) d.SelectedSpans.Any()) Assert.Equal(expectedDocuments.Select(Function(d) GetFilePathAndProjectLabel(d)).Order(), actualReferences.Keys.Order()) For Each doc In expectedDocuments Dim expectedSpans = doc.SelectedSpans.Order() Dim actualSpans = actualReferences(GetFilePathAndProjectLabel(doc)).Order() Dim expectedDocument = If(workspace.CurrentSolution.GetDocument(doc.Id), Await workspace.CurrentSolution.GetSourceGeneratedDocumentAsync(doc.Id, CancellationToken.None)) AssertEx.Equal(expectedSpans, actualSpans, message:=PrintSpans(expectedSpans, actualSpans, expectedDocument, "[|", "|]", messageOnly:=True)) Next Dim valueUsageInfoKeys = workspace.Documents.SelectMany(Function(d) d.AnnotatedSpans.Keys.Where(Function(key) key.StartsWith(ValueUsageInfoKey))) For Each key In valueUsageInfoKeys For Each doc In documentsWithAnnotatedSpans.Where(Function(d) d.AnnotatedSpans.ContainsKey(key)) Dim expectedSpans = doc.AnnotatedSpans(key).Order() Dim valueUsageInfoField = key.Substring(ValueUsageInfoKey.Length) actualReferences = GetActualReferences(result, uiVisibleOnly, options, document, Function(r) r.SymbolUsageInfo.ValueUsageInfoOpt?.ToString() = valueUsageInfoField) Dim actualSpans = actualReferences(GetFilePathAndProjectLabel(doc)).Order() If Not TextSpansMatch(expectedSpans, actualSpans) Then Assert.Fail(PrintSpans(expectedSpans, actualSpans, workspace.CurrentSolution.GetDocument(doc.Id), $"{{|{key}:", "|}")) End If Next Next Dim typeOrNamespaceUsageInfoKeys = workspace.Documents.SelectMany(Function(d) d.AnnotatedSpans.Keys.Where(Function(key) key.StartsWith(TypeOrNamespaceUsageInfoKey))) For Each key In typeOrNamespaceUsageInfoKeys For Each doc In documentsWithAnnotatedSpans.Where(Function(d) d.AnnotatedSpans.ContainsKey(key)) Dim expectedSpans = doc.AnnotatedSpans(key).Order() Dim typeOrNamespaceUsageInfoFieldNames = key.Substring(TypeOrNamespaceUsageInfoKey.Length).Split(","c).Select(Function(s) s.Trim) actualReferences = GetActualReferences(result, uiVisibleOnly, options, document, Function(r) Return r.SymbolUsageInfo.TypeOrNamespaceUsageInfoOpt IsNot Nothing AndAlso r.SymbolUsageInfo.TypeOrNamespaceUsageInfoOpt.ToString().Split(","c).Select(Function(s) s.Trim).SetEquals(typeOrNamespaceUsageInfoFieldNames) End Function) Dim actualSpans = actualReferences(GetFilePathAndProjectLabel(doc)).Order() If Not TextSpansMatch(expectedSpans, actualSpans) Then Assert.Fail(PrintSpans(expectedSpans, actualSpans, workspace.CurrentSolution.GetDocument(doc.Id), $"{{|{key}:", "|}")) End If Next Next Dim additionalPropertiesMap = GetExpectedAdditionalPropertiesMap(workspace) For Each kvp In additionalPropertiesMap Dim propertyName = kvp.Key For Each propertyValue In kvp.Value Dim annotationKey = AdditionalPropertyKey + propertyName + "." + propertyValue For Each doc In documentsWithAnnotatedSpans.Where(Function(d) d.AnnotatedSpans.ContainsKey(annotationKey)) Dim expectedSpans = doc.AnnotatedSpans(annotationKey).Order() actualReferences = GetActualReferences( result, uiVisibleOnly, options, document, Function(r) For Each tuple In r.AdditionalProperties If tuple.key = propertyName Then Return tuple.value = propertyValue End If Next Return propertyValue.Length = 0 End Function) Dim actualSpans = actualReferences(GetFilePathAndProjectLabel(doc)).Order() If Not TextSpansMatch(expectedSpans, actualSpans) Then Assert.Fail(PrintSpans(expectedSpans, actualSpans, workspace.CurrentSolution.GetDocument(doc.Id), $"{{|{annotationKey}:", "|}")) End If Next Next Next Next End Using End Function Private Shared Function GetActualReferences(result As ImmutableArray(Of ReferencedSymbol), uiVisibleOnly As Boolean, options As FindReferencesSearchOptions, document As Document, Optional locationFilterOpt As Func(Of ReferenceLocation, Boolean) = Nothing) As Dictionary(Of String, List(Of TextSpan)) Dim referenceLocations = result.FilterToItemsToShow(options).SelectMany(Function(r) r.Locations) If locationFilterOpt IsNot Nothing Then referenceLocations = referenceLocations.Where(locationFilterOpt) End If Return referenceLocations. Select(Function(loc) loc.Location). Where(Function(loc) IsInSource(loc, uiVisibleOnly)). Distinct(). GroupBy(Function(loc) loc.SourceTree). ToDictionary( Function(g) GetFilePathAndProjectLabel(document.Project.Solution, g.Key), Function(g) g.Select(Function(loc) loc.SourceSpan).Distinct().ToList()) End Function Private Shared Function PrintSpans(expected As IOrderedEnumerable(Of TextSpan), actual As IOrderedEnumerable(Of TextSpan), doc As Document, prefix As String, suffix As String, Optional messageOnly As Boolean = False) As String Debug.Assert(expected IsNot Nothing) Debug.Assert(actual IsNot Nothing) Dim instance = PooledStringBuilder.GetInstance() Dim builder = instance.Builder builder.AppendLine() If Not messageOnly Then builder.AppendLine($"Expected: {String.Join(", ", expected.Select(Function(e) e.ToString()))}") builder.AppendLine($"Actual: {String.Join(", ", actual.Select(Function(a) a.ToString()))}") End If Dim text As SourceText = Nothing doc.TryGetText(text) Dim position = 0 For Each span In actual builder.Append(text.GetSubText(New TextSpan(position, span.Start - position))) builder.Append(prefix) builder.Append(text.GetSubText(span)) builder.Append(suffix) position = span.End Next builder.Append(text.GetSubText(New TextSpan(position, text.Length - position))) Return instance.ToStringAndFree() End Function Private Shared Function TextSpansMatch(expected As IOrderedEnumerable(Of TextSpan), actual As IOrderedEnumerable(Of TextSpan)) As Boolean Debug.Assert(expected IsNot Nothing) Debug.Assert(actual IsNot Nothing) Dim enumeratorExpected As IEnumerator(Of TextSpan) = Nothing Dim enumeratorActual As IEnumerator(Of TextSpan) = Nothing Try enumeratorExpected = expected.GetEnumerator() enumeratorActual = actual.GetEnumerator() While True Dim hasNextExpected = enumeratorExpected.MoveNext() Dim hasNextActual = enumeratorActual.MoveNext() If Not hasNextExpected OrElse Not hasNextActual Then Return hasNextExpected = hasNextActual End If If Not enumeratorExpected.Current.Equals(enumeratorActual.Current) Then Return False End If End While Finally Dim asDisposable = TryCast(enumeratorExpected, IDisposable) If asDisposable IsNot Nothing Then asDisposable.Dispose() End If asDisposable = TryCast(enumeratorActual, IDisposable) If asDisposable IsNot Nothing Then asDisposable.Dispose() End If End Try Return True End Function Private Shared Function IsImplicitNamespace(referencedSymbol As ReferencedSymbol) As Boolean Return referencedSymbol.Definition.IsImplicitlyDeclared AndAlso referencedSymbol.Definition.Kind = SymbolKind.Namespace End Function Private Shared Function IsInSource(loc As Location, uiVisibleOnly As Boolean) As Boolean If uiVisibleOnly Then Return loc.IsInSource AndAlso Not loc.SourceTree.IsHiddenPosition(loc.SourceSpan.Start) Else Return loc.IsInSource End If End Function Private Shared Function GetFilePathAndProjectLabel(solution As Solution, syntaxTree As SyntaxTree) As String Dim document = solution.GetDocument(syntaxTree) Return GetFilePathAndProjectLabel(document) End Function Private Shared Function GetFilePathAndProjectLabel(document As Document) As String Return $"{document.Project.Name}: {document.FilePath}" End Function Private Shared Function GetFilePathAndProjectLabel(hostDocument As TestHostDocument) As String Return $"{hostDocument.Project.Name}: {hostDocument.FilePath}" End Function <Fact> Public Async Function LinkedFilesWhereContentHasChangedInOneLink() As Task Using workspace = EditorTestWorkspace.Create(" <Workspace> <Project Language='C#' CommonReferences='true' AssemblyName='LinkedProj1' Name='CSProj.1'> <Document FilePath='C.cs'> partial class C { int i; public int P { get { return i; } } public C() { this.i = 0; } } </Document> </Project> <Project Language='C#' CommonReferences='true' AssemblyName='LinkedProj2' Name='CSProj.2'> <Document IsLinkFile='true' LinkProjectName='CSProj.1' LinkFilePath='C.cs'/> </Project> </Workspace>") Dim solution = workspace.CurrentSolution Dim document1 = solution.Projects.Single(Function(p) p.Name = "CSProj.1").Documents.Single() Dim text1 = Await document1.GetTextAsync() Dim linkedDocuments = document1.GetLinkedDocumentIds() Assert.Equal(1, linkedDocuments.Length) Dim document2 = solution.GetDocument(linkedDocuments.Single()) Assert.NotSame(document1, document2) ' ensure we normally have two linked symbols when the files are the same. Await LinkedFileTestHelper(solution, expectedLinkedSymbolCount:=2) ' now change the linked file and run again. solution = solution.WithDocumentText(document2.Id, SourceText.From("")) Await LinkedFileTestHelper(solution, expectedLinkedSymbolCount:=1) ' changing the contents back to the original should return us to two symbols solution = solution.WithDocumentText(document2.Id, text1) Await LinkedFileTestHelper(solution, expectedLinkedSymbolCount:=2) ' changing `int i` to `int j` should give us 1 symbol. the text lengths are the same, but the symbols ' have changed. solution = solution.WithDocumentText(document2.Id, SourceText.From(text1.ToString().Replace("int i", "int j"))) Await LinkedFileTestHelper(solution, expectedLinkedSymbolCount:=1) End Using End Function Private Shared Async Function LinkedFileTestHelper(solution As Solution, expectedLinkedSymbolCount As Integer) As Task Dim document1 = solution.Projects.Single(Function(p) p.Name = "CSProj.1").Documents.Single() Dim linkedDocuments = document1.GetLinkedDocumentIds() Assert.Equal(1, linkedDocuments.Length) Dim document2 = solution.GetDocument(linkedDocuments.Single()) Assert.NotSame(document1, document2) Dim semanticModel1 = Await document1.GetSemanticModelAsync() Dim root1 = Await semanticModel1.SyntaxTree.GetRootAsync() Dim declarator1 = root1.DescendantNodes().OfType(Of VariableDeclaratorSyntax).First() Dim symbol1 = semanticModel1.GetDeclaredSymbol(declarator1) Assert.NotNull(symbol1) Dim linkedSymbols = Await SymbolFinder.FindLinkedSymbolsAsync(symbol1, solution, cancellationToken:=Nothing) Assert.Equal(expectedLinkedSymbolCount, linkedSymbols.Length) End Function <Fact, WorkItem("https://devdiv.visualstudio.com/DevDiv/_workitems/edit/1758726")> Public Async Function TestFindReferencesInDocumentsNoCompilation() As Task Using workspace = EditorTestWorkspace.Create(" <Workspace> <Project Language=""NoCompilation"" AssemblyName=""NoCompilationAssembly"" CommonReferencesPortable=""true""> <Document> var x = {}; // e.g., TypeScript code or anything else that doesn't support compilations </Document> </Project> <Project Language=""C#"" AssemblyName=""CSharpAssembly"" CommonReferencesPortable=""true""> <Document> class C { } </Document> </Project> </Workspace> ", composition:=s_composition) Dim solution = workspace.CurrentSolution Dim csProject = solution.Projects.Single(Function(p) p.SupportsCompilation) Dim compilation = Await csProject.GetCompilationAsync() Dim symbol = compilation.GetTypeByMetadataName("C") Dim progress = New StreamingFindReferencesProgressAdapter(NoOpFindReferencesProgress.Instance) Await SymbolFinder.FindReferencesInDocumentsInCurrentProcessAsync( symbol, solution, progress, solution.Projects.SelectMany(Function(p) p.Documents).ToImmutableHashSet(), FindReferencesSearchOptions.Default, cancellationToken:=Nothing) End Using End Function End Class End Namespace