Skip to content

Commit

Permalink
Merge pull request #64760 from CyrusNajmabadi/symbolTreeInfoAnalyzer
Browse files Browse the repository at this point in the history
Move the SymbolTree index cache off of the incremental-analyzer subsystem
  • Loading branch information
CyrusNajmabadi committed Oct 17, 2022
2 parents 048f695 + 58833a4 commit 47a2b15
Show file tree
Hide file tree
Showing 16 changed files with 246 additions and 340 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -60,14 +60,16 @@ Namespace Microsoft.CodeAnalysis.Editor.UnitTests.Diagnostics
Optional verifyTokens As Boolean = True,
Optional fileNameToExpected As Dictionary(Of String, String) = Nothing,
Optional verifySolutions As Func(Of Solution, Solution, Task) = Nothing,
Optional onAfterWorkspaceCreated As Action(Of TestWorkspace) = Nothing,
Optional onAfterWorkspaceCreated As Func(Of TestWorkspace, Task) = Nothing,
Optional glyphTags As ImmutableArray(Of String) = Nothing) As Task
Using workspace = TestWorkspace.CreateWorkspace(definition, composition:=s_compositionWithMockDiagnosticUpdateSourceRegistrationService)
If _outputHelper IsNot Nothing Then
workspace.Services.SolutionServices.SetWorkspaceTestOutput(_outputHelper)
End If

onAfterWorkspaceCreated?.Invoke(workspace)
If onAfterWorkspaceCreated IsNot Nothing Then
Await onAfterWorkspaceCreated(workspace)
End If

Dim diagnosticAndFix = Await GetDiagnosticAndFixAsync(workspace)
Dim codeActions As IList(Of CodeAction) = diagnosticAndFix.Item2.Fixes.Select(Function(f) f.Action).ToList()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,7 @@ namespace CSAssembly2

Await TestAsync(
input, expected, codeActionIndex:=0, addedReference:="CSAssembly1",
glyphTags:=WellKnownTagArrays.CSharpProject, onAfterWorkspaceCreated:=AddressOf WaitForSolutionCrawler)
glyphTags:=WellKnownTagArrays.CSharpProject, onAfterWorkspaceCreated:=AddressOf WaitForSymbolTreeInfoCache)
End Function

<Fact, WorkItem(12169, "https://github.com/dotnet/roslyn/issues/12169")>
Expand Down Expand Up @@ -353,7 +353,7 @@ namespace CSAssembly2

Await TestAsync(
input, expected, codeActionIndex:=0, addedReference:="CSAssembly1",
glyphTags:=WellKnownTagArrays.CSharpProject, onAfterWorkspaceCreated:=AddressOf WaitForSolutionCrawler)
glyphTags:=WellKnownTagArrays.CSharpProject, onAfterWorkspaceCreated:=AddressOf WaitForSymbolTreeInfoCache)
End Function

<WpfFact>
Expand Down Expand Up @@ -401,12 +401,11 @@ namespace CSAssembly2
Await TestAsync(input, expected, codeActionIndex:=0, addedReference:="NewName",
glyphTags:=WellKnownTagArrays.CSharpProject,
onAfterWorkspaceCreated:=
Sub(workspace As TestWorkspace)
WaitForSolutionCrawler(workspace)
Async Function(workspace As TestWorkspace)
Dim project = workspace.CurrentSolution.Projects.Single(Function(p) p.AssemblyName = "CSAssembly1")
workspace.OnProjectNameChanged(project.Id, "NewName", "NewFilePath")
WaitForSolutionCrawler(workspace)
End Sub)
Await WaitForSymbolTreeInfoCache(workspace)
End Function)
End Function

<WpfFact>
Expand Down Expand Up @@ -446,17 +445,16 @@ End Namespace

Await TestAsync(
input, expected, codeActionIndex:=0, addedReference:="VBAssembly1",
glyphTags:=WellKnownTagArrays.VisualBasicProject, onAfterWorkspaceCreated:=AddressOf WaitForSolutionCrawler)
glyphTags:=WellKnownTagArrays.VisualBasicProject, onAfterWorkspaceCreated:=AddressOf WaitForSymbolTreeInfoCache)
End Function

Private Sub WaitForSolutionCrawler(workspace As TestWorkspace)
Dim solutionCrawler = DirectCast(workspace.Services.GetService(Of ISolutionCrawlerRegistrationService), SolutionCrawlerRegistrationService)
solutionCrawler.Register(workspace)
Dim provider = DirectCast(workspace.ExportProvider.GetExports(Of IIncrementalAnalyzerProvider).First(
Function(f) TypeOf f.Value Is SymbolTreeInfoIncrementalAnalyzerProvider).Value, SymbolTreeInfoIncrementalAnalyzerProvider)
Dim analyzer = provider.CreateIncrementalAnalyzer(workspace)
solutionCrawler.GetTestAccessor().WaitUntilCompletion(workspace, ImmutableArray.Create(analyzer))
End Sub
Private Async Function WaitForSymbolTreeInfoCache(workspace As TestWorkspace) As Task
Dim service = DirectCast(
workspace.Services.GetRequiredService(Of ISymbolTreeInfoCacheService),
SymbolTreeInfoCacheServiceFactory.SymbolTreeInfoCacheService)

Await service.GetTestAccessor().AnalyzeSolutionAsync()
End Function

<Fact, WorkItem(8036, "https://github.com/dotnet/Roslyn/issues/8036")>
Public Async Function TestAddProjectReference_CSharpToVB_ExtensionMethod() As Task
Expand Down Expand Up @@ -525,7 +523,7 @@ namespace A
</Workspace>

Await TestAsync(input, addedReference:="CSAssembly2", glyphTags:=WellKnownTagArrays.CSharpProject,
onAfterWorkspaceCreated:=AddressOf WaitForSolutionCrawler)
onAfterWorkspaceCreated:=AddressOf WaitForSymbolTreeInfoCache)
End Function

<Fact>
Expand Down Expand Up @@ -565,7 +563,7 @@ namespace CSAssembly2
Optional expected As String = Nothing,
Optional codeActionIndex As Integer = 0,
Optional addedReference As String = Nothing,
Optional onAfterWorkspaceCreated As Action(Of TestWorkspace) = Nothing,
Optional onAfterWorkspaceCreated As Func(Of TestWorkspace, Task) = Nothing,
Optional glyphTags As ImmutableArray(Of String) = Nothing) As Task
Dim verifySolutions As Func(Of Solution, Solution, Task) = Nothing
Dim workspace As TestWorkspace = Nothing
Expand Down Expand Up @@ -594,10 +592,12 @@ namespace CSAssembly2
Await TestAsync(definition, expected, codeActionIndex,
verifySolutions:=verifySolutions,
glyphTags:=glyphTags,
onAfterWorkspaceCreated:=Sub(ws As TestWorkspace)
onAfterWorkspaceCreated:=Async Function(ws As TestWorkspace)
workspace = ws
onAfterWorkspaceCreated?.Invoke(ws)
End Sub)
If onAfterWorkspaceCreated IsNot Nothing Then
Await onAfterWorkspaceCreated(ws)
End If
End Function)
End Function
End Class
End Namespace
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,7 @@ private async Task FindResultsInUnreferencedMetadataSymbolsAsync(
using var nestedTokenSource = new CancellationTokenSource();
using var linkedTokenSource = CancellationTokenSource.CreateLinkedTokenSource(nestedTokenSource.Token, cancellationToken);

foreach (var (referenceProjectId, reference) in newReferences)
foreach (var (referenceProject, reference) in newReferences)
{
var compilation = referenceToCompilation.GetOrAdd(
reference, r => CreateCompilation(project, r));
Expand All @@ -272,7 +272,7 @@ private async Task FindResultsInUnreferencedMetadataSymbolsAsync(
if (compilation.GetAssemblyOrModuleSymbol(reference) is IAssemblySymbol assembly)
{
findTasks.Add(finder.FindInMetadataSymbolsAsync(
assembly, referenceProjectId, reference, exact, linkedTokenSource.Token));
assembly, referenceProject, reference, exact, linkedTokenSource.Token));
}
}

Expand All @@ -284,10 +284,10 @@ private async Task FindResultsInUnreferencedMetadataSymbolsAsync(
/// by this project. The set returned will be tuples containing the PEReference, and the project-id
/// for the project we found the pe-reference in.
/// </summary>
private static ImmutableArray<(ProjectId, PortableExecutableReference)> GetUnreferencedMetadataReferences(
private static ImmutableArray<(Project, PortableExecutableReference)> GetUnreferencedMetadataReferences(
Project project, HashSet<PortableExecutableReference> seenReferences)
{
var result = ArrayBuilder<(ProjectId, PortableExecutableReference)>.GetInstance();
var result = ArrayBuilder<(Project, PortableExecutableReference)>.GetInstance();

var solution = project.Solution;
foreach (var p in solution.Projects)
Expand All @@ -303,7 +303,7 @@ private async Task FindResultsInUnreferencedMetadataSymbolsAsync(
!IsInPackagesDirectory(peReference) &&
seenReferences.Add(peReference))
{
result.Add((p.Id, peReference));
result.Add((p, peReference));
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,31 +9,29 @@
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.FindSymbols;
using Microsoft.CodeAnalysis.FindSymbols.SymbolTree;
using Microsoft.CodeAnalysis.Shared.Extensions;

namespace Microsoft.CodeAnalysis.AddImport
{
internal abstract partial class AbstractAddImportFeatureService<TSimpleNameSyntax>
{
private class MetadataSymbolsSearchScope : SearchScope
{
private readonly Solution _solution;
private readonly Project _assemblyProject;
private readonly IAssemblySymbol _assembly;
private readonly ProjectId _assemblyProjectId;
private readonly PortableExecutableReference _metadataReference;

public MetadataSymbolsSearchScope(
AbstractAddImportFeatureService<TSimpleNameSyntax> provider,
Solution solution,
Project assemblyProject,
IAssemblySymbol assembly,
ProjectId assemblyProjectId,
PortableExecutableReference metadataReference,
bool exact,
CancellationToken cancellationToken)
: base(provider, exact, cancellationToken)
{
_solution = solution;
_assemblyProject = assemblyProject;
_assembly = assembly;
_assemblyProjectId = assemblyProjectId;
_metadataReference = metadataReference;
}

Expand All @@ -42,15 +40,15 @@ public override SymbolReference CreateReference<T>(SymbolResult<T> searchResult)
return new MetadataSymbolReference(
provider,
searchResult.WithSymbol<INamespaceOrTypeSymbol>(searchResult.Symbol),
_assemblyProjectId,
_assemblyProject.Id,
_metadataReference);
}

protected override async Task<ImmutableArray<ISymbol>> FindDeclarationsAsync(
SymbolFilter filter, SearchQuery searchQuery)
{
var service = _solution.Services.GetService<SymbolTreeInfoCacheService>();
var info = await service.TryGetPotentiallyStaleMetadataSymbolTreeInfoAsync(_solution, _metadataReference, CancellationToken).ConfigureAwait(false);
var service = _assemblyProject.Solution.Services.GetService<ISymbolTreeInfoCacheService>();
var info = await service.TryGetPotentiallyStaleMetadataSymbolTreeInfoAsync(_assemblyProject, _metadataReference, CancellationToken).ConfigureAwait(false);
if (info == null)
return ImmutableArray<ISymbol>.Empty;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public SourceSymbolsProjectSearchScope(
protected override async Task<ImmutableArray<ISymbol>> FindDeclarationsAsync(
SymbolFilter filter, SearchQuery searchQuery)
{
var service = _project.Solution.Services.GetService<SymbolTreeInfoCacheService>();
var service = _project.Solution.Services.GetService<ISymbolTreeInfoCacheService>();
var info = await service.TryGetPotentiallyStaleSourceSymbolTreeInfoAsync(_project, CancellationToken).ConfigureAwait(false);
if (info == null)
{
Expand Down
5 changes: 2 additions & 3 deletions src/Features/Core/Portable/AddImport/SymbolReferenceFinder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -105,12 +105,11 @@ internal Task<ImmutableArray<SymbolReference>> FindInSourceSymbolsInProjectAsync
}

internal Task<ImmutableArray<SymbolReference>> FindInMetadataSymbolsAsync(
IAssemblySymbol assembly, ProjectId assemblyProjectId, PortableExecutableReference metadataReference,
IAssemblySymbol assembly, Project assemblyProject, PortableExecutableReference metadataReference,
bool exact, CancellationToken cancellationToken)
{
var searchScope = new MetadataSymbolsSearchScope(
_owner, _document.Project.Solution, assembly, assemblyProjectId,
metadataReference, exact, cancellationToken);
_owner, assemblyProject, assembly, metadataReference, exact, cancellationToken);
return DoAsync(searchScope);
}

Expand Down

This file was deleted.

This file was deleted.

Loading

0 comments on commit 47a2b15

Please sign in to comment.