未验证 提交 ba95be77 编写于 作者: J Jason Malinowski 提交者: GitHub

Merge pull request #31049 from...

Merge pull request #31049 from jasonmalinowski/fix-project-reference-conversion-during-project-unload

Make sure we convert project references back on project removal
...@@ -85,6 +85,29 @@ IEnumerable<PortableExecutableReference> GetProject3MetadataReferences() ...@@ -85,6 +85,29 @@ IEnumerable<PortableExecutableReference> GetProject3MetadataReferences()
} }
} }
[WpfFact]
[Trait(Traits.Feature, Traits.Features.ProjectSystemShims)]
public void RemoveProjectConvertsProjectReferencesBack()
{
using (var environment = new TestEnvironment())
{
var project1 = CreateCSharpCPSProject(environment, "project1", commandLineArguments: @"/out:c:\project1.dll");
var project2 = CreateCSharpCPSProject(environment, "project2");
// Add project reference as metadata reference: since this is known to be the output path of project1, the metadata reference is converted to a project reference
project2.AddMetadataReference(@"c:\project1.dll", new MetadataReferenceProperties());
Assert.Single(environment.Workspace.CurrentSolution.GetProject(project2.Id).AllProjectReferences);
// Remove project1. project2's reference should have been converted back
project1.Dispose();
Assert.Empty(environment.Workspace.CurrentSolution.GetProject(project2.Id).AllProjectReferences);
Assert.Single(environment.Workspace.CurrentSolution.GetProject(project2.Id).MetadataReferences);
project2.Dispose();
}
}
[WpfFact] [WpfFact]
[Trait(Traits.Feature, Traits.Features.ProjectSystemShims)] [Trait(Traits.Feature, Traits.Features.ProjectSystemShims)]
public void AddRemoveAnalyzerReference_CPS() public void AddRemoveAnalyzerReference_CPS()
......
...@@ -1288,18 +1288,29 @@ public void ApplyBatchChangeToProject(ProjectId projectId, Func<CodeAnalysis.Sol ...@@ -1288,18 +1288,29 @@ public void ApplyBatchChangeToProject(ProjectId projectId, Func<CodeAnalysis.Sol
} }
} }
private Dictionary<ProjectId, ProjectReferenceInformation> _projectReferenceInfo = new Dictionary<ProjectId, ProjectReferenceInformation>(); private Dictionary<ProjectId, ProjectReferenceInformation> _projectReferenceInfoMap = new Dictionary<ProjectId, ProjectReferenceInformation>();
private ProjectReferenceInformation GetReferenceInfo_NoLock(ProjectId projectId) private ProjectReferenceInformation GetReferenceInfo_NoLock(ProjectId projectId)
{ {
return _projectReferenceInfo.GetOrAdd(projectId, _ => new ProjectReferenceInformation()); return _projectReferenceInfoMap.GetOrAdd(projectId, _ => new ProjectReferenceInformation());
} }
protected internal override void OnProjectRemoved(ProjectId projectId) protected internal override void OnProjectRemoved(ProjectId projectId)
{ {
lock (_gate) lock (_gate)
{ {
_projectReferenceInfo.Remove(projectId); if (_projectReferenceInfoMap.TryGetValue(projectId, out var projectReferenceInfo))
{
// If we still had any output paths, we'll want to remove them to cause conversion back to metadata references.
// The call below implicitly is modifying the collection we've fetched, so we'll make a copy.
foreach (var outputPath in projectReferenceInfo.OutputPaths.ToList())
{
RemoveProjectOutputPath(projectId, outputPath);
}
_projectReferenceInfoMap.Remove(projectId);
}
_projectToGuidMap = _projectToGuidMap.Remove(projectId); _projectToGuidMap = _projectToGuidMap.Remove(projectId);
_projectToHierarchyMap = _projectToHierarchyMap.Remove(projectId); _projectToHierarchyMap = _projectToHierarchyMap.Remove(projectId);
...@@ -1390,6 +1401,11 @@ private void ConvertMetadataReferencesToProjectReferences_NoLock(ProjectId proje ...@@ -1390,6 +1401,11 @@ private void ConvertMetadataReferencesToProjectReferences_NoLock(ProjectId proje
SetSolutionAndRaiseWorkspaceChanged_NoLock(modifiedSolution, projectIdsChanged); SetSolutionAndRaiseWorkspaceChanged_NoLock(modifiedSolution, projectIdsChanged);
} }
/// <summary>
/// Finds all projects that had a project reference to <paramref name="projectId"/> and convert it back to a metadata reference.
/// </summary>
/// <param name="projectId">The <see cref="ProjectId"/> of the project being referenced.</param>
/// <param name="outputPath">The output path of the given project to remove the link to.</param>
private void ConvertProjectReferencesToMetadataReferences_NoLock(ProjectId projectId, string outputPath) private void ConvertProjectReferencesToMetadataReferences_NoLock(ProjectId projectId, string outputPath)
{ {
var modifiedSolution = this.CurrentSolution; var modifiedSolution = this.CurrentSolution;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册