提交 e75e49eb 编写于 作者: J Jason Malinowski

Handle dangling project references

We support dangling project references in the workspace API,
and the ProjectDependencyGraph is only supposed to return references
that exist within the project. Therefore, if we add a project, we have
to check to make sure we didn't have a dangling reference becoming a
real reference, and give inconsistent results.

I expect this to be a rare situation in reality so don't want to spend
a lot of time optimizing for it, but if it happens this will keep
everything in sync.
上级 269ebcfe
......@@ -419,7 +419,23 @@ private SolutionState AddProject(ProjectId projectId, ProjectState projectState)
var newStateMap = _projectIdToProjectStateMap.Add(projectId, projectState);
var newDependencyGraph = _dependencyGraph
.WithAdditionalProjects(SpecializedCollections.SingletonEnumerable(projectId))
.WithAdditionalProjectReferences(projectId, projectState.ProjectReferences.Select(r => r.ProjectId).ToList());
.WithAdditionalProjectReferences(projectId,
projectState.ProjectReferences.Where(r => _projectIdToProjectStateMap.ContainsKey(r.ProjectId)).Select(r => r.ProjectId).ToList());
// It's possible that another project already in newStateMap has a reference to this project that we're adding, since we allow
// dangling references like that. If so, we'll need to link those in too.
foreach (var newState in newStateMap)
{
foreach (var projectReference in newState.Value.ProjectReferences)
{
if (projectReference.ProjectId == projectId)
{
newDependencyGraph = newDependencyGraph.WithAdditionalProjectReferences(newState.Key, ImmutableArray.Create(projectId));
break;
}
}
}
var newTrackerMap = CreateCompilationTrackerMap(projectId, newDependencyGraph);
var newLinkedFilesMap = CreateLinkedFilesMapWithAddedProject(newStateMap[projectId]);
......
......@@ -178,7 +178,6 @@ void VerifyAllTransitiveReferences()
VerifyDirectReferences(solution, "A", new string[] { "B", "C" });
}
[Fact, Trait(Traits.Feature, Traits.Features.Workspace)]
public void TestTransitiveReferencesIncrementalUpdateWithProjectThatHasUnknownReferences()
{
......@@ -208,6 +207,32 @@ public void TestTransitiveReferencesIncrementalUpdateWithProjectThatHasUnknownRe
VerifyTransitiveReferences(solution, dependencyGraph, project: "A", expectedResults: new string[] { "B" });
}
[Fact, Trait(Traits.Feature, Traits.Features.Workspace)]
public void TestTransitiveReferencesWithDanglingProjectReference()
{
// We are going to create a solution with the references:
//
// A -> B
//
// but we're going to add A as a reference with B not existing yet. Then we'll add in B and ask.
var solution = CreateSolution();
var projectAId = ProjectId.CreateNewId("A");
var projectBId = ProjectId.CreateNewId("B");
var projectAInfo = ProjectInfo.Create(projectAId, VersionStamp.Create(), "A", "A", LanguageNames.CSharp,
projectReferences: new[] { new ProjectReference(projectBId) });
solution = solution.AddProject(projectAInfo);
VerifyDirectReferences(solution, "A", new string[] { });
VerifyTransitiveReferences(solution, "A", new string[] { });
solution = solution.AddProject(projectBId, "B", "B", LanguageNames.CSharp);
VerifyTransitiveReferences(solution, "A", new string[] { "B" });
}
private void VerifyDirectReferences(Solution solution, string project, string[] expectedResults)
{
var projectDependencyGraph = solution.GetProjectDependencyGraph();
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册