зеркало из https://github.com/dotnet/razor.git
Introduce service for getting code actions from delegated servers
This commit is contained in:
Родитель
03e900f144
Коммит
001ebcfa7e
|
@ -12,8 +12,8 @@ using Microsoft.AspNetCore.Razor.Language;
|
|||
using Microsoft.AspNetCore.Razor.LanguageServer.CodeActions;
|
||||
using Microsoft.AspNetCore.Razor.LanguageServer.EndpointContracts;
|
||||
using Microsoft.AspNetCore.Razor.LanguageServer.Hosting;
|
||||
using Microsoft.AspNetCore.Razor.Telemetry;
|
||||
using Microsoft.CodeAnalysis.Razor.DocumentMapping;
|
||||
using Microsoft.CodeAnalysis.Razor.Logging;
|
||||
using Microsoft.CodeAnalysis.Razor.ProjectSystem;
|
||||
using Microsoft.CodeAnalysis.Razor.Protocol.CodeActions;
|
||||
using Microsoft.CodeAnalysis.Razor.Workspaces;
|
||||
|
@ -53,10 +53,9 @@ public class RazorCodeActionsBenchmark : RazorLanguageServerBenchmarkBase
|
|||
razorCodeActionProviders: RazorLanguageServerHost.GetRequiredService<IEnumerable<IRazorCodeActionProvider>>(),
|
||||
csharpCodeActionProviders: RazorLanguageServerHost.GetRequiredService<IEnumerable<ICSharpCodeActionProvider>>(),
|
||||
htmlCodeActionProviders: RazorLanguageServerHost.GetRequiredService<IEnumerable<IHtmlCodeActionProvider>>(),
|
||||
clientConnection: RazorLanguageServerHost.GetRequiredService<IClientConnection>(),
|
||||
delegatedCodeActionsProvider: RazorLanguageServerHost.GetRequiredService<IDelegatedCodeActionsProvider>(),
|
||||
languageServerFeatureOptions: RazorLanguageServerHost.GetRequiredService<LanguageServerFeatureOptions>(),
|
||||
loggerFactory: RazorLanguageServerHost.GetRequiredService<ILoggerFactory>(),
|
||||
telemetryReporter: null);
|
||||
telemetryReporter: NoOpTelemetryReporter.Instance);
|
||||
|
||||
var projectRoot = Path.Combine(RepoRoot, "src", "Razor", "test", "testapps", "ComponentApp");
|
||||
var projectFilePath = Path.Combine(projectRoot, "ComponentApp.csproj");
|
||||
|
|
|
@ -12,9 +12,9 @@ using System.Threading.Tasks;
|
|||
using Microsoft.AspNetCore.Razor.Language;
|
||||
using Microsoft.AspNetCore.Razor.LanguageServer.CodeActions.Models;
|
||||
using Microsoft.AspNetCore.Razor.LanguageServer.EndpointContracts;
|
||||
using Microsoft.AspNetCore.Razor.LanguageServer.Hosting;
|
||||
using Microsoft.AspNetCore.Razor.PooledObjects;
|
||||
using Microsoft.AspNetCore.Razor.Telemetry;
|
||||
using Microsoft.AspNetCore.Razor.Threading;
|
||||
using Microsoft.CodeAnalysis.ExternalAccess.Razor;
|
||||
using Microsoft.CodeAnalysis.Razor.DocumentMapping;
|
||||
using Microsoft.CodeAnalysis.Razor.Logging;
|
||||
|
@ -24,7 +24,6 @@ using Microsoft.CodeAnalysis.Razor.Protocol.CodeActions;
|
|||
using Microsoft.CodeAnalysis.Razor.Workspaces;
|
||||
using Microsoft.CodeAnalysis.Text;
|
||||
using Microsoft.VisualStudio.LanguageServer.Protocol;
|
||||
using StreamJsonRpc;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.LanguageServer.CodeActions;
|
||||
|
||||
|
@ -34,22 +33,20 @@ internal sealed class CodeActionEndpoint(
|
|||
IEnumerable<IRazorCodeActionProvider> razorCodeActionProviders,
|
||||
IEnumerable<ICSharpCodeActionProvider> csharpCodeActionProviders,
|
||||
IEnumerable<IHtmlCodeActionProvider> htmlCodeActionProviders,
|
||||
IClientConnection clientConnection,
|
||||
IDelegatedCodeActionsProvider delegatedCodeActionsProvider,
|
||||
LanguageServerFeatureOptions languageServerFeatureOptions,
|
||||
ILoggerFactory loggerFactory,
|
||||
ITelemetryReporter? telemetryReporter)
|
||||
ITelemetryReporter telemetryReporter)
|
||||
: IRazorRequestHandler<VSCodeActionParams, SumType<Command, CodeAction>[]?>, ICapabilitiesProvider
|
||||
{
|
||||
private const string LspEndpointName = Methods.TextDocumentCodeActionName;
|
||||
|
||||
private readonly IDocumentMappingService _documentMappingService = documentMappingService ?? throw new ArgumentNullException(nameof(documentMappingService));
|
||||
private readonly IEnumerable<IRazorCodeActionProvider> _razorCodeActionProviders = razorCodeActionProviders ?? throw new ArgumentNullException(nameof(razorCodeActionProviders));
|
||||
private readonly IEnumerable<ICSharpCodeActionProvider> _csharpCodeActionProviders = csharpCodeActionProviders ?? throw new ArgumentNullException(nameof(csharpCodeActionProviders));
|
||||
private readonly IEnumerable<IHtmlCodeActionProvider> _htmlCodeActionProviders = htmlCodeActionProviders ?? throw new ArgumentNullException(nameof(htmlCodeActionProviders));
|
||||
private readonly LanguageServerFeatureOptions _languageServerFeatureOptions = languageServerFeatureOptions ?? throw new ArgumentNullException(nameof(languageServerFeatureOptions));
|
||||
private readonly IClientConnection _clientConnection = clientConnection ?? throw new ArgumentNullException(nameof(clientConnection));
|
||||
private readonly ILogger _logger = loggerFactory.GetOrCreateLogger<CodeActionEndpoint>();
|
||||
private readonly ITelemetryReporter? _telemetryReporter = telemetryReporter;
|
||||
private readonly IDocumentMappingService _documentMappingService = documentMappingService;
|
||||
private readonly IEnumerable<IRazorCodeActionProvider> _razorCodeActionProviders = razorCodeActionProviders;
|
||||
private readonly IEnumerable<ICSharpCodeActionProvider> _csharpCodeActionProviders = csharpCodeActionProviders;
|
||||
private readonly IEnumerable<IHtmlCodeActionProvider> _htmlCodeActionProviders = htmlCodeActionProviders;
|
||||
private readonly LanguageServerFeatureOptions _languageServerFeatureOptions = languageServerFeatureOptions;
|
||||
private readonly IDelegatedCodeActionsProvider _delegatedCodeActionsProvider = delegatedCodeActionsProvider;
|
||||
private readonly ITelemetryReporter _telemetryReporter = telemetryReporter;
|
||||
|
||||
internal bool _supportsCodeActionResolve = false;
|
||||
|
||||
|
@ -74,7 +71,7 @@ internal sealed class CodeActionEndpoint(
|
|||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
var correlationId = Guid.NewGuid();
|
||||
using var __ = _telemetryReporter?.TrackLspRequest(LspEndpointName, LanguageServerConstants.RazorLanguageServerName, correlationId);
|
||||
using var __ = _telemetryReporter.TrackLspRequest(LspEndpointName, LanguageServerConstants.RazorLanguageServerName, correlationId);
|
||||
var razorCodeActions = await GetRazorCodeActionsAsync(razorCodeActionContext, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
@ -265,14 +262,14 @@ internal sealed class CodeActionEndpoint(
|
|||
}
|
||||
|
||||
// Internal for testing
|
||||
internal async Task<RazorVSInternalCodeAction[]> GetCodeActionsFromLanguageServerAsync(RazorLanguageKind languageKind, RazorCodeActionContext context, Guid correlationId, CancellationToken cancellationToken)
|
||||
internal Task<RazorVSInternalCodeAction[]> GetCodeActionsFromLanguageServerAsync(RazorLanguageKind languageKind, RazorCodeActionContext context, Guid correlationId, CancellationToken cancellationToken)
|
||||
{
|
||||
if (languageKind == RazorLanguageKind.CSharp)
|
||||
{
|
||||
// For C# we have to map the ranges to the generated document
|
||||
if (!_documentMappingService.TryMapToGeneratedDocumentRange(context.CodeDocument.GetCSharpDocument(), context.Request.Range, out var projectedRange))
|
||||
{
|
||||
return [];
|
||||
return SpecializedTasks.EmptyArray<RazorVSInternalCodeAction>();
|
||||
}
|
||||
|
||||
var newContext = context.Request.Context;
|
||||
|
@ -288,25 +285,7 @@ internal sealed class CodeActionEndpoint(
|
|||
}
|
||||
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
var delegatedParams = new DelegatedCodeActionParams()
|
||||
{
|
||||
HostDocumentVersion = context.DocumentSnapshot.Version,
|
||||
CodeActionParams = context.Request,
|
||||
LanguageKind = languageKind,
|
||||
CorrelationId = correlationId
|
||||
};
|
||||
|
||||
try
|
||||
{
|
||||
return await _clientConnection.SendRequestAsync<DelegatedCodeActionParams, RazorVSInternalCodeAction[]>(CustomMessageNames.RazorProvideCodeActionsEndpoint, delegatedParams, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
catch (RemoteInvocationException e)
|
||||
{
|
||||
_telemetryReporter?.ReportFault(e, "Error getting code actions from delegate language server for {languageKind}", languageKind);
|
||||
_logger.LogError(e, $"Error getting code actions from delegate language server for {languageKind}");
|
||||
return [];
|
||||
}
|
||||
return _delegatedCodeActionsProvider.GetDelegatedCodeActionsAsync(languageKind, context.Request, context.DocumentSnapshot.Version, correlationId, cancellationToken);
|
||||
}
|
||||
|
||||
private async Task<ImmutableArray<RazorVSInternalCodeAction>> GetRazorCodeActionsAsync(RazorCodeActionContext context, CancellationToken cancellationToken)
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the MIT license. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Razor.LanguageServer.CodeActions.Models;
|
||||
using Microsoft.AspNetCore.Razor.LanguageServer.Hosting;
|
||||
using Microsoft.AspNetCore.Razor.Telemetry;
|
||||
using Microsoft.CodeAnalysis.Razor.Logging;
|
||||
using Microsoft.CodeAnalysis.Razor.Protocol;
|
||||
using Microsoft.CodeAnalysis.Razor.Protocol.CodeActions;
|
||||
using Microsoft.VisualStudio.RpcContracts;
|
||||
using StreamJsonRpc;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.LanguageServer.CodeActions;
|
||||
|
||||
internal sealed class DelegatedCodeActionsProvider(
|
||||
IClientConnection clientConnection,
|
||||
ITelemetryReporter telemetryReporter,
|
||||
ILoggerFactory loggerFactory) : IDelegatedCodeActionsProvider
|
||||
{
|
||||
private readonly IClientConnection _clientConnection = clientConnection;
|
||||
private readonly ITelemetryReporter _telemetryReporter = telemetryReporter;
|
||||
private readonly ILogger _logger = loggerFactory.GetOrCreateLogger<DelegatedCodeActionsProvider>();
|
||||
|
||||
public async Task<RazorVSInternalCodeAction[]> GetDelegatedCodeActionsAsync(RazorLanguageKind languageKind, VSCodeActionParams request, int hostDocumentVersion, Guid correlationId, CancellationToken cancellationToken)
|
||||
{
|
||||
var delegatedParams = new DelegatedCodeActionParams()
|
||||
{
|
||||
HostDocumentVersion = hostDocumentVersion,
|
||||
CodeActionParams = request,
|
||||
LanguageKind = languageKind,
|
||||
CorrelationId = correlationId
|
||||
};
|
||||
|
||||
try
|
||||
{
|
||||
return await _clientConnection.SendRequestAsync<DelegatedCodeActionParams, RazorVSInternalCodeAction[]>(CustomMessageNames.RazorProvideCodeActionsEndpoint, delegatedParams, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
catch (RemoteInvocationException e)
|
||||
{
|
||||
_telemetryReporter.ReportFault(e, "Error getting code actions from delegate language server for {languageKind}", languageKind);
|
||||
_logger.LogError(e, $"Error getting code actions from delegate language server for {languageKind}");
|
||||
return [];
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Razor.LanguageServer.CodeActions.Models;
|
||||
using Microsoft.CodeAnalysis.Razor.Protocol;
|
||||
using Microsoft.CodeAnalysis.Razor.Protocol.CodeActions;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.LanguageServer.CodeActions;
|
||||
|
||||
internal interface IDelegatedCodeActionsProvider
|
||||
{
|
||||
Task<RazorVSInternalCodeAction[]> GetDelegatedCodeActionsAsync(RazorLanguageKind languageKind, VSCodeActionParams request, int hostDocumentVersion, Guid correlationId, CancellationToken cancellationToken);
|
||||
}
|
|
@ -137,6 +137,7 @@ internal static class IServiceCollectionExtensions
|
|||
services.AddHandlerWithCapabilities<CodeActionEndpoint>();
|
||||
services.AddHandler<CodeActionResolveEndpoint>();
|
||||
|
||||
services.AddSingleton<IDelegatedCodeActionsProvider, DelegatedCodeActionsProvider>();
|
||||
services.AddSingleton<IDelegatedCodeActionResolver, DelegatedCodeActionResolver>();
|
||||
|
||||
// CSharp Code actions
|
||||
|
|
|
@ -15,6 +15,7 @@ using Microsoft.AspNetCore.Razor.LanguageServer.CodeActions.Razor;
|
|||
using Microsoft.AspNetCore.Razor.LanguageServer.EndpointContracts;
|
||||
using Microsoft.AspNetCore.Razor.LanguageServer.Formatting;
|
||||
using Microsoft.AspNetCore.Razor.LanguageServer.Hosting;
|
||||
using Microsoft.AspNetCore.Razor.Telemetry;
|
||||
using Microsoft.AspNetCore.Razor.Test.Common.LanguageServer;
|
||||
using Microsoft.AspNetCore.Razor.Test.Common.Workspaces;
|
||||
using Microsoft.AspNetCore.Razor.Utilities;
|
||||
|
@ -1160,6 +1161,7 @@ public class CodeActionEndToEndTest(ITestOutputHelper testOutput) : SingleServer
|
|||
IRazorCodeActionProvider[]? razorProviders = null,
|
||||
Diagnostic[]? diagnostics = null)
|
||||
{
|
||||
var delegatedCodeActionsProvider = new DelegatedCodeActionsProvider(clientConnection, NoOpTelemetryReporter.Instance, LoggerFactory);
|
||||
var endpoint = new CodeActionEndpoint(
|
||||
DocumentMappingService.AssumeNotNull(),
|
||||
razorCodeActionProviders: razorProviders ?? [],
|
||||
|
@ -1169,10 +1171,9 @@ public class CodeActionEndToEndTest(ITestOutputHelper testOutput) : SingleServer
|
|||
new TypeAccessibilityCodeActionProvider()
|
||||
],
|
||||
htmlCodeActionProviders: [],
|
||||
clientConnection,
|
||||
delegatedCodeActionsProvider,
|
||||
LanguageServerFeatureOptions.AssumeNotNull(),
|
||||
LoggerFactory,
|
||||
telemetryReporter: null);
|
||||
NoOpTelemetryReporter.Instance);
|
||||
|
||||
// Call GetRegistration, so the endpoint knows we support resolve
|
||||
endpoint.ApplyCapabilities(new(), new VSInternalClientCapabilities
|
||||
|
|
|
@ -12,6 +12,7 @@ using System.Threading.Tasks;
|
|||
using Microsoft.AspNetCore.Razor.Language;
|
||||
using Microsoft.AspNetCore.Razor.LanguageServer.CodeActions.Models;
|
||||
using Microsoft.AspNetCore.Razor.LanguageServer.Hosting;
|
||||
using Microsoft.AspNetCore.Razor.Telemetry;
|
||||
using Microsoft.AspNetCore.Razor.Test.Common;
|
||||
using Microsoft.AspNetCore.Razor.Test.Common.LanguageServer;
|
||||
using Microsoft.CodeAnalysis.Razor.DocumentMapping;
|
||||
|
@ -591,15 +592,19 @@ public class CodeActionEndpointTest(ITestOutputHelper testOutput) : LanguageServ
|
|||
LanguageServerFeatureOptions? languageServerFeatureOptions = null,
|
||||
bool supportsCodeActionResolve = false)
|
||||
{
|
||||
var delegatedCodeActionsProvider = new DelegatedCodeActionsProvider(
|
||||
clientConnection ?? StrictMock.Of<IClientConnection>(),
|
||||
NoOpTelemetryReporter.Instance,
|
||||
LoggerFactory);
|
||||
|
||||
return new CodeActionEndpoint(
|
||||
documentMappingService ?? CreateDocumentMappingService(),
|
||||
razorCodeActionProviders.NullToEmpty(),
|
||||
csharpCodeActionProviders.NullToEmpty(),
|
||||
htmlCodeActionProviders.NullToEmpty(),
|
||||
clientConnection ?? StrictMock.Of<IClientConnection>(),
|
||||
delegatedCodeActionsProvider,
|
||||
languageServerFeatureOptions ?? StrictMock.Of<LanguageServerFeatureOptions>(x => x.SupportsFileManipulation == true),
|
||||
LoggerFactory,
|
||||
telemetryReporter: null)
|
||||
NoOpTelemetryReporter.Instance)
|
||||
{
|
||||
_supportsCodeActionResolve = supportsCodeActionResolve
|
||||
};
|
||||
|
|
Загрузка…
Ссылка в новой задаче