From 7731184dbe8312ef302bd9efd74ff83e5bd61a0b Mon Sep 17 00:00:00 2001 From: David Wengier Date: Thu, 4 Jul 2024 19:08:14 +1000 Subject: [PATCH 01/18] Centralize capabilities code --- .../VSInternalServerCapabilitiesExtensions.cs | 13 +++++++++++++ .../SignatureHelp/SignatureHelpEndpoint.cs | 13 +++++-------- 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Hosting/VSInternalServerCapabilitiesExtensions.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Hosting/VSInternalServerCapabilitiesExtensions.cs index 62785fb5267..83b32a3dd23 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Hosting/VSInternalServerCapabilitiesExtensions.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Hosting/VSInternalServerCapabilitiesExtensions.cs @@ -40,6 +40,19 @@ public static SemanticTokensOptions EnableSemanticTokens(this SemanticTokensOpti return options; } + public static void EnableSignatureHelp(this VSInternalServerCapabilities serverCapabilities) + { + serverCapabilities.SignatureHelpProvider = new SignatureHelpOptions().EnableSignatureHelp(); + } + + public static SignatureHelpOptions EnableSignatureHelp(this SignatureHelpOptions options) + { + options.TriggerCharacters = ["(", ",", "<"]; + options.RetriggerCharacters = [">", ")"]; + + return options; + } + public static void EnableHoverProvider(this VSInternalServerCapabilities serverCapabilities) { serverCapabilities.HoverProvider = new HoverOptions() diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/SignatureHelp/SignatureHelpEndpoint.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/SignatureHelp/SignatureHelpEndpoint.cs index baa5d4b0000..657d878fc5d 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/SignatureHelp/SignatureHelpEndpoint.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/SignatureHelp/SignatureHelpEndpoint.cs @@ -1,4 +1,5 @@ -// Copyright (c) .NET Foundation. All rights reserved. + +// Copyright (c) .NET Foundation. All rights reserved. // Licensed under the MIT license. See License.txt in the project root for license information. using System.Threading; @@ -11,7 +12,7 @@ using Microsoft.CodeAnalysis.Razor.Protocol; using Microsoft.CodeAnalysis.Razor.Workspaces; using Microsoft.VisualStudio.LanguageServer.Protocol; -using LS = Microsoft.VisualStudio.LanguageServer.Protocol; +using LSP = Microsoft.VisualStudio.LanguageServer.Protocol; namespace Microsoft.AspNetCore.Razor.LanguageServer.SignatureHelp; @@ -22,7 +23,7 @@ internal sealed class SignatureHelpEndpoint( IClientConnection clientConnection, RazorLSPOptionsMonitor optionsMonitor, ILoggerFactory loggerProvider) - : AbstractRazorDelegatingEndpoint( + : AbstractRazorDelegatingEndpoint( languageServerFeatureOptions, documentMappingService, clientConnection, @@ -33,11 +34,7 @@ internal sealed class SignatureHelpEndpoint( public void ApplyCapabilities(VSInternalServerCapabilities serverCapabilities, VSInternalClientCapabilities clientCapabilities) { - serverCapabilities.SignatureHelpProvider = new SignatureHelpOptions() - { - TriggerCharacters = new[] { "(", ",", "<" }, - RetriggerCharacters = new[] { ">", ")" } - }; + serverCapabilities.EnableSignatureHelp(); } protected override Task CreateDelegatedParamsAsync(SignatureHelpParams request, RazorRequestContext requestContext, DocumentPositionInfo positionInfo, CancellationToken cancellationToken) From afb03625935b51a01ba42d6b527586e780dd2314 Mon Sep 17 00:00:00 2001 From: David Wengier Date: Thu, 4 Jul 2024 19:46:36 +1000 Subject: [PATCH 02/18] Create basic endpoint and remote service definition --- .../SignatureHelp/RemoteSignatureHelp.cs | 26 +++++ .../RemoteSignatureInformation.cs | 23 +++++ .../Remote/IRemoteSignatureHelpService.cs | 16 +++ .../Cohost/CohostSignatureHelpEndpoint.cs | 98 +++++++++++++++++++ 4 files changed, 163 insertions(+) create mode 100644 src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Protocol/SignatureHelp/RemoteSignatureHelp.cs create mode 100644 src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Protocol/SignatureHelp/RemoteSignatureInformation.cs create mode 100644 src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Remote/IRemoteSignatureHelpService.cs create mode 100644 src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/LanguageClient/Cohost/CohostSignatureHelpEndpoint.cs diff --git a/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Protocol/SignatureHelp/RemoteSignatureHelp.cs b/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Protocol/SignatureHelp/RemoteSignatureHelp.cs new file mode 100644 index 00000000000..ea41ff45c5a --- /dev/null +++ b/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Protocol/SignatureHelp/RemoteSignatureHelp.cs @@ -0,0 +1,26 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the MIT license. See License.txt in the project root for license information. + +using System.Collections.Generic; +using System.Linq; +using System.Runtime.Serialization; +using LSP = Microsoft.VisualStudio.LanguageServer.Protocol; + +namespace Microsoft.CodeAnalysis.Razor.Workspaces.Protocol.SignatureHelp; + +[DataContract] +internal readonly record struct RemoteSignatureHelp( + [property: DataMember(Order = 0)] int? ActiveParameter, + [property: DataMember(Order = 1)] int? ActiveSignature, + [property: DataMember(Order = 2)] RemoteSignatureInformation[] Signatures) +{ + public LSP.SignatureHelp ToSignatureHelp() + { + return new LSP.SignatureHelp() + { + ActiveParameter = this.ActiveParameter, + ActiveSignature = this.ActiveSignature, + Signatures = this.Signatures.Select(s => s.ToSignatureInformation()).ToArray() + }; + } +} diff --git a/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Protocol/SignatureHelp/RemoteSignatureInformation.cs b/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Protocol/SignatureHelp/RemoteSignatureInformation.cs new file mode 100644 index 00000000000..985d1f6bca1 --- /dev/null +++ b/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Protocol/SignatureHelp/RemoteSignatureInformation.cs @@ -0,0 +1,23 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the MIT license. See License.txt in the project root for license information. + +using System.Runtime.Serialization; +using Microsoft.VisualStudio.LanguageServer.Protocol; + +namespace Microsoft.CodeAnalysis.Razor.Workspaces.Protocol.SignatureHelp; + +[DataContract] +internal readonly record struct RemoteSignatureInformation( + [property: DataMember(Order = 0)] string Label) +{ + internal SignatureInformation ToSignatureInformation() + { + return new SignatureInformation() + { + Label = this.Label, + Documentation = new MarkupContent() + { + } + }; + } +} diff --git a/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Remote/IRemoteSignatureHelpService.cs b/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Remote/IRemoteSignatureHelpService.cs new file mode 100644 index 00000000000..34ffc8a1cf0 --- /dev/null +++ b/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Remote/IRemoteSignatureHelpService.cs @@ -0,0 +1,16 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the MIT license. See License.txt in the project root for license information. + +using System.Threading; +using System.Threading.Tasks; +using Microsoft.CodeAnalysis.ExternalAccess.Razor; +using Microsoft.CodeAnalysis.Razor.Workspaces.Protocol.SignatureHelp; +using Microsoft.CodeAnalysis.Text; +using Microsoft.VisualStudio.LanguageServer.Protocol; + +namespace Microsoft.CodeAnalysis.Razor.Remote; + +internal interface IRemoteSignatureHelpService +{ + ValueTask GetSignatureHelpAsync(RazorPinnedSolutionInfoWrapper solutionInfo, DocumentId id, LinePosition linePosition, SignatureHelpTriggerKind triggerKind, string? triggerCharacter, CancellationToken cancellationToken); +} diff --git a/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/LanguageClient/Cohost/CohostSignatureHelpEndpoint.cs b/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/LanguageClient/Cohost/CohostSignatureHelpEndpoint.cs new file mode 100644 index 00000000000..9e73c36fd52 --- /dev/null +++ b/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/LanguageClient/Cohost/CohostSignatureHelpEndpoint.cs @@ -0,0 +1,98 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the MIT license. See License.txt in the project root for license information. + +using System.Composition; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Razor; +using Microsoft.AspNetCore.Razor.LanguageServer.Hosting; +using Microsoft.CodeAnalysis.ExternalAccess.Razor.Cohost; +using Microsoft.CodeAnalysis.Razor.Logging; +using Microsoft.CodeAnalysis.Razor.Remote; +using Microsoft.CodeAnalysis.Razor.Workspaces; +using Microsoft.CodeAnalysis.Razor.Workspaces.Protocol.SignatureHelp; +using Microsoft.VisualStudio.LanguageServer.ContainedLanguage; +using Microsoft.VisualStudio.LanguageServer.Protocol; +using Microsoft.VisualStudio.Razor.LanguageClient; +using Microsoft.VisualStudio.Razor.LanguageClient.Cohost; +using Microsoft.VisualStudio.Razor.LanguageClient.Extensions; + +namespace Microsoft.VisualStudio.LanguageServices.Razor.LanguageClient.Cohost; + +#pragma warning disable RS0030 // Do not use banned APIs +[Shared] +[CohostEndpoint(Methods.TextDocumentSignatureHelpName)] +[Export(typeof(IDynamicRegistrationProvider))] +[ExportCohostStatelessLspService(typeof(CohostSignatureHelpEndpoint))] +[method: ImportingConstructor] +#pragma warning restore RS0030 // Do not use banned APIs +internal class CohostSignatureHelpEndpoint( + IRemoteServiceProvider remoteServiceProvider, + IHtmlDocumentSynchronizer htmlDocumentSynchronizer, + LSPRequestInvoker requestInvoker, + ILoggerFactory loggerFactory) + : AbstractRazorCohostDocumentRequestHandler, IDynamicRegistrationProvider +{ + private readonly IRemoteServiceProvider _remoteServiceProvider = remoteServiceProvider; + private readonly IHtmlDocumentSynchronizer _htmlDocumentSynchronizer = htmlDocumentSynchronizer; + private readonly LSPRequestInvoker _requestInvoker = requestInvoker; + private readonly ILogger _logger = loggerFactory.GetOrCreateLogger(); + + protected override bool MutatesSolutionState => false; + + protected override bool RequiresLSPSolution => true; + + public Registration? GetRegistration(VSInternalClientCapabilities clientCapabilities, DocumentFilter[] filter, RazorCohostRequestContext requestContext) + { + if (clientCapabilities.TextDocument?.SignatureHelp?.DynamicRegistration == true) + { + return new Registration() + { + Method = Methods.TextDocumentSignatureHelpName, + RegisterOptions = new SignatureHelpRegistrationOptions() + { + DocumentSelector = filter + }.EnableSignatureHelp() + }; + } + + return null; + } + + protected override RazorTextDocumentIdentifier? GetRazorTextDocumentIdentifier(SignatureHelpParams request) + => request.TextDocument.ToRazorTextDocumentIdentifier(); + + protected async override Task HandleRequestAsync(SignatureHelpParams request, RazorCohostRequestContext context, CancellationToken cancellationToken) + { + var razorDocument = context.TextDocument.AssumeNotNull(); + + var data = await _remoteServiceProvider.TryInvokeAsync( + razorDocument.Project.Solution, + (service, solutionInfo, cancellationToken) => service.GetSignatureHelpAsync(solutionInfo, razorDocument.Id, request.Position.ToLinePosition(), request.Context.TriggerKind, request.Context.TriggerCharacter, cancellationToken), + cancellationToken).ConfigureAwait(false); + + // If we got a response back, then either Razor or C# wants to do something with this, so we're good to go + if (data is { } signatureHelp) + { + return signatureHelp.ToSignatureHelp(); + } + + // If we didn't get anything from Razor or Roslyn, lets ask Html what they want to do + var htmlDocument = await _htmlDocumentSynchronizer.TryGetSynchronizedHtmlDocumentAsync(razorDocument, cancellationToken).ConfigureAwait(false); + if (htmlDocument is null) + { + return null; + } + + request.TextDocument = request.TextDocument.WithUri(htmlDocument.Uri); + + var result = await _requestInvoker.ReinvokeRequestOnServerAsync( + htmlDocument.Buffer, + Methods.TextDocumentSignatureHelpName, + RazorLSPConstants.HtmlLanguageServerName, + request, + cancellationToken).ConfigureAwait(false); + + return result?.Response; + } +} From 9f9d250e428e5f16abf6accd310e65ad9d2b7a18 Mon Sep 17 00:00:00 2001 From: David Wengier Date: Thu, 4 Jul 2024 21:22:09 +1000 Subject: [PATCH 03/18] Allow services to use Json --- .../Remote/IRemoteJsonService.cs | 11 ++++++++++ .../Remote/IRemoteSignatureHelpService.cs | 10 ++++----- .../Remote/RazorServices.cs | 13 ++++++++--- .../Remote/RemoteServiceProvider.cs | 22 ++++++++++++++++++- 4 files changed, 47 insertions(+), 9 deletions(-) create mode 100644 src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Remote/IRemoteJsonService.cs diff --git a/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Remote/IRemoteJsonService.cs b/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Remote/IRemoteJsonService.cs new file mode 100644 index 00000000000..4e193d31649 --- /dev/null +++ b/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Remote/IRemoteJsonService.cs @@ -0,0 +1,11 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the MIT license. See License.txt in the project root for license information. + +namespace Microsoft.CodeAnalysis.Razor.Remote; + +/// +/// Marker interface to indicate that an OOP service should use Json for communication +/// +internal interface IRemoteJsonService +{ +} diff --git a/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Remote/IRemoteSignatureHelpService.cs b/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Remote/IRemoteSignatureHelpService.cs index 34ffc8a1cf0..82163933eef 100644 --- a/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Remote/IRemoteSignatureHelpService.cs +++ b/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Remote/IRemoteSignatureHelpService.cs @@ -4,13 +4,13 @@ using System.Threading; using System.Threading.Tasks; using Microsoft.CodeAnalysis.ExternalAccess.Razor; -using Microsoft.CodeAnalysis.Razor.Workspaces.Protocol.SignatureHelp; -using Microsoft.CodeAnalysis.Text; -using Microsoft.VisualStudio.LanguageServer.Protocol; +using Roslyn.LanguageServer.Protocol; namespace Microsoft.CodeAnalysis.Razor.Remote; -internal interface IRemoteSignatureHelpService +using SignatureHelp = Roslyn.LanguageServer.Protocol.SignatureHelp; + +internal interface IRemoteSignatureHelpService : IRemoteJsonService { - ValueTask GetSignatureHelpAsync(RazorPinnedSolutionInfoWrapper solutionInfo, DocumentId id, LinePosition linePosition, SignatureHelpTriggerKind triggerKind, string? triggerCharacter, CancellationToken cancellationToken); + ValueTask GetSignatureHelpAsync(JsonSerializableRazorPinnedSolutionInfoWrapper solutionInfo, JsonSerializableDocumentId documentId, Position linePosition, CancellationToken cancellationToken); } diff --git a/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Remote/RazorServices.cs b/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Remote/RazorServices.cs index a4584786c06..5b79b2b5005 100644 --- a/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Remote/RazorServices.cs +++ b/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Remote/RazorServices.cs @@ -1,8 +1,6 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the MIT license. See License.txt in the project root for license information. -using System.Collections.Immutable; -using MessagePack.Formatters; using Microsoft.AspNetCore.Razor.Serialization.MessagePack.Resolvers; using Microsoft.CodeAnalysis.ExternalAccess.Razor; @@ -15,7 +13,7 @@ internal static class RazorServices public static readonly RazorServiceDescriptorsWrapper Descriptors = new( ComponentName, featureDisplayNameProvider: feature => $"Razor {feature} Feature", - additionalFormatters: ImmutableArray.Empty, + additionalFormatters: [], additionalResolvers: TopLevelResolvers.All, interfaces: [ @@ -27,4 +25,13 @@ internal static class RazorServices (typeof(IRemoteUriPresentationService), null), (typeof(IRemoteFoldingRangeService), null) ]); + + public static readonly RazorServiceDescriptorsWrapper JsonDescriptors = new( + ComponentName, // Needs to match the above because so much of our ServiceHub infrastructure is convention based + featureDisplayNameProvider: feature => $"Razor {feature} Feature", + jsonConverters: RazorServiceDescriptorsWrapper.GetLspConverters(), + interfaces: + [ + (typeof(IRemoteSignatureHelpService), null), + ]); } diff --git a/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/Remote/RemoteServiceProvider.cs b/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/Remote/RemoteServiceProvider.cs index 7f3a4c438f7..ebbcf00cc3b 100644 --- a/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/Remote/RemoteServiceProvider.cs +++ b/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/Remote/RemoteServiceProvider.cs @@ -49,7 +49,9 @@ internal sealed class RemoteServiceProvider( [CallerMemberName] string? callerMemberName = null) where TService : class { - var client = await TryGetClientAsync(cancellationToken).ConfigureAwait(false); + var client = typeof(IRemoteJsonService).IsAssignableFrom(typeof(TService)) + ? await TryGetJsonClientAsync(cancellationToken).ConfigureAwait(false) + : await TryGetClientAsync(cancellationToken).ConfigureAwait(false); if (client is null) { _logger.LogError($"Couldn't get remote client for {typeof(TService).Name} service"); @@ -97,6 +99,24 @@ internal sealed class RemoteServiceProvider( return remoteClient; } + private async Task TryGetJsonClientAsync(CancellationToken cancellationToken) + { + // Even if we're getting a service that wants to use Json, we still have to initialize the OOP client + // so we get the regular (MessagePack) client too. + if (!_fullyInitialized) + { + _ = await TryGetClientAsync(cancellationToken); + } + + var workspace = _workspaceProvider.GetWorkspace(); + + return await RazorRemoteHostClient.TryGetClientAsync( + workspace.Services, + RazorServices.JsonDescriptors, + RazorRemoteServiceCallbackDispatcherRegistry.Empty, + cancellationToken).ConfigureAwait(false); + } + private async Task InitializeRemoteClientAsync(RazorRemoteHostClient remoteClient, CancellationToken cancellationToken) { if (_fullyInitialized) From 3707cb34015c38cff1d88f99e18bef485add9494 Mon Sep 17 00:00:00 2001 From: David Wengier Date: Tue, 9 Jul 2024 11:18:34 +1000 Subject: [PATCH 04/18] Create remote signature help service --- eng/targets/Services.props | 1 + .../RazorLanguageServer.cs | 2 +- .../RemoteSignatureHelpService.cs | 52 +++++++++++++++++++ .../RemoteSignatureHelpServiceFactory.cs | 28 ++++++++++ .../Cohost/CohostSignatureHelpEndpoint.cs | 18 ++++--- 5 files changed, 92 insertions(+), 9 deletions(-) create mode 100644 src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/SignatureHelp/RemoteSignatureHelpService.cs create mode 100644 src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/SignatureHelp/RemoteSignatureHelpServiceFactory.cs diff --git a/eng/targets/Services.props b/eng/targets/Services.props index 9b8e60c7d2f..bd55024d8ab 100644 --- a/eng/targets/Services.props +++ b/eng/targets/Services.props @@ -22,5 +22,6 @@ + diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/RazorLanguageServer.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/RazorLanguageServer.cs index 17c412bd72b..d28cb50e47c 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/RazorLanguageServer.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/RazorLanguageServer.cs @@ -178,7 +178,6 @@ static void AddHandlers(IServiceCollection services, LanguageServerFeatureOption services.AddTransient(sp => sp.GetRequiredService()); services.AddHandlerWithCapabilities(); - services.AddHandlerWithCapabilities(); services.AddHandlerWithCapabilities(); services.AddHandlerWithCapabilities(); @@ -187,6 +186,7 @@ static void AddHandlers(IServiceCollection services, LanguageServerFeatureOption if (!featureOptions.UseRazorCohostServer) { + services.AddHandlerWithCapabilities(); services.AddHandlerWithCapabilities(); services.AddHandlerWithCapabilities(); } diff --git a/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/SignatureHelp/RemoteSignatureHelpService.cs b/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/SignatureHelp/RemoteSignatureHelpService.cs new file mode 100644 index 00000000000..042e76f934b --- /dev/null +++ b/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/SignatureHelp/RemoteSignatureHelpService.cs @@ -0,0 +1,52 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the MIT license. See License.txt in the project root for license information. + +using System.Threading; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Razor.Language; +using Microsoft.CodeAnalysis.ExternalAccess.Razor; +using Microsoft.CodeAnalysis.Razor.DocumentMapping; +using Microsoft.CodeAnalysis.Razor.Remote; +using Microsoft.CodeAnalysis.Razor.Workspaces; +using Microsoft.CodeAnalysis.Remote.Razor.ProjectSystem; +using Microsoft.CodeAnalysis.Text; +using Microsoft.ServiceHub.Framework; +using Roslyn.LanguageServer.Protocol; + +namespace Microsoft.CodeAnalysis.Remote.Razor; + +using SignatureHelp = Roslyn.LanguageServer.Protocol.SignatureHelp; + +internal sealed class RemoteSignatureHelpService( + IServiceBroker serviceBroker, + DocumentSnapshotFactory documentSnapshotFactory, + IFilePathService filePathService, + IRazorDocumentMappingService documentMappingService) + : RazorDocumentServiceBase(serviceBroker, documentSnapshotFactory), IRemoteSignatureHelpService +{ + private readonly IFilePathService _filePathService = filePathService; + private readonly IRazorDocumentMappingService _documentMappingService = documentMappingService; + + public ValueTask GetSignatureHelpAsync(JsonSerializableRazorPinnedSolutionInfoWrapper solutionInfo, JsonSerializableDocumentId documentId, Position position, CancellationToken cancellationToken) + => RunServiceAsync( + solutionInfo, + documentId, + context => GetSignatureHelpsAsync(context, position, cancellationToken), + cancellationToken); + + private async ValueTask GetSignatureHelpsAsync(RemoteDocumentContext context, Position position, CancellationToken cancellationToken) + { + var codeDocument = await context.GetCodeDocumentAsync(cancellationToken).ConfigureAwait(false); + var linePosition = new LinePosition(position.Line, position.Character); + var absoluteIndex = linePosition.GetRequiredAbsoluteIndex(codeDocument.Source.Text, logger: null); + + var generatedDocument = await context.GetGeneratedDocumentAsync(_filePathService, cancellationToken).ConfigureAwait(false); + + if (_documentMappingService.TryMapToGeneratedDocumentPosition(codeDocument.GetCSharpDocument(), absoluteIndex, out var mappedPosition, out _)) + { + return await ExternalAccess.Razor.Cohost.Handlers.SignatureHelp.GetSignatureHelpAsync(generatedDocument, mappedPosition, supportsVisualStudioExtensions: true, cancellationToken); + } + + return null; + } +} diff --git a/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/SignatureHelp/RemoteSignatureHelpServiceFactory.cs b/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/SignatureHelp/RemoteSignatureHelpServiceFactory.cs new file mode 100644 index 00000000000..a7b42c9f564 --- /dev/null +++ b/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/SignatureHelp/RemoteSignatureHelpServiceFactory.cs @@ -0,0 +1,28 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the MIT license. See License.txt in the project root for license information. + +using Microsoft.CodeAnalysis.Razor.DocumentMapping; +using Microsoft.CodeAnalysis.Razor.Remote; +using Microsoft.CodeAnalysis.Razor.Workspaces; +using Microsoft.CodeAnalysis.Remote.Razor.ProjectSystem; +using Microsoft.ServiceHub.Framework; +using Microsoft.VisualStudio.Composition; + +namespace Microsoft.CodeAnalysis.Remote.Razor; + +internal sealed class RemoteSignatureHelpServiceFactory : RazorServiceFactoryBase +{ + // WARNING: We must always have a parameterless constructor in order to be properly handled by ServiceHub. + public RemoteSignatureHelpServiceFactory() + : base(RazorServices.JsonDescriptors) + { + } + + protected override IRemoteSignatureHelpService CreateService(IServiceBroker serviceBroker, ExportProvider exportProvider) + { + var documentSnapshotFactory = exportProvider.GetExportedValue(); + var filePathService = exportProvider.GetExportedValue(); + var documentMappingService = exportProvider.GetExportedValue(); + return new RemoteSignatureHelpService(serviceBroker, documentSnapshotFactory, filePathService, documentMappingService); + } +} diff --git a/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/LanguageClient/Cohost/CohostSignatureHelpEndpoint.cs b/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/LanguageClient/Cohost/CohostSignatureHelpEndpoint.cs index 9e73c36fd52..c62481c67e0 100644 --- a/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/LanguageClient/Cohost/CohostSignatureHelpEndpoint.cs +++ b/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/LanguageClient/Cohost/CohostSignatureHelpEndpoint.cs @@ -9,13 +9,12 @@ using Microsoft.CodeAnalysis.ExternalAccess.Razor.Cohost; using Microsoft.CodeAnalysis.Razor.Logging; using Microsoft.CodeAnalysis.Razor.Remote; -using Microsoft.CodeAnalysis.Razor.Workspaces; -using Microsoft.CodeAnalysis.Razor.Workspaces.Protocol.SignatureHelp; using Microsoft.VisualStudio.LanguageServer.ContainedLanguage; using Microsoft.VisualStudio.LanguageServer.Protocol; using Microsoft.VisualStudio.Razor.LanguageClient; using Microsoft.VisualStudio.Razor.LanguageClient.Cohost; using Microsoft.VisualStudio.Razor.LanguageClient.Extensions; +using RLSP = Roslyn.LanguageServer.Protocol; namespace Microsoft.VisualStudio.LanguageServices.Razor.LanguageClient.Cohost; @@ -31,7 +30,7 @@ internal class CohostSignatureHelpEndpoint( IHtmlDocumentSynchronizer htmlDocumentSynchronizer, LSPRequestInvoker requestInvoker, ILoggerFactory loggerFactory) - : AbstractRazorCohostDocumentRequestHandler, IDynamicRegistrationProvider + : AbstractRazorCohostDocumentRequestHandler?>, IDynamicRegistrationProvider { private readonly IRemoteServiceProvider _remoteServiceProvider = remoteServiceProvider; private readonly IHtmlDocumentSynchronizer _htmlDocumentSynchronizer = htmlDocumentSynchronizer; @@ -60,21 +59,24 @@ internal class CohostSignatureHelpEndpoint( } protected override RazorTextDocumentIdentifier? GetRazorTextDocumentIdentifier(SignatureHelpParams request) - => request.TextDocument.ToRazorTextDocumentIdentifier(); + => new RazorTextDocumentIdentifier(request.TextDocument.Uri, (request.TextDocument as VSTextDocumentIdentifier)?.ProjectContext?.Id); - protected async override Task HandleRequestAsync(SignatureHelpParams request, RazorCohostRequestContext context, CancellationToken cancellationToken) + // NOTE: The use of SumType here is a little odd, but it allows us to return Roslyn LSP types from the Roslyn call, and VS LSP types from the Html + // call. It works because both sets of types are attributed the right way, so the Json ends up looking the same and the client doesn't + // care. Ideally eventually we will be able to move all of this to just Roslyn LSP types, but we might have to wait for Web Tools + protected async override Task?> HandleRequestAsync(SignatureHelpParams request, RazorCohostRequestContext context, CancellationToken cancellationToken) { var razorDocument = context.TextDocument.AssumeNotNull(); - var data = await _remoteServiceProvider.TryInvokeAsync( + var data = await _remoteServiceProvider.TryInvokeAsync( razorDocument.Project.Solution, - (service, solutionInfo, cancellationToken) => service.GetSignatureHelpAsync(solutionInfo, razorDocument.Id, request.Position.ToLinePosition(), request.Context.TriggerKind, request.Context.TriggerCharacter, cancellationToken), + (service, solutionInfo, cancellationToken) => service.GetSignatureHelpAsync(solutionInfo, razorDocument.Id, new RLSP.Position(request.Position.Line, request.Position.Character), cancellationToken), cancellationToken).ConfigureAwait(false); // If we got a response back, then either Razor or C# wants to do something with this, so we're good to go if (data is { } signatureHelp) { - return signatureHelp.ToSignatureHelp(); + return signatureHelp; } // If we didn't get anything from Razor or Roslyn, lets ask Html what they want to do From e14fff4e8944fe921cd4aef85b573d57a666d3f7 Mon Sep 17 00:00:00 2001 From: David Wengier Date: Tue, 9 Jul 2024 11:19:43 +1000 Subject: [PATCH 05/18] Cleanup --- .../SignatureHelp/RemoteSignatureHelp.cs | 26 ------------------- .../RemoteSignatureInformation.cs | 23 ---------------- 2 files changed, 49 deletions(-) delete mode 100644 src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Protocol/SignatureHelp/RemoteSignatureHelp.cs delete mode 100644 src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Protocol/SignatureHelp/RemoteSignatureInformation.cs diff --git a/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Protocol/SignatureHelp/RemoteSignatureHelp.cs b/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Protocol/SignatureHelp/RemoteSignatureHelp.cs deleted file mode 100644 index ea41ff45c5a..00000000000 --- a/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Protocol/SignatureHelp/RemoteSignatureHelp.cs +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the MIT license. See License.txt in the project root for license information. - -using System.Collections.Generic; -using System.Linq; -using System.Runtime.Serialization; -using LSP = Microsoft.VisualStudio.LanguageServer.Protocol; - -namespace Microsoft.CodeAnalysis.Razor.Workspaces.Protocol.SignatureHelp; - -[DataContract] -internal readonly record struct RemoteSignatureHelp( - [property: DataMember(Order = 0)] int? ActiveParameter, - [property: DataMember(Order = 1)] int? ActiveSignature, - [property: DataMember(Order = 2)] RemoteSignatureInformation[] Signatures) -{ - public LSP.SignatureHelp ToSignatureHelp() - { - return new LSP.SignatureHelp() - { - ActiveParameter = this.ActiveParameter, - ActiveSignature = this.ActiveSignature, - Signatures = this.Signatures.Select(s => s.ToSignatureInformation()).ToArray() - }; - } -} diff --git a/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Protocol/SignatureHelp/RemoteSignatureInformation.cs b/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Protocol/SignatureHelp/RemoteSignatureInformation.cs deleted file mode 100644 index 985d1f6bca1..00000000000 --- a/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Protocol/SignatureHelp/RemoteSignatureInformation.cs +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the MIT license. See License.txt in the project root for license information. - -using System.Runtime.Serialization; -using Microsoft.VisualStudio.LanguageServer.Protocol; - -namespace Microsoft.CodeAnalysis.Razor.Workspaces.Protocol.SignatureHelp; - -[DataContract] -internal readonly record struct RemoteSignatureInformation( - [property: DataMember(Order = 0)] string Label) -{ - internal SignatureInformation ToSignatureInformation() - { - return new SignatureInformation() - { - Label = this.Label, - Documentation = new MarkupContent() - { - } - }; - } -} From e8bb55ec4db502d8147e4c64f154491f57d12b04 Mon Sep 17 00:00:00 2001 From: David Wengier Date: Tue, 9 Jul 2024 11:29:15 +1000 Subject: [PATCH 06/18] Don't offer if the option is off --- .../SignatureHelp/SignatureHelpEndpoint.cs | 3 +-- .../Cohost/CohostSignatureHelpEndpoint.cs | 10 ++++++++++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/SignatureHelp/SignatureHelpEndpoint.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/SignatureHelp/SignatureHelpEndpoint.cs index 657d878fc5d..167ee99201a 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/SignatureHelp/SignatureHelpEndpoint.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/SignatureHelp/SignatureHelpEndpoint.cs @@ -1,5 +1,4 @@ - -// Copyright (c) .NET Foundation. All rights reserved. +// Copyright (c) .NET Foundation. All rights reserved. // Licensed under the MIT license. See License.txt in the project root for license information. using System.Threading; diff --git a/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/LanguageClient/Cohost/CohostSignatureHelpEndpoint.cs b/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/LanguageClient/Cohost/CohostSignatureHelpEndpoint.cs index c62481c67e0..5e9164491d0 100644 --- a/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/LanguageClient/Cohost/CohostSignatureHelpEndpoint.cs +++ b/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/LanguageClient/Cohost/CohostSignatureHelpEndpoint.cs @@ -14,6 +14,7 @@ using Microsoft.VisualStudio.Razor.LanguageClient; using Microsoft.VisualStudio.Razor.LanguageClient.Cohost; using Microsoft.VisualStudio.Razor.LanguageClient.Extensions; +using Microsoft.VisualStudio.Razor.Settings; using RLSP = Roslyn.LanguageServer.Protocol; namespace Microsoft.VisualStudio.LanguageServices.Razor.LanguageClient.Cohost; @@ -27,12 +28,14 @@ namespace Microsoft.VisualStudio.LanguageServices.Razor.LanguageClient.Cohost; #pragma warning restore RS0030 // Do not use banned APIs internal class CohostSignatureHelpEndpoint( IRemoteServiceProvider remoteServiceProvider, + IClientSettingsManager clientSettingsManager, IHtmlDocumentSynchronizer htmlDocumentSynchronizer, LSPRequestInvoker requestInvoker, ILoggerFactory loggerFactory) : AbstractRazorCohostDocumentRequestHandler?>, IDynamicRegistrationProvider { private readonly IRemoteServiceProvider _remoteServiceProvider = remoteServiceProvider; + private readonly IClientSettingsManager _clientSettingsManager = clientSettingsManager; private readonly IHtmlDocumentSynchronizer _htmlDocumentSynchronizer = htmlDocumentSynchronizer; private readonly LSPRequestInvoker _requestInvoker = requestInvoker; private readonly ILogger _logger = loggerFactory.GetOrCreateLogger(); @@ -66,6 +69,13 @@ internal class CohostSignatureHelpEndpoint( // care. Ideally eventually we will be able to move all of this to just Roslyn LSP types, but we might have to wait for Web Tools protected async override Task?> HandleRequestAsync(SignatureHelpParams request, RazorCohostRequestContext context, CancellationToken cancellationToken) { + // Return nothing if "Parameter Information" option is disabled unless signature help is invoked explicitly via command as opposed to typing or content change + if (request.Context is { TriggerKind: not SignatureHelpTriggerKind.Invoked } && + !_clientSettingsManager.GetClientSettings().ClientCompletionSettings.AutoListParams) + { + return null; + } + var razorDocument = context.TextDocument.AssumeNotNull(); var data = await _remoteServiceProvider.TryInvokeAsync( From 6e170ed71e2ee27ddc33b655766a22f3d4f288f4 Mon Sep 17 00:00:00 2001 From: David Wengier Date: Tue, 9 Jul 2024 11:35:16 +1000 Subject: [PATCH 07/18] Missed a spot --- .../SignatureHelp/RemoteSignatureHelpService.cs | 2 +- .../Remote/RemoteServiceProvider.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/SignatureHelp/RemoteSignatureHelpService.cs b/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/SignatureHelp/RemoteSignatureHelpService.cs index 042e76f934b..1546f2d991b 100644 --- a/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/SignatureHelp/RemoteSignatureHelpService.cs +++ b/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/SignatureHelp/RemoteSignatureHelpService.cs @@ -44,7 +44,7 @@ internal sealed class RemoteSignatureHelpService( if (_documentMappingService.TryMapToGeneratedDocumentPosition(codeDocument.GetCSharpDocument(), absoluteIndex, out var mappedPosition, out _)) { - return await ExternalAccess.Razor.Cohost.Handlers.SignatureHelp.GetSignatureHelpAsync(generatedDocument, mappedPosition, supportsVisualStudioExtensions: true, cancellationToken); + return await ExternalAccess.Razor.Cohost.Handlers.SignatureHelp.GetSignatureHelpAsync(generatedDocument, mappedPosition, supportsVisualStudioExtensions: true, cancellationToken).ConfigureAwait(false); } return null; diff --git a/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/Remote/RemoteServiceProvider.cs b/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/Remote/RemoteServiceProvider.cs index ebbcf00cc3b..2fe3c3c2768 100644 --- a/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/Remote/RemoteServiceProvider.cs +++ b/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/Remote/RemoteServiceProvider.cs @@ -105,7 +105,7 @@ internal sealed class RemoteServiceProvider( // so we get the regular (MessagePack) client too. if (!_fullyInitialized) { - _ = await TryGetClientAsync(cancellationToken); + _ = await TryGetClientAsync(cancellationToken).ConfigureAwait(false); } var workspace = _workspaceProvider.GetWorkspace(); From 28ff338a9a2a338e865298b4f89afc7aea95886a Mon Sep 17 00:00:00 2001 From: David Wengier Date: Wed, 10 Jul 2024 13:46:07 +1000 Subject: [PATCH 08/18] PR Feedback --- .../SignatureHelp/SignatureHelpEndpoint.cs | 5 +++-- .../LanguageClient/Cohost/CohostSignatureHelpEndpoint.cs | 6 ++++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/SignatureHelp/SignatureHelpEndpoint.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/SignatureHelp/SignatureHelpEndpoint.cs index 167ee99201a..790cd537f07 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/SignatureHelp/SignatureHelpEndpoint.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/SignatureHelp/SignatureHelpEndpoint.cs @@ -11,10 +11,11 @@ using Microsoft.CodeAnalysis.Razor.Protocol; using Microsoft.CodeAnalysis.Razor.Workspaces; using Microsoft.VisualStudio.LanguageServer.Protocol; -using LSP = Microsoft.VisualStudio.LanguageServer.Protocol; namespace Microsoft.AspNetCore.Razor.LanguageServer.SignatureHelp; +using SignatureHelp = VisualStudio.LanguageServer.Protocol.SignatureHelp; + [RazorLanguageServerEndpoint(Methods.TextDocumentSignatureHelpName)] internal sealed class SignatureHelpEndpoint( LanguageServerFeatureOptions languageServerFeatureOptions, @@ -22,7 +23,7 @@ internal sealed class SignatureHelpEndpoint( IClientConnection clientConnection, RazorLSPOptionsMonitor optionsMonitor, ILoggerFactory loggerProvider) - : AbstractRazorDelegatingEndpoint( + : AbstractRazorDelegatingEndpoint( languageServerFeatureOptions, documentMappingService, clientConnection, diff --git a/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/LanguageClient/Cohost/CohostSignatureHelpEndpoint.cs b/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/LanguageClient/Cohost/CohostSignatureHelpEndpoint.cs index 5e9164491d0..e2dc1f050d5 100644 --- a/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/LanguageClient/Cohost/CohostSignatureHelpEndpoint.cs +++ b/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/LanguageClient/Cohost/CohostSignatureHelpEndpoint.cs @@ -81,7 +81,8 @@ internal class CohostSignatureHelpEndpoint( var data = await _remoteServiceProvider.TryInvokeAsync( razorDocument.Project.Solution, (service, solutionInfo, cancellationToken) => service.GetSignatureHelpAsync(solutionInfo, razorDocument.Id, new RLSP.Position(request.Position.Line, request.Position.Character), cancellationToken), - cancellationToken).ConfigureAwait(false); + cancellationToken) + .ConfigureAwait(false); // If we got a response back, then either Razor or C# wants to do something with this, so we're good to go if (data is { } signatureHelp) @@ -103,7 +104,8 @@ internal class CohostSignatureHelpEndpoint( Methods.TextDocumentSignatureHelpName, RazorLSPConstants.HtmlLanguageServerName, request, - cancellationToken).ConfigureAwait(false); + cancellationToken) + .ConfigureAwait(false); return result?.Response; } From c80b84acc5536b298737db6922def2e3290eefbe Mon Sep 17 00:00:00 2001 From: David Wengier Date: Wed, 17 Jul 2024 12:22:11 +1000 Subject: [PATCH 09/18] Updates after merge --- eng/targets/Services.props | 2 +- .../RemoteSignatureHelpService.cs | 21 +++++++------- .../RemoteSignatureHelpServiceFactory.cs | 28 ------------------- 3 files changed, 12 insertions(+), 39 deletions(-) delete mode 100644 src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/SignatureHelp/RemoteSignatureHelpServiceFactory.cs diff --git a/eng/targets/Services.props b/eng/targets/Services.props index 6a00dfbc442..068c5f2e0ab 100644 --- a/eng/targets/Services.props +++ b/eng/targets/Services.props @@ -22,6 +22,6 @@ - + diff --git a/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/SignatureHelp/RemoteSignatureHelpService.cs b/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/SignatureHelp/RemoteSignatureHelpService.cs index 1546f2d991b..dc94aa76584 100644 --- a/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/SignatureHelp/RemoteSignatureHelpService.cs +++ b/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/SignatureHelp/RemoteSignatureHelpService.cs @@ -10,22 +10,23 @@ using Microsoft.CodeAnalysis.Razor.Workspaces; using Microsoft.CodeAnalysis.Remote.Razor.ProjectSystem; using Microsoft.CodeAnalysis.Text; -using Microsoft.ServiceHub.Framework; using Roslyn.LanguageServer.Protocol; +using ExternalHandlers = Microsoft.CodeAnalysis.ExternalAccess.Razor.Cohost.Handlers; namespace Microsoft.CodeAnalysis.Remote.Razor; using SignatureHelp = Roslyn.LanguageServer.Protocol.SignatureHelp; -internal sealed class RemoteSignatureHelpService( - IServiceBroker serviceBroker, - DocumentSnapshotFactory documentSnapshotFactory, - IFilePathService filePathService, - IRazorDocumentMappingService documentMappingService) - : RazorDocumentServiceBase(serviceBroker, documentSnapshotFactory), IRemoteSignatureHelpService +internal sealed class RemoteSignatureHelpService(in ServiceArgs args) : RazorDocumentServiceBase(in args), IRemoteSignatureHelpService { - private readonly IFilePathService _filePathService = filePathService; - private readonly IRazorDocumentMappingService _documentMappingService = documentMappingService; + internal sealed class Factory : FactoryBase + { + protected override IRemoteSignatureHelpService CreateService(in ServiceArgs args) + => new RemoteSignatureHelpService(in args); + } + + private readonly IFilePathService _filePathService = args.ExportProvider.GetExportedValue(); + private readonly IRazorDocumentMappingService _documentMappingService = args.ExportProvider.GetExportedValue(); public ValueTask GetSignatureHelpAsync(JsonSerializableRazorPinnedSolutionInfoWrapper solutionInfo, JsonSerializableDocumentId documentId, Position position, CancellationToken cancellationToken) => RunServiceAsync( @@ -44,7 +45,7 @@ internal sealed class RemoteSignatureHelpService( if (_documentMappingService.TryMapToGeneratedDocumentPosition(codeDocument.GetCSharpDocument(), absoluteIndex, out var mappedPosition, out _)) { - return await ExternalAccess.Razor.Cohost.Handlers.SignatureHelp.GetSignatureHelpAsync(generatedDocument, mappedPosition, supportsVisualStudioExtensions: true, cancellationToken).ConfigureAwait(false); + return await ExternalHandlers.SignatureHelp.GetSignatureHelpAsync(generatedDocument, mappedPosition, supportsVisualStudioExtensions: true, cancellationToken).ConfigureAwait(false); } return null; diff --git a/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/SignatureHelp/RemoteSignatureHelpServiceFactory.cs b/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/SignatureHelp/RemoteSignatureHelpServiceFactory.cs deleted file mode 100644 index a7b42c9f564..00000000000 --- a/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/SignatureHelp/RemoteSignatureHelpServiceFactory.cs +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the MIT license. See License.txt in the project root for license information. - -using Microsoft.CodeAnalysis.Razor.DocumentMapping; -using Microsoft.CodeAnalysis.Razor.Remote; -using Microsoft.CodeAnalysis.Razor.Workspaces; -using Microsoft.CodeAnalysis.Remote.Razor.ProjectSystem; -using Microsoft.ServiceHub.Framework; -using Microsoft.VisualStudio.Composition; - -namespace Microsoft.CodeAnalysis.Remote.Razor; - -internal sealed class RemoteSignatureHelpServiceFactory : RazorServiceFactoryBase -{ - // WARNING: We must always have a parameterless constructor in order to be properly handled by ServiceHub. - public RemoteSignatureHelpServiceFactory() - : base(RazorServices.JsonDescriptors) - { - } - - protected override IRemoteSignatureHelpService CreateService(IServiceBroker serviceBroker, ExportProvider exportProvider) - { - var documentSnapshotFactory = exportProvider.GetExportedValue(); - var filePathService = exportProvider.GetExportedValue(); - var documentMappingService = exportProvider.GetExportedValue(); - return new RemoteSignatureHelpService(serviceBroker, documentSnapshotFactory, filePathService, documentMappingService); - } -} From bdf5796fd32369e45533ab362115f8a473e375e2 Mon Sep 17 00:00:00 2001 From: David Wengier Date: Wed, 17 Jul 2024 12:23:47 +1000 Subject: [PATCH 10/18] Bump Roslyn --- eng/Versions.props | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/eng/Versions.props b/eng/Versions.props index ab3d814a8d8..898101a3ff1 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -53,25 +53,25 @@ 9.0.0-beta.24352.2 1.0.0-beta.23475.1 1.0.0-beta.23475.1 - 4.11.0-3.24303.3 - 4.11.0-3.24303.3 - 4.11.0-3.24303.3 - 4.11.0-3.24303.3 - 4.11.0-3.24303.3 - 4.11.0-3.24303.3 - 4.11.0-3.24303.3 - 4.11.0-3.24303.3 - 4.11.0-3.24303.3 - 4.11.0-3.24303.3 - 4.11.0-3.24303.3 - 4.11.0-3.24303.3 - 4.11.0-3.24303.3 - 4.11.0-3.24303.3 - 4.11.0-3.24303.3 - 4.11.0-3.24303.3 - 4.11.0-3.24303.3 - 4.11.0-3.24303.3 - 4.11.0-3.24303.3 + 4.12.0-1.24366.3 + 4.12.0-1.24366.3 + 4.12.0-1.24366.3 + 4.12.0-1.24366.3 + 4.12.0-1.24366.3 + 4.12.0-1.24366.3 + 4.12.0-1.24366.3 + 4.12.0-1.24366.3 + 4.12.0-1.24366.3 + 4.12.0-1.24366.3 + 4.12.0-1.24366.3 + 4.12.0-1.24366.3 + 4.12.0-1.24366.3 + 4.12.0-1.24366.3 + 4.12.0-1.24366.3 + 4.12.0-1.24366.3 + 4.12.0-1.24366.3 + 4.12.0-1.24366.3 + 4.12.0-1.24366.3