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

Merge pull request #31766 from jasonmalinowski/fix-handling-of-duplicate-project-names

Remove assumption that project names are unique
......@@ -60,7 +60,7 @@ private VisualStudioProject FindMatchingProject(IVsHierarchy hierarchy, uint ite
return null;
}
return this.Workspace.GetProjectForUniqueName(projectName);
return this.Workspace.GetProjectWithHierarchyAndName(hierarchy, projectName);
}
public int GetLanguage(IVsHierarchy hierarchy, uint itemid, IVsTextBufferCoordinator bufferCoordinator, out IVsContainedLanguage language)
......
......@@ -19,7 +19,6 @@ internal sealed class VisualStudioProject
{
private readonly VisualStudioWorkspaceImpl _workspace;
private readonly HostDiagnosticUpdateSource _hostDiagnosticUpdateSource;
private readonly string _projectUniqueName;
/// <summary>
/// Provides dynamic source files for files added through <see cref="AddDynamicSourceFile" />.
......@@ -119,7 +118,7 @@ internal sealed class VisualStudioProject
ImmutableArray<Lazy<IDynamicFileInfoProvider, FileExtensionsMetadata>> dynamicFileInfoProviders,
HostDiagnosticUpdateSource hostDiagnosticUpdateSource,
ProjectId id,
string projectUniqueName,
string displayName,
string language,
string directoryNameOpt)
{
......@@ -129,8 +128,7 @@ internal sealed class VisualStudioProject
Id = id;
Language = language;
_displayName = projectUniqueName;
_projectUniqueName = projectUniqueName;
_displayName = displayName;
if (directoryNameOpt != null)
{
......
......@@ -31,33 +31,35 @@ internal sealed class VisualStudioProjectFactory
_hostDiagnosticUpdateSource = hostDiagnosticUpdateSource;
}
public VisualStudioProject CreateAndAddToWorkspace(string projectUniqueName, string language)
public VisualStudioProject CreateAndAddToWorkspace(string projectSystemName, string language)
{
return CreateAndAddToWorkspace(projectUniqueName, language, new VisualStudioProjectCreationInfo());
return CreateAndAddToWorkspace(projectSystemName, language, new VisualStudioProjectCreationInfo());
}
public VisualStudioProject CreateAndAddToWorkspace(string projectUniqueName, string language, VisualStudioProjectCreationInfo creationInfo)
public VisualStudioProject CreateAndAddToWorkspace(string projectSystemName, string language, VisualStudioProjectCreationInfo creationInfo)
{
// HACK: Fetch this service to ensure it's still created on the UI thread; once this is moved off we'll need to fix up it's constructor to be free-threaded.
_visualStudioWorkspaceImpl.Services.GetRequiredService<VisualStudioMetadataReferenceManager>();
var id = ProjectId.CreateNewId(projectUniqueName);
var id = ProjectId.CreateNewId(projectSystemName);
var directoryNameOpt = creationInfo.FilePath != null ? Path.GetDirectoryName(creationInfo.FilePath) : null;
var project = new VisualStudioProject(_visualStudioWorkspaceImpl, _dynamicFileInfoProviders, _hostDiagnosticUpdateSource, id, projectUniqueName, language, directoryNameOpt);
// We will use the project system name as the default display name of the project
var project = new VisualStudioProject(_visualStudioWorkspaceImpl, _dynamicFileInfoProviders, _hostDiagnosticUpdateSource, id, displayName: projectSystemName, language, directoryNameOpt);
var versionStamp = creationInfo.FilePath != null ? VersionStamp.Create(File.GetLastWriteTimeUtc(creationInfo.FilePath))
: VersionStamp.Create();
var assemblyName = creationInfo.AssemblyName ?? projectUniqueName;
var assemblyName = creationInfo.AssemblyName ?? projectSystemName;
_visualStudioWorkspaceImpl.AddProjectToInternalMaps(project, creationInfo.Hierarchy, creationInfo.ProjectGuid, projectUniqueName);
_visualStudioWorkspaceImpl.AddProjectToInternalMaps(project, creationInfo.Hierarchy, creationInfo.ProjectGuid, projectSystemName);
_visualStudioWorkspaceImpl.ApplyChangeToWorkspace(w =>
{
var projectInfo = ProjectInfo.Create(
id,
versionStamp,
name: projectUniqueName,
name: projectSystemName,
assemblyName: assemblyName,
language: language,
filePath: creationInfo.FilePath,
......
......@@ -61,7 +61,7 @@ internal abstract partial class VisualStudioWorkspaceImpl : VisualStudioWorkspac
private ImmutableDictionary<ProjectId, IVsHierarchy> _projectToHierarchyMap = ImmutableDictionary<ProjectId, IVsHierarchy>.Empty;
private ImmutableDictionary<ProjectId, Guid> _projectToGuidMap = ImmutableDictionary<ProjectId, Guid>.Empty;
private ImmutableDictionary<string, VisualStudioProject> _projectUniqueNameToProjectMap = ImmutableDictionary<string, VisualStudioProject>.Empty;
private Dictionary<string, List<VisualStudioProject>> _projectSystemNameToProjectsMap = new Dictionary<string, List<VisualStudioProject>>();
/// <summary>
/// A set of documents that were added by <see cref="VisualStudioProject.AddSourceTextContainer"/>, and aren't otherwise
......@@ -129,13 +129,13 @@ public void CheckForOpenDocuments(ImmutableArray<string> newFileNames)
_openFileTrackerOpt?.CheckForFilesBeingOpen(newFileNames);
}
internal void AddProjectToInternalMaps(VisualStudioProject project, IVsHierarchy hierarchy, Guid guid, string projectUniqueName)
internal void AddProjectToInternalMaps(VisualStudioProject project, IVsHierarchy hierarchy, Guid guid, string projectSystemName)
{
lock (_gate)
{
_projectToHierarchyMap = _projectToHierarchyMap.Add(project.Id, hierarchy);
_projectToGuidMap = _projectToGuidMap.Add(project.Id, guid);
_projectUniqueNameToProjectMap = _projectUniqueNameToProjectMap.Add(projectUniqueName, project);
_projectSystemNameToProjectsMap.MultiAdd(projectSystemName, project);
}
}
......@@ -181,10 +181,26 @@ internal ContainedDocument TryGetContainedDocument(DocumentId documentId)
return ContainedDocument.TryGetContainedDocument(documentId);
}
internal VisualStudioProject GetProjectForUniqueName(string projectName)
internal VisualStudioProject GetProjectWithHierarchyAndName(IVsHierarchy hierarchy, string projectName)
{
// This doesn't take a lock since _projectNameToProjectMap is immutable
return _projectUniqueNameToProjectMap.GetValueOrDefault(projectName, defaultValue: null);
lock (_gate)
{
if (_projectSystemNameToProjectsMap.TryGetValue(projectName, out var projects))
{
foreach (var project in projects)
{
if (_projectToHierarchyMap.TryGetValue(project.Id, out var projectHierarchy))
{
if (projectHierarchy == hierarchy)
{
return project;
}
}
}
}
}
return null;
}
[Obsolete("This is a compatibility shim for Live Unit Testing; please do not use it.")]
......@@ -1330,12 +1346,16 @@ protected internal override void OnProjectRemoved(ProjectId projectId)
_projectToGuidMap = _projectToGuidMap.Remove(projectId);
_projectToHierarchyMap = _projectToHierarchyMap.Remove(projectId);
foreach (var pair in _projectUniqueNameToProjectMap)
foreach (var (projectName, projects) in _projectSystemNameToProjectsMap)
{
if (pair.Value.Id == projectId)
if (projects.RemoveAll(p => p.Id == projectId) > 0)
{
_projectUniqueNameToProjectMap = _projectUniqueNameToProjectMap.Remove(pair.Key);
break;
if (projects.Count == 0)
{
_projectSystemNameToProjectsMap.Remove(projectName);
}
return;
}
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册