public async Task ProvideSemanticTokensAsync_CannotLookupVirtualDocument_ReturnsNullAsync() { // Arrange var testDocUri = new Uri("C:/path/to/file.razor"); LSPDocumentSnapshot testDocument = new TestLSPDocumentSnapshot(testDocUri, 0); var documentManager = new Mock <TrackingLSPDocumentManager>(MockBehavior.Strict); documentManager.Setup(manager => manager.TryGetDocument(It.IsAny <Uri>(), out testDocument)) .Returns(true); var target = new DefaultRazorLanguageServerCustomMessageTarget(documentManager.Object); var request = new ProvideSemanticTokensRangeParams( textDocument: new OmniSharpTextDocumentIdentifier() { Uri = new Uri("C:/path/to/file.razor") }, requiredHostDocumentVersion: 0, range: new OmniSharp.Extensions.LanguageServer.Protocol.Models.Range()); // Act var result = await target.ProvideSemanticTokensRangeAsync(request, CancellationToken.None); // Assert Assert.Null(result); }
private async Task <int[]?> GetMatchingCSharpResponseAsync( TextDocumentIdentifier textDocumentIdentifier, long documentVersion, Range csharpRange, CancellationToken cancellationToken) { var parameter = new ProvideSemanticTokensRangeParams(textDocumentIdentifier, documentVersion, csharpRange); var request = await _languageServer.SendRequestAsync(LanguageServerConstants.RazorProvideSemanticTokensRangeEndpoint, parameter); var csharpResponse = await request.Returning <ProvideSemanticTokensResponse>(cancellationToken); if (csharpResponse is null) { // C# isn't ready yet, don't make Razor wait for it. Once C# is ready they'll send a refresh notification. return(Array.Empty <int>()); } else if (csharpResponse.HostDocumentSyncVersion != null && csharpResponse.HostDocumentSyncVersion != documentVersion) { // No C# response or C# is out of sync with us. Unrecoverable, return null to indicate no change. // Once C# syncs up they'll send a refresh notification. return(null); } var response = csharpResponse.Tokens ?? Array.Empty <int>(); return(response); }
public async Task ProvideSemanticTokensAsync_ReturnsSemanticTokensAsync() { // Arrange var testDocUri = new Uri("C:/path/to - project/file.razor"); var testVirtualDocUri = new Uri("C:/path/to - project/file2.razor.g"); var testCSharpDocUri = new Uri("C:/path/to - project/file.razor.g.cs"); var documentVersion = 0; var testVirtualDocument = new TestVirtualDocumentSnapshot(testVirtualDocUri, 0); var csharpVirtualDocument = new CSharpVirtualDocumentSnapshot(testCSharpDocUri, TextBuffer.CurrentSnapshot, 0); LSPDocumentSnapshot testDocument = new TestLSPDocumentSnapshot(testDocUri, documentVersion, testVirtualDocument, csharpVirtualDocument); var documentManager = new Mock <TrackingLSPDocumentManager>(MockBehavior.Strict); documentManager.Setup(manager => manager.TryGetDocument(testDocUri, out testDocument)) .Returns(true); var expectedcSharpResults = new VSSemanticTokensResponse(); var requestInvoker = new Mock <LSPRequestInvoker>(MockBehavior.Strict); requestInvoker.Setup(invoker => invoker.ReinvokeRequestOnServerAsync <OmniSharp.Extensions.LanguageServer.Protocol.Models.SemanticTokensRangeParams, VSSemanticTokensResponse>( TextBuffer, Methods.TextDocumentSemanticTokensRangeName, LanguageServerKind.CSharp.ToLanguageServerName(), It.IsAny <OmniSharp.Extensions.LanguageServer.Protocol.Models.SemanticTokensRangeParams>(), It.IsAny <CancellationToken>() )).Returns(Task.FromResult(new ReinvocationResponse <VSSemanticTokensResponse>("languageClient", expectedcSharpResults))); var uIContextManager = new Mock <RazorUIContextManager>(MockBehavior.Strict); var disposable = new Mock <IDisposable>(MockBehavior.Strict); var documentSynchronizer = new Mock <LSPDocumentSynchronizer>(MockBehavior.Strict); documentSynchronizer.Setup(r => r.TrySynchronizeVirtualDocumentAsync(0, It.IsAny <CSharpVirtualDocumentSnapshot>(), It.IsAny <CancellationToken>())) .Returns(Task.FromResult(true)); var target = new DefaultRazorLanguageServerCustomMessageTarget( documentManager.Object, JoinableTaskContext, requestInvoker.Object, uIContextManager.Object, disposable.Object, EditorSettingsManager, documentSynchronizer.Object); var request = new ProvideSemanticTokensRangeParams( textDocument: new OmniSharpTextDocumentIdentifier() { Uri = new Uri("C:/path/to%20-%20project/file.razor") }, requiredHostDocumentVersion: 0, range: new OmniSharp.Extensions.LanguageServer.Protocol.Models.Range()); var expectedResults = new ProvideSemanticTokensResponse(expectedcSharpResults.Data, documentVersion); // Act var result = await target.ProvideSemanticTokensRangeAsync(request, CancellationToken.None); // Assert Assert.Equal(expectedResults, result); }
public abstract Task <ProvideSemanticTokensResponse?> ProvideSemanticTokensRangeAsync(ProvideSemanticTokensRangeParams semanticTokensParams, CancellationToken cancellationToken);
public override async Task <ProvideSemanticTokensResponse?> ProvideSemanticTokensRangeAsync( ProvideSemanticTokensRangeParams semanticTokensParams, CancellationToken cancellationToken) { if (semanticTokensParams is null) { throw new ArgumentNullException(nameof(semanticTokensParams)); } if (semanticTokensParams.Range is null) { throw new ArgumentNullException(nameof(semanticTokensParams.Range)); } var csharpDoc = GetCSharpDocumentSnapshsot(semanticTokensParams.TextDocument.Uri.ToUri()); if (csharpDoc is null) { return(null); } var synchronized = await _documentSynchronizer.TrySynchronizeVirtualDocumentAsync( (int)semanticTokensParams.RequiredHostDocumentVersion, csharpDoc, cancellationToken); if (!synchronized) { // If we're unable to synchronize we won't produce useful results, but we have to indicate // it's due to out of sync by providing the old version return(new ProvideSemanticTokensResponse(tokens: null, hostDocumentSyncVersion: csharpDoc.HostDocumentSyncVersion)); } var csharpTextDocument = semanticTokensParams.TextDocument with { Uri = csharpDoc.Uri }; semanticTokensParams = semanticTokensParams with { TextDocument = csharpTextDocument }; var newParams = new SemanticTokensRangeParams { TextDocument = semanticTokensParams.TextDocument, PartialResultToken = semanticTokensParams.PartialResultToken, Range = semanticTokensParams.Range, }; var textBuffer = csharpDoc.Snapshot.TextBuffer; var csharpResults = await _requestInvoker.ReinvokeRequestOnServerAsync <SemanticTokensRangeParams, VSSemanticTokensResponse>( textBuffer, Methods.TextDocumentSemanticTokensRangeName, RazorLSPConstants.RazorCSharpLanguageServerName, newParams, cancellationToken).ConfigureAwait(false); var result = csharpResults?.Response; if (result is null) { // Weren't able to re-invoke C# semantic tokens but we have to indicate it's due to out of sync by providing the old version return(new ProvideSemanticTokensResponse(tokens: null, hostDocumentSyncVersion: csharpDoc.HostDocumentSyncVersion)); } var response = new ProvideSemanticTokensResponse(result.Data, semanticTokensParams.RequiredHostDocumentVersion); return(response); }