зеркало из https://github.com/dotnet/razor.git
Create cohost spell check endpoints and services
This commit is contained in:
Родитель
56128c3c26
Коммит
4a44a99239
|
@ -29,5 +29,6 @@
|
||||||
<ServiceHubService Include="Microsoft.VisualStudio.Razor.GoToDefinition" ClassName="Microsoft.CodeAnalysis.Remote.Razor.RemoteGoToDefinitionService+Factory" />
|
<ServiceHubService Include="Microsoft.VisualStudio.Razor.GoToDefinition" ClassName="Microsoft.CodeAnalysis.Remote.Razor.RemoteGoToDefinitionService+Factory" />
|
||||||
<ServiceHubService Include="Microsoft.VisualStudio.Razor.Rename" ClassName="Microsoft.CodeAnalysis.Remote.Razor.RemoteRenameService+Factory" />
|
<ServiceHubService Include="Microsoft.VisualStudio.Razor.Rename" ClassName="Microsoft.CodeAnalysis.Remote.Razor.RemoteRenameService+Factory" />
|
||||||
<ServiceHubService Include="Microsoft.VisualStudio.Razor.AutoInsert" ClassName="Microsoft.CodeAnalysis.Remote.Razor.RemoteAutoInsertService+Factory" />
|
<ServiceHubService Include="Microsoft.VisualStudio.Razor.AutoInsert" ClassName="Microsoft.CodeAnalysis.Remote.Razor.RemoteAutoInsertService+Factory" />
|
||||||
|
<ServiceHubService Include="Microsoft.VisualStudio.Razor.SpellCheck" ClassName="Microsoft.CodeAnalysis.Remote.Razor.RemoteSpellCheckService+Factory" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
|
|
@ -158,12 +158,13 @@ internal static class IServiceCollectionExtensions
|
||||||
{
|
{
|
||||||
services.AddHandlerWithCapabilities<TextDocumentTextPresentationEndpoint>();
|
services.AddHandlerWithCapabilities<TextDocumentTextPresentationEndpoint>();
|
||||||
services.AddHandlerWithCapabilities<TextDocumentUriPresentationEndpoint>();
|
services.AddHandlerWithCapabilities<TextDocumentUriPresentationEndpoint>();
|
||||||
|
|
||||||
|
services.AddSingleton<ISpellCheckService, SpellCheckService>();
|
||||||
|
services.AddSingleton<ICSharpSpellCheckService, LspCSharpSpellCheckService>();
|
||||||
|
services.AddHandlerWithCapabilities<DocumentSpellCheckEndpoint>();
|
||||||
|
services.AddHandler<WorkspaceSpellCheckEndpoint>();
|
||||||
}
|
}
|
||||||
|
|
||||||
services.AddSingleton<ISpellCheckService, SpellCheckService>();
|
|
||||||
services.AddSingleton<ICSharpSpellCheckService, LspCSharpSpellCheckService>();
|
|
||||||
services.AddHandlerWithCapabilities<DocumentSpellCheckEndpoint>();
|
|
||||||
services.AddHandler<WorkspaceSpellCheckEndpoint>();
|
|
||||||
|
|
||||||
services.AddHandlerWithCapabilities<DocumentDidChangeEndpoint>();
|
services.AddHandlerWithCapabilities<DocumentDidChangeEndpoint>();
|
||||||
services.AddHandler<DocumentDidCloseEndpoint>();
|
services.AddHandler<DocumentDidCloseEndpoint>();
|
||||||
|
|
|
@ -36,11 +36,13 @@ internal sealed class DocumentSpellCheckEndpoint(
|
||||||
|
|
||||||
var data = await _spellCheckService.GetSpellCheckRangeTriplesAsync(documentContext, cancellationToken).ConfigureAwait(false);
|
var data = await _spellCheckService.GetSpellCheckRangeTriplesAsync(documentContext, cancellationToken).ConfigureAwait(false);
|
||||||
|
|
||||||
return [new VSInternalSpellCheckableRangeReport
|
return
|
||||||
{
|
[
|
||||||
Ranges =data,
|
new VSInternalSpellCheckableRangeReport
|
||||||
ResultId = Guid.NewGuid().ToString()
|
{
|
||||||
}
|
Ranges =data,
|
||||||
];
|
ResultId = Guid.NewGuid().ToString()
|
||||||
|
}
|
||||||
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
namespace Microsoft.CodeAnalysis.Razor.Remote;
|
||||||
|
|
||||||
|
internal interface IRemoteSpellCheckService
|
||||||
|
{
|
||||||
|
ValueTask<int[]> GetSpellCheckRangeTriplesAsync(
|
||||||
|
RazorPinnedSolutionInfoWrapper solutionInfo,
|
||||||
|
DocumentId razorDocumentId,
|
||||||
|
CancellationToken cancellationToken);
|
||||||
|
}
|
|
@ -22,6 +22,7 @@ internal static class RazorServices
|
||||||
(typeof(IRemoteFoldingRangeService), null),
|
(typeof(IRemoteFoldingRangeService), null),
|
||||||
(typeof(IRemoteDocumentHighlightService), null),
|
(typeof(IRemoteDocumentHighlightService), null),
|
||||||
(typeof(IRemoteAutoInsertService), null),
|
(typeof(IRemoteAutoInsertService), null),
|
||||||
|
(typeof(IRemoteSpellCheckService), null),
|
||||||
];
|
];
|
||||||
|
|
||||||
// Internal for testing
|
// Internal for testing
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
// 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 Microsoft.CodeAnalysis.Razor.DocumentMapping;
|
||||||
|
using Microsoft.CodeAnalysis.Razor.SpellCheck;
|
||||||
|
|
||||||
|
namespace Microsoft.CodeAnalysis.Remote.Razor.SpellCheck;
|
||||||
|
|
||||||
|
[Export(typeof(ISpellCheckService)), Shared]
|
||||||
|
[method: ImportingConstructor]
|
||||||
|
internal sealed class OOPSpellCheckService(
|
||||||
|
ICSharpSpellCheckService csharpSpellCheckService,
|
||||||
|
IDocumentMappingService documentMappingService)
|
||||||
|
: SpellCheckService(csharpSpellCheckService, documentMappingService)
|
||||||
|
{
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
// 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 System.Composition;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.CodeAnalysis.Razor.ProjectSystem;
|
||||||
|
using Microsoft.CodeAnalysis.Razor.SpellCheck;
|
||||||
|
using Microsoft.CodeAnalysis.Remote.Razor.ProjectSystem;
|
||||||
|
|
||||||
|
namespace Microsoft.CodeAnalysis.Remote.Razor.SpellCheck;
|
||||||
|
|
||||||
|
[Export(typeof(ICSharpSpellCheckService)), Shared]
|
||||||
|
[method: ImportingConstructor]
|
||||||
|
internal class RemoteCSharpSpellCheckService() : ICSharpSpellCheckService
|
||||||
|
{
|
||||||
|
public async Task<ImmutableArray<SpellCheckRange>> GetCSharpSpellCheckRangesAsync(DocumentContext documentContext, CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
// We have a razor document, lets find the generated C# document
|
||||||
|
Debug.Assert(documentContext is RemoteDocumentContext, "This method only works on document snapshots created in the OOP process");
|
||||||
|
var snapshot = (RemoteDocumentSnapshot)documentContext.Snapshot;
|
||||||
|
var generatedDocument = await snapshot.GetGeneratedDocumentAsync().ConfigureAwait(false);
|
||||||
|
|
||||||
|
var csharpRanges = await ExternalAccess.Razor.Cohost.Handlers.SpellCheck.GetSpellCheckSpansAsync(generatedDocument, cancellationToken).ConfigureAwait(false);
|
||||||
|
|
||||||
|
return csharpRanges.SelectAsArray(r => new SpellCheckRange((int)r.Kind, r.StartIndex, r.Length));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,34 @@
|
||||||
|
// 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.Remote;
|
||||||
|
using Microsoft.CodeAnalysis.Razor.SpellCheck;
|
||||||
|
using Microsoft.CodeAnalysis.Remote.Razor.ProjectSystem;
|
||||||
|
|
||||||
|
namespace Microsoft.CodeAnalysis.Remote.Razor;
|
||||||
|
|
||||||
|
internal sealed partial class RemoteSpellCheckService(in ServiceArgs args) : RazorDocumentServiceBase(in args), IRemoteSpellCheckService
|
||||||
|
{
|
||||||
|
internal sealed class Factory : FactoryBase<IRemoteSpellCheckService>
|
||||||
|
{
|
||||||
|
protected override IRemoteSpellCheckService CreateService(in ServiceArgs args)
|
||||||
|
=> new RemoteSpellCheckService(in args);
|
||||||
|
}
|
||||||
|
|
||||||
|
private readonly ISpellCheckService _spellCheckService = args.ExportProvider.GetExportedValue<ISpellCheckService>();
|
||||||
|
|
||||||
|
public ValueTask<int[]> GetSpellCheckRangeTriplesAsync(RazorPinnedSolutionInfoWrapper solutionInfo, DocumentId razorDocumentId, CancellationToken cancellationToken)
|
||||||
|
=> RunServiceAsync(
|
||||||
|
solutionInfo,
|
||||||
|
razorDocumentId,
|
||||||
|
context => GetSpellCheckRangeTriplesAsync(context, cancellationToken),
|
||||||
|
cancellationToken);
|
||||||
|
|
||||||
|
private async ValueTask<int[]> GetSpellCheckRangeTriplesAsync(RemoteDocumentContext context, CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
return await _spellCheckService.GetSpellCheckRangeTriplesAsync(context, cancellationToken).ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,80 @@
|
||||||
|
// 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.Composition;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.AspNetCore.Razor;
|
||||||
|
using Microsoft.CodeAnalysis;
|
||||||
|
using Microsoft.CodeAnalysis.ExternalAccess.Razor.Cohost;
|
||||||
|
using Microsoft.CodeAnalysis.Razor.Remote;
|
||||||
|
using Microsoft.VisualStudio.LanguageServer.Protocol;
|
||||||
|
|
||||||
|
namespace Microsoft.VisualStudio.Razor.LanguageClient.Cohost;
|
||||||
|
|
||||||
|
#pragma warning disable RS0030 // Do not use banned APIs
|
||||||
|
[Shared]
|
||||||
|
[CohostEndpoint(VSInternalMethods.TextDocumentSpellCheckableRangesName)]
|
||||||
|
[Export(typeof(IDynamicRegistrationProvider))]
|
||||||
|
[ExportCohostStatelessLspService(typeof(CohostDocumentSpellCheckEndpoint))]
|
||||||
|
[method: ImportingConstructor]
|
||||||
|
#pragma warning restore RS0030 // Do not use banned APIs
|
||||||
|
internal class CohostDocumentSpellCheckEndpoint(
|
||||||
|
IRemoteServiceInvoker remoteServiceInvoker)
|
||||||
|
: AbstractRazorCohostDocumentRequestHandler<VSInternalDocumentSpellCheckableParams, VSInternalSpellCheckableRangeReport[]>, IDynamicRegistrationProvider
|
||||||
|
{
|
||||||
|
private readonly IRemoteServiceInvoker _remoteServiceInvoker = remoteServiceInvoker;
|
||||||
|
|
||||||
|
protected override bool MutatesSolutionState => false;
|
||||||
|
|
||||||
|
protected override bool RequiresLSPSolution => true;
|
||||||
|
|
||||||
|
public Registration? GetRegistration(VSInternalClientCapabilities clientCapabilities, DocumentFilter[] filter, RazorCohostRequestContext requestContext)
|
||||||
|
{
|
||||||
|
if (clientCapabilities.SupportsVisualStudioExtensions)
|
||||||
|
{
|
||||||
|
return new Registration
|
||||||
|
{
|
||||||
|
Method = VSInternalMethods.TextDocumentSpellCheckableRangesName,
|
||||||
|
RegisterOptions = new TextDocumentRegistrationOptions()
|
||||||
|
{
|
||||||
|
DocumentSelector = filter
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override RazorTextDocumentIdentifier? GetRazorTextDocumentIdentifier(VSInternalDocumentSpellCheckableParams request)
|
||||||
|
=> request.TextDocument.ToRazorTextDocumentIdentifier();
|
||||||
|
|
||||||
|
protected override Task<VSInternalSpellCheckableRangeReport[]> HandleRequestAsync(VSInternalDocumentSpellCheckableParams request, RazorCohostRequestContext context, CancellationToken cancellationToken)
|
||||||
|
=> HandleRequestAsync(context.TextDocument.AssumeNotNull(), cancellationToken);
|
||||||
|
|
||||||
|
private async Task<VSInternalSpellCheckableRangeReport[]> HandleRequestAsync(TextDocument razorDocument, CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
var data = await _remoteServiceInvoker.TryInvokeAsync<IRemoteSpellCheckService, int[]>(
|
||||||
|
razorDocument.Project.Solution,
|
||||||
|
(service, solutionInfo, cancellationToken) => service.GetSpellCheckRangeTriplesAsync(solutionInfo, razorDocument.Id, cancellationToken),
|
||||||
|
cancellationToken).ConfigureAwait(false);
|
||||||
|
|
||||||
|
return
|
||||||
|
[
|
||||||
|
new VSInternalSpellCheckableRangeReport
|
||||||
|
{
|
||||||
|
Ranges = data,
|
||||||
|
ResultId = Guid.NewGuid().ToString()
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
internal TestAccessor GetTestAccessor() => new(this);
|
||||||
|
|
||||||
|
internal readonly struct TestAccessor(CohostDocumentSpellCheckEndpoint instance)
|
||||||
|
{
|
||||||
|
public Task<VSInternalSpellCheckableRangeReport[]> HandleRequestAsync(TextDocument razorDocument, CancellationToken cancellationToken)
|
||||||
|
=> instance.HandleRequestAsync(razorDocument, cancellationToken);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,34 @@
|
||||||
|
// 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.Threading;
|
||||||
|
using Microsoft.CodeAnalysis.ExternalAccess.Razor.Cohost;
|
||||||
|
using Microsoft.CodeAnalysis.Razor.Remote;
|
||||||
|
using Microsoft.VisualStudio.LanguageServer.Protocol;
|
||||||
|
|
||||||
|
namespace Microsoft.VisualStudio.Razor.LanguageClient.Cohost;
|
||||||
|
|
||||||
|
#pragma warning disable RS0030 // Do not use banned APIs
|
||||||
|
[Shared]
|
||||||
|
[CohostEndpoint(VSInternalMethods.WorkspaceSpellCheckableRangesName)]
|
||||||
|
[ExportCohostStatelessLspService(typeof(CohostWorkspaceSpellCheckEndpoint))]
|
||||||
|
[method: ImportingConstructor]
|
||||||
|
#pragma warning restore RS0030 // Do not use banned APIs
|
||||||
|
internal class CohostWorkspaceSpellCheckEndpoint(
|
||||||
|
IRemoteServiceInvoker remoteServiceInvoker)
|
||||||
|
: AbstractRazorCohostRequestHandler<VSInternalWorkspaceSpellCheckableParams, VSInternalWorkspaceSpellCheckableReport[]>
|
||||||
|
{
|
||||||
|
private readonly IRemoteServiceInvoker _remoteServiceInvoker = remoteServiceInvoker;
|
||||||
|
|
||||||
|
protected override bool MutatesSolutionState => false;
|
||||||
|
|
||||||
|
protected override bool RequiresLSPSolution => false;
|
||||||
|
|
||||||
|
// Razor files generally don't do anything at the workspace level
|
||||||
|
|
||||||
|
protected override Task<VSInternalWorkspaceSpellCheckableReport[]> HandleRequestAsync(VSInternalWorkspaceSpellCheckableParams request, RazorCohostRequestContext context, CancellationToken cancellationToken)
|
||||||
|
=> SpecializedTasks.EmptyArray<VSInternalWorkspaceSpellCheckableReport>();
|
||||||
|
}
|
Загрузка…
Ссылка в новой задаче