From 4b842c8c955aeb9001121dd6e935729b2b295816 Mon Sep 17 00:00:00 2001 From: Jonathon Marolf Date: Thu, 2 Sep 2021 10:31:30 -0700 Subject: [PATCH 1/5] Wait for the workspace to be initialized fixes #54568 fixes #55508 fixes #54495 --- .../EditorConfigSettings/SettingsEditorPane.cs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/VisualStudio/Core/Def/EditorConfigSettings/SettingsEditorPane.cs b/src/VisualStudio/Core/Def/EditorConfigSettings/SettingsEditorPane.cs index 472af983c6853..b1b7ad315189a 100644 --- a/src/VisualStudio/Core/Def/EditorConfigSettings/SettingsEditorPane.cs +++ b/src/VisualStudio/Core/Def/EditorConfigSettings/SettingsEditorPane.cs @@ -5,11 +5,13 @@ using System; using System.ComponentModel.Design; using System.Runtime.InteropServices; +using System.Threading; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.Editor.EditorConfigSettings; using Microsoft.CodeAnalysis.Editor.EditorConfigSettings.Data; using Microsoft.CodeAnalysis.Editor.Shared.Extensions; using Microsoft.CodeAnalysis.Editor.Shared.Utilities; +using Microsoft.CodeAnalysis.Host; using Microsoft.Internal.VisualStudio.PlatformUI; using Microsoft.Internal.VisualStudio.Shell.TableControl; using Microsoft.VisualStudio.Editor; @@ -94,6 +96,19 @@ protected override void Initialize() } } + var statusService = _workspace.Services.GetService(); + if (statusService is not null) + { + // This will show the 'Waiting for Intellisense to initalize' message until the workspace is loaded. + _threadingContext.JoinableTaskFactory.Run(async () => + { + if (!await statusService.IsFullyLoadedAsync(CancellationToken.None).ConfigureAwait(false)) + { + await statusService.WaitUntilFullyLoadedAsync(CancellationToken.None).ConfigureAwait(false); + } + }); + } + // hook up our panel _control = new SettingsEditorControl( GetWhitespaceView(), From a3f82cec46ee3b8e1bfab036254f8a6d07343979 Mon Sep 17 00:00:00 2001 From: Jonathon Marolf Date: Thu, 2 Sep 2021 11:01:19 -0700 Subject: [PATCH 2/5] Only attempt to show the settings from the workspace if the editorconfig file is in the workspace fixes #53845 --- .../Def/EditorConfigSettings/SettingsEditorFactory.cs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/VisualStudio/Core/Def/EditorConfigSettings/SettingsEditorFactory.cs b/src/VisualStudio/Core/Def/EditorConfigSettings/SettingsEditorFactory.cs index 8b8bb0770e07b..56fdf7c628a3c 100644 --- a/src/VisualStudio/Core/Def/EditorConfigSettings/SettingsEditorFactory.cs +++ b/src/VisualStudio/Core/Def/EditorConfigSettings/SettingsEditorFactory.cs @@ -63,7 +63,7 @@ public void Dispose() } public int CreateEditorInstance(uint grfCreateDoc, - string pszMkDocument, + string filePath, string pszPhysicalView, IVsHierarchy pvHier, uint itemid, @@ -88,6 +88,12 @@ public int CreateEditorInstance(uint grfCreateDoc, return VSConstants.VS_E_UNSUPPORTEDFORMAT; } + if (!_workspace.CurrentSolution.Projects.Any(p => p.AnalyzerConfigDocuments.Any(editorconfig => StringComparer.OrdinalIgnoreCase.Equals(editorconfig.FilePath, filePath)))) + { + // If the user is simply opening an editorconfig file that does not apply to the current solution we just want to show the text view + return VSConstants.VS_E_UNSUPPORTEDFORMAT; + } + // Validate inputs if ((grfCreateDoc & (VSConstants.CEF_OPENFILE | VSConstants.CEF_SILENT)) == 0) { @@ -138,7 +144,7 @@ public int CreateEditorInstance(uint grfCreateDoc, _settingsDataProviderFactory, _controlProvider, _tableMangerProvider, - pszMkDocument, + filePath, textBuffer, _workspace); ppunkDocView = Marshal.GetIUnknownForObject(newEditor); From 183440b20338fee0a6d17ee858925ae1349dff6b Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Thu, 2 Sep 2021 13:43:24 -0700 Subject: [PATCH 3/5] Remove dead code in the compilation tracker. --- .../Test2/Compilation/CompilationTests.vb | 3 --- .../Portable/Workspace/Solution/Project.cs | 3 --- .../SolutionState.CompilationTracker.cs | 18 --------------- ...eneratedFileReplacingCompilationTracker.cs | 5 ----- .../SolutionState.ICompilationTracker.cs | 1 - .../Workspace/Solution/SolutionState.cs | 22 ------------------- 6 files changed, 52 deletions(-) diff --git a/src/EditorFeatures/Test2/Compilation/CompilationTests.vb b/src/EditorFeatures/Test2/Compilation/CompilationTests.vb index 5480254f22361..5ad2edc80af85 100644 --- a/src/EditorFeatures/Test2/Compilation/CompilationTests.vb +++ b/src/EditorFeatures/Test2/Compilation/CompilationTests.vb @@ -7,7 +7,6 @@ Imports Microsoft.CodeAnalysis.Editor.UnitTests Imports Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces Namespace Microsoft.CodeAnalysis.Editor.Implementation.Compilation.UnitTests - <[UseExportProvider]> Public Class CompilationTests Private Shared Function GetProject(snapshot As Solution, assemblyName As String) As Project @@ -36,9 +35,7 @@ Namespace Microsoft.CodeAnalysis.Editor.Implementation.Compilation.UnitTests Assert.Null(Await project.GetCompilationAsync()) Assert.False(Await project.ContainsSymbolsWithNameAsync(Function(dummy) True, SymbolFilter.TypeAndMember, CancellationToken.None)) - Assert.Empty(Await project.GetDocumentsWithNameAsync(Function(dummy) True, SymbolFilter.TypeAndMember, CancellationToken.None)) End Using End Function End Class - End Namespace diff --git a/src/Workspaces/Core/Portable/Workspace/Solution/Project.cs b/src/Workspaces/Core/Portable/Workspace/Solution/Project.cs index 2fcb8a0e4cba2..6eb2e015b39ac 100644 --- a/src/Workspaces/Core/Portable/Workspace/Solution/Project.cs +++ b/src/Workspaces/Core/Portable/Workspace/Solution/Project.cs @@ -348,9 +348,6 @@ internal async Task ContainsSymbolsWithNameAsync(Func predic await _solution.State.ContainsSymbolsWithNameAsync(Id, predicate, filter, cancellationToken).ConfigureAwait(false); } - internal async Task> GetDocumentsWithNameAsync(Func predicate, SymbolFilter filter, CancellationToken cancellationToken) - => (await _solution.State.GetDocumentsWithNameAsync(Id, predicate, filter, cancellationToken).ConfigureAwait(false)).Select(s => _solution.GetDocument(s.Id)!); - private static readonly Func s_tryCreateDocumentFunction = (documentId, project) => project._projectState.DocumentStates.TryGetState(documentId, out var state) ? new Document(project, state) : null; diff --git a/src/Workspaces/Core/Portable/Workspace/Solution/SolutionState.CompilationTracker.cs b/src/Workspaces/Core/Portable/Workspace/Solution/SolutionState.CompilationTracker.cs index a04b9e6044d01..a1157d4cc5716 100644 --- a/src/Workspaces/Core/Portable/Workspace/Solution/SolutionState.CompilationTracker.cs +++ b/src/Workspaces/Core/Portable/Workspace/Solution/SolutionState.CompilationTracker.cs @@ -1093,24 +1093,6 @@ private async Task GetMetadataOnlyImageReferenceAsync( : state.DeclarationOnlyCompilation.ContainsSymbolsWithName(predicate, filter, cancellationToken); } - /// - /// get all syntax trees that contain declaration node with the given name - /// - public IEnumerable? GetSyntaxTreesWithNameFromDeclarationOnlyCompilation(Func predicate, SymbolFilter filter, CancellationToken cancellationToken) - { - var state = this.ReadState(); - if (state.DeclarationOnlyCompilation == null) - { - return null; - } - - // DO NOT expose declaration only compilation to outside since it can be held alive long time, we don't want to create any symbol from the declaration only compilation. - - // use cloned compilation since this will cause symbols to be created. - var clone = state.DeclarationOnlyCompilation.Clone(); - return clone.GetSymbolsWithName(predicate, filter, cancellationToken).SelectMany(s => s.DeclaringSyntaxReferences.Select(r => r.SyntaxTree)); - } - public Task HasSuccessfullyLoadedAsync(SolutionState solution, CancellationToken cancellationToken) { var state = this.ReadState(); diff --git a/src/Workspaces/Core/Portable/Workspace/Solution/SolutionState.GeneratedFileReplacingCompilationTracker.cs b/src/Workspaces/Core/Portable/Workspace/Solution/SolutionState.GeneratedFileReplacingCompilationTracker.cs index 51d3aead327b3..edcebd2b2ad9d 100644 --- a/src/Workspaces/Core/Portable/Workspace/Solution/SolutionState.GeneratedFileReplacingCompilationTracker.cs +++ b/src/Workspaces/Core/Portable/Workspace/Solution/SolutionState.GeneratedFileReplacingCompilationTracker.cs @@ -180,11 +180,6 @@ public async ValueTask> GetSour } } - public IEnumerable? GetSyntaxTreesWithNameFromDeclarationOnlyCompilation(Func predicate, SymbolFilter filter, CancellationToken cancellationToken) - { - return _underlyingTracker.GetSyntaxTreesWithNameFromDeclarationOnlyCompilation(predicate, filter, cancellationToken); - } - public Task HasSuccessfullyLoadedAsync(SolutionState solution, CancellationToken cancellationToken) { return _underlyingTracker.HasSuccessfullyLoadedAsync(solution, cancellationToken); diff --git a/src/Workspaces/Core/Portable/Workspace/Solution/SolutionState.ICompilationTracker.cs b/src/Workspaces/Core/Portable/Workspace/Solution/SolutionState.ICompilationTracker.cs index 7aa776dc26801..4d95ba64ced56 100644 --- a/src/Workspaces/Core/Portable/Workspace/Solution/SolutionState.ICompilationTracker.cs +++ b/src/Workspaces/Core/Portable/Workspace/Solution/SolutionState.ICompilationTracker.cs @@ -62,7 +62,6 @@ private interface ICompilationTracker Task GetMetadataReferenceAsync(SolutionState solution, ProjectState fromProject, ProjectReference projectReference, CancellationToken cancellationToken); CompilationReference? GetPartialMetadataReference(ProjectState fromProject, ProjectReference projectReference); ValueTask> GetSourceGeneratedDocumentStatesAsync(SolutionState solution, CancellationToken cancellationToken); - IEnumerable? GetSyntaxTreesWithNameFromDeclarationOnlyCompilation(Func predicate, SymbolFilter filter, CancellationToken cancellationToken); Task HasSuccessfullyLoadedAsync(SolutionState solution, CancellationToken cancellationToken); bool TryGetCompilation([NotNullWhen(true)] out Compilation? compilation); SourceGeneratedDocumentState? TryGetSourceGeneratedDocumentStateForAlreadyGeneratedId(DocumentId documentId); diff --git a/src/Workspaces/Core/Portable/Workspace/Solution/SolutionState.cs b/src/Workspaces/Core/Portable/Workspace/Solution/SolutionState.cs index 213acc84b3b2c..b600fec92c46a 100644 --- a/src/Workspaces/Core/Portable/Workspace/Solution/SolutionState.cs +++ b/src/Workspaces/Core/Portable/Workspace/Solution/SolutionState.cs @@ -1976,28 +1976,6 @@ public async Task ContainsSymbolsWithNameAsync(ProjectId id, Func> GetDocumentsWithNameAsync( - ProjectId id, Func predicate, SymbolFilter filter, CancellationToken cancellationToken) - { - // this will be used to find documents that contain declaration information in IDE cache such as DeclarationSyntaxTreeInfo for "NavigateTo" - var trees = GetCompilationTracker(id).GetSyntaxTreesWithNameFromDeclarationOnlyCompilation(predicate, filter, cancellationToken); - if (trees != null) - { - return ConvertTreesToDocuments(id, trees); - } - - // it looks like declaration compilation doesn't exist yet. we have to build full compilation - var compilation = await GetCompilationAsync(id, cancellationToken).ConfigureAwait(false); - if (compilation == null) - { - // some projects don't support compilations (e.g., TypeScript) so there's nothing to check - return ImmutableArray.Empty; - } - - return ConvertTreesToDocuments( - id, compilation.GetSymbolsWithName(predicate, filter, cancellationToken).SelectMany(s => s.DeclaringSyntaxReferences.Select(r => r.SyntaxTree))); - } - private ImmutableArray ConvertTreesToDocuments(ProjectId id, IEnumerable trees) { var result = ArrayBuilder.GetInstance(); From 85b40bfa75c16fc9716d98fb44dc6f359242becc Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Thu, 2 Sep 2021 13:51:43 -0700 Subject: [PATCH 4/5] Remove another dead function --- .../Workspace/Solution/SolutionState.cs | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/src/Workspaces/Core/Portable/Workspace/Solution/SolutionState.cs b/src/Workspaces/Core/Portable/Workspace/Solution/SolutionState.cs index b600fec92c46a..0d66180fc3e74 100644 --- a/src/Workspaces/Core/Portable/Workspace/Solution/SolutionState.cs +++ b/src/Workspaces/Core/Portable/Workspace/Solution/SolutionState.cs @@ -1976,24 +1976,6 @@ public async Task ContainsSymbolsWithNameAsync(ProjectId id, Func ConvertTreesToDocuments(ProjectId id, IEnumerable trees) - { - var result = ArrayBuilder.GetInstance(); - foreach (var tree in trees) - { - var document = GetDocumentState(tree, id); - if (document == null) - { - // ignore trees that are not known to solution such as VB synthesized trees made by compilation. - continue; - } - - result.Add(document); - } - - return result.ToImmutableAndFree(); - } - /// /// Gets a that details the dependencies between projects for this solution. /// From 136930bc1c94db124ee7b0e19f4618a672a260d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Matou=C5=A1ek?= Date: Thu, 2 Sep 2021 14:24:41 -0700 Subject: [PATCH 5/5] Delete unused UnitTesting API (#56122) --- .../UnitTestingRemoteHostOptionsAccessor.cs | 19 ------------------- 1 file changed, 19 deletions(-) delete mode 100644 src/VisualStudio/Core/Def/ExternalAccess/UnitTesting/Api/UnitTestingRemoteHostOptionsAccessor.cs diff --git a/src/VisualStudio/Core/Def/ExternalAccess/UnitTesting/Api/UnitTestingRemoteHostOptionsAccessor.cs b/src/VisualStudio/Core/Def/ExternalAccess/UnitTesting/Api/UnitTestingRemoteHostOptionsAccessor.cs deleted file mode 100644 index 5c1167f9242ea..0000000000000 --- a/src/VisualStudio/Core/Def/ExternalAccess/UnitTesting/Api/UnitTestingRemoteHostOptionsAccessor.cs +++ /dev/null @@ -1,19 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -#nullable disable - -using System.Linq; -using Microsoft.CodeAnalysis.Options; -using Microsoft.CodeAnalysis.Remote; - -namespace Microsoft.CodeAnalysis.ExternalAccess.UnitTesting.Api -{ - internal static class UnitTestingRemoteHostOptionsAccessor - { - public static Option OOP64Bit => new( - RemoteHostOptions.OOP64Bit.Feature, RemoteHostOptions.OOP64Bit.Name, defaultValue: RemoteHostOptions.OOP64Bit.DefaultValue, - storageLocations: RemoteHostOptions.OOP64Bit.StorageLocations.ToArray()); - } -}