From da2980580df65ba8ef7a9c9265ec4a385bcc2efa Mon Sep 17 00:00:00 2001
From: me <30739723+dmgonch@users.noreply.github.com>
Date: Mon, 20 Dec 2021 18:58:20 -0800
Subject: [PATCH] Add project to solution and apply the change to the workspace
as a unit
---
src/OmniSharp.MSBuild/ProjectManager.cs | 43 ++++++++++++++-----------
1 file changed, 25 insertions(+), 18 deletions(-)
diff --git a/src/OmniSharp.MSBuild/ProjectManager.cs b/src/OmniSharp.MSBuild/ProjectManager.cs
index 621b494e9a..ca0a023fc7 100644
--- a/src/OmniSharp.MSBuild/ProjectManager.cs
+++ b/src/OmniSharp.MSBuild/ProjectManager.cs
@@ -60,6 +60,7 @@ public ProjectToUpdate(string filePath, bool allowAutoRestore, ProjectIdInfo pro
private readonly ConcurrentDictionary _projectsRequestedOnDemand;
private readonly ProjectLoader _projectLoader;
private readonly OmniSharpWorkspace _workspace;
+ private readonly object _workspaceGate = new();
private readonly ImmutableArray _eventSinks;
private const int LoopDelay = 100; // milliseconds
private readonly BufferBlock _queue;
@@ -365,14 +366,17 @@ private void AddProject(ProjectFileInfo projectFileInfo)
var projectInfo = projectFileInfo.CreateProjectInfo(_analyzerAssemblyLoader);
- var newSolution = _workspace.CurrentSolution.AddProject(projectInfo);
- _workspace.AddDocumentInclusionRuleForProject(projectInfo.Id, (filePath) => projectFileInfo.IsFileIncluded(filePath));
+ lock (_workspaceGate)
+ {
+ var newSolution = _workspace.CurrentSolution.AddProject(projectInfo);
+ _workspace.AddDocumentInclusionRuleForProject(projectInfo.Id, (filePath) => projectFileInfo.IsFileIncluded(filePath));
- SubscribeToAnalyzerReferenceLoadFailures(projectInfo.AnalyzerReferences.Cast(), _logger);
+ SubscribeToAnalyzerReferenceLoadFailures(projectInfo.AnalyzerReferences.Cast(), _logger);
- if (!_workspace.TryApplyChanges(newSolution))
- {
- _logger.LogError($"Failed to add project to workspace: '{projectFileInfo.FilePath}'");
+ if (!_workspace.TryApplyChanges(newSolution))
+ {
+ _logger.LogError($"Failed to add project to workspace: '{projectFileInfo.FilePath}'");
+ }
}
WatchProjectFiles(projectFileInfo);
@@ -694,23 +698,26 @@ private void UpdateSourceFiles(Project project, IList sourceFiles)
private void OnDirectoryFileChanged(string path, FileChangeType changeType)
{
- // Hosts may not have passed through a file change type
- if (changeType == FileChangeType.Unspecified && !File.Exists(path) || changeType == FileChangeType.Delete)
+ lock (_workspaceGate)
{
- foreach (var documentId in _workspace.CurrentSolution.GetDocumentIdsWithFilePath(path))
+ // Hosts may not have passed through a file change type
+ if (changeType == FileChangeType.Unspecified && !File.Exists(path) || changeType == FileChangeType.Delete)
{
- _workspace.RemoveDocument(documentId);
+ foreach (var documentId in _workspace.CurrentSolution.GetDocumentIdsWithFilePath(path))
+ {
+ _workspace.RemoveDocument(documentId);
+ }
}
- }
- if (changeType == FileChangeType.Unspecified || changeType == FileChangeType.Create || changeType == FileChangeType.Change)
- {
- // Only add cs files. Also, make sure the path is a file, and not a directory name that happens to end in ".cs"
- if (string.Equals(Path.GetExtension(path), ".cs", StringComparison.CurrentCultureIgnoreCase) && File.Exists(path))
+ if (changeType == FileChangeType.Unspecified || changeType == FileChangeType.Create || changeType == FileChangeType.Change)
{
- // Use the buffer manager to add the new file to the appropriate projects
- // Hosts that don't pass the FileChangeType may wind up updating the buffer twice
- _workspace.BufferManager.UpdateBufferAsync(new UpdateBufferRequest() { FileName = path, FromDisk = true }, isCreate: changeType == FileChangeType.Create).Wait();
+ // Only add cs files. Also, make sure the path is a file, and not a directory name that happens to end in ".cs"
+ if (string.Equals(Path.GetExtension(path), ".cs", StringComparison.CurrentCultureIgnoreCase) && File.Exists(path))
+ {
+ // Use the buffer manager to add the new file to the appropriate projects
+ // Hosts that don't pass the FileChangeType may wind up updating the buffer twice
+ _workspace.BufferManager.UpdateBufferAsync(new UpdateBufferRequest() { FileName = path, FromDisk = true }, isCreate: changeType == FileChangeType.Create).Wait();
+ }
}
}
}