提交 041bd3ae 编写于 作者: S Sam Harwell

Avoid dropping compilations that can be reused

上级 a5a7760e
......@@ -484,6 +484,7 @@ public async Task TestGetCompilationOnCrossLanguageDependentProjectChanged()
var solutionZ = workspace.CurrentSolution;
var docZ = solutionZ.GetDocument(document1.Id);
var docZText = await docZ.GetTextAsync();
Assert.Equal("public class X { }", docZText.ToString());
var compilation2Z = await solutionZ.GetProject(id2).GetCompilationAsync();
var classDz = compilation2Z.SourceModule.GlobalNamespace.GetTypeMembers("D").Single();
......
......@@ -5,6 +5,7 @@
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Threading;
......@@ -652,6 +653,21 @@ private ImmutableHashSet<ProjectId> GetProjectsThatDirectlyDependOnThisProject_N
.ToImmutableDictionary();
}
/// <summary>
/// Gets the list of projects that directly or transitively this project depends on, if it has already been
/// cached.
/// </summary>
internal ImmutableHashSet<ProjectId>? TryGetProjectsThatThisProjectTransitivelyDependsOn(ProjectId projectId)
{
if (projectId is null)
{
throw new ArgumentNullException(nameof(projectId));
}
_transitiveReferencesMap.TryGetValue(projectId, out var projects);
return projects;
}
/// <summary>
/// Gets the list of projects that directly or transitively this project depends on
/// </summary>
......
......@@ -1812,20 +1812,32 @@ public ImmutableArray<DocumentId> GetDocumentIdsWithFilePath(string? filePath)
private ImmutableDictionary<ProjectId, CompilationTracker> CreateCompilationTrackerMap(ProjectId projectId, ProjectDependencyGraph dependencyGraph)
{
var builder = ImmutableDictionary.CreateBuilder<ProjectId, CompilationTracker>();
var dependencies = dependencyGraph.TryGetProjectsThatTransitivelyDependOnThisProject(projectId);
IEnumerable<ProjectId>? dependencies = null;
foreach (var projectIdAndTracker in _projectIdToTrackerMap)
foreach (var (id, tracker) in _projectIdToTrackerMap)
{
var id = projectIdAndTracker.Key;
var tracker = projectIdAndTracker.Value;
if (!tracker.HasCompilation)
{
continue;
}
var canReuse = id == projectId || (dependencies is object && !dependencies.Contains(id));
builder.Add(id, canReuse ? tracker : tracker.Fork(tracker.ProjectState));
builder.Add(id, CanReuse() ? tracker : tracker.Fork(tracker.ProjectState));
// Returns true if 'tracker' can be reused for project 'id'
bool CanReuse()
{
if (id == projectId)
return true;
var forwardDependencies = dependencyGraph.TryGetProjectsThatThisProjectTransitivelyDependsOn(id);
if (forwardDependencies is object && !forwardDependencies.Contains(projectId))
{
return true;
}
dependencies ??= dependencyGraph.GetProjectsThatTransitivelyDependOnThisProject(projectId);
return !dependencies.Contains(id);
}
}
return builder.ToImmutable();
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册