From 73b303c7f173f2438576c6cd0eb23ef4c11da532 Mon Sep 17 00:00:00 2001 From: "Stephen Weatherford (MSFT)" Date: Thu, 11 Jul 2024 10:19:52 -0700 Subject: [PATCH 1/9] Improve scripts --- src/vs-bicep/build-release.cmd | 2 +- src/vs-bicep/install-release.cmd | 2 +- src/vs-bicep/{Install.cmd => install.cmd} | 22 +++++++--------- src/vs-bicep/patch.cmd | 31 +++++++++++++++++++++++ 4 files changed, 42 insertions(+), 15 deletions(-) rename src/vs-bicep/{Install.cmd => install.cmd} (63%) create mode 100644 src/vs-bicep/patch.cmd diff --git a/src/vs-bicep/build-release.cmd b/src/vs-bicep/build-release.cmd index f9bc06e41c8..efa21e239f5 100644 --- a/src/vs-bicep/build-release.cmd +++ b/src/vs-bicep/build-release.cmd @@ -1 +1 @@ -call "%~dp0\Install.cmd" release +@call "%~dp0\Install.cmd" release diff --git a/src/vs-bicep/install-release.cmd b/src/vs-bicep/install-release.cmd index 5bf1b6d1352..efa21e239f5 100644 --- a/src/vs-bicep/install-release.cmd +++ b/src/vs-bicep/install-release.cmd @@ -1 +1 @@ -call "%~dp0\Install.cmd" release \ No newline at end of file +@call "%~dp0\Install.cmd" release diff --git a/src/vs-bicep/Install.cmd b/src/vs-bicep/install.cmd similarity index 63% rename from src/vs-bicep/Install.cmd rename to src/vs-bicep/install.cmd index dc5268724cb..90e41258150 100644 --- a/src/vs-bicep/Install.cmd +++ b/src/vs-bicep/install.cmd @@ -17,19 +17,15 @@ echo VSIXInstaller.exe location: "%VSIXInstallerExe%" set BicepVsixPath=%ExtensionsRoot%Bicep.VSLanguageServerClient.Vsix\bin\%CONFIGURATION%\vs-bicep.vsix echo Bicep vsix location: %BicepVsixPath% -choice /M "Uninstall first? (Y/N)" -if errorlevel 2 goto skip_uninstall -taskkill /im devenv.exe /t /f 2>&1 | findstr /v "not found" -call "%VSIXInstallerExe%" /uninstall:ms-azuretools.visualstudio-bicep -goto do_install - -:skip_uninstall - +echo. choice /M "Install? (Y/N)" -if errorlevel 2 goto skip_install +if errorlevel 2 goto end + +echo. +echo Uninstalling current extension... +call "%VSIXInstallerExe%" /shutdownprocesses /quiet /uninstall:ms-azuretools.visualstudio-bicep -:do_install -taskkill /im devenv.exe /t /f 2>&1 | findstr /v "not found" -call "%VSIXInstallerExe%" "%BicepVsixPath%" +echo Installing extension... +call "%VSIXInstallerExe%" /force /shutdownprocesses /quiet "%BicepVsixPath%" -:skip_install +:end diff --git a/src/vs-bicep/patch.cmd b/src/vs-bicep/patch.cmd new file mode 100644 index 00000000000..fb02afcccb8 --- /dev/null +++ b/src/vs-bicep/patch.cmd @@ -0,0 +1,31 @@ +@if (%_echo%)==() echo off +setlocal + +set DEST=%1 + +if (%DEST%)==() ( + goto help +) + +if not exist "%DEST%\Bicep.VSLanguageServerClient.dll" ( + if not exist "%DEST%\LanguageServer\Bicep.LangServer.exe" ( + echo ** The specified location does not appear to be a valid Bicep for Visual Studio extension directory. ** + echo. + goto help + ) +) + +:help +echo You can quickly patch an existing installation if you know the correct destination location +echo (you can figure this out with the VS "modules" window after attaching to devenv.exe) +echo. +echo Example (note the quotes): +echo. +echo patch "C:\Users\\AppData\Local\Microsoft\VisualStudio\17.0_a219d5e7Exp\Extensions\Microsoft\Bicep for Visual Studio\0.28.171.25288" +exit /b 1 + +:start + +xcopy /s Bicep.VSLanguageServerClient\bin\Debug\net472\*.* %DEST% +xcopy /s ..\Bicep.LangServer\bin\Debug\net8.0\*.* %DEST%\LanguageServer + From b0f519c1fbde75342395b974ee06056734c829b9 Mon Sep 17 00:00:00 2001 From: "Stephen Weatherford (MSFT)" Date: Thu, 11 Jul 2024 11:15:11 -0700 Subject: [PATCH 2/9] speling :-) --- src/Bicep.LangServer/Handlers/BicepTextDocumentSyncHandler.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Bicep.LangServer/Handlers/BicepTextDocumentSyncHandler.cs b/src/Bicep.LangServer/Handlers/BicepTextDocumentSyncHandler.cs index 7a7670457d9..14357c0319b 100644 --- a/src/Bicep.LangServer/Handlers/BicepTextDocumentSyncHandler.cs +++ b/src/Bicep.LangServer/Handlers/BicepTextDocumentSyncHandler.cs @@ -66,7 +66,7 @@ public override Task Handle(DidOpenTextDocumentParams request, Cancellatio var documentUri = request.TextDocument.Uri; // If the documentUri corresponds to bicepconfig.json, we'll add an entry to activeBicepConfigCache. - if (ConfigurationHelper.IsBicepConfigFile(documentUri)) //potentialy copy this for bicep params + if (ConfigurationHelper.IsBicepConfigFile(documentUri)) //potentially copy this for bicep params { bicepConfigChangeHandler.HandleBicepConfigOpenEvent(documentUri); } From 8246b91dc893b3e25177ac7fd92bfd7c47007dd2 Mon Sep 17 00:00:00 2001 From: "Stephen Weatherford (MSFT)" Date: Thu, 11 Jul 2024 11:15:53 -0700 Subject: [PATCH 3/9] Fix Bicep in VS receiving messages --- .../Utils/DocumentSelectorFactory.cs | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/src/Bicep.LangServer/Utils/DocumentSelectorFactory.cs b/src/Bicep.LangServer/Utils/DocumentSelectorFactory.cs index 5489a5764e7..b2ee50b728a 100644 --- a/src/Bicep.LangServer/Utils/DocumentSelectorFactory.cs +++ b/src/Bicep.LangServer/Utils/DocumentSelectorFactory.cs @@ -7,17 +7,30 @@ namespace Bicep.LanguageServer.Utils { public class DocumentSelectorFactory { + // VS doesn't currently support language filters in the document selector, so we must give it a file pattern + private static string Glob(params string[] extensions) + { + return "**/*{" + string.Join(',', extensions) + "}"; + } + public static readonly TextDocumentFilter[] BicepAndParams = [ TextDocumentFilter.ForLanguage(LanguageConstants.LanguageId), - TextDocumentFilter.ForLanguage(LanguageConstants.ParamsLanguageId) + TextDocumentFilter.ForLanguage(LanguageConstants.ParamsLanguageId), + TextDocumentFilter.ForPattern(Glob(LanguageConstants.LanguageFileExtension, LanguageConstants.ParamsFileExtension)) ]; public static readonly TextDocumentFilter[] AllSupportedLangIds = [ - TextDocumentFilter.ForLanguage(LanguageConstants.LanguageId), + TextDocumentFilter.ForLanguage(LanguageConstants.LanguageId), TextDocumentFilter.ForLanguage(LanguageConstants.ParamsLanguageId), TextDocumentFilter.ForLanguage(LanguageConstants.JsoncLanguageId), TextDocumentFilter.ForLanguage(LanguageConstants.JsonLanguageId), - TextDocumentFilter.ForLanguage(LanguageConstants.ArmTemplateLanguageId) + TextDocumentFilter.ForLanguage(LanguageConstants.ArmTemplateLanguageId), + TextDocumentFilter.ForPattern(Glob( + LanguageConstants.LanguageFileExtension, + LanguageConstants.ParamsFileExtension, + LanguageConstants.JsoncFileExtension, + LanguageConstants.JsonFileExtension, + LanguageConstants.ArmTemplateFileExtension)) ]; public static TextDocumentSelector CreateForBicepAndParams() => new(BicepAndParams); From 4490ebffa7456d2ffe41a233914550b33709a2ae Mon Sep 17 00:00:00 2001 From: "Stephen Weatherford (MSFT)" Date: Fri, 12 Jul 2024 15:15:01 -0700 Subject: [PATCH 4/9] Make change only for VS --- .../Handlers/BicepCodeActionHandlerTests.cs | 3 +- .../BicepTextDocumentSyncHandlerTests.cs | 4 +- .../Handlers/BicepCodeActionHandler.cs | 6 ++- .../Handlers/BicepCodeLensHandler.cs | 6 ++- .../Handlers/BicepCompletionHandler.cs | 6 ++- .../Handlers/BicepDefinitionHandler.cs | 7 ++- .../BicepDocumentFormattingHandler.cs | 5 +- .../Handlers/BicepDocumentHighlightHandler.cs | 13 ++--- .../Handlers/BicepDocumentSymbolHandler.cs | 7 ++- .../Handlers/BicepHoverHandler.cs | 7 ++- .../Handlers/BicepReferencesHandler.cs | 13 ++--- .../Handlers/BicepRenameHandler.cs | 13 ++--- .../Handlers/BicepSemanticTokensHandler.cs | 13 ++--- .../Handlers/BicepSignatureHelpHandler.cs | 13 ++--- .../Handlers/BicepTextDocumentSyncHandler.cs | 6 ++- .../IServiceCollectionExtensions.cs | 6 ++- .../Options/BicepLangServerOptions.cs | 12 +++++ .../Options/IBicepLangServerOptions.cs | 12 +++++ src/Bicep.LangServer/Program.cs | 6 +++ src/Bicep.LangServer/Server.cs | 3 ++ .../Utils/DocumentSelectorFactory.cs | 53 ++++++++++--------- .../BicepLanguageServerClient.cs | 2 +- .../DidChangeWatchedFilesNotifier.cs | 2 +- 23 files changed, 123 insertions(+), 95 deletions(-) create mode 100644 src/Bicep.LangServer/Options/BicepLangServerOptions.cs create mode 100644 src/Bicep.LangServer/Options/IBicepLangServerOptions.cs diff --git a/src/Bicep.LangServer.UnitTests/Handlers/BicepCodeActionHandlerTests.cs b/src/Bicep.LangServer.UnitTests/Handlers/BicepCodeActionHandlerTests.cs index 6a645c8c4f5..d6e8b9888d0 100644 --- a/src/Bicep.LangServer.UnitTests/Handlers/BicepCodeActionHandlerTests.cs +++ b/src/Bicep.LangServer.UnitTests/Handlers/BicepCodeActionHandlerTests.cs @@ -8,6 +8,7 @@ using Bicep.LanguageServer; using Bicep.LanguageServer.Handlers; using Bicep.LanguageServer.Providers; +using Bicep.LanguageServer.Utils; using FluentAssertions; using Microsoft.VisualStudio.TestTools.UnitTesting; using OmniSharp.Extensions.LanguageServer.Protocol; @@ -62,7 +63,7 @@ private async Task> GetCodeActions( clientCapabilitiesProvider.Setup(m => m.DoesClientSupportShowDocumentRequest()).Returns(clientSupportShowDocumentRequestAndWorkspaceFolders); clientCapabilitiesProvider.Setup(m => m.DoesClientSupportWorkspaceFolders()).Returns(clientSupportShowDocumentRequestAndWorkspaceFolders); - var bicepEditLinterRuleHandler = new BicepCodeActionHandler(bicepCompilationManager, clientCapabilitiesProvider.Object); + var bicepEditLinterRuleHandler = new BicepCodeActionHandler(bicepCompilationManager, clientCapabilitiesProvider.Object, new DocumentSelectorFactory(null)); var range = new Range() { diff --git a/src/Bicep.LangServer.UnitTests/Handlers/BicepTextDocumentSyncHandlerTests.cs b/src/Bicep.LangServer.UnitTests/Handlers/BicepTextDocumentSyncHandlerTests.cs index 56bf2a5e46b..06609af9fbd 100644 --- a/src/Bicep.LangServer.UnitTests/Handlers/BicepTextDocumentSyncHandlerTests.cs +++ b/src/Bicep.LangServer.UnitTests/Handlers/BicepTextDocumentSyncHandlerTests.cs @@ -10,6 +10,7 @@ using Bicep.LanguageServer.Configuration; using Bicep.LanguageServer.Handlers; using Bicep.LanguageServer.Telemetry; +using Bicep.LanguageServer.Utils; using Microsoft.VisualStudio.TestTools.UnitTesting; using Moq; @@ -195,7 +196,8 @@ private async Task ChangeLinterRuleState(Mock telemetryProvi telemetryProvider.Object, new Workspace()); - var bicepTextDocumentSyncHandler = new BicepTextDocumentSyncHandler(compilationManager, bicepConfigChangeHandler); + + var bicepTextDocumentSyncHandler = new BicepTextDocumentSyncHandler(compilationManager, bicepConfigChangeHandler, new DocumentSelectorFactory(null)); await bicepTextDocumentSyncHandler.Handle(TextDocumentParamHelper.CreateDidOpenDocumentParams(bicepConfigUri, prevBicepConfigFileContents, 1), CancellationToken.None); diff --git a/src/Bicep.LangServer/Handlers/BicepCodeActionHandler.cs b/src/Bicep.LangServer/Handlers/BicepCodeActionHandler.cs index 7c7cb08bb2d..95320873940 100644 --- a/src/Bicep.LangServer/Handlers/BicepCodeActionHandler.cs +++ b/src/Bicep.LangServer/Handlers/BicepCodeActionHandler.cs @@ -32,11 +32,13 @@ public class BicepCodeActionHandler : CodeActionHandlerBase { private readonly IClientCapabilitiesProvider clientCapabilitiesProvider; private readonly ICompilationManager compilationManager; + private readonly DocumentSelectorFactory documentSelectorFactory; - public BicepCodeActionHandler(ICompilationManager compilationManager, IClientCapabilitiesProvider clientCapabilitiesProvider) + public BicepCodeActionHandler(ICompilationManager compilationManager, IClientCapabilitiesProvider clientCapabilitiesProvider, DocumentSelectorFactory documentSelectorFactory) { this.clientCapabilitiesProvider = clientCapabilitiesProvider; this.compilationManager = compilationManager; + this.documentSelectorFactory = documentSelectorFactory; } public override async Task Handle(CodeActionParams request, CancellationToken cancellationToken) @@ -237,7 +239,7 @@ private static CommandOrCodeAction CreateCodeFix(DocumentUri uri, CompilationCon protected override CodeActionRegistrationOptions CreateRegistrationOptions(CodeActionCapability capability, ClientCapabilities clientCapabilities) => new() { - DocumentSelector = DocumentSelectorFactory.CreateForBicepAndParams(), + DocumentSelector = documentSelectorFactory.CreateForBicepAndParams(), CodeActionKinds = new Container(CodeActionKind.QuickFix), ResolveProvider = false }; diff --git a/src/Bicep.LangServer/Handlers/BicepCodeLensHandler.cs b/src/Bicep.LangServer/Handlers/BicepCodeLensHandler.cs index b682ba6a273..ed0564bdb2e 100644 --- a/src/Bicep.LangServer/Handlers/BicepCodeLensHandler.cs +++ b/src/Bicep.LangServer/Handlers/BicepCodeLensHandler.cs @@ -14,10 +14,12 @@ namespace Bicep.LanguageServer.Handlers public class BicepCodeLensHandler : CodeLensHandlerBase { private readonly IModuleDispatcher moduleDispatcher; + private readonly DocumentSelectorFactory documentSelectorFactory; - public BicepCodeLensHandler(IModuleDispatcher moduleDispatcher) + public BicepCodeLensHandler(IModuleDispatcher moduleDispatcher, DocumentSelectorFactory documentSelectorFactory) { this.moduleDispatcher = moduleDispatcher; + this.documentSelectorFactory = documentSelectorFactory; } public override Task Handle(CodeLensParams request, CancellationToken cancellationToken) @@ -37,7 +39,7 @@ public override Task Handle(CodeLens request, CancellationToken cancel protected override CodeLensRegistrationOptions CreateRegistrationOptions(CodeLensCapability capability, ClientCapabilities clientCapabilities) => new() { DocumentSelector = new( - DocumentSelectorFactory.AllSupportedLangIds + documentSelectorFactory.CreateForAllSupportedLangIds() .Concat(TextDocumentFilter.ForScheme(LangServerConstants.ExternalSourceFileScheme))), ResolveProvider = false }; diff --git a/src/Bicep.LangServer/Handlers/BicepCompletionHandler.cs b/src/Bicep.LangServer/Handlers/BicepCompletionHandler.cs index 600ce4598d6..033ef01853a 100644 --- a/src/Bicep.LangServer/Handlers/BicepCompletionHandler.cs +++ b/src/Bicep.LangServer/Handlers/BicepCompletionHandler.cs @@ -19,13 +19,15 @@ public class BicepCompletionHandler : CompletionHandlerBase private readonly ICompilationManager compilationManager; private readonly ICompletionProvider completionProvider; private readonly IFeatureProviderFactory featureProviderFactory; + private readonly DocumentSelectorFactory documentSelectorFactory; - public BicepCompletionHandler(ILogger logger, ICompilationManager compilationManager, ICompletionProvider completionProvider, IFeatureProviderFactory featureProviderFactory) + public BicepCompletionHandler(ILogger logger, ICompilationManager compilationManager, ICompletionProvider completionProvider, IFeatureProviderFactory featureProviderFactory, DocumentSelectorFactory documentSelectorFactory) { this.logger = logger; this.compilationManager = compilationManager; this.completionProvider = completionProvider; this.featureProviderFactory = featureProviderFactory; + this.documentSelectorFactory = documentSelectorFactory; } public override async Task Handle(CompletionParams request, CancellationToken cancellationToken) @@ -63,7 +65,7 @@ public override Task Handle(CompletionItem request, Cancellation protected override CompletionRegistrationOptions CreateRegistrationOptions(CompletionCapability capability, ClientCapabilities clientCapabilities) => new() { - DocumentSelector = DocumentSelectorFactory.CreateForBicepAndParams(), + DocumentSelector = documentSelectorFactory.CreateForBicepAndParams(), AllCommitCharacters = new Container(), ResolveProvider = false, TriggerCharacters = new Container(":", " ", ".", "/", "'", "@", "{", "#", "?") diff --git a/src/Bicep.LangServer/Handlers/BicepDefinitionHandler.cs b/src/Bicep.LangServer/Handlers/BicepDefinitionHandler.cs index 3eb5b68e899..a7c31606379 100644 --- a/src/Bicep.LangServer/Handlers/BicepDefinitionHandler.cs +++ b/src/Bicep.LangServer/Handlers/BicepDefinitionHandler.cs @@ -40,6 +40,7 @@ public class BicepDefinitionHandler : DefinitionHandlerBase private readonly ILanguageServerFacade languageServer; private readonly IModuleDispatcher moduleDispatcher; private readonly IFeatureProviderFactory featureProviderFactory; + private readonly DocumentSelectorFactory documentSelectorFactory; public BicepDefinitionHandler( ISymbolResolver symbolResolver, @@ -47,7 +48,8 @@ public BicepDefinitionHandler( IFileResolver fileResolver, ILanguageServerFacade languageServer, IModuleDispatcher moduleDispatcher, - IFeatureProviderFactory featureProviderFactory) : base() + IFeatureProviderFactory featureProviderFactory, + DocumentSelectorFactory documentSelectorFactory) : base() { this.symbolResolver = symbolResolver; this.compilationManager = compilationManager; @@ -55,6 +57,7 @@ public BicepDefinitionHandler( this.languageServer = languageServer; this.moduleDispatcher = moduleDispatcher; this.featureProviderFactory = featureProviderFactory; + this.documentSelectorFactory = documentSelectorFactory; } public override async Task Handle(DefinitionParams request, CancellationToken cancellationToken) @@ -98,7 +101,7 @@ public BicepDefinitionHandler( protected override DefinitionRegistrationOptions CreateRegistrationOptions(DefinitionCapability capability, ClientCapabilities clientCapabilities) => new() { - DocumentSelector = DocumentSelectorFactory.CreateForBicepAndParams() + DocumentSelector = documentSelectorFactory.CreateForBicepAndParams() }; private LocationOrLocationLinks HandleUnboundSymbolLocation(DefinitionParams request, CompilationContext context) diff --git a/src/Bicep.LangServer/Handlers/BicepDocumentFormattingHandler.cs b/src/Bicep.LangServer/Handlers/BicepDocumentFormattingHandler.cs index 2c5304702c6..79940571b33 100644 --- a/src/Bicep.LangServer/Handlers/BicepDocumentFormattingHandler.cs +++ b/src/Bicep.LangServer/Handlers/BicepDocumentFormattingHandler.cs @@ -15,7 +15,8 @@ namespace Bicep.LanguageServer.Handlers { public class BicepDocumentFormattingHandler( ILogger logger, - ICompilationManager compilationManager) : DocumentFormattingHandlerBase + ICompilationManager compilationManager, + DocumentSelectorFactory documentSelectorFactory) : DocumentFormattingHandlerBase { public override Task Handle(DocumentFormattingParams request, CancellationToken cancellationToken) { @@ -64,7 +65,7 @@ public class BicepDocumentFormattingHandler( protected override DocumentFormattingRegistrationOptions CreateRegistrationOptions(DocumentFormattingCapability capability, ClientCapabilities clientCapabilities) => new() { - DocumentSelector = DocumentSelectorFactory.CreateForBicepAndParams() + DocumentSelector = documentSelectorFactory.CreateForBicepAndParams() }; } } diff --git a/src/Bicep.LangServer/Handlers/BicepDocumentHighlightHandler.cs b/src/Bicep.LangServer/Handlers/BicepDocumentHighlightHandler.cs index a219a7059c3..ae622a219a7 100644 --- a/src/Bicep.LangServer/Handlers/BicepDocumentHighlightHandler.cs +++ b/src/Bicep.LangServer/Handlers/BicepDocumentHighlightHandler.cs @@ -10,18 +10,11 @@ namespace Bicep.LanguageServer.Handlers { - public class BicepDocumentHighlightHandler : DocumentHighlightHandlerBase + public class BicepDocumentHighlightHandler(ISymbolResolver symbolResolver, DocumentSelectorFactory documentSelectorFactory) : DocumentHighlightHandlerBase { - private readonly ISymbolResolver symbolResolver; - - public BicepDocumentHighlightHandler(ISymbolResolver symbolResolver) : base() - { - this.symbolResolver = symbolResolver; - } - public override Task Handle(DocumentHighlightParams request, CancellationToken cancellationToken) { - var result = this.symbolResolver.ResolveSymbol(request.TextDocument.Uri, request.Position); + var result = symbolResolver.ResolveSymbol(request.TextDocument.Uri, request.Position); if (result == null) { return Task.FromResult(null); @@ -45,7 +38,7 @@ public BicepDocumentHighlightHandler(ISymbolResolver symbolResolver) : base() protected override DocumentHighlightRegistrationOptions CreateRegistrationOptions(DocumentHighlightCapability capability, ClientCapabilities clientCapabilities) => new() { - DocumentSelector = DocumentSelectorFactory.CreateForBicepAndParams() + DocumentSelector = documentSelectorFactory.CreateForBicepAndParams() }; } } diff --git a/src/Bicep.LangServer/Handlers/BicepDocumentSymbolHandler.cs b/src/Bicep.LangServer/Handlers/BicepDocumentSymbolHandler.cs index e358adebed2..f9ea767c8d9 100644 --- a/src/Bicep.LangServer/Handlers/BicepDocumentSymbolHandler.cs +++ b/src/Bicep.LangServer/Handlers/BicepDocumentSymbolHandler.cs @@ -1,6 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. using System.Collections.Immutable; +using System.DirectoryServices.AccountManagement; using Bicep.Core.Semantics; using Bicep.Core.Syntax; using Bicep.LanguageServer.CompilationManager; @@ -18,11 +19,13 @@ public class BicepDocumentSymbolHandler : DocumentSymbolHandlerBase { private readonly ILogger logger; private readonly ICompilationManager compilationManager; + private readonly DocumentSelectorFactory documentSelectorFactory; - public BicepDocumentSymbolHandler(ILogger logger, ICompilationManager compilationManager) + public BicepDocumentSymbolHandler(ILogger logger, ICompilationManager compilationManager, DocumentSelectorFactory documentSelectorFactory) { this.logger = logger; this.compilationManager = compilationManager; + this.documentSelectorFactory = documentSelectorFactory; } public override async Task Handle(DocumentSymbolParams request, CancellationToken cancellationToken) @@ -104,7 +107,7 @@ private DocumentSymbol CreateDocumentSymbol(SemanticModel model, DeclaredSymbol protected override DocumentSymbolRegistrationOptions CreateRegistrationOptions(DocumentSymbolCapability capability, ClientCapabilities clientCapabilities) => new() { - DocumentSelector = DocumentSelectorFactory.CreateForBicepAndParams() + DocumentSelector = documentSelectorFactory.CreateForBicepAndParams() }; } } diff --git a/src/Bicep.LangServer/Handlers/BicepHoverHandler.cs b/src/Bicep.LangServer/Handlers/BicepHoverHandler.cs index 11b5637a8bb..4adf0af367b 100644 --- a/src/Bicep.LangServer/Handlers/BicepHoverHandler.cs +++ b/src/Bicep.LangServer/Handlers/BicepHoverHandler.cs @@ -25,15 +25,18 @@ public class BicepHoverHandler : HoverHandlerBase private readonly IModuleDispatcher moduleDispatcher; private readonly IArtifactRegistryProvider moduleRegistryProvider; private readonly ISymbolResolver symbolResolver; + private readonly DocumentSelectorFactory documentSelectorFactory; public BicepHoverHandler( IModuleDispatcher moduleDispatcher, IArtifactRegistryProvider moduleRegistryProvider, - ISymbolResolver symbolResolver) + ISymbolResolver symbolResolver, + DocumentSelectorFactory documentSelectorFactory) { this.moduleDispatcher = moduleDispatcher; this.moduleRegistryProvider = moduleRegistryProvider; this.symbolResolver = symbolResolver; + this.documentSelectorFactory = documentSelectorFactory; } public override async Task Handle(HoverParams request, CancellationToken cancellationToken) @@ -341,7 +344,7 @@ private static MarkedStringsOrMarkupContent AsMarkdown(IEnumerable markd protected override HoverRegistrationOptions CreateRegistrationOptions(HoverCapability capability, ClientCapabilities clientCapabilities) => new() { - DocumentSelector = DocumentSelectorFactory.CreateForBicepAndParams() + DocumentSelector = documentSelectorFactory.CreateForBicepAndParams() }; } } diff --git a/src/Bicep.LangServer/Handlers/BicepReferencesHandler.cs b/src/Bicep.LangServer/Handlers/BicepReferencesHandler.cs index 7906b57e370..2b1993619f6 100644 --- a/src/Bicep.LangServer/Handlers/BicepReferencesHandler.cs +++ b/src/Bicep.LangServer/Handlers/BicepReferencesHandler.cs @@ -10,19 +10,12 @@ namespace Bicep.LanguageServer.Handlers { - public class BicepReferencesHandler : ReferencesHandlerBase + public class BicepReferencesHandler(ISymbolResolver symbolResolver, DocumentSelectorFactory documentSelectorFactory) : ReferencesHandlerBase { - private readonly ISymbolResolver symbolResolver; - - public BicepReferencesHandler(ISymbolResolver symbolResolver) - { - this.symbolResolver = symbolResolver; - } - public override async Task Handle(ReferenceParams request, CancellationToken cancellationToken) { await Task.CompletedTask; - var result = this.symbolResolver.ResolveSymbol(request.TextDocument.Uri, request.Position); + var result = symbolResolver.ResolveSymbol(request.TextDocument.Uri, request.Position); if (result == null) { return null; @@ -48,7 +41,7 @@ public BicepReferencesHandler(ISymbolResolver symbolResolver) protected override ReferenceRegistrationOptions CreateRegistrationOptions(ReferenceCapability capability, ClientCapabilities clientCapabilities) => new() { - DocumentSelector = DocumentSelectorFactory.CreateForBicepAndParams() + DocumentSelector = documentSelectorFactory.CreateForBicepAndParams() }; } } diff --git a/src/Bicep.LangServer/Handlers/BicepRenameHandler.cs b/src/Bicep.LangServer/Handlers/BicepRenameHandler.cs index a89a688e874..73ced90e230 100644 --- a/src/Bicep.LangServer/Handlers/BicepRenameHandler.cs +++ b/src/Bicep.LangServer/Handlers/BicepRenameHandler.cs @@ -14,18 +14,11 @@ namespace Bicep.LanguageServer.Handlers { - public class BicepRenameHandler : RenameHandlerBase + public class BicepRenameHandler(ISymbolResolver symbolResolver, DocumentSelectorFactory documentSelectorFactory) : RenameHandlerBase { - private readonly ISymbolResolver symbolResolver; - - public BicepRenameHandler(ISymbolResolver symbolResolver) : base() - { - this.symbolResolver = symbolResolver; - } - public override Task Handle(RenameParams request, CancellationToken cancellationToken) { - var result = this.symbolResolver.ResolveSymbol(request.TextDocument.Uri, request.Position); + var result = symbolResolver.ResolveSymbol(request.TextDocument.Uri, request.Position); if (result == null || !(result.Symbol is DeclaredSymbol)) { // result is not a symbol or it's a built-in symbol that was not declared by the user (namespaces, functions, for example) @@ -89,7 +82,7 @@ public BicepRenameHandler(ISymbolResolver symbolResolver) : base() protected override RenameRegistrationOptions CreateRegistrationOptions(RenameCapability capability, ClientCapabilities clientCapabilities) => new() { - DocumentSelector = DocumentSelectorFactory.CreateForBicepAndParams(), + DocumentSelector = documentSelectorFactory.CreateForBicepAndParams(), PrepareProvider = false }; } diff --git a/src/Bicep.LangServer/Handlers/BicepSemanticTokensHandler.cs b/src/Bicep.LangServer/Handlers/BicepSemanticTokensHandler.cs index a77a10eea8d..98ff3a6ee25 100644 --- a/src/Bicep.LangServer/Handlers/BicepSemanticTokensHandler.cs +++ b/src/Bicep.LangServer/Handlers/BicepSemanticTokensHandler.cs @@ -8,18 +8,11 @@ namespace Bicep.LanguageServer.Handlers { - public class BicepSemanticTokensHandler : SemanticTokensHandlerBase + public class BicepSemanticTokensHandler(ICompilationManager compilationManager, DocumentSelectorFactory documentSelectorFactory) : SemanticTokensHandlerBase { - private readonly ICompilationManager compilationManager; - // TODO: Not sure if this needs to be shared. private readonly SemanticTokensLegend legend = new(); - public BicepSemanticTokensHandler(ICompilationManager compilationManager) - { - this.compilationManager = compilationManager; - } - protected override Task GetSemanticTokensDocument(ITextDocumentIdentifierParams @params, CancellationToken cancellationToken) { return Task.FromResult(new SemanticTokensDocument(this.legend)); @@ -31,7 +24,7 @@ protected override Task Tokenize(SemanticTokensBuilder builder, ITextDocumentIde * do not check for file extension here because that will prevent untitled files from getting syntax highlighting */ - var compilationContext = this.compilationManager.GetCompilation(identifier.TextDocument.Uri); + var compilationContext = compilationManager.GetCompilation(identifier.TextDocument.Uri); if (compilationContext is not null) { SemanticTokenVisitor.BuildSemanticTokens(builder, compilationContext.Compilation.GetEntrypointSemanticModel()); @@ -44,7 +37,7 @@ protected override Task Tokenize(SemanticTokensBuilder builder, ITextDocumentIde { // the semantic tokens handler requests don't get routed like other handlers // it seems we can only have one and it must be shared between all the language IDs we support - DocumentSelector = DocumentSelectorFactory.CreateForBicepAndParams(), + DocumentSelector = documentSelectorFactory.CreateForBicepAndParams(), Legend = this.legend, Full = new SemanticTokensCapabilityRequestFull { diff --git a/src/Bicep.LangServer/Handlers/BicepSignatureHelpHandler.cs b/src/Bicep.LangServer/Handlers/BicepSignatureHelpHandler.cs index af849a50a98..cd344f99c71 100644 --- a/src/Bicep.LangServer/Handlers/BicepSignatureHelpHandler.cs +++ b/src/Bicep.LangServer/Handlers/BicepSignatureHelpHandler.cs @@ -19,25 +19,18 @@ namespace Bicep.LanguageServer.Handlers { - public class BicepSignatureHelpHandler : SignatureHelpHandlerBase + public class BicepSignatureHelpHandler(ICompilationManager compilationManager, DocumentSelectorFactory documentSelectorFactory) : SignatureHelpHandlerBase { private const string FunctionArgumentStart = "("; private const string FunctionArgumentEnd = ")"; private const string TypeArgumentsStart = "<"; private const string TypeArgumentsEnd = ">"; - private readonly ICompilationManager compilationManager; - - public BicepSignatureHelpHandler(ICompilationManager compilationManager) - { - this.compilationManager = compilationManager; - } - public override Task Handle(SignatureHelpParams request, CancellationToken cancellationToken) { // local function - CompilationContext? context = this.compilationManager.GetCompilation(request.TextDocument.Uri); + CompilationContext? context = compilationManager.GetCompilation(request.TextDocument.Uri); if (context == null) { return NoHelp(); @@ -371,7 +364,7 @@ private static SignatureInformation CreateSignature(TypeTemplate typeTemplate, s protected override SignatureHelpRegistrationOptions CreateRegistrationOptions(SignatureHelpCapability capability, ClientCapabilities clientCapabilities) => new() { - DocumentSelector = DocumentSelectorFactory.CreateForBicepAndParams(), + DocumentSelector = documentSelectorFactory.CreateForBicepAndParams(), /* * ( - triggers sig. help when starting function arguments * , - separates function arguments diff --git a/src/Bicep.LangServer/Handlers/BicepTextDocumentSyncHandler.cs b/src/Bicep.LangServer/Handlers/BicepTextDocumentSyncHandler.cs index 14357c0319b..56eb086f2d1 100644 --- a/src/Bicep.LangServer/Handlers/BicepTextDocumentSyncHandler.cs +++ b/src/Bicep.LangServer/Handlers/BicepTextDocumentSyncHandler.cs @@ -18,11 +18,13 @@ public class BicepTextDocumentSyncHandler : TextDocumentSyncHandlerBase { private readonly ICompilationManager compilationManager; private readonly IBicepConfigChangeHandler bicepConfigChangeHandler; + private readonly DocumentSelectorFactory documentSelectorFactory; - public BicepTextDocumentSyncHandler(ICompilationManager compilationManager, IBicepConfigChangeHandler bicepConfigChangeHandler) + public BicepTextDocumentSyncHandler(ICompilationManager compilationManager, IBicepConfigChangeHandler bicepConfigChangeHandler, DocumentSelectorFactory documentSelectorFactory) { this.bicepConfigChangeHandler = bicepConfigChangeHandler; this.compilationManager = compilationManager; + this.documentSelectorFactory = documentSelectorFactory; } public override TextDocumentAttributes GetTextDocumentAttributes(DocumentUri uri) @@ -110,7 +112,7 @@ public override Task Handle(DidCloseTextDocumentParams request, Cancellati protected override TextDocumentSyncRegistrationOptions CreateRegistrationOptions(TextSynchronizationCapability capability, ClientCapabilities clientCapabilities) => new() { Change = TextDocumentSyncKind.Full, - DocumentSelector = DocumentSelectorFactory.CreateForAllSupportedLangIds() + DocumentSelector = documentSelectorFactory.CreateForAllSupportedLangIds() }; } } diff --git a/src/Bicep.LangServer/IServiceCollectionExtensions.cs b/src/Bicep.LangServer/IServiceCollectionExtensions.cs index c896d312781..ffe7c469829 100644 --- a/src/Bicep.LangServer/IServiceCollectionExtensions.cs +++ b/src/Bicep.LangServer/IServiceCollectionExtensions.cs @@ -19,11 +19,13 @@ using Bicep.LanguageServer.Completions; using Bicep.LanguageServer.Configuration; using Bicep.LanguageServer.Deploy; +using Bicep.LanguageServer.Options; using Bicep.LanguageServer.Providers; using Bicep.LanguageServer.Registry; using Bicep.LanguageServer.Settings; using Bicep.LanguageServer.Snippets; using Bicep.LanguageServer.Telemetry; +using Bicep.LanguageServer.Utils; using Microsoft.Extensions.DependencyInjection; using IOFileSystem = System.IO.Abstractions.FileSystem; @@ -74,5 +76,7 @@ public static IServiceCollection AddServerDependencies(this IServiceCollection s .AddSingleton() .AddSingleton() .AddSingleton() - .AddSingleton(); + .AddSingleton() + .AddSingleton() + .AddSingleton(); } diff --git a/src/Bicep.LangServer/Options/BicepLangServerOptions.cs b/src/Bicep.LangServer/Options/BicepLangServerOptions.cs new file mode 100644 index 00000000000..6c5d95b3ac7 --- /dev/null +++ b/src/Bicep.LangServer/Options/BicepLangServerOptions.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Bicep.LanguageServer.Options; + +public class BicepLangServerOptions : IBicepLangServerOptions +{ + public bool VsCompatibilityMode { get; set; } +} diff --git a/src/Bicep.LangServer/Options/IBicepLangServerOptions.cs b/src/Bicep.LangServer/Options/IBicepLangServerOptions.cs new file mode 100644 index 00000000000..c9e8b18485d --- /dev/null +++ b/src/Bicep.LangServer/Options/IBicepLangServerOptions.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Bicep.LanguageServer.Options; + +public interface IBicepLangServerOptions +{ + public bool VsCompatibilityMode { get; set; } +} diff --git a/src/Bicep.LangServer/Program.cs b/src/Bicep.LangServer/Program.cs index a16b13f1d7f..1c0c77a5dbb 100644 --- a/src/Bicep.LangServer/Program.cs +++ b/src/Bicep.LangServer/Program.cs @@ -6,6 +6,7 @@ using System.Net.Sockets; using System.Runtime; using Bicep.Core.Utils; +using Bicep.LanguageServer.Options; using CommandLine; namespace Bicep.LanguageServer @@ -25,6 +26,9 @@ public class CommandLineOptions [Option("wait-for-debugger", Required = false, HelpText = "If set, wait for a dotnet debugger to be attached before starting the server")] public bool WaitForDebugger { get; set; } + + [Option("vs-compatibility-mode", Required = false, HelpText = "If set, runs in a mode to better support Visual Studio as a host")] + public bool VsCompatibilityMode { get; set; } } public static async Task Main(string[] args) @@ -101,6 +105,8 @@ private static async Task RunServer(CommandLineOptions options, CancellationToke .WithOutput(Console.OpenStandardOutput())); } + server.GetRequiredService().VsCompatibilityMode = options.VsCompatibilityMode; + await server.RunAsync(cancellationToken); } diff --git a/src/Bicep.LangServer/Server.cs b/src/Bicep.LangServer/Server.cs index 1814bac604a..06c8266d5cd 100644 --- a/src/Bicep.LangServer/Server.cs +++ b/src/Bicep.LangServer/Server.cs @@ -24,6 +24,9 @@ public class Server : IDisposable { private readonly OmnisharpLanguageServer server; + public T? GetService() => server.GetService(); + public T GetRequiredService() where T : notnull => server.GetRequiredService(); + public Server(Action onOptionsFunc) { server = OmnisharpLanguageServer.PreInit(options => diff --git a/src/Bicep.LangServer/Utils/DocumentSelectorFactory.cs b/src/Bicep.LangServer/Utils/DocumentSelectorFactory.cs index b2ee50b728a..f7308dcc385 100644 --- a/src/Bicep.LangServer/Utils/DocumentSelectorFactory.cs +++ b/src/Bicep.LangServer/Utils/DocumentSelectorFactory.cs @@ -1,40 +1,45 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. + using Bicep.Core; +using Bicep.LanguageServer.Settings; using OmniSharp.Extensions.LanguageServer.Protocol.Models; +using Azure.Deployments.Core.Extensions; +using Bicep.LanguageServer.Options; namespace Bicep.LanguageServer.Utils { - public class DocumentSelectorFactory + public class DocumentSelectorFactory(IBicepLangServerOptions? langServerOptions) { - // VS doesn't currently support language filters in the document selector, so we must give it a file pattern private static string Glob(params string[] extensions) { - return "**/*{" + string.Join(',', extensions) + "}"; + return "**/*{" + string.Join(',', extensions) + "}"; } - public static readonly TextDocumentFilter[] BicepAndParams = [ - TextDocumentFilter.ForLanguage(LanguageConstants.LanguageId), - TextDocumentFilter.ForLanguage(LanguageConstants.ParamsLanguageId), - TextDocumentFilter.ForPattern(Glob(LanguageConstants.LanguageFileExtension, LanguageConstants.ParamsFileExtension)) - ]; - - public static readonly TextDocumentFilter[] AllSupportedLangIds = [ - TextDocumentFilter.ForLanguage(LanguageConstants.LanguageId), - TextDocumentFilter.ForLanguage(LanguageConstants.ParamsLanguageId), - TextDocumentFilter.ForLanguage(LanguageConstants.JsoncLanguageId), - TextDocumentFilter.ForLanguage(LanguageConstants.JsonLanguageId), - TextDocumentFilter.ForLanguage(LanguageConstants.ArmTemplateLanguageId), - TextDocumentFilter.ForPattern(Glob( - LanguageConstants.LanguageFileExtension, - LanguageConstants.ParamsFileExtension, - LanguageConstants.JsoncFileExtension, - LanguageConstants.JsonFileExtension, - LanguageConstants.ArmTemplateFileExtension)) - ]; + public TextDocumentSelector CreateForBicepAndParams() => new( + langServerOptions?.VsCompatibilityMode == true + // VS doesn't currently support language filters in the document selector, so we must give it a file pattern + ? [TextDocumentFilter.ForPattern(Glob(LanguageConstants.LanguageFileExtension, LanguageConstants.ParamsFileExtension))] + : [TextDocumentFilter.ForLanguage(LanguageConstants.LanguageId), TextDocumentFilter.ForLanguage(LanguageConstants.ParamsLanguageId)] + ); - public static TextDocumentSelector CreateForBicepAndParams() => new(BicepAndParams); - public static TextDocumentSelector CreateForAllSupportedLangIds() => new(AllSupportedLangIds); + public TextDocumentSelector CreateForAllSupportedLangIds() => new( + langServerOptions?.VsCompatibilityMode == true + ? [ + // VS doesn't currently support language filters in the document selector, so we must give it a file pattern + TextDocumentFilter.ForPattern(Glob( + LanguageConstants.LanguageFileExtension, + LanguageConstants.ParamsFileExtension, + LanguageConstants.JsoncFileExtension, + LanguageConstants.JsonFileExtension, + LanguageConstants.ArmTemplateFileExtension)) + ] : [ + TextDocumentFilter.ForLanguage(LanguageConstants.LanguageId), + TextDocumentFilter.ForLanguage(LanguageConstants.ParamsLanguageId), + TextDocumentFilter.ForLanguage(LanguageConstants.JsoncLanguageId), + TextDocumentFilter.ForLanguage(LanguageConstants.JsonLanguageId), + TextDocumentFilter.ForLanguage(LanguageConstants.ArmTemplateLanguageId) + ]); } } diff --git a/src/vs-bicep/Bicep.VSLanguageServerClient/BicepLanguageServerClient.cs b/src/vs-bicep/Bicep.VSLanguageServerClient/BicepLanguageServerClient.cs index e7260bc099c..fb8955bf66f 100644 --- a/src/vs-bicep/Bicep.VSLanguageServerClient/BicepLanguageServerClient.cs +++ b/src/vs-bicep/Bicep.VSLanguageServerClient/BicepLanguageServerClient.cs @@ -73,7 +73,7 @@ public BicepLanguageServerClient(IProcessTracker processTracker) string languageServerExePath = Path.Combine(vsixInstallPath, BicepLanguageServerClientConstants.BicepLanguageServerInstallationSubPath, "Bicep.LangServer.exe"); var launchServerArguments = $" --contentType {BicepLanguageServerClientConstants.BicepContentType}" + - $" --lcid {Thread.CurrentThread.CurrentUICulture.LCID}"; + $" --lcid {Thread.CurrentThread.CurrentUICulture.LCID} --vs-compatibility-mode"; await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(); diff --git a/src/vs-bicep/Bicep.VSLanguageServerClient/DidChangeWatchedFilesNotifier.cs b/src/vs-bicep/Bicep.VSLanguageServerClient/DidChangeWatchedFilesNotifier.cs index 686542f7fea..b95c50defca 100644 --- a/src/vs-bicep/Bicep.VSLanguageServerClient/DidChangeWatchedFilesNotifier.cs +++ b/src/vs-bicep/Bicep.VSLanguageServerClient/DidChangeWatchedFilesNotifier.cs @@ -22,7 +22,7 @@ namespace Bicep.VSLanguageServerClient /// public class DidChangeWatchedFilesNotifier : IDisposable { - private readonly string[] filters = ["*.arm", "*.bicep", "*.json", "*.jsonc"]; + private readonly string[] filters = ["*.arm", "*.bicep", "*.json", "*.jsonc", "*.bicepparam"]; private readonly string? location; private readonly JsonRpc rpc; private List fileSystemWatchers = new(); From bfa4473f2be0d8796df887fa6e6de4bbf3ac1daa Mon Sep 17 00:00:00 2001 From: "Stephen Weatherford (MSFT)" Date: Mon, 15 Jul 2024 09:29:19 -0700 Subject: [PATCH 5/9] fix script --- src/vs-bicep/install.cmd | 4 +++- src/vs-bicep/patch.cmd | 24 ++++++++++++------------ 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/src/vs-bicep/install.cmd b/src/vs-bicep/install.cmd index 90e41258150..125d2b4ceac 100644 --- a/src/vs-bicep/install.cmd +++ b/src/vs-bicep/install.cmd @@ -23,9 +23,11 @@ if errorlevel 2 goto end echo. echo Uninstalling current extension... +taskkill /im:Bicep.LangServer.exe /f +taskkill /im:devenv.exe /f call "%VSIXInstallerExe%" /shutdownprocesses /quiet /uninstall:ms-azuretools.visualstudio-bicep echo Installing extension... -call "%VSIXInstallerExe%" /force /shutdownprocesses /quiet "%BicepVsixPath%" +call "%VSIXInstallerExe%" /shutdownprocesses /quiet /force "%BicepVsixPath%" :end diff --git a/src/vs-bicep/patch.cmd b/src/vs-bicep/patch.cmd index fb02afcccb8..b9b4bcf1b82 100644 --- a/src/vs-bicep/patch.cmd +++ b/src/vs-bicep/patch.cmd @@ -1,19 +1,20 @@ -@if (%_echo%)==() echo off -setlocal +@if "%_echo%"=="" echo off +setlocal enableextensions -set DEST=%1 +set DEST="%~1" -if (%DEST%)==() ( +if %DEST% equ "" ( goto help ) -if not exist "%DEST%\Bicep.VSLanguageServerClient.dll" ( - if not exist "%DEST%\LanguageServer\Bicep.LangServer.exe" ( - echo ** The specified location does not appear to be a valid Bicep for Visual Studio extension directory. ** - echo. - goto help - ) -) +if not exist %DEST%\Bicep.VSLanguageServerClient.dll goto badpath +if not exist %DEST%\LanguageServer\Bicep.LangServer.exe goto badpath +goto :start + +:badpath +echo ** The specified location does not appear to be a valid Bicep for Visual Studio extension directory. ** +echo. +goto help :help echo You can quickly patch an existing installation if you know the correct destination location @@ -28,4 +29,3 @@ exit /b 1 xcopy /s Bicep.VSLanguageServerClient\bin\Debug\net472\*.* %DEST% xcopy /s ..\Bicep.LangServer\bin\Debug\net8.0\*.* %DEST%\LanguageServer - From eeff892f105d1a4ddd87ab861266e2984b8f1110 Mon Sep 17 00:00:00 2001 From: "Stephen Weatherford (MSFT)" Date: Mon, 15 Jul 2024 17:13:54 -0700 Subject: [PATCH 6/9] Require 17.10 or higher --- .../source.extension.vsixmanifest | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs-bicep/Bicep.VSLanguageServerClient.Vsix/source.extension.vsixmanifest b/src/vs-bicep/Bicep.VSLanguageServerClient.Vsix/source.extension.vsixmanifest index 2d581d6d01c..dddaf9ab483 100644 --- a/src/vs-bicep/Bicep.VSLanguageServerClient.Vsix/source.extension.vsixmanifest +++ b/src/vs-bicep/Bicep.VSLanguageServerClient.Vsix/source.extension.vsixmanifest @@ -8,7 +8,7 @@ Icons\bicep-logo-256.png - + amd64 @@ -21,6 +21,6 @@ - + From 5df10849ca3924af598f5b4905348b5cc7016a92 Mon Sep 17 00:00:00 2001 From: "Stephen Weatherford (MSFT)" Date: Tue, 16 Jul 2024 12:57:03 -0700 Subject: [PATCH 7/9] CR: Improve DI initizliation --- .../Helpers/LanguageServerHelper.cs | 3 +++ .../IServiceCollectionExtensions.cs | 7 +++++-- src/Bicep.LangServer/Program.cs | 8 ++++++-- src/Bicep.LangServer/Server.cs | 14 +++----------- src/Bicep.Tools.Benchmark/LanguageServer.cs | 15 +++++++++------ 5 files changed, 26 insertions(+), 21 deletions(-) diff --git a/src/Bicep.LangServer.IntegrationTests/Helpers/LanguageServerHelper.cs b/src/Bicep.LangServer.IntegrationTests/Helpers/LanguageServerHelper.cs index 4a5878f5b7f..ab1f766d98c 100644 --- a/src/Bicep.LangServer.IntegrationTests/Helpers/LanguageServerHelper.cs +++ b/src/Bicep.LangServer.IntegrationTests/Helpers/LanguageServerHelper.cs @@ -1,12 +1,14 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. using System.IO.Pipelines; +using System.Security.Cryptography.Xml; using Bicep.Core.Tracing; using Bicep.Core.UnitTests; using Bicep.Core.UnitTests.FileSystem; using Bicep.Core.UnitTests.Utils; using Bicep.LangServer.IntegrationTests.Helpers; using Bicep.LanguageServer; +using Bicep.LanguageServer.Options; using Microsoft.Extensions.DependencyInjection; using Microsoft.VisualStudio.TestTools.UnitTesting; using OmniSharp.Extensions.LanguageServer.Client; @@ -39,6 +41,7 @@ public static async Task StartServer(TestContext testConte var serverPipe = new Pipe(); var server = new Server( + new BicepLangServerOptions(), options => options .WithInput(serverPipe.Reader) .WithOutput(clientPipe.Writer) diff --git a/src/Bicep.LangServer/IServiceCollectionExtensions.cs b/src/Bicep.LangServer/IServiceCollectionExtensions.cs index ffe7c469829..86b60a5923e 100644 --- a/src/Bicep.LangServer/IServiceCollectionExtensions.cs +++ b/src/Bicep.LangServer/IServiceCollectionExtensions.cs @@ -54,7 +54,10 @@ public static IServiceCollection AddBicepCore(this IServiceCollection services) public static IServiceCollection AddBicepDecompiler(this IServiceCollection services) => services .AddSingleton(); - public static IServiceCollection AddServerDependencies(this IServiceCollection services) => services + public static IServiceCollection AddServerDependencies( + this IServiceCollection services, + IBicepLangServerOptions bicepLangServerOptions + ) => services .AddBicepCore() .AddBicepDecompiler() .AddSingleton() @@ -77,6 +80,6 @@ public static IServiceCollection AddServerDependencies(this IServiceCollection s .AddSingleton() .AddSingleton() .AddSingleton() - .AddSingleton() + .AddSingleton(bicepLangServerOptions) .AddSingleton(); } diff --git a/src/Bicep.LangServer/Program.cs b/src/Bicep.LangServer/Program.cs index 1c0c77a5dbb..40c4e0eceba 100644 --- a/src/Bicep.LangServer/Program.cs +++ b/src/Bicep.LangServer/Program.cs @@ -66,6 +66,9 @@ private static async Task RunServer(CommandLineOptions options, CancellationToke } Server server; + + var bicepLangServerOptions = new BicepLangServerOptions() { VsCompatibilityMode = options.VsCompatibilityMode }; + if (options.Pipe is { } pipeName) { if (pipeName.StartsWith(@"\\.\pipe\")) @@ -79,6 +82,7 @@ private static async Task RunServer(CommandLineOptions options, CancellationToke await clientPipe.ConnectAsync(cancellationToken); server = new( + bicepLangServerOptions, options => options .WithInput(clientPipe) .WithOutput(clientPipe) @@ -92,6 +96,7 @@ private static async Task RunServer(CommandLineOptions options, CancellationToke var tcpStream = tcpClient.GetStream(); server = new( + bicepLangServerOptions, options => options .WithInput(tcpStream) .WithOutput(tcpStream) @@ -100,13 +105,12 @@ private static async Task RunServer(CommandLineOptions options, CancellationToke else { server = new( + bicepLangServerOptions, options => options .WithInput(Console.OpenStandardInput()) .WithOutput(Console.OpenStandardOutput())); } - server.GetRequiredService().VsCompatibilityMode = options.VsCompatibilityMode; - await server.RunAsync(cancellationToken); } diff --git a/src/Bicep.LangServer/Server.cs b/src/Bicep.LangServer/Server.cs index 06c8266d5cd..5650c0c5cca 100644 --- a/src/Bicep.LangServer/Server.cs +++ b/src/Bicep.LangServer/Server.cs @@ -8,6 +8,7 @@ using Bicep.Core.Registry.PublicRegistry; using Bicep.Core.Tracing; using Bicep.LanguageServer.Handlers; +using Bicep.LanguageServer.Options; using Bicep.LanguageServer.Providers; using Bicep.LanguageServer.Registry; using Bicep.LanguageServer.Settings; @@ -23,11 +24,7 @@ namespace Bicep.LanguageServer public class Server : IDisposable { private readonly OmnisharpLanguageServer server; - - public T? GetService() => server.GetService(); - public T GetRequiredService() where T : notnull => server.GetRequiredService(); - - public Server(Action onOptionsFunc) + public Server(IBicepLangServerOptions bicepLangServerOptions, Action onOptionsFunc) { server = OmnisharpLanguageServer.PreInit(options => { @@ -72,7 +69,7 @@ public Server(Action onOptionsFunc) .WithHandler() .WithHandler() .WithHandler() - .WithServices(RegisterServices); + .WithServices(services => services.AddServerDependencies(bicepLangServerOptions)); onOptionsFunc(options); }); @@ -103,11 +100,6 @@ public async Task RunAsync(CancellationToken cancellationToken) moduleMetadataProvider.StartUpdateCache(); } - private static void RegisterServices(IServiceCollection services) - { - services.AddServerDependencies(); - } - public void Dispose() { server.Dispose(); diff --git a/src/Bicep.Tools.Benchmark/LanguageServer.cs b/src/Bicep.Tools.Benchmark/LanguageServer.cs index 37319832b1a..74736b27057 100644 --- a/src/Bicep.Tools.Benchmark/LanguageServer.cs +++ b/src/Bicep.Tools.Benchmark/LanguageServer.cs @@ -8,6 +8,7 @@ using Bicep.Core.UnitTests.Utils; using Bicep.LangServer.IntegrationTests; using Bicep.LanguageServer; +using Bicep.LanguageServer.Options; using Microsoft.Extensions.DependencyInjection; using OmniSharp.Extensions.LanguageServer.Client; using OmniSharp.Extensions.LanguageServer.Protocol; @@ -38,12 +39,14 @@ private static async Task StartServer(IFileSystem fileSystem, M var clientPipe = new Pipe(); var serverPipe = new Pipe(); - var server = new Server(options => options - .WithInput(serverPipe.Reader) - .WithOutput(clientPipe.Writer) - .WithServices(services => services - .AddSingleton(ImmediateScheduler.Instance) // force work to run on a single thread to make snapshot profiling simpler - .AddSingleton(fileSystem))); + var server = new Server( + new BicepLangServerOptions(), + options => options + .WithInput(serverPipe.Reader) + .WithOutput(clientPipe.Writer) + .WithServices(services => services + .AddSingleton(ImmediateScheduler.Instance) // force work to run on a single thread to make snapshot profiling simpler + .AddSingleton(fileSystem))); var _ = server.RunAsync(CancellationToken.None); // do not wait on this async method, or you'll be waiting a long time! From 4a9ec406bcc119939ccdc7eeb1be72d5b0811a6a Mon Sep 17 00:00:00 2001 From: "Stephen Weatherford (MSFT)" Date: Tue, 16 Jul 2024 13:37:43 -0700 Subject: [PATCH 8/9] Unintended using --- .../Helpers/LanguageServerHelper.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Bicep.LangServer.IntegrationTests/Helpers/LanguageServerHelper.cs b/src/Bicep.LangServer.IntegrationTests/Helpers/LanguageServerHelper.cs index ab1f766d98c..a6e08f7d1d2 100644 --- a/src/Bicep.LangServer.IntegrationTests/Helpers/LanguageServerHelper.cs +++ b/src/Bicep.LangServer.IntegrationTests/Helpers/LanguageServerHelper.cs @@ -1,7 +1,6 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. using System.IO.Pipelines; -using System.Security.Cryptography.Xml; using Bicep.Core.Tracing; using Bicep.Core.UnitTests; using Bicep.Core.UnitTests.FileSystem; From 7a833789b80fae27020f7397d59a88f7cbf68618 Mon Sep 17 00:00:00 2001 From: "Stephen Weatherford (MSFT)" Date: Tue, 16 Jul 2024 13:48:55 -0700 Subject: [PATCH 9/9] CR: use record --- .../Helpers/LanguageServerHelper.cs | 2 +- .../Handlers/BicepCodeActionHandlerTests.cs | 3 ++- .../Handlers/BicepTextDocumentSyncHandlerTests.cs | 3 ++- src/Bicep.LangServer/IServiceCollectionExtensions.cs | 2 +- .../Options/BicepLangServerOptions.cs | 4 ++-- .../Options/IBicepLangServerOptions.cs | 12 ------------ src/Bicep.LangServer/Server.cs | 2 +- .../Utils/DocumentSelectorFactory.cs | 2 +- 8 files changed, 10 insertions(+), 20 deletions(-) delete mode 100644 src/Bicep.LangServer/Options/IBicepLangServerOptions.cs diff --git a/src/Bicep.LangServer.IntegrationTests/Helpers/LanguageServerHelper.cs b/src/Bicep.LangServer.IntegrationTests/Helpers/LanguageServerHelper.cs index a6e08f7d1d2..939c1d32e98 100644 --- a/src/Bicep.LangServer.IntegrationTests/Helpers/LanguageServerHelper.cs +++ b/src/Bicep.LangServer.IntegrationTests/Helpers/LanguageServerHelper.cs @@ -40,7 +40,7 @@ public static async Task StartServer(TestContext testConte var serverPipe = new Pipe(); var server = new Server( - new BicepLangServerOptions(), + BicepLangServerOptions.Default, options => options .WithInput(serverPipe.Reader) .WithOutput(clientPipe.Writer) diff --git a/src/Bicep.LangServer.UnitTests/Handlers/BicepCodeActionHandlerTests.cs b/src/Bicep.LangServer.UnitTests/Handlers/BicepCodeActionHandlerTests.cs index d6e8b9888d0..a8550b3c187 100644 --- a/src/Bicep.LangServer.UnitTests/Handlers/BicepCodeActionHandlerTests.cs +++ b/src/Bicep.LangServer.UnitTests/Handlers/BicepCodeActionHandlerTests.cs @@ -7,6 +7,7 @@ using Bicep.Core.UnitTests.Utils; using Bicep.LanguageServer; using Bicep.LanguageServer.Handlers; +using Bicep.LanguageServer.Options; using Bicep.LanguageServer.Providers; using Bicep.LanguageServer.Utils; using FluentAssertions; @@ -63,7 +64,7 @@ private async Task> GetCodeActions( clientCapabilitiesProvider.Setup(m => m.DoesClientSupportShowDocumentRequest()).Returns(clientSupportShowDocumentRequestAndWorkspaceFolders); clientCapabilitiesProvider.Setup(m => m.DoesClientSupportWorkspaceFolders()).Returns(clientSupportShowDocumentRequestAndWorkspaceFolders); - var bicepEditLinterRuleHandler = new BicepCodeActionHandler(bicepCompilationManager, clientCapabilitiesProvider.Object, new DocumentSelectorFactory(null)); + var bicepEditLinterRuleHandler = new BicepCodeActionHandler(bicepCompilationManager, clientCapabilitiesProvider.Object, new DocumentSelectorFactory(BicepLangServerOptions.Default)); var range = new Range() { diff --git a/src/Bicep.LangServer.UnitTests/Handlers/BicepTextDocumentSyncHandlerTests.cs b/src/Bicep.LangServer.UnitTests/Handlers/BicepTextDocumentSyncHandlerTests.cs index 06609af9fbd..3a0e0cad170 100644 --- a/src/Bicep.LangServer.UnitTests/Handlers/BicepTextDocumentSyncHandlerTests.cs +++ b/src/Bicep.LangServer.UnitTests/Handlers/BicepTextDocumentSyncHandlerTests.cs @@ -9,6 +9,7 @@ using Bicep.LangServer.IntegrationTests.Helpers; using Bicep.LanguageServer.Configuration; using Bicep.LanguageServer.Handlers; +using Bicep.LanguageServer.Options; using Bicep.LanguageServer.Telemetry; using Bicep.LanguageServer.Utils; using Microsoft.VisualStudio.TestTools.UnitTesting; @@ -197,7 +198,7 @@ private async Task ChangeLinterRuleState(Mock telemetryProvi new Workspace()); - var bicepTextDocumentSyncHandler = new BicepTextDocumentSyncHandler(compilationManager, bicepConfigChangeHandler, new DocumentSelectorFactory(null)); + var bicepTextDocumentSyncHandler = new BicepTextDocumentSyncHandler(compilationManager, bicepConfigChangeHandler, new DocumentSelectorFactory(BicepLangServerOptions.Default)); await bicepTextDocumentSyncHandler.Handle(TextDocumentParamHelper.CreateDidOpenDocumentParams(bicepConfigUri, prevBicepConfigFileContents, 1), CancellationToken.None); diff --git a/src/Bicep.LangServer/IServiceCollectionExtensions.cs b/src/Bicep.LangServer/IServiceCollectionExtensions.cs index 86b60a5923e..fbe19292b34 100644 --- a/src/Bicep.LangServer/IServiceCollectionExtensions.cs +++ b/src/Bicep.LangServer/IServiceCollectionExtensions.cs @@ -56,7 +56,7 @@ public static IServiceCollection AddBicepDecompiler(this IServiceCollection serv public static IServiceCollection AddServerDependencies( this IServiceCollection services, - IBicepLangServerOptions bicepLangServerOptions + BicepLangServerOptions bicepLangServerOptions ) => services .AddBicepCore() .AddBicepDecompiler() diff --git a/src/Bicep.LangServer/Options/BicepLangServerOptions.cs b/src/Bicep.LangServer/Options/BicepLangServerOptions.cs index 6c5d95b3ac7..7e4a96a6d06 100644 --- a/src/Bicep.LangServer/Options/BicepLangServerOptions.cs +++ b/src/Bicep.LangServer/Options/BicepLangServerOptions.cs @@ -6,7 +6,7 @@ namespace Bicep.LanguageServer.Options; -public class BicepLangServerOptions : IBicepLangServerOptions +public record BicepLangServerOptions(bool VsCompatibilityMode = false) { - public bool VsCompatibilityMode { get; set; } + public static BicepLangServerOptions Default = new(); } diff --git a/src/Bicep.LangServer/Options/IBicepLangServerOptions.cs b/src/Bicep.LangServer/Options/IBicepLangServerOptions.cs deleted file mode 100644 index c9e8b18485d..00000000000 --- a/src/Bicep.LangServer/Options/IBicepLangServerOptions.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Bicep.LanguageServer.Options; - -public interface IBicepLangServerOptions -{ - public bool VsCompatibilityMode { get; set; } -} diff --git a/src/Bicep.LangServer/Server.cs b/src/Bicep.LangServer/Server.cs index 5650c0c5cca..ac989eaeb79 100644 --- a/src/Bicep.LangServer/Server.cs +++ b/src/Bicep.LangServer/Server.cs @@ -24,7 +24,7 @@ namespace Bicep.LanguageServer public class Server : IDisposable { private readonly OmnisharpLanguageServer server; - public Server(IBicepLangServerOptions bicepLangServerOptions, Action onOptionsFunc) + public Server(BicepLangServerOptions bicepLangServerOptions, Action onOptionsFunc) { server = OmnisharpLanguageServer.PreInit(options => { diff --git a/src/Bicep.LangServer/Utils/DocumentSelectorFactory.cs b/src/Bicep.LangServer/Utils/DocumentSelectorFactory.cs index f7308dcc385..c8ed7d1d7dd 100644 --- a/src/Bicep.LangServer/Utils/DocumentSelectorFactory.cs +++ b/src/Bicep.LangServer/Utils/DocumentSelectorFactory.cs @@ -9,7 +9,7 @@ namespace Bicep.LanguageServer.Utils { - public class DocumentSelectorFactory(IBicepLangServerOptions? langServerOptions) + public class DocumentSelectorFactory(BicepLangServerOptions langServerOptions) { private static string Glob(params string[] extensions) {