diff --git a/Razor.Slim.slnf b/Razor.Slim.slnf index 1dc8a06ff9a..0b48b024740 100644 --- a/Razor.Slim.slnf +++ b/Razor.Slim.slnf @@ -20,13 +20,11 @@ "src\\Compiler\\tools\\Microsoft.CodeAnalysis.Razor.Tooling.Internal\\Microsoft.CodeAnalysis.Razor.Tooling.Internal.csproj", "src\\Razor\\src\\Microsoft.CodeAnalysis.Razor.Workspaces\\Microsoft.CodeAnalysis.Razor.Workspaces.csproj", "src\\Razor\\src\\Microsoft.CodeAnalysis.Remote.Razor\\Microsoft.CodeAnalysis.Remote.Razor.csproj", - "src\\Razor\\src\\Microsoft.VisualStudio.DevKit.Razor\\Microsoft.VisualStudio.DevKit.Razor.csproj", "src\\Razor\\src\\Microsoft.VisualStudio.LanguageServer.ContainedLanguage\\Microsoft.VisualStudio.LanguageServer.ContainedLanguage.csproj", "src\\Razor\\src\\Microsoft.VisualStudio.LanguageServices.Razor\\Microsoft.VisualStudio.LanguageServices.Razor.csproj", "src\\Razor\\src\\Microsoft.VisualStudio.RazorExtension\\Microsoft.VisualStudio.RazorExtension.csproj", "src\\Razor\\src\\Microsoft.VisualStudioCode.RazorExtension\\Microsoft.VisualStudioCode.RazorExtension.csproj", "src\\Razor\\src\\Microsoft.AspNetCore.Razor.LanguageServer\\Microsoft.AspNetCore.Razor.LanguageServer.csproj", - "src\\Razor\\src\\rzls\\rzls.csproj", "src\\Razor\\test\\Microsoft.AspNetCore.Razor.Test.Common.Tooling\\Microsoft.AspNetCore.Razor.Test.Common.Tooling.csproj", "src\\Razor\\test\\Microsoft.AspNetCore.Razor.LanguageServer.Test\\Microsoft.AspNetCore.Razor.LanguageServer.Test.csproj", "src\\Razor\\test\\Microsoft.CodeAnalysis.Razor.Workspaces.Test\\Microsoft.CodeAnalysis.Razor.Workspaces.Test.csproj", diff --git a/Razor.sln b/Razor.sln index f1e04d80f6f..2bbba6da485 100644 --- a/Razor.sln +++ b/Razor.sln @@ -32,8 +32,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Razor. EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Razor.LanguageServer.Test", "src\Razor\test\Microsoft.AspNetCore.Razor.LanguageServer.Test\Microsoft.AspNetCore.Razor.LanguageServer.Test.csproj", "{FBAE9975-77BE-411B-A1A3-4790C8A367EF}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "rzls", "src\Razor\src\rzls\rzls.csproj", "{35FEC0EA-09B5-45D2-832D-D6FEBA364871}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.VisualStudio.LanguageServer.ContainedLanguage", "src\Razor\src\Microsoft.VisualStudio.LanguageServer.ContainedLanguage\Microsoft.VisualStudio.LanguageServer.ContainedLanguage.csproj", "{0D6FD2CD-3C0A-452B-AC12-DE6301C287AC}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.VisualStudio.LanguageServer.ContainedLanguage.Test", "src\Razor\test\Microsoft.VisualStudio.LanguageServer.ContainedLanguage.Test\Microsoft.VisualStudio.LanguageServer.ContainedLanguage.Test.csproj", "{0FC409AF-B92B-42D0-9096-1F20360D2672}" @@ -124,8 +122,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Razor.Diagnostics.Analyzers EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Razor.Diagnostics.Analyzers.Test", "src\Analyzers\Razor.Diagnostics.Analyzers.Test\Razor.Diagnostics.Analyzers.Test.csproj", "{167F1426-D9AE-49DF-B214-F00536DBC305}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.VisualStudio.DevKit.Razor", "src\Razor\src\Microsoft.VisualStudio.DevKit.Razor\Microsoft.VisualStudio.DevKit.Razor.csproj", "{0F2D75D1-89AD-40A6-9F02-D45708AEA3EB}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Razor.Test.Common", "src\Shared\Microsoft.AspNetCore.Razor.Test.Common\Microsoft.AspNetCore.Razor.Test.Common.csproj", "{64A72A33-38B4-4C23-9E12-D7FEBD673FB7}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Razor.Language.Legacy.Test", "src\Compiler\Microsoft.AspNetCore.Razor.Language\legacyTest\Microsoft.AspNetCore.Razor.Language.Legacy.Test.csproj", "{C504C2D7-8313-46D8-A159-7EB79047C09C}" @@ -236,14 +232,6 @@ Global {FBAE9975-77BE-411B-A1A3-4790C8A367EF}.Release|Any CPU.Build.0 = Release|Any CPU {FBAE9975-77BE-411B-A1A3-4790C8A367EF}.ReleaseNoVSIX|Any CPU.ActiveCfg = Release|Any CPU {FBAE9975-77BE-411B-A1A3-4790C8A367EF}.ReleaseNoVSIX|Any CPU.Build.0 = Release|Any CPU - {35FEC0EA-09B5-45D2-832D-D6FEBA364871}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {35FEC0EA-09B5-45D2-832D-D6FEBA364871}.Debug|Any CPU.Build.0 = Debug|Any CPU - {35FEC0EA-09B5-45D2-832D-D6FEBA364871}.DebugNoVSIX|Any CPU.ActiveCfg = Debug|Any CPU - {35FEC0EA-09B5-45D2-832D-D6FEBA364871}.DebugNoVSIX|Any CPU.Build.0 = Debug|Any CPU - {35FEC0EA-09B5-45D2-832D-D6FEBA364871}.Release|Any CPU.ActiveCfg = Release|Any CPU - {35FEC0EA-09B5-45D2-832D-D6FEBA364871}.Release|Any CPU.Build.0 = Release|Any CPU - {35FEC0EA-09B5-45D2-832D-D6FEBA364871}.ReleaseNoVSIX|Any CPU.ActiveCfg = Release|Any CPU - {35FEC0EA-09B5-45D2-832D-D6FEBA364871}.ReleaseNoVSIX|Any CPU.Build.0 = Release|Any CPU {0D6FD2CD-3C0A-452B-AC12-DE6301C287AC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {0D6FD2CD-3C0A-452B-AC12-DE6301C287AC}.Debug|Any CPU.Build.0 = Debug|Any CPU {0D6FD2CD-3C0A-452B-AC12-DE6301C287AC}.DebugNoVSIX|Any CPU.ActiveCfg = Debug|Any CPU @@ -476,14 +464,6 @@ Global {167F1426-D9AE-49DF-B214-F00536DBC305}.Release|Any CPU.Build.0 = Release|Any CPU {167F1426-D9AE-49DF-B214-F00536DBC305}.ReleaseNoVSIX|Any CPU.ActiveCfg = Release|Any CPU {167F1426-D9AE-49DF-B214-F00536DBC305}.ReleaseNoVSIX|Any CPU.Build.0 = Release|Any CPU - {0F2D75D1-89AD-40A6-9F02-D45708AEA3EB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {0F2D75D1-89AD-40A6-9F02-D45708AEA3EB}.Debug|Any CPU.Build.0 = Debug|Any CPU - {0F2D75D1-89AD-40A6-9F02-D45708AEA3EB}.DebugNoVSIX|Any CPU.ActiveCfg = Debug|Any CPU - {0F2D75D1-89AD-40A6-9F02-D45708AEA3EB}.DebugNoVSIX|Any CPU.Build.0 = Debug|Any CPU - {0F2D75D1-89AD-40A6-9F02-D45708AEA3EB}.Release|Any CPU.ActiveCfg = Release|Any CPU - {0F2D75D1-89AD-40A6-9F02-D45708AEA3EB}.Release|Any CPU.Build.0 = Release|Any CPU - {0F2D75D1-89AD-40A6-9F02-D45708AEA3EB}.ReleaseNoVSIX|Any CPU.ActiveCfg = Release|Any CPU - {0F2D75D1-89AD-40A6-9F02-D45708AEA3EB}.ReleaseNoVSIX|Any CPU.Build.0 = Release|Any CPU {64A72A33-38B4-4C23-9E12-D7FEBD673FB7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {64A72A33-38B4-4C23-9E12-D7FEBD673FB7}.Debug|Any CPU.Build.0 = Debug|Any CPU {64A72A33-38B4-4C23-9E12-D7FEBD673FB7}.DebugNoVSIX|Any CPU.ActiveCfg = Debug|Any CPU @@ -563,7 +543,6 @@ Global {6205467F-E381-4C42-AEEC-763BD62B3D5E} = {C2C98051-0F39-47F2-80B6-E72B29159F2C} {1D15867E-E50F-4107-92A4-BBC2EE6B088C} = {3C0D6505-79B3-49D0-B4C3-176F0F1836ED} {FBAE9975-77BE-411B-A1A3-4790C8A367EF} = {92463391-81BE-462B-AC3C-78C6C760741F} - {35FEC0EA-09B5-45D2-832D-D6FEBA364871} = {3C0D6505-79B3-49D0-B4C3-176F0F1836ED} {0D6FD2CD-3C0A-452B-AC12-DE6301C287AC} = {3C0D6505-79B3-49D0-B4C3-176F0F1836ED} {0FC409AF-B92B-42D0-9096-1F20360D2672} = {92463391-81BE-462B-AC3C-78C6C760741F} {39233703-B752-43AC-AD86-E9D3E61B4AD9} = {92463391-81BE-462B-AC3C-78C6C760741F} @@ -600,7 +579,6 @@ Global {BAFE178B-7AD4-41AE-A75D-9B920B9EA050} = {3AE210D1-C435-4693-BF79-2EF13ED554B9} {45B207E2-DDB3-44F0-87C5-DEFB5A9534A5} = {4AA319E0-C81E-47CC-841A-6EFCB6784A1F} {167F1426-D9AE-49DF-B214-F00536DBC305} = {4AA319E0-C81E-47CC-841A-6EFCB6784A1F} - {0F2D75D1-89AD-40A6-9F02-D45708AEA3EB} = {3C0D6505-79B3-49D0-B4C3-176F0F1836ED} {64A72A33-38B4-4C23-9E12-D7FEBD673FB7} = {3AE210D1-C435-4693-BF79-2EF13ED554B9} {C504C2D7-8313-46D8-A159-7EB79047C09C} = {C2E49955-A0B0-4F4A-B3AC-F120DCF9B13F} {CD6913F3-EC47-4470-9C45-F5F898615E9D} = {3AE210D1-C435-4693-BF79-2EF13ED554B9} diff --git a/eng/config/PublishData.json b/eng/config/PublishData.json index 29cdd9c2330..34151846556 100644 --- a/eng/config/PublishData.json +++ b/eng/config/PublishData.json @@ -4,20 +4,6 @@ }, "packages": { "default": { - "rzls": "vs-impl", - "rzls.alpine-arm64": "vs-impl", - "rzls.alpine-x64": "vs-impl", - "rzls.linux-arm64": "vs-impl", - "rzls.linux-x64": "vs-impl", - "rzls.linux-musl-x64": "vs-impl", - "rzls.linux-musl-arm64": "vs-impl", - "rzls.neutral": "vs-impl", - "rzls.osx-arm64": "vs-impl", - "rzls.osx-x64": "vs-impl", - "rzls.win-arm64": "vs-impl", - "rzls.win-x64": "vs-impl", - "rzls.win-x86": "vs-impl", - "Microsoft.VisualStudio.DevKit.Razor": "vs-impl", "Microsoft.VisualStudioCode.RazorExtension": "vs-impl" } }, diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Hosting/ConfigurableLanguageServerFeatureOptions.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Hosting/ConfigurableLanguageServerFeatureOptions.cs deleted file mode 100644 index d05d28421b2..00000000000 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Hosting/ConfigurableLanguageServerFeatureOptions.cs +++ /dev/null @@ -1,96 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using Microsoft.CodeAnalysis.Razor.Workspaces; - -namespace Microsoft.AspNetCore.Razor.LanguageServer.Hosting; - -internal class ConfigurableLanguageServerFeatureOptions : LanguageServerFeatureOptions -{ - private readonly LanguageServerFeatureOptions _defaults = new DefaultLanguageServerFeatureOptions(); - - private readonly bool? _supportsFileManipulation; - private readonly string? _csharpVirtualDocumentSuffix; - private readonly string? _htmlVirtualDocumentSuffix; - private readonly bool? _singleServerSupport; - private readonly bool? _delegateToCSharpOnDiagnosticPublish; - private readonly bool? _returnCodeActionAndRenamePathsWithPrefixedSlash; - private readonly bool? _showAllCSharpCodeActions; - private readonly bool? _updateBuffersForClosedDocuments; - private readonly bool? _includeProjectKeyInGeneratedFilePath; - private readonly bool? _useRazorCohostServer; - private readonly bool? _doNotInitializeMiscFilesProjectFromWorkspace; - - public override bool SupportsFileManipulation => _supportsFileManipulation ?? _defaults.SupportsFileManipulation; - public override string CSharpVirtualDocumentSuffix => _csharpVirtualDocumentSuffix ?? DefaultLanguageServerFeatureOptions.DefaultCSharpVirtualDocumentSuffix; - public override string HtmlVirtualDocumentSuffix => _htmlVirtualDocumentSuffix ?? DefaultLanguageServerFeatureOptions.DefaultHtmlVirtualDocumentSuffix; - public override bool SingleServerSupport => _singleServerSupport ?? _defaults.SingleServerSupport; - public override bool DelegateToCSharpOnDiagnosticPublish => _delegateToCSharpOnDiagnosticPublish ?? _defaults.DelegateToCSharpOnDiagnosticPublish; - public override bool ReturnCodeActionAndRenamePathsWithPrefixedSlash => _returnCodeActionAndRenamePathsWithPrefixedSlash ?? _defaults.ReturnCodeActionAndRenamePathsWithPrefixedSlash; - public override bool ShowAllCSharpCodeActions => _showAllCSharpCodeActions ?? _defaults.ShowAllCSharpCodeActions; - public override bool UpdateBuffersForClosedDocuments => _updateBuffersForClosedDocuments ?? _defaults.UpdateBuffersForClosedDocuments; - public override bool IncludeProjectKeyInGeneratedFilePath => _includeProjectKeyInGeneratedFilePath ?? _defaults.IncludeProjectKeyInGeneratedFilePath; - public override bool UseRazorCohostServer => _useRazorCohostServer ?? _defaults.UseRazorCohostServer; - public override bool SupportsSoftSelectionInCompletion => false; - public override bool UseVsCodeCompletionCommitCharacters => true; - - // Note: This option is defined in the negative because the default behavior should be to add documents to misc files project - // when the language server is initialized. Adding the option at the command-line should disable that behavior. - // - // This is a temporary option and should be removed as part of https://github.com/dotnet/razor/issues/11594. - public override bool DoNotInitializeMiscFilesProjectFromWorkspace => _doNotInitializeMiscFilesProjectFromWorkspace ?? _defaults.DoNotInitializeMiscFilesProjectFromWorkspace; - - public ConfigurableLanguageServerFeatureOptions(string[] args) - { - for (var i = 0; i < args.Length; i++) - { - if (args[i] is not ['-', '-', .. var option]) - { - continue; - } - - TryProcessBoolOption(nameof(SupportsFileManipulation), ref _supportsFileManipulation, option, args, i); - TryProcessStringOption(nameof(CSharpVirtualDocumentSuffix), ref _csharpVirtualDocumentSuffix, option, args, i); - TryProcessStringOption(nameof(HtmlVirtualDocumentSuffix), ref _htmlVirtualDocumentSuffix, option, args, i); - TryProcessBoolOption(nameof(SingleServerSupport), ref _singleServerSupport, option, args, i); - TryProcessBoolOption(nameof(DelegateToCSharpOnDiagnosticPublish), ref _delegateToCSharpOnDiagnosticPublish, option, args, i); - TryProcessBoolOption(nameof(ReturnCodeActionAndRenamePathsWithPrefixedSlash), ref _returnCodeActionAndRenamePathsWithPrefixedSlash, option, args, i); - TryProcessBoolOption(nameof(ShowAllCSharpCodeActions), ref _showAllCSharpCodeActions, option, args, i); - TryProcessBoolOption(nameof(UpdateBuffersForClosedDocuments), ref _updateBuffersForClosedDocuments, option, args, i); - TryProcessBoolOption(nameof(IncludeProjectKeyInGeneratedFilePath), ref _includeProjectKeyInGeneratedFilePath, option, args, i); - TryProcessBoolOption(nameof(UseRazorCohostServer), ref _useRazorCohostServer, option, args, i); - TryProcessBoolOption(nameof(DoNotInitializeMiscFilesProjectFromWorkspace), ref _doNotInitializeMiscFilesProjectFromWorkspace, option, args, i); - } - } - - private static void TryProcessStringOption(string optionName, ref string? field, string option, string[] args, int i) - { - // String properties must have at least one option following this one - if (i >= args.Length - 1) - { - return; - } - - if (string.Equals(option, optionName, StringComparison.OrdinalIgnoreCase)) - { - field = args[++i]; - } - } - - private static void TryProcessBoolOption(string optionName, ref bool? field, string option, string[] args, int i) - { - if (string.Equals(option, optionName, StringComparison.OrdinalIgnoreCase)) - { - // bool properties are true if they're the last thing in the args, or the next thing is another option - if (i >= args.Length - 1 || args[i + 1] is ['-', '-', ..]) - { - field = true; - } - else - { - field = bool.Parse(args[++i]); - } - } - } -} diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Microsoft.AspNetCore.Razor.LanguageServer.csproj b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Microsoft.AspNetCore.Razor.LanguageServer.csproj index 186426906fa..67bd5694abf 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Microsoft.AspNetCore.Razor.LanguageServer.csproj +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Microsoft.AspNetCore.Razor.LanguageServer.csproj @@ -82,10 +82,8 @@ - - diff --git a/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Microsoft.CodeAnalysis.Razor.Workspaces.csproj b/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Microsoft.CodeAnalysis.Razor.Workspaces.csproj index a28d1009766..10b487228a6 100644 --- a/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Microsoft.CodeAnalysis.Razor.Workspaces.csproj +++ b/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Microsoft.CodeAnalysis.Razor.Workspaces.csproj @@ -49,7 +49,6 @@ - @@ -58,7 +57,6 @@ - diff --git a/src/Razor/src/Microsoft.VisualStudio.DevKit.Razor/Microsoft.VisualStudio.DevKit.Razor.csproj b/src/Razor/src/Microsoft.VisualStudio.DevKit.Razor/Microsoft.VisualStudio.DevKit.Razor.csproj deleted file mode 100644 index fedb3b7609e..00000000000 --- a/src/Razor/src/Microsoft.VisualStudio.DevKit.Razor/Microsoft.VisualStudio.DevKit.Razor.csproj +++ /dev/null @@ -1,43 +0,0 @@ - - - - $(NetVSCode) - Library - Razor is a markup syntax for adding server-side logic to web pages. This package contains the language server assets for C# DevKit. - false - true - true - - - $(NoWarn);NU5100 - - - - - - - - - - - - - - - - - - - - - PreserveNewest - - - - - - - diff --git a/src/Razor/src/Microsoft.VisualStudio.DevKit.Razor/Telemetry/DevKitTelemetryReporter.cs b/src/Razor/src/Microsoft.VisualStudio.DevKit.Razor/Telemetry/DevKitTelemetryReporter.cs deleted file mode 100644 index 87f3b9d319b..00000000000 --- a/src/Razor/src/Microsoft.VisualStudio.DevKit.Razor/Telemetry/DevKitTelemetryReporter.cs +++ /dev/null @@ -1,111 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using System.Composition; -using System.Diagnostics; -using System.Text; -using Microsoft.AspNetCore.Razor.PooledObjects; -using Microsoft.CodeAnalysis.Razor.Telemetry; -using Microsoft.VisualStudio.Razor.Telemetry; -using Microsoft.VisualStudio.Telemetry; - -namespace Microsoft.VisualStudio.DevKit.Razor.Telemetry; - -[Shared] -[Export(typeof(ITelemetryReporter))] -internal sealed class DevKitTelemetryReporter : TelemetryReporter, ITelemetryReporterInitializer -{ - private const string CollectorApiKey = "0c6ae279ed8443289764825290e4f9e2-1a736e7c-1324-4338-be46-fc2a58ae4d14-7255"; - - [ImportingConstructor] - public DevKitTelemetryReporter() - : base(null) - { - } - - public void InitializeSession(string telemetryLevel, string? sessionId, bool isDefaultSession) - { - var sessionSettingsJson = CreateSessionSettingsJson(telemetryLevel, sessionId); - var session = new TelemetrySession(sessionSettingsJson); - - if (isDefaultSession) - { - TelemetryService.SetDefaultSession(session); - } - - session.Start(); - session.RegisterForReliabilityEvent(); - - SetSession(session); - } - - private static string CreateSessionSettingsJson(string telemetryLevel, string? sessionId) - { - sessionId ??= Guid.NewGuid().ToString(); - - // Generate a new startTime for process to be consumed by Telemetry Settings - using var curProcess = Process.GetCurrentProcess(); - var processStartTime = curProcess.StartTime.ToFileTimeUtc().ToString(); - - using var _ = StringBuilderPool.GetPooledObject(out var builder); - - builder.Append('{'); - - AppendNameValuePair(builder, "Id", sessionId); - AppendNameValuePair(builder, "HostName", "Default"); - - // Insert Telemetry Level instead of Opt-Out status. The telemetry service handles - // validation of this value so there is no need to do so on this end. If it's invalid, - // it defaults to off. - AppendNameValuePair(builder, "TelemetryLevel", telemetryLevel); - - // this sets the Telemetry Session Created by LSP Server to be the Root Initial session - // This means that the SessionID set here by "Id" will be the SessionID used by cloned session - // further down stream - AppendNameValuePair(builder, "IsInitialSession", "true", quoteValue: false); - AppendNameValuePair(builder, "CollectorApiKey", CollectorApiKey); - - // using 1010 to indicate VS Code and not to match it to devenv 1000 - AppendNameValuePair(builder, "AppId", "1010", quoteValue: false); - - // Don't add a comma to the last property. - AppendNameValuePair(builder, "ProcessStartTime", processStartTime, quoteValue: false, addComma: false); - - builder.Append('}'); - - return builder.ToString(); - - static void AppendNameValuePair(StringBuilder builder, string name, string? value, bool quoteValue = true, bool addComma = true) - { - builder.Append('"'); - builder.Append(name); - builder.Append('"'); - builder.Append(':'); - - if (value is string s) - { - if (quoteValue) - { - builder.Append('"'); - } - - builder.Append(value); - - if (quoteValue) - { - builder.Append('"'); - } - } - else - { - builder.Append("null"); - } - - if (addComma) - { - builder.Append(','); - } - } - } -} diff --git a/src/Razor/src/Microsoft.VisualStudioCode.RazorExtension/Endpoints/RazorDynamicFileChangedEndpoint.cs b/src/Razor/src/Microsoft.VisualStudioCode.RazorExtension/Endpoints/RazorDynamicFileChangedEndpoint.cs deleted file mode 100644 index ffb0e9e4f50..00000000000 --- a/src/Razor/src/Microsoft.VisualStudioCode.RazorExtension/Endpoints/RazorDynamicFileChangedEndpoint.cs +++ /dev/null @@ -1,28 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Composition; -using System.Threading; -using System.Threading.Tasks; -using Microsoft.CodeAnalysis.ExternalAccess.Razor.Features; -using Microsoft.CodeAnalysis.Razor; - -namespace Microsoft.VisualStudioCode.RazorExtension.Endpoints; - -[Shared] -[ExportRazorStatelessLspService(typeof(RazorDynamicFileChangedEndpoint))] -[RazorEndpoint("razor/dynamicFileInfoChanged")] -internal class RazorDynamicFileChangedEndpoint : AbstractRazorNotificationHandler -{ - public override bool MutatesSolutionState => false; - - public override bool RequiresLSPSolution => false; - - protected override Task HandleNotificationAsync(RazorDynamicFileChangedParams request, RazorRequestContext context, CancellationToken cancellationToken) - { - var dynamicFileInfoProvider = context.GetRequiredService(); - dynamicFileInfoProvider.Update(request.RazorDocument.DocumentUri.GetRequiredParsedUri()); - - return Task.CompletedTask; - } -} diff --git a/src/Razor/src/Microsoft.VisualStudioCode.RazorExtension/Endpoints/RazorDynamicFileChangedParams.cs b/src/Razor/src/Microsoft.VisualStudioCode.RazorExtension/Endpoints/RazorDynamicFileChangedParams.cs deleted file mode 100644 index 017a2ff7e71..00000000000 --- a/src/Razor/src/Microsoft.VisualStudioCode.RazorExtension/Endpoints/RazorDynamicFileChangedParams.cs +++ /dev/null @@ -1,12 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Text.Json.Serialization; - -namespace Microsoft.VisualStudioCode.RazorExtension.Endpoints; - -internal class RazorDynamicFileChangedParams -{ - [JsonPropertyName("razorDocument")] - public required TextDocumentIdentifier RazorDocument { get; set; } -} diff --git a/src/Razor/src/Microsoft.VisualStudioCode.RazorExtension/Endpoints/RazorInitializeEndpoint.cs b/src/Razor/src/Microsoft.VisualStudioCode.RazorExtension/Endpoints/RazorInitializeEndpoint.cs deleted file mode 100644 index 043d85330a3..00000000000 --- a/src/Razor/src/Microsoft.VisualStudioCode.RazorExtension/Endpoints/RazorInitializeEndpoint.cs +++ /dev/null @@ -1,34 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Composition; -using System.Text.Json.Serialization; -using System.Threading; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Razor; -using Microsoft.CodeAnalysis.ExternalAccess.Razor.Features; - -namespace Microsoft.VisualStudioCode.RazorExtension.Endpoints; - -[Shared] -[ExportRazorStatelessLspService(typeof(RazorInitializeEndpoint))] -[RazorEndpoint("razor/initialize")] -internal class RazorInitializeEndpoint : AbstractRazorNotificationHandler -{ - public override bool MutatesSolutionState => false; - - public override bool RequiresLSPSolution => true; - - protected override Task HandleNotificationAsync(RazorInitializeParams request, RazorRequestContext requestContext, CancellationToken cancellationToken) - { - var workspaceService = requestContext.GetRequiredService(); - workspaceService.Initialize(requestContext.Workspace.AssumeNotNull(), request.PipeName); - return Task.CompletedTask; - } -} - -internal class RazorInitializeParams -{ - [JsonPropertyName("pipeName")] - public required string PipeName { get; set; } -} diff --git a/src/Razor/src/Microsoft.VisualStudioCode.RazorExtension/Microsoft.VisualStudioCode.RazorExtension.csproj b/src/Razor/src/Microsoft.VisualStudioCode.RazorExtension/Microsoft.VisualStudioCode.RazorExtension.csproj index 39f71733982..4c6b22d59d6 100644 --- a/src/Razor/src/Microsoft.VisualStudioCode.RazorExtension/Microsoft.VisualStudioCode.RazorExtension.csproj +++ b/src/Razor/src/Microsoft.VisualStudioCode.RazorExtension/Microsoft.VisualStudioCode.RazorExtension.csproj @@ -46,14 +46,7 @@ - - Targets - true - content\Targets - PreserveNewest - - - + true content\Targets PreserveNewest diff --git a/src/Razor/src/Microsoft.VisualStudioCode.RazorExtension/RazorVSCodeEndpoint.cs b/src/Razor/src/Microsoft.VisualStudioCode.RazorExtension/RazorVSCodeEndpoint.cs deleted file mode 100644 index b8a93855781..00000000000 --- a/src/Razor/src/Microsoft.VisualStudioCode.RazorExtension/RazorVSCodeEndpoint.cs +++ /dev/null @@ -1,13 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using Microsoft.CodeAnalysis.ExternalAccess.Razor.Features; - -namespace Microsoft.VisualStudioCode.RazorExtension; - -internal class RazorVSCodeEndpoint : RazorEndpointAttribute -{ - public RazorVSCodeEndpoint(string method) : base(method, "Razor") - { - } -} diff --git a/src/Razor/src/Microsoft.VisualStudioCode.RazorExtension/RazorWorkspaceListener.cs b/src/Razor/src/Microsoft.VisualStudioCode.RazorExtension/RazorWorkspaceListener.cs deleted file mode 100644 index 5a470eb38e6..00000000000 --- a/src/Razor/src/Microsoft.VisualStudioCode.RazorExtension/RazorWorkspaceListener.cs +++ /dev/null @@ -1,44 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.IO; -using System.IO.Pipes; -using System.Threading; -using System.Threading.Tasks; -using Microsoft.CodeAnalysis; -using Microsoft.Extensions.Logging; - -namespace Microsoft.VisualStudioCode.RazorExtension; - -internal sealed class RazorWorkspaceListener : RazorWorkspaceListenerBase -{ - public RazorWorkspaceListener(ILoggerFactory loggerFactory) : base(loggerFactory.CreateLogger()) - { - } - - /// - /// Initializes the workspace and begins hooking up to workspace events. This is not thread safe - /// but may be called multiple times. - /// - public void EnsureInitialized(Workspace workspace, string pipeName) - { - // Configuration of the server stream is very important. Please - // be _very_ careful if changing any of the options used to initialize this. - EnsureInitialized(workspace, () => new NamedPipeServerStream( - pipeName, - PipeDirection.Out, - maxNumberOfServerInstances: 1, - PipeTransmissionMode.Byte, - PipeOptions.CurrentUserOnly | PipeOptions.Asynchronous)); - } - - private protected override Task CheckConnectionAsync(Stream stream, CancellationToken cancellationToken) - { - if (stream is NamedPipeServerStream { IsConnected: false } namedPipe) - { - return namedPipe.WaitForConnectionAsync(cancellationToken); - } - - return Task.CompletedTask; - } -} diff --git a/src/Razor/src/Microsoft.VisualStudioCode.RazorExtension/RazorWorkspaceListenerBase.cs b/src/Razor/src/Microsoft.VisualStudioCode.RazorExtension/RazorWorkspaceListenerBase.cs deleted file mode 100644 index 125c80435c2..00000000000 --- a/src/Razor/src/Microsoft.VisualStudioCode.RazorExtension/RazorWorkspaceListenerBase.cs +++ /dev/null @@ -1,301 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using System.Collections.Generic; -using System.Collections.Immutable; -using System.IO; -using System.Threading; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Razor; -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.Razor.Utilities; -using Microsoft.Extensions.Logging; - -namespace Microsoft.VisualStudioCode.RazorExtension; - -internal abstract class RazorWorkspaceListenerBase : IDisposable -{ - private static readonly TimeSpan s_debounceTime = TimeSpan.FromMilliseconds(500); - private readonly CancellationTokenSource _disposeTokenSource = new(); - - private readonly ILogger _logger; - private readonly AsyncBatchingWorkQueue _workQueue; - - // Use an immutable dictionary for ImmutableInterlocked operations. The value isn't checked, just - // the existance of the key so work is only done for projects with dynamic files. - private ImmutableDictionary _projectsWithDynamicFile = ImmutableDictionary.Empty; - - private Stream? _stream; - private Workspace? _workspace; - private WorkspaceEventRegistration? _changeRegistration; - private bool _disposed; - - internal record Work(ProjectId ProjectId); - internal record UpdateWork(ProjectId ProjectId) : Work(ProjectId); - internal record RemovalWork(ProjectId ProjectId, string IntermediateOutputPath) : Work(ProjectId); - - protected RazorWorkspaceListenerBase(ILogger logger) - { - _logger = logger; - _workQueue = new(s_debounceTime, ProcessWorkAsync, EqualityComparer.Default, _disposeTokenSource.Token); - } - - private protected abstract Task CheckConnectionAsync(Stream stream, CancellationToken cancellationToken); - - public void Dispose() - { - _changeRegistration?.Dispose(); - - if (_disposed) - { - _logger.LogInformation("Disposal was called twice"); - return; - } - - _disposed = true; - _logger.LogInformation("Tearing down named pipe for pid {pid}", Environment.ProcessId); - - _disposeTokenSource.Cancel(); - _disposeTokenSource.Dispose(); - - _stream?.Dispose(); - _stream = null; - } - - public void NotifyDynamicFile(ProjectId projectId) - { - // Since there is no "un-notify" API to indicate that callers no longer care about a project, it's entirely - // possible that by the time we get notified, a project might have been removed from the workspace. Whilst - // that wouldn't cause any issues we may as well avoid creating a task scheduler. - if (_workspace is null || !_workspace.CurrentSolution.ContainsProject(projectId)) - { - return; - } - - // Other modifications of projects happen on Workspace.Changed events, which are not - // assumed to be on the same thread as dynamic file notification. - ImmutableInterlocked.GetOrAdd(ref _projectsWithDynamicFile, projectId, static (_) => true); - - // Schedule a task, in case adding a dynamic file is the last thing that happens - _logger.LogTrace("{projectId} scheduling task due to dynamic file", projectId); - _workQueue.AddWork(new UpdateWork(projectId)); - } - - /// - /// Initializes the workspace and begins hooking up to workspace events. This is not thread safe - /// and intended to be called only once. - /// - private protected void EnsureInitialized(Workspace workspace, Func createStream) - { - // Early exit check. Initialization should only happen once. Handle as safely as possible but - if (_workspace is not null) - { - _logger.LogInformation("EnsureInitialized was called multiple times when it shouldn't have been."); - return; - } - - // Early check for disposal just to reduce any work further - if (_disposed) - { - return; - } - - _workspace = workspace; - _changeRegistration = _workspace.RegisterWorkspaceChangedHandler(Workspace_WorkspaceChanged); - _stream = createStream(); - } - - private void Workspace_WorkspaceChanged(WorkspaceChangeEventArgs e) - { - switch (e.Kind) - { - case WorkspaceChangeKind.SolutionChanged: - case WorkspaceChangeKind.SolutionReloaded: - foreach (var project in e.NewSolution.Projects) - { - EnqueueUpdate(project); - } - - break; - - case WorkspaceChangeKind.SolutionAdded: - foreach (var project in e.NewSolution.Projects) - { - EnqueueUpdate(project); - } - - break; - - case WorkspaceChangeKind.ProjectReloaded: - EnqueueUpdate(e.NewSolution.GetProject(e.ProjectId)); - break; - - case WorkspaceChangeKind.ProjectRemoved: - RemoveProject(e.OldSolution.GetProject(e.ProjectId.AssumeNotNull()).AssumeNotNull()); - break; - - case WorkspaceChangeKind.ProjectAdded: - case WorkspaceChangeKind.ProjectChanged: - case WorkspaceChangeKind.DocumentAdded: - case WorkspaceChangeKind.DocumentRemoved: - case WorkspaceChangeKind.DocumentReloaded: - case WorkspaceChangeKind.DocumentChanged: - case WorkspaceChangeKind.AdditionalDocumentAdded: - case WorkspaceChangeKind.AdditionalDocumentRemoved: - case WorkspaceChangeKind.AdditionalDocumentReloaded: - case WorkspaceChangeKind.AdditionalDocumentChanged: - case WorkspaceChangeKind.DocumentInfoChanged: - case WorkspaceChangeKind.AnalyzerConfigDocumentAdded: - case WorkspaceChangeKind.AnalyzerConfigDocumentRemoved: - case WorkspaceChangeKind.AnalyzerConfigDocumentReloaded: - case WorkspaceChangeKind.AnalyzerConfigDocumentChanged: - var projectId = e.ProjectId ?? e.DocumentId?.ProjectId; - if (projectId is not null) - { - EnqueueUpdate(e.NewSolution.GetProject(projectId)); - } - - break; - - case WorkspaceChangeKind.SolutionCleared: - case WorkspaceChangeKind.SolutionRemoved: - foreach (var project in e.OldSolution.Projects) - { - RemoveProject(project); - } - - break; - - default: - break; - } - - // - // Local functions - // - void EnqueueUpdate(Project? project) - { - if (_disposed || - project is not - { - Language: LanguageNames.CSharp - }) - { - return; - } - - // Don't queue work for projects that don't have a dynamic file - if (!_projectsWithDynamicFile.TryGetValue(project.Id, out _)) - { - return; - } - - _workQueue.AddWork(new UpdateWork(project.Id)); - } - - void RemoveProject(Project project) - { - // Remove project is called from Workspace.Changed, while other notifications of _projectsWithDynamicFile - // are handled with NotifyDynamicFile. Use ImmutableInterlocked here to be sure the updates happen - // in a thread safe manner since those are not assumed to be the same thread. - if (ImmutableInterlocked.TryRemove(ref _projectsWithDynamicFile, project.Id, out _)) - { - var intermediateOutputPath = Path.GetDirectoryName(project.CompilationOutputInfo.AssemblyPath); - if (intermediateOutputPath is null) - { - _logger.LogTrace("intermediatePath is null, skipping notification of removal for {projectId}", project.Id); - return; - } - - _workQueue.AddWork(new RemovalWork(project.Id, intermediateOutputPath)); - } - } - } - - /// - /// Work controlled by the . Cancellation of that work queue propagates - /// to cancellation of this thread and should be handled accordingly - /// - /// - /// private protected virtual for testing - /// - private protected async virtual ValueTask ProcessWorkAsync(ImmutableArray work, CancellationToken cancellationToken) - { - // Capture as locals here. Cancellation of the work queue still need to propogate. The cancellation - // token itself represents the work queue halting, but this will help avoid any assumptions about nullability of locals - // through the use in this function. - var stream = _stream; - var solution = _workspace?.CurrentSolution; - - cancellationToken.ThrowIfCancellationRequested(); - - // Early bail check for if we are disposed or somewhere in the middle of disposal - if (_disposed || stream is null || solution is null) - { - _logger.LogTrace("Skipping work due to disposal"); - return; - } - - await CheckConnectionAsync(stream, cancellationToken).ConfigureAwait(false); - await ProcessWorkCoreAsync(work, stream, solution, _logger, cancellationToken).ConfigureAwait(false); - } - - private static async Task ProcessWorkCoreAsync(ImmutableArray work, Stream stream, Solution solution, ILogger logger, CancellationToken cancellationToken) - { - foreach (var unit in work) - { - try - { - cancellationToken.ThrowIfCancellationRequested(); - - if (unit is RemovalWork removalWork) - { - await ReportRemovalAsync(stream, removalWork, logger, cancellationToken).ConfigureAwait(false); - } - - var project = solution.GetProject(unit.ProjectId); - if (project is null) - { - logger.LogTrace("Project {projectId} is not in workspace", unit.ProjectId); - continue; - } - - await ReportUpdateProjectAsync(stream, project, logger, cancellationToken).ConfigureAwait(false); - } - catch (Exception ex) when (ex is not OperationCanceledException) - { - logger.LogError(ex, "Encountered exception while processing unit: {message}", ex.Message); - } - } - - try - { - await stream.FlushAsync(cancellationToken).ConfigureAwait(false); - } - catch (Exception ex) - { - logger.LogError(ex, "Encountered error flusingh stream"); - } - } - - private static async Task ReportUpdateProjectAsync(Stream stream, Project project, ILogger logger, CancellationToken cancellationToken) - { - logger.LogTrace("Serializing information for {projectId}", project.Id); - var result = await RazorProjectInfoFactory.ConvertAsync(project, cancellationToken).ConfigureAwait(false); - if (!result.Succeeded) - { - logger.LogTrace("Skipped writing data for {projectId} because of '{reason}'", project.Id, result.Reason); - return; - } - - stream.WriteProjectInfoAction(RazorProjectInfoAction.Update); - await stream.WriteProjectInfoAsync(result.ProjectInfo, cancellationToken).ConfigureAwait(false); - } - - private static Task ReportRemovalAsync(Stream stream, RemovalWork unit, ILogger logger, CancellationToken cancellationToken) - { - logger.LogTrace("Reporting removal of {projectId}", unit.ProjectId); - return stream.WriteProjectInfoRemovalAsync(unit.IntermediateOutputPath, cancellationToken); - } -} diff --git a/src/Razor/src/Microsoft.VisualStudioCode.RazorExtension/Services/DynamicFileProviderFactory.cs b/src/Razor/src/Microsoft.VisualStudioCode.RazorExtension/Services/DynamicFileProviderFactory.cs deleted file mode 100644 index 5b2361d1c04..00000000000 --- a/src/Razor/src/Microsoft.VisualStudioCode.RazorExtension/Services/DynamicFileProviderFactory.cs +++ /dev/null @@ -1,24 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Composition; -using Microsoft.CodeAnalysis.ExternalAccess.Razor; -using Microsoft.CodeAnalysis.ExternalAccess.Razor.Features; -using Microsoft.CodeAnalysis.Razor.Workspaces; - -namespace Microsoft.VisualStudioCode.RazorExtension.Services; - -[ExportRazorLspServiceFactory(typeof(RazorLspDynamicFileInfoProvider)), Shared] -[method: ImportingConstructor] -internal sealed class DynamicFileProviderFactory( - LanguageServerFeatureOptions featureOptions) : AbstractRazorLspServiceFactory -{ - private readonly LanguageServerFeatureOptions _featureOptions = featureOptions; - - protected override AbstractRazorLspService CreateService(IRazorLspServices lspServices) - { - var clientLanguageServerManager = lspServices.GetRequiredService(); - return new LspDynamicFileProvider(clientLanguageServerManager, _featureOptions); - } -} - diff --git a/src/Razor/src/Microsoft.VisualStudioCode.RazorExtension/Services/EmptyServiceProvider.cs b/src/Razor/src/Microsoft.VisualStudioCode.RazorExtension/Services/EmptyServiceProvider.cs deleted file mode 100644 index 95ccb530cf4..00000000000 --- a/src/Razor/src/Microsoft.VisualStudioCode.RazorExtension/Services/EmptyServiceProvider.cs +++ /dev/null @@ -1,20 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using Microsoft.CodeAnalysis.ExternalAccess.Razor; - -namespace Microsoft.VisualStudioCode.RazorExtension.Services; - -internal sealed class EmptyServiceProvider : IRazorDocumentServiceProvider -{ - public static readonly EmptyServiceProvider Instance = new(); - - public bool CanApplyChange => false; - - public bool SupportDiagnostics => true; - - public TService? GetService() where TService : class - { - return null; - } -} diff --git a/src/Razor/src/Microsoft.VisualStudioCode.RazorExtension/Services/LspDocumentServiceProvider.cs b/src/Razor/src/Microsoft.VisualStudioCode.RazorExtension/Services/LspDocumentServiceProvider.cs deleted file mode 100644 index e15d3018847..00000000000 --- a/src/Razor/src/Microsoft.VisualStudioCode.RazorExtension/Services/LspDocumentServiceProvider.cs +++ /dev/null @@ -1,34 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using Microsoft.AspNetCore.Razor; -using Microsoft.CodeAnalysis.ExternalAccess.Razor; - -namespace Microsoft.VisualStudioCode.RazorExtension.Services; - -internal sealed class LspDocumentServiceProvider(IRazorClientLanguageServerManager razorClientLanguageServerManager) : IRazorDocumentServiceProvider -{ - public bool CanApplyChange => true; - - public bool SupportDiagnostics => true; - - private IRazorMappingService? _mappingService; - - public TService? GetService() where TService : class - { - var serviceType = typeof(TService); - - if (serviceType == typeof(IRazorMappingService)) - { - var mappingService = _mappingService ?? InterlockedOperations.Initialize(ref _mappingService, CreateMappingService()); - return (TService?)mappingService; - } - - return this as TService; - } - - private IRazorMappingService CreateMappingService() - { - return new MappingService(razorClientLanguageServerManager); - } -} diff --git a/src/Razor/src/Microsoft.VisualStudioCode.RazorExtension/Services/LspDynamicFileProvider.LspTextChangesTextLoader.cs b/src/Razor/src/Microsoft.VisualStudioCode.RazorExtension/Services/LspDynamicFileProvider.LspTextChangesTextLoader.cs deleted file mode 100644 index ddee6860b71..00000000000 --- a/src/Razor/src/Microsoft.VisualStudioCode.RazorExtension/Services/LspDynamicFileProvider.LspTextChangesTextLoader.cs +++ /dev/null @@ -1,124 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using System.Collections.Generic; -using System.Collections.Immutable; -using System.Linq; -using System.Text; -using System.Threading; -using System.Threading.Tasks; -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.ExternalAccess.Razor; -using Microsoft.CodeAnalysis.Razor.Protocol; -using Microsoft.CodeAnalysis.Text; - -namespace Microsoft.VisualStudioCode.RazorExtension.Services; - -internal sealed partial class LspDynamicFileProvider -{ - private sealed class LspTextChangesTextLoader( - TextDocument? document, - RazorTextChange[] changes, - byte[] checksum, - SourceHashAlgorithm checksumAlgorithm, - int? codePage, - Uri razorUri, - IRazorClientLanguageServerManager razorClientLanguageServerManager) : TextLoader - { - private readonly TextDocument? _document = document; - private readonly ImmutableArray _changes = changes.SelectAsArray(c => c.ToTextChange()); - private readonly byte[] _checksum = checksum; - private readonly SourceHashAlgorithm _checksumAlgorithm = checksumAlgorithm; - private readonly int? _codePage = codePage; - private readonly DocumentUri _razorUri = new(razorUri); - private readonly IRazorClientLanguageServerManager _razorClientLanguageServerManager = razorClientLanguageServerManager; - private readonly Lazy _emptySourceText = new(() => - { - var encoding = codePage is null ? null : Encoding.GetEncoding(codePage.Value); - return SourceText.From("", checksumAlgorithm: checksumAlgorithm, encoding: encoding); - }); - - public override async Task LoadTextAndVersionAsync(LoadTextOptions options, CancellationToken cancellationToken) - { - try - { - if (_document is null) - { - var text = ApplyChanges(_emptySourceText.Value, _changes); - return TextAndVersion.Create(text, VersionStamp.Default.GetNewerVersion()); - } - - var sourceText = await _document.GetTextAsync(cancellationToken).ConfigureAwait(false); - - // Validate the checksum information so the edits are known to be correct - - if (IsSourceTextMatching(sourceText)) - { - var version = await _document.GetTextVersionAsync(cancellationToken).ConfigureAwait(false); - var newText = ApplyChanges(sourceText, _changes); - return TextAndVersion.Create(newText, version.GetNewerVersion()); - } - } - catch (Exception ex) when (ex is not OperationCanceledException) - { - // This happens if ApplyChanges tries to apply an invalid TextChange. - // This is recoverable but incurs a perf hit for getting the full text below. - - // TODO: Add ability to capture a fault here in EA. There's something wrong if - // the Checksum matches but the text changes can't be applied. - } - - return await GetFullDocumentFromServerAsync(cancellationToken).ConfigureAwait(false); - } - - private bool IsSourceTextMatching(SourceText sourceText) - { - if (sourceText.ChecksumAlgorithm != _checksumAlgorithm) - { - return false; - } - - if (sourceText.Encoding?.CodePage != _codePage) - { - return false; - } - - if (!sourceText.GetChecksum().SequenceEqual(_checksum)) - { - return false; - } - - return true; - } - - private async Task GetFullDocumentFromServerAsync(CancellationToken cancellationToken) - { - var response = await _razorClientLanguageServerManager.SendRequestAsync( - ProvideRazorDynamicFileInfoMethodName, - new RazorProvideDynamicFileParams - { - RazorDocument = new() - { - DocumentUri = _razorUri, - }, - FullText = true - }, - cancellationToken).ConfigureAwait(false); - - var text = ApplyChanges(_emptySourceText.Value, response.Edits.SelectAsArray(e => e.ToTextChange())); - return TextAndVersion.Create(text, VersionStamp.Default.GetNewerVersion()); - } - - private static SourceText ApplyChanges(SourceText sourceText, ImmutableArray changes) - { - foreach (var change in changes) - { - sourceText = sourceText.WithChanges(change); - } - - return sourceText; - } - } -} - diff --git a/src/Razor/src/Microsoft.VisualStudioCode.RazorExtension/Services/LspDynamicFileProvider.cs b/src/Razor/src/Microsoft.VisualStudioCode.RazorExtension/Services/LspDynamicFileProvider.cs deleted file mode 100644 index e903d18a9bd..00000000000 --- a/src/Razor/src/Microsoft.VisualStudioCode.RazorExtension/Services/LspDynamicFileProvider.cs +++ /dev/null @@ -1,83 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using System.Threading; -using System.Threading.Tasks; -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.ExternalAccess.Razor; -using Microsoft.CodeAnalysis.ExternalAccess.Razor.Features; -using Microsoft.CodeAnalysis.Razor; -using Microsoft.CodeAnalysis.Razor.Workspaces; - -namespace Microsoft.VisualStudioCode.RazorExtension.Services; - -internal sealed partial class LspDynamicFileProvider( - IRazorClientLanguageServerManager clientLanguageServerManager, - LanguageServerFeatureOptions languageServerFeatureOptions) : RazorLspDynamicFileInfoProvider -{ - private const string ProvideRazorDynamicFileInfoMethodName = "razor/provideDynamicFileInfo"; - private const string RemoveRazorDynamicFileInfoMethodName = "razor/removeDynamicFileInfo"; - - private readonly IRazorClientLanguageServerManager _clientLanguageServerManager = clientLanguageServerManager; - private readonly LanguageServerFeatureOptions _languageServerFeatureOptions = languageServerFeatureOptions; - - public override async Task GetDynamicFileInfoAsync(Workspace workspace, ProjectId projectId, string? projectFilePath, string filePath, CancellationToken cancellationToken) - { - if (_languageServerFeatureOptions.UseRazorCohostServer) - { - return null; - } - - var razorUri = new Uri(filePath); - - var requestParams = new RazorProvideDynamicFileParams - { - RazorDocument = new() - { - DocumentUri = new(razorUri) - } - }; - - var response = await _clientLanguageServerManager.SendRequestAsync( - ProvideRazorDynamicFileInfoMethodName, - requestParams, - cancellationToken).ConfigureAwait(false); - - if (response is null) - { - return null; - } - - var textDocument = await WorkspaceExtensions.GetTextDocumentAsync(workspace, response.CSharpDocument.DocumentUri, cancellationToken).ConfigureAwait(false); - var checksum = Convert.FromBase64String(response.Checksum); - var textLoader = new LspTextChangesTextLoader( - textDocument, - response.Edits, - checksum, - response.ChecksumAlgorithm, - response.SourceEncodingCodePage, - razorUri, - _clientLanguageServerManager); - - return new RazorDynamicFileInfo( - RazorUri.GetDocumentFilePathFromUri(response.CSharpDocument.DocumentUri.GetRequiredParsedUri()), - SourceCodeKind.Regular, - textLoader, - documentServiceProvider: new LspDocumentServiceProvider(_clientLanguageServerManager)); - } - - public override Task RemoveDynamicFileInfoAsync(Workspace workspace, ProjectId projectId, string? projectFilePath, string filePath, CancellationToken cancellationToken) - { - var notificationParams = new RazorRemoveDynamicFileParams - { - CSharpDocument = new() - { - DocumentUri = new(new Uri(filePath)) - } - }; - return _clientLanguageServerManager.SendNotificationAsync( - RemoveRazorDynamicFileInfoMethodName, notificationParams, cancellationToken).AsTask(); - } -} - diff --git a/src/Razor/src/Microsoft.VisualStudioCode.RazorExtension/Services/MappingService.cs b/src/Razor/src/Microsoft.VisualStudioCode.RazorExtension/Services/MappingService.cs deleted file mode 100644 index 3e44b71d65c..00000000000 --- a/src/Razor/src/Microsoft.VisualStudioCode.RazorExtension/Services/MappingService.cs +++ /dev/null @@ -1,118 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using System.Collections.Generic; -using System.Collections.Immutable; -using System.Diagnostics; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Razor.PooledObjects; -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.ExternalAccess.Razor; -using Microsoft.CodeAnalysis.Razor; -using Microsoft.CodeAnalysis.Razor.Protocol; -using Microsoft.CodeAnalysis.Text; - -namespace Microsoft.VisualStudioCode.RazorExtension.Services; - -internal sealed class MappingService(IRazorClientLanguageServerManager razorClientLanguageServerManager) : IRazorMappingService -{ - private const string RazorMapSpansEndpoint = "razor/mapSpans"; - private const string RazorMapTextChangesEndpoint = "razor/mapTextChanges"; - - private readonly IRazorClientLanguageServerManager _razorClientLanguageServerManager = razorClientLanguageServerManager; - - public async Task> MapSpansAsync(Document document, IEnumerable spans, CancellationToken cancellationToken) - { - if (string.IsNullOrWhiteSpace(document.FilePath) || - (spans.TryGetNonEnumeratedCount(out var count) && count == 0)) - { - return []; - } - - var sourceText = await document.GetTextAsync(cancellationToken).ConfigureAwait(false); - - var mapParams = new RazorMapSpansParams() - { - CSharpDocument = new() - { - DocumentUri = new(new Uri(document.FilePath)) - }, - Ranges = [.. spans.Select(sourceText.GetRange)] - }; - - var response = await _razorClientLanguageServerManager.SendRequestAsync( - RazorMapSpansEndpoint, - mapParams, - cancellationToken).ConfigureAwait(false); - - if (response is not { Spans.Length: > 0, Ranges.Length: > 0 }) - { - return []; - } - - Debug.Assert(response.Spans.Length == spans.Count(), "The number of mapped spans should match the number of input spans."); - Debug.Assert(response.Ranges.Length == spans.Count(), "The number of mapped ranges should match the number of input spans."); - - using var builder = new PooledArrayBuilder(response.Spans.Length); - var filePath = response.RazorDocument.DocumentUri.GetRequiredParsedUri().GetDocumentFilePath(); - - for (var i = 0; i < response.Spans.Length; i++) - { - var span = response.Spans[i]; - var range = response.Ranges[i]; - - if (range.IsUndefined()) - { - continue; - } - - builder.Add(new RazorMappedSpanResult(filePath, range.ToLinePositionSpan(), span.ToTextSpan())); - } - - return builder.ToImmutableAndClear(); - } - - public async Task> MapTextChangesAsync(Document oldDocument, Document newDocument, CancellationToken cancellationToken) - { - if (string.IsNullOrWhiteSpace(newDocument.FilePath)) - { - return []; - } - - var changes = await newDocument.GetTextChangesAsync(oldDocument, cancellationToken).ConfigureAwait(false); - var textChanges = changes.Select(c => c.ToRazorTextChange()).ToArray(); - - if (textChanges.Length == 0) - { - return []; - } - - var mapParams = new RazorMapTextChangesParams() - { - CSharpDocument = new() - { - DocumentUri = new(new Uri(newDocument.FilePath)) - }, - TextChanges = textChanges - }; - - var response = await _razorClientLanguageServerManager.SendRequestAsync( - RazorMapTextChangesEndpoint, - mapParams, - cancellationToken).ConfigureAwait(false); - - if (response is not { MappedTextChanges.Length: > 0 }) - { - return []; - } - - Debug.Assert(response.MappedTextChanges.Length == changes.Count(), "The number of mapped text changes should match the number of input text changes."); - var filePath = response.RazorDocument.DocumentUri.GetRequiredParsedUri().GetDocumentFilePath(); - var convertedChanges = Array.ConvertAll(response.MappedTextChanges, mappedChange => mappedChange.ToTextChange()); - var result = new RazorMappedEditResult(filePath, convertedChanges); - return [result]; - } -} diff --git a/src/Razor/src/Microsoft.VisualStudioCode.RazorExtension/Services/RazorMapSpansParams.cs b/src/Razor/src/Microsoft.VisualStudioCode.RazorExtension/Services/RazorMapSpansParams.cs deleted file mode 100644 index a134e4de14e..00000000000 --- a/src/Razor/src/Microsoft.VisualStudioCode.RazorExtension/Services/RazorMapSpansParams.cs +++ /dev/null @@ -1,15 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Text.Json.Serialization; - -namespace Microsoft.VisualStudioCode.RazorExtension.Services; - -internal sealed class RazorMapSpansParams -{ - [JsonPropertyName("csharpDocument")] - public required TextDocumentIdentifier CSharpDocument { get; set; } - - [JsonPropertyName("ranges")] - public required LspRange[] Ranges { get; set; } -} diff --git a/src/Razor/src/Microsoft.VisualStudioCode.RazorExtension/Services/RazorMapSpansResponse.cs b/src/Razor/src/Microsoft.VisualStudioCode.RazorExtension/Services/RazorMapSpansResponse.cs deleted file mode 100644 index 8edb110afe0..00000000000 --- a/src/Razor/src/Microsoft.VisualStudioCode.RazorExtension/Services/RazorMapSpansResponse.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. - -using System.Text.Json.Serialization; -using Microsoft.CodeAnalysis.Razor.Protocol; - -namespace Microsoft.VisualStudioCode.RazorExtension.Services; - -internal sealed class RazorMapSpansResponse -{ - [JsonPropertyName("ranges")] - public required LspRange[] Ranges { get; set; } - - [JsonPropertyName("spans")] - public required RazorTextSpan[] Spans { get; set; } - - [JsonPropertyName("razorDocument")] - public required TextDocumentIdentifier RazorDocument { get; set; } -} diff --git a/src/Razor/src/Microsoft.VisualStudioCode.RazorExtension/Services/RazorMapTextChangesParams.cs b/src/Razor/src/Microsoft.VisualStudioCode.RazorExtension/Services/RazorMapTextChangesParams.cs deleted file mode 100644 index 9e0595a5e0d..00000000000 --- a/src/Razor/src/Microsoft.VisualStudioCode.RazorExtension/Services/RazorMapTextChangesParams.cs +++ /dev/null @@ -1,16 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Text.Json.Serialization; -using Microsoft.CodeAnalysis.Razor.Protocol; - -namespace Microsoft.VisualStudioCode.RazorExtension.Services; - -internal sealed class RazorMapTextChangesParams -{ - [JsonPropertyName("csharpDocument")] - public required TextDocumentIdentifier CSharpDocument { get; set; } - - [JsonPropertyName("textChanges")] - public required RazorTextChange[] TextChanges { get; set; } -} diff --git a/src/Razor/src/Microsoft.VisualStudioCode.RazorExtension/Services/RazorMapTextChangesResponse.cs b/src/Razor/src/Microsoft.VisualStudioCode.RazorExtension/Services/RazorMapTextChangesResponse.cs deleted file mode 100644 index 83aa78252c6..00000000000 --- a/src/Razor/src/Microsoft.VisualStudioCode.RazorExtension/Services/RazorMapTextChangesResponse.cs +++ /dev/null @@ -1,17 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Text.Json.Serialization; -using Microsoft.CodeAnalysis.Razor.Protocol; - -namespace Microsoft.VisualStudioCode.RazorExtension.Services; - -internal sealed class RazorMapTextChangesResponse -{ - [JsonPropertyName("razorDocument")] - public required TextDocumentIdentifier RazorDocument { get; set; } - - [JsonPropertyName("mappedTextChanges")] - public required RazorTextChange[] MappedTextChanges { get; set; } -} - diff --git a/src/Razor/src/Microsoft.VisualStudioCode.RazorExtension/Services/RazorProvideDynamicFileParams.cs b/src/Razor/src/Microsoft.VisualStudioCode.RazorExtension/Services/RazorProvideDynamicFileParams.cs deleted file mode 100644 index 3275f19a494..00000000000 --- a/src/Razor/src/Microsoft.VisualStudioCode.RazorExtension/Services/RazorProvideDynamicFileParams.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. - -using System.Text.Json.Serialization; - -namespace Microsoft.VisualStudioCode.RazorExtension.Services; - -internal sealed class RazorProvideDynamicFileParams -{ - [JsonPropertyName("razorDocument")] - public required TextDocumentIdentifier RazorDocument { get; set; } - - /// - /// When true, the full text of the document will be sent over as a single - /// edit instead of diff edits - /// - [JsonPropertyName("fullText")] - public bool FullText { get; set; } -} diff --git a/src/Razor/src/Microsoft.VisualStudioCode.RazorExtension/Services/RazorProvideDynamicFileResponse.cs b/src/Razor/src/Microsoft.VisualStudioCode.RazorExtension/Services/RazorProvideDynamicFileResponse.cs deleted file mode 100644 index 716733def66..00000000000 --- a/src/Razor/src/Microsoft.VisualStudioCode.RazorExtension/Services/RazorProvideDynamicFileResponse.cs +++ /dev/null @@ -1,26 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Text.Json.Serialization; -using Microsoft.CodeAnalysis.Text; -using Microsoft.CodeAnalysis.Razor.Protocol; - -namespace Microsoft.VisualStudioCode.RazorExtension.Services; - -internal sealed class RazorProvideDynamicFileResponse -{ - [JsonPropertyName("csharpDocument")] - public required TextDocumentIdentifier CSharpDocument { get; set; } - - [JsonPropertyName("edits")] - public required RazorTextChange[] Edits { get; set; } - - [JsonPropertyName("checksum")] - public required string Checksum { get; set; } - - [JsonPropertyName("checksumAlgorithm")] - public SourceHashAlgorithm ChecksumAlgorithm { get; set; } - - [JsonPropertyName("encodingCodePage")] - public int? SourceEncodingCodePage { get; set; } -} diff --git a/src/Razor/src/Microsoft.VisualStudioCode.RazorExtension/Services/RazorRemoveDynamicFileParams.cs b/src/Razor/src/Microsoft.VisualStudioCode.RazorExtension/Services/RazorRemoveDynamicFileParams.cs deleted file mode 100644 index f8ff21e222d..00000000000 --- a/src/Razor/src/Microsoft.VisualStudioCode.RazorExtension/Services/RazorRemoveDynamicFileParams.cs +++ /dev/null @@ -1,12 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Text.Json.Serialization; - -namespace Microsoft.VisualStudioCode.RazorExtension.Services; - -internal class RazorRemoveDynamicFileParams -{ - [JsonPropertyName("csharpDocument")] - public required TextDocumentIdentifier CSharpDocument { get; set; } -} diff --git a/src/Razor/src/Microsoft.VisualStudioCode.RazorExtension/Services/VSCodeLanguageServerFeatureOptions.cs b/src/Razor/src/Microsoft.VisualStudioCode.RazorExtension/Services/VSCodeLanguageServerFeatureOptions.cs index 247399ffee9..d5f60566ce4 100644 --- a/src/Razor/src/Microsoft.VisualStudioCode.RazorExtension/Services/VSCodeLanguageServerFeatureOptions.cs +++ b/src/Razor/src/Microsoft.VisualStudioCode.RazorExtension/Services/VSCodeLanguageServerFeatureOptions.cs @@ -2,29 +2,16 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Composition; -using System.Text.Json.Nodes; -using System.Threading; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Razor; -using Microsoft.AspNetCore.Razor.LanguageServer; using Microsoft.AspNetCore.Razor.Utilities; -using Microsoft.CodeAnalysis.ExternalAccess.Razor.Cohost; using Microsoft.CodeAnalysis.Razor.Workspaces; -using Microsoft.NET.Sdk.Razor.SourceGenerators; -using Microsoft.VisualStudio.Razor.LanguageClient.Cohost; namespace Microsoft.VisualStudioCode.RazorExtension.Services; [Shared] -[Export(typeof(IRazorCohostStartupService))] [Export(typeof(LanguageServerFeatureOptions))] [method: ImportingConstructor] -internal class VSCodeLanguageServerFeatureOptions(RazorClientServerManagerProvider razorClientServerManagerProvider) : LanguageServerFeatureOptions, IRazorCohostStartupService +internal class VSCodeLanguageServerFeatureOptions() : LanguageServerFeatureOptions { - private bool _useRazorCohostServer = false; - - private readonly RazorClientServerManagerProvider _razorClientServerManagerProvider = razorClientServerManagerProvider; - // Options that are set to their defaults public override bool SupportsFileManipulation => true; public override bool SingleServerSupport => false; @@ -42,39 +29,5 @@ internal class VSCodeLanguageServerFeatureOptions(RazorClientServerManagerProvid public override bool UseVsCodeCompletionCommitCharacters => true; // User configurable options - public override bool UseRazorCohostServer => _useRazorCohostServer; - - public int Order => WellKnownStartupOrder.LanguageServerFeatureOptions; - - public async Task StartupAsync(VSInternalClientCapabilities clientCapabilities, RazorCohostRequestContext requestContext, CancellationToken cancellationToken) - { - var razorClientLanguageServerManager = _razorClientServerManagerProvider.ClientLanguageServerManager.AssumeNotNull(); - - // Attempt to get configurations from the client. If this throws we'll get NFW reports. - var configurationParams = new ConfigurationParams() - { - Items = [ - // Roslyn's typescript config handler will convert underscores to camelcase, ie 'razor.languageServer.cohostingEnabled' - new ConfigurationItem { Section = "razor.language_server.cohosting_enabled" }, - ] - }; - var options = await razorClientLanguageServerManager.SendRequestAsync( - Methods.WorkspaceConfigurationName, - configurationParams, - cancellationToken).ConfigureAwait(false); - - _useRazorCohostServer = GetBooleanOptionValue(options[0], _useRazorCohostServer); - - RazorCohostingOptions.UseRazorCohostServer = _useRazorCohostServer; - } - - private static bool GetBooleanOptionValue(JsonNode? jsonNode, bool defaultValue) - { - if (jsonNode is null) - { - return defaultValue; - } - - return jsonNode.ToString() == "true"; - } + public override bool UseRazorCohostServer => true; } diff --git a/src/Razor/src/Microsoft.VisualStudioCode.RazorExtension/Services/WorkspaceService.cs b/src/Razor/src/Microsoft.VisualStudioCode.RazorExtension/Services/WorkspaceService.cs deleted file mode 100644 index cc9bcdb4654..00000000000 --- a/src/Razor/src/Microsoft.VisualStudioCode.RazorExtension/Services/WorkspaceService.cs +++ /dev/null @@ -1,88 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Collections.Generic; -using System.Composition; -using System.Threading; -using Microsoft.AspNetCore.Razor; -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.ExternalAccess.Razor.Features; -using Microsoft.CodeAnalysis.Razor.Workspaces; -using Microsoft.Extensions.Logging; - -namespace Microsoft.VisualStudioCode.RazorExtension.Services; - -[ExportRazorStatelessLspService(typeof(RazorWorkspaceService)), Shared] -[method: ImportingConstructor] -internal sealed class WorkspaceService(ILoggerFactory loggerFactory, LanguageServerFeatureOptions languageServerFeatureOptions) : RazorWorkspaceService -{ - private readonly ILoggerFactory _loggerFactory = loggerFactory; - private readonly ILogger _logger = loggerFactory.CreateLogger(); - private readonly Lock _initializeLock = new(); - private readonly LanguageServerFeatureOptions _languageServerFeatureOptions = languageServerFeatureOptions; - - private RazorWorkspaceListener? _razorWorkspaceListener; - private HashSet? _projectIdWithDynamicFiles = []; - - public override void Initialize(Workspace workspace, string pipeName) - { - if (_languageServerFeatureOptions.UseRazorCohostServer) - { - // Cohost server doesn't need to initialize the workspace listener. - return; - } - - HashSet projectsToInitialize; - lock (_initializeLock) - { - // Only initialize once - if (_razorWorkspaceListener is not null) - { - return; - } - - //_logger.LogTrace("Initializing the Razor workspace listener with pipe name {0}", pipeName); - _razorWorkspaceListener = new RazorWorkspaceListener(_loggerFactory); - _razorWorkspaceListener.EnsureInitialized(workspace, pipeName); - - // _projectIdWithDynamicFiles won't be used again after initialization is done - projectsToInitialize = _projectIdWithDynamicFiles.AssumeNotNull(); - _projectIdWithDynamicFiles = null; - } - - foreach (var projectId in projectsToInitialize) - { - _logger.LogTrace("{projectId} notifying a dynamic file for the first time", projectId); - _razorWorkspaceListener.NotifyDynamicFile(projectId); - } - } - - public override void NotifyDynamicFile(ProjectId projectId) - { - if (_languageServerFeatureOptions.UseRazorCohostServer) - { - // Cohost server doesn't need to initialize the workspace listener. - return; - } - - if (_razorWorkspaceListener is null) - { - lock (_initializeLock) - { - if (_razorWorkspaceListener is not null) - { - _razorWorkspaceListener.NotifyDynamicFile(projectId); - return; - } - - _projectIdWithDynamicFiles - .AssumeNotNull() - .Add(projectId); - } - } - else - { - _razorWorkspaceListener?.NotifyDynamicFile(projectId); - } - } -} diff --git a/src/Razor/src/rzls/Targets/Microsoft.NET.Sdk.Razor.DesignTime.targets b/src/Razor/src/Microsoft.VisualStudioCode.RazorExtension/Targets/Microsoft.NET.Sdk.Razor.DesignTime.targets similarity index 100% rename from src/Razor/src/rzls/Targets/Microsoft.NET.Sdk.Razor.DesignTime.targets rename to src/Razor/src/Microsoft.VisualStudioCode.RazorExtension/Targets/Microsoft.NET.Sdk.Razor.DesignTime.targets diff --git a/src/Razor/src/rzls/Targets/Readme.md b/src/Razor/src/Microsoft.VisualStudioCode.RazorExtension/Targets/Readme.md similarity index 100% rename from src/Razor/src/rzls/Targets/Readme.md rename to src/Razor/src/Microsoft.VisualStudioCode.RazorExtension/Targets/Readme.md diff --git a/src/Razor/src/rzls/Targets/Rules/RazorComponentWithTargetPath.xaml b/src/Razor/src/Microsoft.VisualStudioCode.RazorExtension/Targets/Rules/RazorComponentWithTargetPath.xaml similarity index 100% rename from src/Razor/src/rzls/Targets/Rules/RazorComponentWithTargetPath.xaml rename to src/Razor/src/Microsoft.VisualStudioCode.RazorExtension/Targets/Rules/RazorComponentWithTargetPath.xaml diff --git a/src/Razor/src/rzls/Targets/Rules/RazorConfiguration.xaml b/src/Razor/src/Microsoft.VisualStudioCode.RazorExtension/Targets/Rules/RazorConfiguration.xaml similarity index 100% rename from src/Razor/src/rzls/Targets/Rules/RazorConfiguration.xaml rename to src/Razor/src/Microsoft.VisualStudioCode.RazorExtension/Targets/Rules/RazorConfiguration.xaml diff --git a/src/Razor/src/rzls/Targets/Rules/RazorExtension.xaml b/src/Razor/src/Microsoft.VisualStudioCode.RazorExtension/Targets/Rules/RazorExtension.xaml similarity index 100% rename from src/Razor/src/rzls/Targets/Rules/RazorExtension.xaml rename to src/Razor/src/Microsoft.VisualStudioCode.RazorExtension/Targets/Rules/RazorExtension.xaml diff --git a/src/Razor/src/rzls/Targets/Rules/RazorGeneral.xaml b/src/Razor/src/Microsoft.VisualStudioCode.RazorExtension/Targets/Rules/RazorGeneral.xaml similarity index 100% rename from src/Razor/src/rzls/Targets/Rules/RazorGeneral.xaml rename to src/Razor/src/Microsoft.VisualStudioCode.RazorExtension/Targets/Rules/RazorGeneral.xaml diff --git a/src/Razor/src/rzls/Targets/Rules/RazorGenerateWithTargetPath.xaml b/src/Razor/src/Microsoft.VisualStudioCode.RazorExtension/Targets/Rules/RazorGenerateWithTargetPath.xaml similarity index 100% rename from src/Razor/src/rzls/Targets/Rules/RazorGenerateWithTargetPath.xaml rename to src/Razor/src/Microsoft.VisualStudioCode.RazorExtension/Targets/Rules/RazorGenerateWithTargetPath.xaml diff --git a/src/Razor/src/rzls/CustomExportAssemblyLoader.cs b/src/Razor/src/rzls/CustomExportAssemblyLoader.cs deleted file mode 100644 index 8883f7d7b53..00000000000 --- a/src/Razor/src/rzls/CustomExportAssemblyLoader.cs +++ /dev/null @@ -1,111 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Collections.Generic; -using System.IO; -using System.Reflection; -using Microsoft.VisualStudio.Composition; - -namespace Microsoft.AspNetCore.Razor.LanguageServer; - -internal class CustomExportAssemblyLoader(string baseDirectory) : IAssemblyLoader -{ - /// - /// Cache assemblies that are already loaded by AssemblyName comparison - /// - private readonly Dictionary _loadedAssemblies = new(AssemblyNameComparer.Instance); - - /// - /// Base directory to search for if initial load fails - /// - private readonly string _baseDirectory = baseDirectory; - - public Assembly LoadAssembly(AssemblyName assemblyName) - { - Assembly? assembly; - - lock (_loadedAssemblies) - { - if (_loadedAssemblies.TryGetValue(assemblyName, out assembly)) - { - return assembly; - } - } - - assembly = LoadAssemblyCore(assemblyName); - - lock (_loadedAssemblies) - { - _loadedAssemblies[assemblyName] = assembly; - } - - return assembly; - } - - public Assembly LoadAssembly(string assemblyFullName, string? codeBasePath) - { - var assemblyName = new AssemblyName(assemblyFullName); - - if (codeBasePath is not null) - { -#pragma warning disable SYSLIB0044 // Type or member is obsolete - assemblyName.CodeBase = codeBasePath; -#pragma warning restore SYSLIB0044 // Type or member is obsolete - } - - return LoadAssembly(assemblyName); - } - - private Assembly LoadAssemblyCore(AssemblyName assemblyName) - { - // Attempt to load the assembly normally, but fall back to Assembly.LoadFrom in the base - // directory if the assembly load fails - - try - { - return Assembly.Load(assemblyName); - } - catch (FileNotFoundException) - { - // Carry on trying to load by path below. - } - - var simpleName = assemblyName.Name!; - var assemblyPath = Path.Combine(_baseDirectory, simpleName + ".dll"); - if (File.Exists(assemblyPath)) - { - return Assembly.LoadFrom(assemblyPath); - } - - throw new FileNotFoundException($"Could not find assembly {assemblyName} at {assemblyPath}"); - } - - private sealed class AssemblyNameComparer : IEqualityComparer - { - public static readonly AssemblyNameComparer Instance = new(); - - private AssemblyNameComparer() - { - } - - public bool Equals(AssemblyName? x, AssemblyName? y) - { - if (x == null && y == null) - { - return true; - } - - if (x == null || y == null) - { - return false; - } - - return x.Name == y.Name; - } - - public int GetHashCode(AssemblyName obj) - { - return obj.Name?.GetHashCode() ?? 0; - } - } -} diff --git a/src/Razor/src/rzls/ExportProviderBuilder.cs b/src/Razor/src/rzls/ExportProviderBuilder.cs deleted file mode 100644 index 2f3fbeef46d..00000000000 --- a/src/Razor/src/rzls/ExportProviderBuilder.cs +++ /dev/null @@ -1,44 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.IO; -using System.Threading.Tasks; -using Microsoft.VisualStudio.Composition; - -namespace Microsoft.AspNetCore.Razor.LanguageServer; - -internal sealed class ExportProviderBuilder -{ - public static async Task CreateExportProviderAsync(string extensionPath) - { - var baseDirectory = Path.GetDirectoryName(extensionPath); - var assemblyLoader = new CustomExportAssemblyLoader(baseDirectory!); - var resolver = new Resolver(assemblyLoader); - - var discovery = PartDiscovery.Combine( - resolver, - new AttributedPartDiscovery(resolver, isNonPublicSupported: true), // "NuGet MEF" attributes (Microsoft.Composition) - new AttributedPartDiscoveryV1(resolver)); - - // TODO - we should likely cache the catalog so we don't have to rebuild it every time. - var parts = await discovery.CreatePartsAsync(new[] { extensionPath! }).ConfigureAwait(true); - var catalog = ComposableCatalog.Create(resolver) - .AddParts(parts) - .WithCompositionService(); // Makes an ICompositionService export available to MEF parts to import - - // Assemble the parts into a valid graph. - var config = CompositionConfiguration.Create(catalog); - - // Verify we have no errors. - config.ThrowOnErrors(); - - // Prepare an ExportProvider factory based on this graph. - var exportProviderFactory = config.CreateExportProviderFactory(); - - // Create an export provider, which represents a unique container of values. - // You can create as many of these as you want, but typically an app needs just one. - var exportProvider = exportProviderFactory.CreateExportProvider(); - - return exportProvider; - } -} diff --git a/src/Razor/src/rzls/LoggerFactory.cs b/src/Razor/src/rzls/LoggerFactory.cs deleted file mode 100644 index c3c1a109348..00000000000 --- a/src/Razor/src/rzls/LoggerFactory.cs +++ /dev/null @@ -1,13 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using System.Collections.Immutable; -using Microsoft.CodeAnalysis.Razor.Logging; - -namespace Microsoft.AspNetCore.Razor.LanguageServer; - -internal sealed class LoggerFactory(ImmutableArray> providers) - : AbstractLoggerFactory(providers) -{ -} diff --git a/src/Razor/src/rzls/LoggerProvider.cs b/src/Razor/src/rzls/LoggerProvider.cs deleted file mode 100644 index 92c0ffd3c0d..00000000000 --- a/src/Razor/src/rzls/LoggerProvider.cs +++ /dev/null @@ -1,16 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using Microsoft.AspNetCore.Razor.LanguageServer.Hosting; -using Microsoft.AspNetCore.Razor.LanguageServer.Hosting.Logging; -using Microsoft.CodeAnalysis.Razor.Logging; - -namespace Microsoft.AspNetCore.Razor.LanguageServer; - -internal class LoggerProvider(LogLevelProvider logLevelProvider, IClientConnection clientConnection) : ILoggerProvider -{ - public ILogger CreateLogger(string categoryName) - { - return new LspLogger(categoryName, logLevelProvider, clientConnection); - } -} diff --git a/src/Razor/src/rzls/LspLogger.cs b/src/Razor/src/rzls/LspLogger.cs deleted file mode 100644 index 8dfbc2864c3..00000000000 --- a/src/Razor/src/rzls/LspLogger.cs +++ /dev/null @@ -1,56 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using System.Threading; -using Microsoft.AspNetCore.Razor.LanguageServer.Hosting; -using Microsoft.AspNetCore.Razor.LanguageServer.Hosting.Logging; -using Microsoft.CodeAnalysis.Razor.Logging; -using Microsoft.VisualStudio.Threading; -using Roslyn.LanguageServer.Protocol; - -namespace Microsoft.AspNetCore.Razor.LanguageServer; - -/// -/// ILogger implementation that logs via the window/logMessage LSP method -/// -internal class LspLogger(string categoryName, LogLevelProvider logLevelProvider, IClientConnection clientConnection) : ILogger -{ - private LogLevel LogLevel => logLevelProvider.Current; - private readonly string _categoryName = categoryName; - private readonly IClientConnection _clientConnection = clientConnection; - - public bool IsEnabled(LogLevel logLevel) - { - return logLevel.IsAtLeast(LogLevel); - } - - public void Log(LogLevel logLevel, string message, Exception? exception) - { - if (!IsEnabled(logLevel)) - { - return; - } - - var messageType = logLevel switch - { - LogLevel.Critical => MessageType.Error, - LogLevel.Error => MessageType.Error, - LogLevel.Warning => MessageType.Warning, - LogLevel.Information => MessageType.Info, - LogLevel.Debug => MessageType.Debug, - LogLevel.Trace => MessageType.Log, - _ => throw new NotImplementedException(), - }; - - var formattedMessage = LogMessageFormatter.FormatMessage(message, _categoryName, exception, includeTimeStamp: false); - - var @params = new LogMessageParams - { - MessageType = messageType, - Message = formattedMessage, - }; - - _clientConnection.SendNotificationAsync(Methods.WindowLogMessageName, @params, CancellationToken.None).Forget(); - } -} diff --git a/src/Razor/src/rzls/NamedPipeBasedRazorProjectInfoDriver.cs b/src/Razor/src/rzls/NamedPipeBasedRazorProjectInfoDriver.cs deleted file mode 100644 index ffb89e488b2..00000000000 --- a/src/Razor/src/rzls/NamedPipeBasedRazorProjectInfoDriver.cs +++ /dev/null @@ -1,106 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using System.Diagnostics; -using System.IO.Pipes; -using System.Threading; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Razor.LanguageServer.Hosting.NamedPipes; -using Microsoft.CodeAnalysis.Razor.Logging; -using Microsoft.CodeAnalysis.Razor.ProjectSystem; -using Microsoft.CodeAnalysis.Razor.Utilities; -using Microsoft.VisualStudio.Threading; - -namespace Microsoft.AspNetCore.Razor.LanguageServer; - -internal sealed class NamedPipeBasedRazorProjectInfoDriver : AbstractRazorProjectInfoDriver, INamedPipeProjectInfoDriver -{ - private NamedPipeClientStream? _namedPipe; - - public NamedPipeBasedRazorProjectInfoDriver(ILoggerFactory loggerFactory) : base(loggerFactory) - { - StartInitialization(); - } - - public async Task CreateNamedPipeAsync(string pipeName, CancellationToken cancellationToken) - { - Assumed.True(_namedPipe is null); - Logger.LogTrace($"Connecting to named pipe {pipeName} on PID: {Process.GetCurrentProcess().Id}"); - - _namedPipe = new NamedPipeClientStream(".", pipeName, PipeDirection.In, PipeOptions.CurrentUserOnly | PipeOptions.Asynchronous); - await _namedPipe.ConnectAsync(cancellationToken).ConfigureAwait(false); - - // Don't block reading the stream on the caller of this - ReadFromStreamAsync(DisposalToken).Forget(); - } - - protected override Task InitializeAsync(CancellationToken cancellationToken) => Task.CompletedTask; - - protected override void OnDispose() - { - _namedPipe?.Dispose(); - _namedPipe = null; - } - - private async Task ReadFromStreamAsync(CancellationToken cancellationToken) - { - Logger.LogTrace($"Starting read from named pipe."); - var failedActionReads = 0; - - while ( - _namedPipe is { IsConnected: true } && - !cancellationToken.IsCancellationRequested) - { - RazorProjectInfoAction? projectInfoAction; - try - { - projectInfoAction = _namedPipe.ReadProjectInfoAction(); - } - catch - { - if (failedActionReads++ > 0) - { - throw; - } - - Logger.LogError("Failed to read ProjectInfoAction from stream"); - continue; - } - - if (failedActionReads > 0) - { - Logger.LogInformation($"Failed {failedActionReads} times but things may be back on track"); - } - - failedActionReads = 0; - - try - { - switch (projectInfoAction) - { - case RazorProjectInfoAction.Remove: - Logger.LogTrace($"Attempting to read project id for removal"); - var id = await _namedPipe.ReadProjectInfoRemovalAsync(cancellationToken).ConfigureAwait(false); - EnqueueRemove(new ProjectKey(id)); - - break; - - case RazorProjectInfoAction.Update: - Logger.LogTrace($"Attempting to read project info for update"); - var projectInfo = await _namedPipe.ReadProjectInfoAsync(cancellationToken).ConfigureAwait(false); - if (projectInfo is not null) - { - EnqueueUpdate(projectInfo); - } - - break; - } - } - catch (Exception ex) - { - Logger.LogError(ex, $"{ex.Message}"); - } - } - } -} diff --git a/src/Razor/src/rzls/Program.cs b/src/Razor/src/rzls/Program.cs deleted file mode 100644 index c163ae6466a..00000000000 --- a/src/Razor/src/rzls/Program.cs +++ /dev/null @@ -1,160 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using System.Diagnostics; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Razor.LanguageServer.Hosting; -using Microsoft.AspNetCore.Razor.LanguageServer.Hosting.Diagnostics; -using Microsoft.AspNetCore.Razor.LanguageServer.Hosting.Logging; -using Microsoft.AspNetCore.Razor.LanguageServer.Hosting.NamedPipes; -using Microsoft.AspNetCore.Razor.Utilities; -using Microsoft.CodeAnalysis.Razor.Logging; -using Microsoft.CodeAnalysis.Razor.ProjectSystem; -using Microsoft.CodeAnalysis.Razor.Telemetry; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.VisualStudio.Composition; - -namespace Microsoft.AspNetCore.Razor.LanguageServer; - -public class Program -{ - public static async Task Main(string[] args) - { - var logLevel = LogLevel.Information; - var telemetryLevel = string.Empty; - var sessionId = string.Empty; - var telemetryExtensionPath = string.Empty; - - for (var i = 0; i < args.Length; i++) - { - if (args[i].Contains("debug", StringComparison.OrdinalIgnoreCase)) - { - await Console.Error.WriteLineAsync($"Server started with process ID {Environment.ProcessId}").ConfigureAwait(true); - if (PlatformInformation.IsWindows) - { - // Debugger.Launch() only works on Windows. - Debugger.Launch(); - } - else - { - var timeout = TimeSpan.FromMinutes(1); - await Console.Error.WriteLineAsync($"Waiting {timeout:g} for a debugger to attach").ConfigureAwait(true); - using var timeoutSource = new CancellationTokenSource(timeout); - while (!Debugger.IsAttached && !timeoutSource.Token.IsCancellationRequested) - { - await Task.Delay(100, CancellationToken.None).ConfigureAwait(true); - } - } - - continue; - } - - if (args[i] == "--logLevel" && i + 1 < args.Length) - { - var logLevelArg = args[++i]; - if (!Enum.TryParse(logLevelArg, out logLevel)) - { - logLevel = LogLevel.Information; - await Console.Error.WriteLineAsync($"Invalid Razor log level '{logLevelArg}'. Defaulting to {logLevel}.").ConfigureAwait(true); - } - } - - if (args[i] == "--telemetryLevel" && i + 1 < args.Length) - { - telemetryLevel = args[++i]; - } - - if (args[i] == "--sessionId" && i + 1 < args.Length) - { - sessionId = args[++i]; - } - - if (args[i] == "--telemetryExtensionPath" && i + 1 < args.Length) - { - telemetryExtensionPath = args[++i]; - } - } - - var languageServerFeatureOptions = new ConfigurableLanguageServerFeatureOptions(args); - - using var telemetryContext = await TryGetTelemetryReporterAsync(telemetryLevel, sessionId, telemetryExtensionPath).ConfigureAwait(true); - - // Have to create a logger factory to give to the server, but can't create any logger providers until we have - // a server. - var loggerFactory = new LoggerFactory([]); - var logLevelProvider = new LogLevelProvider(logLevel); - - using var host = RazorLanguageServerHost.Create( - Console.OpenStandardInput(), - Console.OpenStandardOutput(), - loggerFactory, - telemetryContext?.TelemetryReporter ?? NoOpTelemetryReporter.Instance, - featureOptions: languageServerFeatureOptions, - configureServices: services => - { - services.AddSingleton(); - services.AddHandler(); - services.AddHandlerWithCapabilities(); - - services.AddSingleton(logLevelProvider); - services.AddHandler(); - }); - - // Now we have a server, and hence a connection, we have somewhere to log - var clientConnection = host.GetRequiredService(); - var loggerProvider = new LoggerProvider(logLevelProvider, clientConnection); - loggerFactory.AddLoggerProvider(loggerProvider); - - loggerFactory.GetOrCreateLogger("RZLS").LogInformation($"Razor Language Server started successfully."); - - await host.WaitForExitAsync().ConfigureAwait(true); - } - - private static async Task TryGetTelemetryReporterAsync(string telemetryLevel, string sessionId, string telemetryExtensionPath) - { - ExportProvider? exportProvider = null; - if (!telemetryExtensionPath.IsNullOrEmpty()) - { - try - { - exportProvider = await ExportProviderBuilder - .CreateExportProviderAsync(telemetryExtensionPath) - .ConfigureAwait(true); - - // Initialize the telemetry reporter if available - var devKitTelemetryReporter = exportProvider.GetExports().SingleOrDefault()?.Value; - - if (devKitTelemetryReporter is ITelemetryReporterInitializer initializer) - { - initializer.InitializeSession(telemetryLevel, sessionId, isDefaultSession: true); - return new TelemetryContext(exportProvider, devKitTelemetryReporter); - } - else - { - exportProvider.Dispose(); - } - } - catch (Exception ex) - { - await Console.Error.WriteLineAsync($"Failed to load telemetry extension in {telemetryExtensionPath}.").ConfigureAwait(true); - await Console.Error.WriteLineAsync(ex.ToString()).ConfigureAwait(true); - exportProvider?.Dispose(); - } - } - - return null; - } - - private readonly record struct TelemetryContext(IDisposable ExportProvider, ITelemetryReporter TelemetryReporter) : IDisposable - { - public void Dispose() - { - // No need to explicitly dispose of the telemetry reporter. The lifetime - // is managed by the ExportProvider and will be disposed with it. - ExportProvider.Dispose(); - } - } -} diff --git a/src/Razor/src/rzls/PublishAllRids.targets b/src/Razor/src/rzls/PublishAllRids.targets deleted file mode 100644 index a035664d84c..00000000000 --- a/src/Razor/src/rzls/PublishAllRids.targets +++ /dev/null @@ -1,32 +0,0 @@ - - - - false - <_RazorPublishReadyToRun>false - <_RazorPublishReadyToRun Condition="'$(Configuration)' == 'Release'">true - - - - - - - - - - - - - - PackRuntimeIdentifier=%(RuntimeIdentifierForPack.Identity) - - - - - - diff --git a/src/Razor/src/rzls/rzls.csproj b/src/Razor/src/rzls/rzls.csproj deleted file mode 100644 index e7ac625f83f..00000000000 --- a/src/Razor/src/rzls/rzls.csproj +++ /dev/null @@ -1,122 +0,0 @@ - - - - $(NetVSCode) - Exe - - Razor is a markup syntax for adding server-side logic to web pages. This package - contains a Razor language server. - - Microsoft.AspNetCore.Razor.LanguageServer - false - true - LatestMajor - - true - - $(PackRuntimeIdentifier) - - - false - - $(AssemblyName).$(PackRuntimeIdentifier) - - - PackPublishContent;$(BeforePack) - - - $(NoWarn);NU5100;NETSDK1206 - - - false - $(ArtifactsDir)LanguageServer\$(Configuration)\$(TargetFramework)\$(RuntimeIdentifier) - $(ArtifactsDir)LanguageServer\$(Configuration)\$(TargetFramework)\neutral - - - - $(TargetRid) - win-x64;win-arm64;linux-x64;linux-arm64;linux-musl-x64;linux-musl-arm64;osx-x64;osx-arm64 - - true - - - - - - PackRuntimeIdentifier - - - - - - - - - - PreserveNewest - - - - PreserveNewest - - - - PreserveNewest - - - - - - - - true - content\LanguageServer\$(PackRuntimeIdentifier) - false - None - - - - - - - diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/CodeActions/CSharp/CSharpCodeActionProviderTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/CodeActions/CSharp/CSharpCodeActionProviderTest.cs index 169222c6cb7..de1c6eda877 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/CodeActions/CSharp/CSharpCodeActionProviderTest.cs +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/CodeActions/CSharp/CSharpCodeActionProviderTest.cs @@ -242,7 +242,7 @@ public async Task ProvideAsync_InvalidCodeActions_ShowAllFeatureFlagOn_ReturnsCo var context = CreateRazorCodeActionContext(request, cursorPosition, documentPath, contents, new SourceSpan(8, 4)); - var options = new ConfigurableLanguageServerFeatureOptions(new[] { $"--{nameof(ConfigurableLanguageServerFeatureOptions.ShowAllCSharpCodeActions)}" }); + var options = new TestLanguageServerFeatureOptions(showAllCSharpCodeActions: true); var provider = new CSharpCodeActionProvider(options); ImmutableArray codeActions = diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/ConfigurableLanguageServerFeatureOptionsTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/ConfigurableLanguageServerFeatureOptionsTest.cs deleted file mode 100644 index e997418bd61..00000000000 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/ConfigurableLanguageServerFeatureOptionsTest.cs +++ /dev/null @@ -1,135 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using Microsoft.AspNetCore.Razor.LanguageServer.Hosting; -using Xunit; - -namespace Microsoft.AspNetCore.Razor.LanguageServer; - -public class ConfigurableLanguageServerFeatureOptionsTest -{ - [Fact] - public void NoArgs_AllDefault() - { - var expected = new DefaultLanguageServerFeatureOptions(); - - var actual = new ConfigurableLanguageServerFeatureOptions(Array.Empty()); - - Assert.Equal(expected.SupportsFileManipulation, actual.SupportsFileManipulation); - Assert.Equal(expected.CSharpVirtualDocumentSuffix, actual.CSharpVirtualDocumentSuffix); - Assert.Equal(expected.HtmlVirtualDocumentSuffix, actual.HtmlVirtualDocumentSuffix); - Assert.Equal(expected.SingleServerSupport, actual.SingleServerSupport); - Assert.Equal(expected.ReturnCodeActionAndRenamePathsWithPrefixedSlash, actual.ReturnCodeActionAndRenamePathsWithPrefixedSlash); - } - - [Fact] - public void ProvideStringOption_OthersDefault() - { - var expected = new DefaultLanguageServerFeatureOptions(); - - var singleServerSupport = !expected.SingleServerSupport; - var args = new[] { "--singleServerSupport", singleServerSupport.ToString() }; - - var actual = new ConfigurableLanguageServerFeatureOptions(args); - - Assert.Equal(expected.SupportsFileManipulation, actual.SupportsFileManipulation); - Assert.Equal(expected.CSharpVirtualDocumentSuffix, actual.CSharpVirtualDocumentSuffix); - Assert.Equal(expected.HtmlVirtualDocumentSuffix, actual.HtmlVirtualDocumentSuffix); - Assert.Equal(singleServerSupport, actual.SingleServerSupport); - Assert.Equal(expected.ReturnCodeActionAndRenamePathsWithPrefixedSlash, actual.ReturnCodeActionAndRenamePathsWithPrefixedSlash); - } - - [Fact] - public void ProvideStringOption_IgnoresNoise() - { - var expected = new DefaultLanguageServerFeatureOptions(); - - var singleServerSupport = !expected.SingleServerSupport; - var args = new[] { "--singleServerSupport", singleServerSupport.ToString(), "ignore", "this" }; - - var actual = new ConfigurableLanguageServerFeatureOptions(args); - - Assert.Equal(expected.SupportsFileManipulation, actual.SupportsFileManipulation); - Assert.Equal(expected.CSharpVirtualDocumentSuffix, actual.CSharpVirtualDocumentSuffix); - Assert.Equal(expected.HtmlVirtualDocumentSuffix, actual.HtmlVirtualDocumentSuffix); - Assert.Equal(singleServerSupport, actual.SingleServerSupport); - Assert.Equal(expected.ReturnCodeActionAndRenamePathsWithPrefixedSlash, actual.ReturnCodeActionAndRenamePathsWithPrefixedSlash); - } - - [Fact] - public void ProvideBoolOption_LastArgument() - { - var expected = new DefaultLanguageServerFeatureOptions(); - - var args = new[] { "hoo", "goo", "--singleServerSupport" }; - - var actual = new ConfigurableLanguageServerFeatureOptions(args); - - // If the default ever changes, this test would be invalid - Assert.False(expected.SingleServerSupport); - Assert.True(actual.SingleServerSupport); - - Assert.Equal(expected.SupportsFileManipulation, actual.SupportsFileManipulation); - Assert.Equal(expected.CSharpVirtualDocumentSuffix, actual.CSharpVirtualDocumentSuffix); - Assert.Equal(expected.HtmlVirtualDocumentSuffix, actual.HtmlVirtualDocumentSuffix); - Assert.Equal(expected.ReturnCodeActionAndRenamePathsWithPrefixedSlash, actual.ReturnCodeActionAndRenamePathsWithPrefixedSlash); - } - - [Fact] - public void ProvideBoolOption_SingleArgument() - { - var expected = new DefaultLanguageServerFeatureOptions(); - - var args = new[] { "--singleServerSupport", "--otherOption", "false" }; - - var actual = new ConfigurableLanguageServerFeatureOptions(args); - - // If the default ever changes, this test would be invalid - Assert.False(expected.SingleServerSupport); - Assert.True(actual.SingleServerSupport); - - Assert.Equal(expected.SupportsFileManipulation, actual.SupportsFileManipulation); - Assert.Equal(expected.CSharpVirtualDocumentSuffix, actual.CSharpVirtualDocumentSuffix); - Assert.Equal(expected.HtmlVirtualDocumentSuffix, actual.HtmlVirtualDocumentSuffix); - Assert.Equal(expected.ReturnCodeActionAndRenamePathsWithPrefixedSlash, actual.ReturnCodeActionAndRenamePathsWithPrefixedSlash); - } - - [Fact] - public void ProvideBoolOption_ExplicitTrue() - { - var expected = new DefaultLanguageServerFeatureOptions(); - - var args = new[] { "--singleServerSupport", "true", "false" }; - - var actual = new ConfigurableLanguageServerFeatureOptions(args); - - // If the default ever changes, this test would be invalid - Assert.False(expected.SingleServerSupport); - Assert.True(actual.SingleServerSupport); - - Assert.Equal(expected.SupportsFileManipulation, actual.SupportsFileManipulation); - Assert.Equal(expected.CSharpVirtualDocumentSuffix, actual.CSharpVirtualDocumentSuffix); - Assert.Equal(expected.HtmlVirtualDocumentSuffix, actual.HtmlVirtualDocumentSuffix); - Assert.Equal(expected.ReturnCodeActionAndRenamePathsWithPrefixedSlash, actual.ReturnCodeActionAndRenamePathsWithPrefixedSlash); - } - - [Fact] - public void ProvideBoolOption_ExplicitFalse() - { - var expected = new DefaultLanguageServerFeatureOptions(); - - var args = new[] { "--supportsFileManipulation", "false", "true" }; - - var actual = new ConfigurableLanguageServerFeatureOptions(args); - - // If the default ever changes, this test would be invalid - Assert.True(expected.SupportsFileManipulation); - Assert.False(actual.SupportsFileManipulation); - - Assert.Equal(expected.CSharpVirtualDocumentSuffix, actual.CSharpVirtualDocumentSuffix); - Assert.Equal(expected.HtmlVirtualDocumentSuffix, actual.HtmlVirtualDocumentSuffix); - Assert.Equal(expected.SingleServerSupport, actual.SingleServerSupport); - Assert.Equal(expected.ReturnCodeActionAndRenamePathsWithPrefixedSlash, actual.ReturnCodeActionAndRenamePathsWithPrefixedSlash); - } -} diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Test.Common.Tooling/Microsoft.AspNetCore.Razor.Test.Common.Tooling.csproj b/src/Razor/test/Microsoft.AspNetCore.Razor.Test.Common.Tooling/Microsoft.AspNetCore.Razor.Test.Common.Tooling.csproj index 860631080d2..5b493fc1cc2 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.Test.Common.Tooling/Microsoft.AspNetCore.Razor.Test.Common.Tooling.csproj +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Test.Common.Tooling/Microsoft.AspNetCore.Razor.Test.Common.Tooling.csproj @@ -83,7 +83,6 @@ -