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(); + } } } }