private async Task AssertSemanticTokensAsync( string[] documentTexts, bool[] isRazorArray, OSharp.Range range, RazorSemanticTokensInfoService?service = null, ProvideSemanticTokensResponse?csharpTokens = null, int?documentVersion = 0) { // Arrange if (documentVersion == 0 && csharpTokens != null) { documentVersion = (int?)csharpTokens.HostDocumentSyncVersion; } if (csharpTokens is null) { csharpTokens = new ProvideSemanticTokensResponse(tokens: null, documentVersion); } var(documentSnapshots, textDocumentIdentifiers) = CreateDocumentSnapshot(documentTexts, isRazorArray, DefaultTagHelpers); if (service is null) { service = GetDefaultRazorSemanticTokenInfoService(documentSnapshots, csharpTokens, documentVersion); } var textDocumentIdentifier = textDocumentIdentifiers.Dequeue(); // Act var tokens = await service.GetSemanticTokensAsync(textDocumentIdentifier, range, CancellationToken.None); // Assert AssertSemanticTokensMatchesBaseline(tokens?.Data); }
#pragma warning disable CS0809 // Obsolete member overrides non-obsolete member public override async Task <ProvideSemanticTokensResponse> ProvideSemanticTokensAsync(SemanticTokensParams semanticTokensParams, CancellationToken cancellationToken) #pragma warning restore CS0809 // Obsolete member overrides non-obsolete member { if (semanticTokensParams is null) { throw new ArgumentNullException(nameof(semanticTokensParams)); } if (!_documentManager.TryGetDocument(semanticTokensParams.TextDocument.Uri, out var documentSnapshot)) { return(null); } if (!documentSnapshot.TryGetVirtualDocument <CSharpVirtualDocumentSnapshot>(out var csharpDoc)) { return(null); } semanticTokensParams.TextDocument.Uri = csharpDoc.Uri; var csharpResults = await _requestInvoker.ReinvokeRequestOnServerAsync <SemanticTokensParams, SemanticTokens>( LanguageServerConstants.LegacyRazorSemanticTokensEndpoint, LanguageServerKind.CSharp.ToContentType(), semanticTokensParams, cancellationToken).ConfigureAwait(false); var result = new ProvideSemanticTokensResponse(csharpResults, csharpDoc.HostDocumentSyncVersion); return(result); }
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.SemanticTokensParams, VSSemanticTokensResponse>( TextBuffer, Methods.TextDocumentSemanticTokensFullName, LanguageServerKind.CSharp.ToLanguageServerName(), It.IsAny <OmniSharp.Extensions.LanguageServer.Protocol.Models.SemanticTokensParams>(), 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 clientOptionsMonitor = new Mock <RazorLSPClientOptionsMonitor>(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, clientOptionsMonitor.Object, documentSynchronizer.Object); var request = new ProvideSemanticTokensParams() { TextDocument = new OmniSharpTextDocumentIdentifier() { Uri = new Uri("C:/path/to%20-%20project/file.razor") }, RequiredHostDocumentVersion = 0, }; var expectedResults = new ProvideSemanticTokensResponse( expectedcSharpResults.ResultId, expectedcSharpResults.Data, expectedcSharpResults.IsFinalized, documentVersion); // Act var result = await target.ProvideSemanticTokensAsync(request, CancellationToken.None); // Assert Assert.Equal(expectedResults, result); }
public async Task GetSemanticTokens_CSharp_RazorIfNotReady() { var txt = $@"<p></p>@{{ var d = ""t""; }}"; var cSharpResponse = new ProvideSemanticTokensResponse( resultId: null, tokens: Array.Empty <int>(), isFinalized: true, hostDocumentSyncVersion: 1); await AssertSemanticTokensAsync(txt, isRazor : false, csharpTokens : cSharpResponse, documentMappings : null, documentVersion : 1); }
public async Task GetSemanticTokensEdits_CSharp_RazorIfNotReady() { var txt = $@"<p></p>@{{ var d = ""t""; }}"; var cSharpResponse = new ProvideSemanticTokensResponse( resultId: null, tokens: Array.Empty <int>(), isFinalized: true, hostDocumentSyncVersion: 0); var isRazor = true; var response = await AssertSemanticTokensAsync(txt, isRazor, csharpTokens : cSharpResponse, documentVersion : 0); _ = await AssertSemanticTokenEditsAsync(txt, expectDelta : true, isRazor, response.Item1, response.Item2); }
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, Mock.Of <ITextSnapshot>(MockBehavior.Strict), 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 OmniSharp.Extensions.LanguageServer.Protocol.Models.Proposals.SemanticTokens(); var requestInvoker = new Mock <LSPRequestInvoker>(MockBehavior.Strict); requestInvoker.Setup(invoker => invoker.ReinvokeRequestOnServerAsync <SemanticTokensParams, OmniSharp.Extensions.LanguageServer.Protocol.Models.Proposals.SemanticTokens>( LanguageServerConstants.LegacyRazorSemanticTokensEndpoint, LanguageServerKind.CSharp.ToContentType(), It.IsAny <SemanticTokensParams>(), It.IsAny <CancellationToken>() )).Returns(Task.FromResult(expectedcSharpResults)); var uIContextManager = new Mock <RazorUIContextManager>(MockBehavior.Strict); var disposable = new Mock <IDisposable>(MockBehavior.Strict); var clientOptionsMonitor = new Mock <RazorLSPClientOptionsMonitor>(MockBehavior.Strict); var target = new DefaultRazorLanguageServerCustomMessageTarget( documentManager.Object, JoinableTaskContext, requestInvoker.Object, uIContextManager.Object, disposable.Object, clientOptionsMonitor.Object); var request = new SemanticTokensParams() { TextDocument = new TextDocumentIdentifier() { Uri = new Uri("C:/path/to%20-%20project/file.razor") } }; var expectedResults = new ProvideSemanticTokensResponse(expectedcSharpResults, documentVersion); // Act var result = await target.ProvideSemanticTokensAsync(request, CancellationToken.None); // Assert Assert.Equal(expectedResults, result); }
public async Task GetSemanticTokens_CSharp_VSCodeWorks() { var documentText = @"@addTagHelper *, TestAssembly @{ var d = } "; var razorRange = new OSharp.Range { Start = new OSharp.Position { Line = 0, Character = 0 }, End = new OSharp.Position { Line = 2, Character = 0 } }; var csharpTokens = new ProvideSemanticTokensResponse(tokens: Array.Empty <int>(), hostDocumentSyncVersion: null); await AssertSemanticTokensAsync(documentText, isRazorFile : false, razorRange, csharpTokens : csharpTokens, documentVersion : 1); }
public async Task GetSemanticTokens_CSharp_RazorIfNotReady() { var documentText = @"<p></p>@{ var d = ""t""; } "; var razorRange = new OSharp.Range { Start = new OSharp.Position { Line = 0, Character = 0 }, End = new OSharp.Position { Line = 3, Character = 0 } }; var csharpTokens = new ProvideSemanticTokensResponse(tokens: Array.Empty <int>(), hostDocumentSyncVersion: 1); await AssertSemanticTokensAsync(documentText, isRazorFile : false, razorRange, csharpTokens : csharpTokens, documentVersion : 1); }
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); }