зеркало из 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.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.SpellCheck" ClassName="Microsoft.CodeAnalysis.Remote.Razor.RemoteSpellCheckService+Factory" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
|
|
@ -158,12 +158,13 @@ internal static class IServiceCollectionExtensions
|
|||
{
|
||||
services.AddHandlerWithCapabilities<TextDocumentTextPresentationEndpoint>();
|
||||
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.AddHandler<DocumentDidCloseEndpoint>();
|
||||
|
|
|
@ -36,11 +36,13 @@ internal sealed class DocumentSpellCheckEndpoint(
|
|||
|
||||
var data = await _spellCheckService.GetSpellCheckRangeTriplesAsync(documentContext, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
return [new VSInternalSpellCheckableRangeReport
|
||||
{
|
||||
Ranges =data,
|
||||
ResultId = Guid.NewGuid().ToString()
|
||||
}
|
||||
];
|
||||
return
|
||||
[
|
||||
new VSInternalSpellCheckableRangeReport
|
||||
{
|
||||
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(IRemoteDocumentHighlightService), null),
|
||||
(typeof(IRemoteAutoInsertService), null),
|
||||
(typeof(IRemoteSpellCheckService), null),
|
||||
];
|
||||
|
||||
// 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>();
|
||||
}
|
Загрузка…
Ссылка в новой задаче