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);
        }
Exemple #2
0
#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);
        }
Exemple #9
0
        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);
        }