Skip to content

Commit

Permalink
Fix active file analysis in BackgroundCompiler
Browse files Browse the repository at this point in the history
  • Loading branch information
sharwell committed Apr 21, 2021
1 parent a1ad041 commit 56203e6
Showing 1 changed file with 24 additions and 6 deletions.
30 changes: 24 additions & 6 deletions src/Features/Core/Portable/Workspace/BackgroundCompiler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ namespace Microsoft.CodeAnalysis.Host
internal sealed class BackgroundCompiler : IDisposable
{
private Workspace _workspace;
private readonly IDocumentTrackingService _documentTrackingService;
private readonly TaskQueue _taskQueue;

#pragma warning disable IDE0052 // Remove unread private members
Expand All @@ -31,6 +32,7 @@ internal sealed class BackgroundCompiler : IDisposable
public BackgroundCompiler(Workspace workspace)
{
_workspace = workspace;
_documentTrackingService = _workspace.Services.GetRequiredService<IDocumentTrackingService>();

// make a scheduler that runs on the thread pool
var listenerProvider = workspace.Services.GetRequiredService<IWorkspaceAsynchronousOperationListenerProvider>();
Expand Down Expand Up @@ -101,12 +103,13 @@ private void Rebuild(Solution solution, ProjectId initialProject = null)
// build the current compilations without rebuilding the entire DeclarationTable
CancelBuild(releasePreviousCompilations: false);

var allProjects = _workspace.GetOpenDocumentIds().Select(d => d.ProjectId).ToSet();
var allOpenProjects = _workspace.GetOpenDocumentIds().Select(d => d.ProjectId).ToSet();
var activeProject = _documentTrackingService.TryGetActiveDocument()?.ProjectId;

// don't even get started if there is nothing to do
if (allProjects.Count > 0)
if (allOpenProjects.Count > 0)
{
_ = BuildCompilationsAsync(solution, initialProject, allProjects);
_ = BuildCompilationsAsync(solution, initialProject, allOpenProjects, activeProject);
}
}
}
Expand All @@ -127,19 +130,21 @@ private void CancelBuild(bool releasePreviousCompilations)
private Task BuildCompilationsAsync(
Solution solution,
ProjectId initialProject,
ISet<ProjectId> allProjects)
ISet<ProjectId> allOpenProjects,
ProjectId activeProject)
{
var cancellationToken = _cancellationSource.Token;
return _taskQueue.ScheduleTask(
"BackgroundCompiler.BuildCompilationsAsync",
() => BuildCompilationsAsync(solution, initialProject, allProjects, cancellationToken),
() => BuildCompilationsAsync(solution, initialProject, allOpenProjects, activeProject, cancellationToken),
cancellationToken);
}

private Task BuildCompilationsAsync(
Solution solution,
ProjectId initialProject,
ISet<ProjectId> projectsToBuild,
ProjectId activeProject,
CancellationToken cancellationToken)
{
var allProjectIds = new List<ProjectId>();
Expand All @@ -156,7 +161,20 @@ private Task BuildCompilationsAsync(
// set the background analysis scope to only analyze active files.
var compilationTasks = allProjectIds
.Select(solution.GetProject)
.Where(p => p != null && SolutionCrawlerOptions.GetBackgroundAnalysisScope(p) != BackgroundAnalysisScope.ActiveFile)
.Where(p =>
{
if (p is null)
return false;
if (SolutionCrawlerOptions.GetBackgroundAnalysisScope(p) == BackgroundAnalysisScope.ActiveFile)
{
// For open files with Active File analysis scope, only build the compilation if the project is
// active.
return p.Id == activeProject;
}
return true;
})
.Select(p => p.GetCompilationAsync(cancellationToken))
.ToArray();
return Task.WhenAll(compilationTasks).SafeContinueWith(t =>
Expand Down

0 comments on commit 56203e6

Please sign in to comment.