From a4d4605d5daac2366d932cb8f2f1ee50429eecf6 Mon Sep 17 00:00:00 2001 From: David Barbet Date: Mon, 14 Dec 2020 17:08:28 -0800 Subject: [PATCH] Add feature flag to allow VS to use the LSP based editor --- .../RenameCommandHandler_RenameHandler.cs | 4 ++- .../Suggestions/SuggestedActionsSource.cs | 5 +++ .../SemanticClassificationUtilities.cs | 5 +++ .../AlwaysActivateInProcLanguageClient.cs | 34 +++++++++++++------ .../LiveShareInProcLanguageClient.cs | 14 +++++++- .../VisualStudioWorkspaceContextService.cs | 17 ++++++++-- .../Core/Def/PackageRegistration.pkgdef | 5 +++ 7 files changed, 69 insertions(+), 15 deletions(-) diff --git a/src/EditorFeatures/Core.Wpf/InlineRename/CommandHandlers/RenameCommandHandler_RenameHandler.cs b/src/EditorFeatures/Core.Wpf/InlineRename/CommandHandlers/RenameCommandHandler_RenameHandler.cs index dc1ab07721623..ef7e6ca6347f7 100644 --- a/src/EditorFeatures/Core.Wpf/InlineRename/CommandHandlers/RenameCommandHandler_RenameHandler.cs +++ b/src/EditorFeatures/Core.Wpf/InlineRename/CommandHandlers/RenameCommandHandler_RenameHandler.cs @@ -10,6 +10,7 @@ using Microsoft.CodeAnalysis.Editor.Shared.Extensions; using Microsoft.CodeAnalysis.Notification; using Roslyn.Utilities; +using Microsoft.CodeAnalysis.Editor.Shared.Utilities; namespace Microsoft.CodeAnalysis.Editor.Implementation.InlineRename { @@ -108,7 +109,8 @@ private static bool CanRename(RenameCommandArgs args) { return args.SubjectBuffer.TryGetWorkspace(out var workspace) && workspace.CanApplyChange(ApplyChangesKind.ChangeDocument) && - args.SubjectBuffer.SupportsRename(); + args.SubjectBuffer.SupportsRename() && + !workspace.Services.GetService().IsInLspEditorContext(); } private static void ShowErrorDialog(Workspace workspace, string message) diff --git a/src/EditorFeatures/Core.Wpf/Suggestions/SuggestedActionsSource.cs b/src/EditorFeatures/Core.Wpf/Suggestions/SuggestedActionsSource.cs index 9a9c19a21a071..bb585ad70d166 100644 --- a/src/EditorFeatures/Core.Wpf/Suggestions/SuggestedActionsSource.cs +++ b/src/EditorFeatures/Core.Wpf/Suggestions/SuggestedActionsSource.cs @@ -178,6 +178,11 @@ public bool TryGetTelemetryId(out Guid telemetryId) return null; } + if (range.Snapshot.TextBuffer.IsInLspEditorContext()) + { + return null; + } + if (_workspaceStatusService != null) { using (operationContext?.AddScope(allowCancellation: true, description: EditorFeaturesWpfResources.Gathering_Suggestions_Waiting_for_the_solution_to_fully_load)) diff --git a/src/EditorFeatures/Core/Implementation/Classification/SemanticClassificationUtilities.cs b/src/EditorFeatures/Core/Implementation/Classification/SemanticClassificationUtilities.cs index d6bb70b17cc47..650ddeb2d30c9 100644 --- a/src/EditorFeatures/Core/Implementation/Classification/SemanticClassificationUtilities.cs +++ b/src/EditorFeatures/Core/Implementation/Classification/SemanticClassificationUtilities.cs @@ -34,6 +34,11 @@ public static async Task ProduceTagsAsync( IClassificationService classificationService, ClassificationTypeMap typeMap) { + if (spanToTag.SnapshotSpan.Snapshot.TextBuffer.IsInLspEditorContext()) + { + return; + } + var document = spanToTag.Document; if (document == null) { diff --git a/src/VisualStudio/Core/Def/Implementation/LanguageClient/AlwaysActivateInProcLanguageClient.cs b/src/VisualStudio/Core/Def/Implementation/LanguageClient/AlwaysActivateInProcLanguageClient.cs index 82d6531edb516..65da7adaf0780 100644 --- a/src/VisualStudio/Core/Def/Implementation/LanguageClient/AlwaysActivateInProcLanguageClient.cs +++ b/src/VisualStudio/Core/Def/Implementation/LanguageClient/AlwaysActivateInProcLanguageClient.cs @@ -6,6 +6,7 @@ using System.ComponentModel.Composition; using Microsoft.CodeAnalysis.Diagnostics; using Microsoft.CodeAnalysis.Editor; +using Microsoft.CodeAnalysis.Experiments; using Microsoft.CodeAnalysis.Host.Mef; using Microsoft.CodeAnalysis.LanguageServer; using Microsoft.CodeAnalysis.Options; @@ -27,6 +28,7 @@ namespace Microsoft.VisualStudio.LanguageServices.Implementation.LanguageClient [Export(typeof(AlwaysActivateInProcLanguageClient))] internal class AlwaysActivateInProcLanguageClient : AbstractInProcLanguageClient { + private readonly DefaultCapabilitiesProvider _defaultCapabilitiesProvider; private readonly IGlobalOptionService _globalOptionService; [ImportingConstructor] @@ -36,27 +38,37 @@ public AlwaysActivateInProcLanguageClient( LanguageServerProtocol languageServerProtocol, VisualStudioWorkspace workspace, IAsynchronousOperationListenerProvider listenerProvider, - ILspSolutionProvider solutionProvider) + ILspSolutionProvider solutionProvider, + DefaultCapabilitiesProvider defaultCapabilitiesProvider) : base(languageServerProtocol, workspace, diagnosticService: null, listenerProvider, solutionProvider, diagnosticsClientName: null) { _globalOptionService = globalOptionService; + _defaultCapabilitiesProvider = defaultCapabilitiesProvider; } public override string Name => ServicesVSResources.CSharp_Visual_Basic_Language_Server_Client; protected internal override VSServerCapabilities GetCapabilities() - => new VSServerCapabilities + { + var serverCapabilities = new VSServerCapabilities(); + + // If the LSP editor feature flag is enabled advertise support for LSP features here so they are available locally and remote. + if (Workspace.Services.GetRequiredService().IsExperimentEnabled(VisualStudioWorkspaceContextService.LspEditorFeatureFlagName)) + { + serverCapabilities = _defaultCapabilitiesProvider.GetCapabilities(); + } + + serverCapabilities.TextDocumentSync = new TextDocumentSyncOptions { - TextDocumentSync = new TextDocumentSyncOptions - { - Change = TextDocumentSyncKind.Incremental, - OpenClose = true, - }, - SupportsDiagnosticRequests = this.Workspace.IsPullDiagnostics(InternalDiagnosticsOptions.NormalDiagnosticMode), - // This flag ensures that ctrl+, search locally uses the old editor APIs so that only ctrl+Q search is powered via LSP. - DisableGoToWorkspaceSymbols = true, - WorkspaceSymbolProvider = true, + Change = TextDocumentSyncKind.Incremental, + OpenClose = true, }; + serverCapabilities.SupportsDiagnosticRequests = this.Workspace.IsPullDiagnostics(InternalDiagnosticsOptions.NormalDiagnosticMode); + serverCapabilities.DisableGoToWorkspaceSymbols = true; + serverCapabilities.WorkspaceSymbolProvider = true; + + return serverCapabilities; + } } } diff --git a/src/VisualStudio/Core/Def/Implementation/LanguageClient/LiveShareInProcLanguageClient.cs b/src/VisualStudio/Core/Def/Implementation/LanguageClient/LiveShareInProcLanguageClient.cs index 3928fea420a2c..1b0ceff0c3977 100644 --- a/src/VisualStudio/Core/Def/Implementation/LanguageClient/LiveShareInProcLanguageClient.cs +++ b/src/VisualStudio/Core/Def/Implementation/LanguageClient/LiveShareInProcLanguageClient.cs @@ -6,6 +6,7 @@ using System.ComponentModel.Composition; using Microsoft.CodeAnalysis.Diagnostics; using Microsoft.CodeAnalysis.Editor; +using Microsoft.CodeAnalysis.Experiments; using Microsoft.CodeAnalysis.Host.Mef; using Microsoft.CodeAnalysis.LanguageServer; using Microsoft.CodeAnalysis.Shared.TestHooks; @@ -42,6 +43,17 @@ public LiveShareInProcLanguageClient( public override string Name => ServicesVSResources.Live_Share_CSharp_Visual_Basic_Language_Server_Client; protected internal override VSServerCapabilities GetCapabilities() - => _defaultCapabilitiesProvider.GetCapabilities(); + { + var experimentationService = Workspace.Services.GetRequiredService(); + var isLspEditorEnabled = experimentationService.IsExperimentEnabled(VisualStudioWorkspaceContextService.LspEditorFeatureFlagName); + // If the preview feature flag to turn on the LSP editor in local scenarios is on, advertise no capabilities for this Live Share + // LSP server as LSP requests will be serviced by the AlwaysActiveInProcLanguageClient in both local and remote scenarios. + if (isLspEditorEnabled) + { + return new VSServerCapabilities(); + } + + return _defaultCapabilitiesProvider.GetCapabilities(); + } } } diff --git a/src/VisualStudio/Core/Def/Implementation/VisualStudioWorkspaceContextService.cs b/src/VisualStudio/Core/Def/Implementation/VisualStudioWorkspaceContextService.cs index ccf672ef87c03..c1d65481e5d66 100644 --- a/src/VisualStudio/Core/Def/Implementation/VisualStudioWorkspaceContextService.cs +++ b/src/VisualStudio/Core/Def/Implementation/VisualStudioWorkspaceContextService.cs @@ -4,7 +4,9 @@ using System; using System.Composition; +using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.Editor.Shared.Utilities; +using Microsoft.CodeAnalysis.Experiments; using Microsoft.CodeAnalysis.Host.Mef; using Microsoft.VisualStudio.Shell; @@ -13,14 +15,23 @@ namespace Microsoft.VisualStudio.LanguageServices.Implementation [ExportWorkspaceService(typeof(IWorkspaceContextService), ServiceLayer.Host), Shared] internal class VisualStudioWorkspaceContextService : IWorkspaceContextService { + /// + /// Roslyn LSP feature flag name, as defined in the PackageRegistraion.pkgdef + /// by everything following '$RootKey$\FeatureFlags\' and '\' replaced by '.' + /// + public const string LspEditorFeatureFlagName = "Roslyn.LSP.Editor"; + // UI context defined by Live Share when connected as a guest in a Live Share session // https://devdiv.visualstudio.com/DevDiv/_git/Cascade?path=%2Fsrc%2FVS%2FContracts%2FGuidList.cs&version=GBmaster&line=32&lineEnd=33&lineStartColumn=1&lineEndColumn=1&lineStyle=plain&_a=contents private static readonly Guid LiveShareGuestUIContextGuid = Guid.Parse("fd93f3eb-60da-49cd-af15-acda729e357e"); + private readonly Workspace _workspace; + [ImportingConstructor] [Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] - public VisualStudioWorkspaceContextService() + public VisualStudioWorkspaceContextService(VisualStudioWorkspace vsWorkspace) { + _workspace = vsWorkspace; } public bool IsCloudEnvironmentClient() @@ -31,7 +42,9 @@ public bool IsCloudEnvironmentClient() public bool IsInLspEditorContext() { - return IsLiveShareGuest() || IsCloudEnvironmentClient(); + var featureFlagService = _workspace.Services.GetRequiredService(); + var isInLspContext = IsLiveShareGuest() || IsCloudEnvironmentClient() || featureFlagService.IsExperimentEnabled(LspEditorFeatureFlagName); + return isInLspContext; } /// diff --git a/src/VisualStudio/Core/Def/PackageRegistration.pkgdef b/src/VisualStudio/Core/Def/PackageRegistration.pkgdef index 114cb938c11bc..e04a669cde883 100644 --- a/src/VisualStudio/Core/Def/PackageRegistration.pkgdef +++ b/src/VisualStudio/Core/Def/PackageRegistration.pkgdef @@ -13,3 +13,8 @@ "CS"="CA719A03-D55C-48F9-85DE-D934346E7F70" "VB"="EEC3DF0D-6D3F-4544-ABF9-8E26E6A90275" +[$RootKey$\FeatureFlags\Roslyn\LSP\Editor] +"Description"="Enables the LSP powered C#/VB editing experience outside of CodeSpaces." +"Value"=dword:00000000 +"Title"="Enable experimental C#/VB editor (requires restart)" +"PreviewPaneChannels"="Preview,int.main"