diff --git a/src/EditorFeatures/Test/SolutionCrawler/WorkCoordinatorTests.cs b/src/EditorFeatures/Test/SolutionCrawler/WorkCoordinatorTests.cs index 2bb8424b5110d..955e649141d88 100644 --- a/src/EditorFeatures/Test/SolutionCrawler/WorkCoordinatorTests.cs +++ b/src/EditorFeatures/Test/SolutionCrawler/WorkCoordinatorTests.cs @@ -335,6 +335,8 @@ internal async Task Project_AnalyzerOptions_Change(BackgroundAnalysisScope analy Assert.Equal(expectedDocumentEvents, worker.SyntaxDocumentIds.Count); Assert.Equal(expectedDocumentEvents, worker.DocumentIds.Count); + + Assert.Equal(1, worker.NonSourceDocumentIds.Count); } [InlineData(BackgroundAnalysisScope.ActiveFile, false)] @@ -701,22 +703,26 @@ internal async Task Document_AdditionalFileChange(BackgroundAnalysisScope analys var expectedDocumentSyntaxEvents = 5; var expectedDocumentSemanticEvents = 5; + var expectedNonSourceDocumentEvents = 1; var ncfile = DocumentInfo.Create(DocumentId.CreateNewId(project.Id), "D6"); var worker = await ExecuteOperation(workspace, w => w.OnAdditionalDocumentAdded(ncfile)); Assert.Equal(expectedDocumentSyntaxEvents, worker.SyntaxDocumentIds.Count); Assert.Equal(expectedDocumentSemanticEvents, worker.DocumentIds.Count); + Assert.Equal(expectedNonSourceDocumentEvents, worker.NonSourceDocumentIds.Count); worker = await ExecuteOperation(workspace, w => w.ChangeAdditionalDocument(ncfile.Id, SourceText.From("//"))); Assert.Equal(expectedDocumentSyntaxEvents, worker.SyntaxDocumentIds.Count); Assert.Equal(expectedDocumentSemanticEvents, worker.DocumentIds.Count); + Assert.Equal(expectedNonSourceDocumentEvents, worker.NonSourceDocumentIds.Count); worker = await ExecuteOperation(workspace, w => w.OnAdditionalDocumentRemoved(ncfile.Id)); Assert.Equal(expectedDocumentSyntaxEvents, worker.SyntaxDocumentIds.Count); Assert.Equal(expectedDocumentSemanticEvents, worker.DocumentIds.Count); + Assert.Empty(worker.NonSourceDocumentIds); } [InlineData(BackgroundAnalysisScope.ActiveFile, false)] @@ -1619,7 +1625,7 @@ internal static class Metadata public static readonly IncrementalAnalyzerProviderMetadata Crawler = new IncrementalAnalyzerProviderMetadata(new Dictionary { { "WorkspaceKinds", new[] { SolutionCrawlerWorkspaceKind } }, { "HighPriorityForActiveFile", false }, { "Name", "TestAnalyzer" } }); } - private class Analyzer : IIncrementalAnalyzer + private class Analyzer : IIncrementalAnalyzer2 { public static readonly Option TestOption = new Option("TestOptions", "TestOption", defaultValue: true); @@ -1628,6 +1634,7 @@ private class Analyzer : IIncrementalAnalyzer public readonly HashSet SyntaxDocumentIds = new HashSet(); public readonly HashSet DocumentIds = new HashSet(); + public readonly HashSet NonSourceDocumentIds = new HashSet(); public readonly HashSet ProjectIds = new HashSet(); public readonly HashSet InvalidateDocumentIds = new HashSet(); @@ -1653,6 +1660,7 @@ public void Reset() SyntaxDocumentIds.Clear(); DocumentIds.Clear(); + NonSourceDocumentIds.Clear(); ProjectIds.Clear(); InvalidateDocumentIds.Clear(); @@ -1682,6 +1690,12 @@ public Task AnalyzeSyntaxAsync(Document document, InvocationReasons reasons, Can return Task.CompletedTask; } + public Task AnalyzeNonSourceDocumentAsync(TextDocument textDocument, InvocationReasons reasons, CancellationToken cancellationToken) + { + this.NonSourceDocumentIds.Add(textDocument.Id); + return Task.CompletedTask; + } + public Task RemoveDocumentAsync(DocumentId documentId, CancellationToken cancellationToken) { InvalidateDocumentIds.Add(documentId); @@ -1732,6 +1746,15 @@ public Task DocumentCloseAsync(Document document, CancellationToken cancellation public Task DocumentResetAsync(Document document, CancellationToken cancellationToken) => Task.CompletedTask; + + public Task NonSourceDocumentOpenAsync(TextDocument textDocument, CancellationToken cancellationToken) + => Task.CompletedTask; + + public Task NonSourceDocumentCloseAsync(TextDocument textDocument, CancellationToken cancellationToken) + => Task.CompletedTask; + + public Task NonSourceDocumentResetAsync(TextDocument textDocument, CancellationToken cancellationToken) + => Task.CompletedTask; #endregion } diff --git a/src/Features/Core/Portable/SolutionCrawler/WorkCoordinator.cs b/src/Features/Core/Portable/SolutionCrawler/WorkCoordinator.cs index 0a3a83b8c8615..5be133bc20d64 100644 --- a/src/Features/Core/Portable/SolutionCrawler/WorkCoordinator.cs +++ b/src/Features/Core/Portable/SolutionCrawler/WorkCoordinator.cs @@ -439,7 +439,8 @@ private async Task EnqueueWorkItemAsync(Project project, DocumentId documentId, _shutdownToken.ThrowIfCancellationRequested(); var priorityService = project.GetLanguageService(); - var isLowPriority = priorityService != null && await priorityService.IsLowPriorityAsync(GetRequiredDocument(project, documentId, document), _shutdownToken).ConfigureAwait(false); + document ??= project.GetDocument(documentId); + var isLowPriority = priorityService != null && document != null && await priorityService.IsLowPriorityAsync(document, _shutdownToken).ConfigureAwait(false); var currentMember = GetSyntaxPath(changedMember); @@ -475,6 +476,12 @@ private async Task EnqueueWorkItemAsync(Project project, InvocationReasons invoc { foreach (var documentId in project.DocumentIds) await EnqueueWorkItemAsync(project, documentId, document: null, invocationReasons).ConfigureAwait(false); + + foreach (var documentId in project.AdditionalDocumentIds) + await EnqueueWorkItemAsync(project, documentId, document: null, invocationReasons).ConfigureAwait(false); + + foreach (var documentId in project.AnalyzerConfigDocumentIds) + await EnqueueWorkItemAsync(project, documentId, document: null, invocationReasons).ConfigureAwait(false); } private async Task EnqueueWorkItemAsync(IIncrementalAnalyzer analyzer, ReanalyzeScope scope, bool highPriority)