diff --git a/src/Razor/src/Microsoft.VisualStudio.LanguageServerClient.Razor/HtmlCSharp/CompletionHandler.cs b/src/Razor/src/Microsoft.VisualStudio.LanguageServerClient.Razor/HtmlCSharp/CompletionHandler.cs index 6cdd52c299..66a1e7bf51 100644 --- a/src/Razor/src/Microsoft.VisualStudio.LanguageServerClient.Razor/HtmlCSharp/CompletionHandler.cs +++ b/src/Razor/src/Microsoft.VisualStudio.LanguageServerClient.Razor/HtmlCSharp/CompletionHandler.cs @@ -12,6 +12,7 @@ using Microsoft.VisualStudio.LanguageServer.ContainedLanguage; using Microsoft.VisualStudio.LanguageServer.Protocol; using Microsoft.VisualStudio.LanguageServerClient.Razor.Extensions; using Microsoft.VisualStudio.LanguageServerClient.Razor.Logging; +using Microsoft.VisualStudio.Text; using Microsoft.VisualStudio.Text.Operations; using Microsoft.VisualStudio.Threading; @@ -212,12 +213,18 @@ namespace Microsoft.VisualStudio.LanguageServerClient.Razor.HtmlCSharp _logger.LogInformation($"Requesting non-provisional completions for {projectedDocumentUri}."); + var textBuffer = serverKind.GetTextBuffer(documentSnapshot); var response = await _requestInvoker.ReinvokeRequestOnServerAsync?>( + textBuffer, Methods.TextDocumentCompletionName, languageServerName, completionParams, cancellationToken).ConfigureAwait(false); - result = response.Result; + + if (!response.TryExtractResultOrLog(_logger, languageServerName, out result)) + { + return null; + } _logger.LogInformation("Found non-provisional completion"); } @@ -546,7 +553,7 @@ namespace Microsoft.VisualStudio.LanguageServerClient.Razor.HtmlCSharp // to ensure that we still get completion results at `|Da`. internalContext.InvokeKind = VSInternalCompletionInvokeKind.Explicit; } - + return context; } @@ -652,12 +659,18 @@ namespace Microsoft.VisualStudio.LanguageServerClient.Razor.HtmlCSharp _logger.LogInformation($"Requesting provisional completion for {previousCharacterProjection.Uri}."); + var textBuffer = LanguageServerKind.CSharp.GetTextBuffer(documentSnapshot); var response = await _requestInvoker.ReinvokeRequestOnServerAsync?>( + textBuffer, Methods.TextDocumentCompletionName, RazorLSPConstants.RazorCSharpLanguageServerName, provisionalCompletionParams, cancellationToken).ConfigureAwait(true); - result = response.Result; + + if (!response.TryExtractResultOrLog(_logger, RazorLSPConstants.RazorCSharpLanguageServerName, out result)) + { + return (false, result); + } // We have now obtained the necessary completion items. We no longer need the provisional change. Revert. var removeProvisionalDot = new VisualStudioTextChange(previousCharacterProjection.PositionIndex, 1, string.Empty); diff --git a/src/Razor/src/Microsoft.VisualStudio.LanguageServerClient.Razor/ReinvocationResponseExtensions.cs b/src/Razor/src/Microsoft.VisualStudio.LanguageServerClient.Razor/ReinvocationResponseExtensions.cs new file mode 100644 index 0000000000..dbebd78646 --- /dev/null +++ b/src/Razor/src/Microsoft.VisualStudio.LanguageServerClient.Razor/ReinvocationResponseExtensions.cs @@ -0,0 +1,38 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the MIT license. See License.txt in the project root for license information. + +using System.Diagnostics.CodeAnalysis; +using Microsoft.Extensions.Logging; +using Microsoft.VisualStudio.LanguageServer.ContainedLanguage; + +#nullable enable + +namespace Microsoft.VisualStudio.LanguageServerClient.Razor +{ + internal static class ReinvocationResponseExtensions + { + public static bool TryExtractResultOrLog( + this ReinvocationResponse response, + ILogger logger, + string fromLanguageServerName, + [NotNullWhen(true)] out TResponseType? result) + { + if (response is null) + { + logger.LogInformation("Could not make a request against language server {0}.", fromLanguageServerName); + result = default; + return false; + } + + if (response.Response is null) + { + logger.LogInformation("Language server {0} returned a `null` result.", fromLanguageServerName); + result = default; + return false; + } + + result = response.Response; + return true; + } + } +} diff --git a/src/Razor/test/Microsoft.VisualStudio.LanguageServerClient.Razor.Test/HtmlCSharp/CompletionHandlerTest.cs b/src/Razor/test/Microsoft.VisualStudio.LanguageServerClient.Razor.Test/HtmlCSharp/CompletionHandlerTest.cs index 37b36368c0..9b48a1a5b3 100644 --- a/src/Razor/test/Microsoft.VisualStudio.LanguageServerClient.Razor.Test/HtmlCSharp/CompletionHandlerTest.cs +++ b/src/Razor/test/Microsoft.VisualStudio.LanguageServerClient.Razor.Test/HtmlCSharp/CompletionHandlerTest.cs @@ -9,6 +9,7 @@ using Microsoft.AspNetCore.Razor.Test.Common; using Microsoft.VisualStudio.LanguageServer.Client; using Microsoft.VisualStudio.LanguageServer.ContainedLanguage; using Microsoft.VisualStudio.LanguageServer.Protocol; +using Microsoft.VisualStudio.Test; using Microsoft.VisualStudio.Text; using Microsoft.VisualStudio.Text.Operations; using Microsoft.VisualStudio.Threading; @@ -32,6 +33,10 @@ namespace Microsoft.VisualStudio.LanguageServerClient.Razor.HtmlCSharp CompletionRequestContextCache = new CompletionRequestContextCache(); FormattingOptionsProvider = TestFormattingOptionsProvider.Default; + + TextBuffer = new TestTextBuffer(new StringTextSnapshot(string.Empty)); + CSharpVirtualDocumentSnapshot = new CSharpVirtualDocumentSnapshot(new Uri("C:/path/to/file.razor.g.cs"), TextBuffer.CurrentSnapshot, 0); + HtmlVirtualDocumentSnapshot = new HtmlVirtualDocumentSnapshot(new Uri("C:/path/to/file.razor__virtual.html"), TextBuffer.CurrentSnapshot, 0); } private JoinableTaskContext JoinableTaskContext { get; } @@ -42,9 +47,15 @@ namespace Microsoft.VisualStudio.LanguageServerClient.Razor.HtmlCSharp private FormattingOptionsProvider FormattingOptionsProvider { get; } + private TestTextBuffer TextBuffer { get; } + + private CSharpVirtualDocumentSnapshot CSharpVirtualDocumentSnapshot { get; } + + private HtmlVirtualDocumentSnapshot HtmlVirtualDocumentSnapshot { get; } + private Uri Uri { get; } - private readonly ILanguageClient _languageClient = Mock.Of(MockBehavior.Strict); + private readonly string _languageClient = "languageClient"; [Theory] [WorkItem("https://github.com/dotnet/razor-tooling/issues/5606")] @@ -161,7 +172,7 @@ namespace Microsoft.VisualStudio.LanguageServerClient.Razor.HtmlCSharp { // Arrange var documentManager = new TestDocumentManager(); - documentManager.AddDocument(Uri, new TestLSPDocumentSnapshot(new Uri("C:/path/file.razor"), 0)); + documentManager.AddDocument(Uri, new TestLSPDocumentSnapshot(new Uri("C:/path/file.razor"), 0, CSharpVirtualDocumentSnapshot)); var requestInvoker = Mock.Of(MockBehavior.Strict); var projectionProvider = new Mock(MockBehavior.Strict).Object; Mock.Get(projectionProvider).Setup(projectionProvider => projectionProvider.GetProjectionAsync(It.IsAny(), It.IsAny(), CancellationToken.None)) @@ -237,12 +248,12 @@ namespace Microsoft.VisualStudio.LanguageServerClient.Razor.HtmlCSharp }; var documentManager = new TestDocumentManager(); - documentManager.AddDocument(Uri, new TestLSPDocumentSnapshot(new Uri("C:/path/file.razor"), 0)); + documentManager.AddDocument(Uri, new TestLSPDocumentSnapshot(new Uri("C:/path/file.razor"), 0, HtmlVirtualDocumentSnapshot)); var requestInvoker = new Mock(MockBehavior.Strict); requestInvoker - .Setup(r => r.ReinvokeRequestOnServerAsync?>(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) - .Callback((method, clientName, completionParams, ct) => + .Setup(r => r.ReinvokeRequestOnServerAsync?>(TextBuffer, It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) + .Callback((textBuffer, method, clientName, completionParams, ct) => { Assert.Equal(Methods.TextDocumentCompletionName, method); Assert.Equal(RazorLSPConstants.HtmlLanguageServerName, clientName); @@ -250,7 +261,7 @@ namespace Microsoft.VisualStudio.LanguageServerClient.Razor.HtmlCSharp Assert.Equal(VSInternalCompletionInvokeKind.Typing, vsCompletionContext.InvokeKind); called = true; }) - .Returns(Task.FromResult(new ReinvokeResponse?>(_languageClient, new[] { expectedItem }))); + .Returns(Task.FromResult(new ReinvocationResponse?>(_languageClient, new[] { expectedItem }))); var projectionResult = new ProjectionResult() { @@ -287,19 +298,24 @@ namespace Microsoft.VisualStudio.LanguageServerClient.Razor.HtmlCSharp }; var documentManager = new TestDocumentManager(); - documentManager.AddDocument(Uri, new TestLSPDocumentSnapshot(new Uri("C:/path/file.razor"), 0)); + documentManager.AddDocument(Uri, new TestLSPDocumentSnapshot(new Uri("C:/path/file.razor"), 0, HtmlVirtualDocumentSnapshot, CSharpVirtualDocumentSnapshot)); var requestInvoker = new Mock(MockBehavior.Strict); requestInvoker - .Setup(r => r.ReinvokeRequestOnServerAsync?>(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) - .Callback((method, clientName, completionParams, ct) => + .Setup(r => r.ReinvokeRequestOnServerAsync?>( + It.IsAny(), + It.IsAny(), + It.IsAny(), + It.IsAny(), + It.IsAny())) + .Callback((textBuffer, method, clientName, completionParams, ct) => { Assert.Equal(Methods.TextDocumentCompletionName, method); var vsCompletionContext = Assert.IsType(completionParams.Context); Assert.Equal(VSInternalCompletionInvokeKind.Explicit, vsCompletionContext.InvokeKind); called = true; }) - .Returns(Task.FromResult(new ReinvokeResponse?>(_languageClient, new[] { expectedItem }))); + .Returns(Task.FromResult(new ReinvocationResponse?>(_languageClient, new[] { expectedItem }))); var projectionResult = new ProjectionResult() { @@ -331,12 +347,12 @@ namespace Microsoft.VisualStudio.LanguageServerClient.Razor.HtmlCSharp }; var documentManager = new TestDocumentManager(); - documentManager.AddDocument(Uri, new TestLSPDocumentSnapshot(new Uri("C:/path/file.razor"), 0)); + documentManager.AddDocument(Uri, new TestLSPDocumentSnapshot(new Uri("C:/path/file.razor"), 0, HtmlVirtualDocumentSnapshot)); var requestInvoker = new Mock(MockBehavior.Strict); requestInvoker - .Setup(r => r.ReinvokeRequestOnServerAsync?>(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) - .Returns(Task.FromResult(new ReinvokeResponse?>(null, null))) + .Setup(r => r.ReinvokeRequestOnServerAsync?>(TextBuffer, It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) + .Returns(Task.FromResult(new ReinvocationResponse?>(String.Empty, null))) .Verifiable(); var projectionResult = new ProjectionResult() @@ -370,12 +386,12 @@ namespace Microsoft.VisualStudio.LanguageServerClient.Razor.HtmlCSharp }; var documentManager = new TestDocumentManager(); - documentManager.AddDocument(Uri, new TestLSPDocumentSnapshot(new Uri("C:/path/file.razor"), 0)); + documentManager.AddDocument(Uri, new TestLSPDocumentSnapshot(new Uri("C:/path/file.razor"), 0, CSharpVirtualDocumentSnapshot)); var requestInvoker = new Mock(MockBehavior.Strict); requestInvoker - .Setup(r => r.ReinvokeRequestOnServerAsync?>(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) - .Callback((method, clientName, completionParams, ct) => + .Setup(r => r.ReinvokeRequestOnServerAsync?>(TextBuffer, It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) + .Callback((textBuffer, method, clientName, completionParams, ct) => { Assert.Equal(Methods.TextDocumentCompletionName, method); Assert.Equal(RazorLSPConstants.RazorCSharpLanguageServerName, clientName); @@ -383,7 +399,7 @@ namespace Microsoft.VisualStudio.LanguageServerClient.Razor.HtmlCSharp Assert.Equal(VSInternalCompletionInvokeKind.Explicit, vsCompletionContext.InvokeKind); called = true; }) - .Returns(Task.FromResult(new ReinvokeResponse?>(_languageClient, new[] { expectedItem }))); + .Returns(Task.FromResult(new ReinvocationResponse?>(_languageClient, new[] { expectedItem }))); var projectionResult = new ProjectionResult() { @@ -417,18 +433,19 @@ namespace Microsoft.VisualStudio.LanguageServerClient.Razor.HtmlCSharp }; var documentManager = new TestDocumentManager(); - documentManager.AddDocument(Uri, new TestLSPDocumentSnapshot(new Uri("C:/path/file.razor"), 0)); + documentManager.AddDocument(Uri, new TestLSPDocumentSnapshot(new Uri("C:/path/file.razor"), 0, CSharpVirtualDocumentSnapshot)); var requestInvoker = new Mock(MockBehavior.Strict); requestInvoker .Setup(r => r.ReinvokeRequestOnServerAsync?>( + TextBuffer, Methods.TextDocumentCompletionName, RazorLSPConstants.RazorCSharpLanguageServerName, It.IsAny(), It.IsAny())) - .Callback((method, _, completionParams, ct) => called = true) + .Callback((textBuffer, method, _, completionParams, ct) => called = true) .Returns(Task.FromResult( - new ReinvokeResponse?>( + new ReinvocationResponse?>( _languageClient, new CompletionList { @@ -499,17 +516,18 @@ namespace Microsoft.VisualStudio.LanguageServerClient.Razor.HtmlCSharp }; var documentManager = new TestDocumentManager(); - documentManager.AddDocument(Uri, new TestLSPDocumentSnapshot(new Uri("C:/path/file.razor"), 0)); + documentManager.AddDocument(Uri, new TestLSPDocumentSnapshot(new Uri("C:/path/file.razor"), 0, CSharpVirtualDocumentSnapshot)); var requestInvoker = new Mock(MockBehavior.Strict); requestInvoker .Setup(r => r.ReinvokeRequestOnServerAsync?>( + TextBuffer, Methods.TextDocumentCompletionName, RazorLSPConstants.RazorCSharpLanguageServerName, It.IsAny(), It.IsAny())) - .Callback((method, clientName, completionParams, ct) => called = true) - .Returns(Task.FromResult(new ReinvokeResponse?>(_languageClient, new CompletionList + .Callback((textBuffer, method, clientName, completionParams, ct) => called = true) + .Returns(Task.FromResult(new ReinvocationResponse?>(_languageClient, new CompletionList { Items = new[] { expectedItem } }))); @@ -555,18 +573,18 @@ namespace Microsoft.VisualStudio.LanguageServerClient.Razor.HtmlCSharp }; var documentManager = new TestDocumentManager(); - documentManager.AddDocument(Uri, new TestLSPDocumentSnapshot(new Uri("C:/path/file.razor"), 0)); + documentManager.AddDocument(Uri, new TestLSPDocumentSnapshot(new Uri("C:/path/file.razor"), 0, CSharpVirtualDocumentSnapshot)); var requestInvoker = new Mock(MockBehavior.Strict); requestInvoker - .Setup(r => r.ReinvokeRequestOnServerAsync?>(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) - .Callback((method, clientName, completionParams, ct) => + .Setup(r => r.ReinvokeRequestOnServerAsync?>(TextBuffer, It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) + .Callback((textBuffer, method, clientName, completionParams, ct) => { Assert.Equal(Methods.TextDocumentCompletionName, method); Assert.Equal(RazorLSPConstants.RazorCSharpLanguageServerName, clientName); called = true; }) - .Returns(Task.FromResult(new ReinvokeResponse?>(_languageClient, new CompletionList + .Returns(Task.FromResult(new ReinvocationResponse?>(_languageClient, new CompletionList { Items = new[] { expectedItem } }))); @@ -617,18 +635,18 @@ namespace Microsoft.VisualStudio.LanguageServerClient.Razor.HtmlCSharp }; var documentManager = new TestDocumentManager(); - documentManager.AddDocument(Uri, new TestLSPDocumentSnapshot(new Uri("C:/path/file.razor"), 0)); + documentManager.AddDocument(Uri, new TestLSPDocumentSnapshot(new Uri("C:/path/file.razor"), 0, CSharpVirtualDocumentSnapshot)); var requestInvoker = new Mock(MockBehavior.Strict); requestInvoker - .Setup(r => r.ReinvokeRequestOnServerAsync?>(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) - .Callback((method, clientName, completionParams, ct) => + .Setup(r => r.ReinvokeRequestOnServerAsync?>(TextBuffer, It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) + .Callback((textBuffer, method, clientName, completionParams, ct) => { Assert.Equal(Methods.TextDocumentCompletionName, method); Assert.Equal(RazorLSPConstants.RazorCSharpLanguageServerName, clientName); called = true; }) - .Returns(Task.FromResult(new ReinvokeResponse?>(_languageClient, expectedItems))); + .Returns(Task.FromResult(new ReinvocationResponse?>(_languageClient, expectedItems))); var projectionResult = new ProjectionResult() { @@ -692,7 +710,7 @@ namespace Microsoft.VisualStudio.LanguageServerClient.Razor.HtmlCSharp Position = new Position(0, 1) }; - var documentSnapshot = new TestLSPDocumentSnapshot(new Uri("C:/path/file.razor"), 0, snapshotContent: "@Da"); + var documentSnapshot = new TestLSPDocumentSnapshot(new Uri("C:/path/file.razor"), 0, snapshotContent: "@Da", CSharpVirtualDocumentSnapshot); var documentManager = new TestDocumentManager(); documentManager.AddDocument(Uri, documentSnapshot); @@ -701,14 +719,14 @@ namespace Microsoft.VisualStudio.LanguageServerClient.Razor.HtmlCSharp var navigatorSelector = BuildNavigatorSelector(wordRange); var requestInvoker = new Mock(MockBehavior.Strict); requestInvoker - .Setup(r => r.ReinvokeRequestOnServerAsync?>(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) - .Callback((method, clientName, completionParams, ct) => + .Setup(r => r.ReinvokeRequestOnServerAsync?>(TextBuffer, It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) + .Callback((textBuffer, method, clientName, completionParams, ct) => { Assert.Equal(Methods.TextDocumentCompletionName, method); Assert.Equal(RazorLSPConstants.RazorCSharpLanguageServerName, clientName); called = true; }) - .Returns(Task.FromResult(new ReinvokeResponse?>(_languageClient, expectedItems))); + .Returns(Task.FromResult(new ReinvocationResponse?>(_languageClient, expectedItems))); var projectionResult = new ProjectionResult() { @@ -768,7 +786,7 @@ namespace Microsoft.VisualStudio.LanguageServerClient.Razor.HtmlCSharp Position = new Position(0, 3) }; - var documentSnapshot = new TestLSPDocumentSnapshot(new Uri("C:/path/file.razor"), 0, snapshotContent: "@us"); + var documentSnapshot = new TestLSPDocumentSnapshot(new Uri("C:/path/file.razor"), 0, snapshotContent: "@us", CSharpVirtualDocumentSnapshot); var documentManager = new TestDocumentManager(); documentManager.AddDocument(Uri, documentSnapshot); @@ -777,14 +795,14 @@ namespace Microsoft.VisualStudio.LanguageServerClient.Razor.HtmlCSharp var navigatorSelector = BuildNavigatorSelector(wordRange); var requestInvoker = new Mock(MockBehavior.Strict); requestInvoker - .Setup(r => r.ReinvokeRequestOnServerAsync?>(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) - .Callback((method, clientName, completionParams, ct) => + .Setup(r => r.ReinvokeRequestOnServerAsync?>(TextBuffer, It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) + .Callback((textBuffer, method, clientName, completionParams, ct) => { Assert.Equal(Methods.TextDocumentCompletionName, method); Assert.Equal(RazorLSPConstants.RazorCSharpLanguageServerName, clientName); called = true; }) - .Returns(Task.FromResult(new ReinvokeResponse?>(_languageClient, Array.Empty()))); + .Returns(Task.FromResult(new ReinvocationResponse?>(_languageClient, Array.Empty()))); var projectionResult = new ProjectionResult() { @@ -838,7 +856,7 @@ namespace Microsoft.VisualStudio.LanguageServerClient.Razor.HtmlCSharp }; var documentManager = new TestDocumentManager(); - documentManager.AddDocument(Uri, new TestLSPDocumentSnapshot(new Uri("C:/path/file.razor"), 0)); + documentManager.AddDocument(Uri, new TestLSPDocumentSnapshot(new Uri("C:/path/file.razor"), 0, CSharpVirtualDocumentSnapshot)); var requestInvoker = new Mock(MockBehavior.Strict); @@ -870,7 +888,7 @@ namespace Microsoft.VisualStudio.LanguageServerClient.Razor.HtmlCSharp }; var documentManager = new TestDocumentManager(); - documentManager.AddDocument(Uri, new TestLSPDocumentSnapshot(new Uri("C:/path/file.razor"), 0)); + documentManager.AddDocument(Uri, new TestLSPDocumentSnapshot(new Uri("C:/path/file.razor"), 0, CSharpVirtualDocumentSnapshot)); var requestInvoker = new Mock(MockBehavior.Strict); @@ -904,17 +922,18 @@ namespace Microsoft.VisualStudio.LanguageServerClient.Razor.HtmlCSharp }; var documentManager = new TestDocumentManager(); - documentManager.AddDocument(Uri, new TestLSPDocumentSnapshot(new Uri("C:/path/file.razor"), 0)); + documentManager.AddDocument(Uri, new TestLSPDocumentSnapshot(new Uri("C:/path/file.razor"), 0, CSharpVirtualDocumentSnapshot)); var requestInvoker = new Mock(MockBehavior.Strict); requestInvoker .Setup(r => r.ReinvokeRequestOnServerAsync?>( + TextBuffer, Methods.TextDocumentCompletionName, RazorLSPConstants.RazorCSharpLanguageServerName, It.IsAny(), It.IsAny())) - .Callback((method, clientName, completionParams, ct) => called = true) - .Returns(Task.FromResult(new ReinvokeResponse?>(_languageClient, new[] { expectedItem }))); + .Callback((textBuffer, method, clientName, completionParams, ct) => called = true) + .Returns(Task.FromResult(new ReinvocationResponse?>(_languageClient, new[] { expectedItem }))); var projectionResult = new ProjectionResult() { @@ -949,19 +968,19 @@ namespace Microsoft.VisualStudio.LanguageServerClient.Razor.HtmlCSharp }; var documentManager = new TestDocumentManager(); - documentManager.AddDocument(Uri, new TestLSPDocumentSnapshot(new Uri("C:/path/file.razor"), 0)); + documentManager.AddDocument(Uri, new TestLSPDocumentSnapshot(new Uri("C:/path/file.razor"), 0, CSharpVirtualDocumentSnapshot)); var requestInvoker = new Mock(MockBehavior.Strict); requestInvoker - .Setup(r => r.ReinvokeRequestOnServerAsync?>(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) - .Callback((method, clientName, completionParams, ct) => + .Setup(r => r.ReinvokeRequestOnServerAsync?>(TextBuffer, It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) + .Callback((textBuffer, method, clientName, completionParams, ct) => { Assert.Equal(Methods.TextDocumentCompletionName, method); Assert.Equal(RazorLSPConstants.RazorCSharpLanguageServerName, clientName); Assert.Equal(CompletionTriggerKind.Invoked, completionParams.Context.TriggerKind); called = true; }) - .Returns(Task.FromResult(new ReinvokeResponse?>(_languageClient, new[] { expectedItem }))); + .Returns(Task.FromResult(new ReinvocationResponse?>(_languageClient, new[] { expectedItem }))); var projectionResult = new ProjectionResult() { @@ -1004,18 +1023,18 @@ namespace Microsoft.VisualStudio.LanguageServerClient.Razor.HtmlCSharp }; var documentManager = new TestDocumentManager(); - documentManager.AddDocument(Uri, new TestLSPDocumentSnapshot(new Uri("C:/path/file.razor"), 0)); + documentManager.AddDocument(Uri, new TestLSPDocumentSnapshot(new Uri("C:/path/file.razor"), 0, CSharpVirtualDocumentSnapshot)); var requestInvoker = new Mock(MockBehavior.Strict); requestInvoker - .Setup(r => r.ReinvokeRequestOnServerAsync?>(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) - .Callback((method, clientName, completionParams, ct) => + .Setup(r => r.ReinvokeRequestOnServerAsync?>(TextBuffer, It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) + .Callback((textBuffer, method, clientName, completionParams, ct) => { Assert.Equal(Methods.TextDocumentCompletionName, method); Assert.Equal(RazorLSPConstants.RazorCSharpLanguageServerName, clientName); called = true; }) - .Returns(Task.FromResult(new ReinvokeResponse?>(_languageClient, expectedItems))); + .Returns(Task.FromResult(new ReinvocationResponse?>(_languageClient, expectedItems))); var projectionResult = new ProjectionResult() { @@ -1079,7 +1098,11 @@ namespace Microsoft.VisualStudio.LanguageServerClient.Razor.HtmlCSharp Position = new Position(0, 29) }; - var documentSnapshot = new TestLSPDocumentSnapshot(new Uri("C:/path/file.razor"), 0, snapshotContent: "@{ void M() { var __x = 1; __ } }"); + var documentSnapshot = new TestLSPDocumentSnapshot( + new Uri("C:/path/file.razor"), + version: 0, + snapshotContent: "@{ void M() { var __x = 1; __ } }", + CSharpVirtualDocumentSnapshot); var documentManager = new TestDocumentManager(); documentManager.AddDocument(Uri, documentSnapshot); @@ -1088,14 +1111,14 @@ namespace Microsoft.VisualStudio.LanguageServerClient.Razor.HtmlCSharp var navigatorSelector = BuildNavigatorSelector(wordRange); var requestInvoker = new Mock(MockBehavior.Strict); requestInvoker - .Setup(r => r.ReinvokeRequestOnServerAsync?>(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) - .Callback((method, clientName, completionParams, ct) => + .Setup(r => r.ReinvokeRequestOnServerAsync?>(TextBuffer, It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) + .Callback((textBuffer, method, clientName, completionParams, ct) => { Assert.Equal(Methods.TextDocumentCompletionName, method); Assert.Equal(RazorLSPConstants.RazorCSharpLanguageServerName, clientName); called = true; }) - .Returns(Task.FromResult(new ReinvokeResponse?>(_languageClient, expectedItems))); + .Returns(Task.FromResult(new ReinvocationResponse?>(_languageClient, expectedItems))); var projectionResult = new ProjectionResult() { @@ -1135,18 +1158,18 @@ namespace Microsoft.VisualStudio.LanguageServerClient.Razor.HtmlCSharp }; var documentManager = new TestDocumentManager(); - documentManager.AddDocument(Uri, new TestLSPDocumentSnapshot(new Uri("C:/path/file.razor"), 0)); + documentManager.AddDocument(Uri, new TestLSPDocumentSnapshot(new Uri("C:/path/file.razor"), 0, HtmlVirtualDocumentSnapshot)); var requestInvoker = new Mock(MockBehavior.Strict); requestInvoker - .Setup(r => r.ReinvokeRequestOnServerAsync?>(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) - .Callback((method, clientName, completionParams, ct) => + .Setup(r => r.ReinvokeRequestOnServerAsync?>(TextBuffer, It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) + .Callback((textBuffer, method, clientName, completionParams, ct) => { Assert.Equal(Methods.TextDocumentCompletionName, method); Assert.Equal(RazorLSPConstants.HtmlLanguageServerName, clientName); called = true; }) - .Returns(Task.FromResult(new ReinvokeResponse?>(_languageClient, new[] { expectedItem }))); + .Returns(Task.FromResult(new ReinvocationResponse?>(_languageClient, new[] { expectedItem }))); var projectionResult = new ProjectionResult() { @@ -1235,18 +1258,18 @@ namespace Microsoft.VisualStudio.LanguageServerClient.Razor.HtmlCSharp }; var documentManager = new TestDocumentManager(); - documentManager.AddDocument(Uri, new TestLSPDocumentSnapshot(new Uri("C:/path/file.razor"), 0)); + documentManager.AddDocument(Uri, new TestLSPDocumentSnapshot(new Uri("C:/path/file.razor"), 0, HtmlVirtualDocumentSnapshot, CSharpVirtualDocumentSnapshot)); var requestInvoker = new Mock(MockBehavior.Strict); requestInvoker - .Setup(r => r.ReinvokeRequestOnServerAsync?>(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) - .Callback((method, clientName, completionParams, ct) => + .Setup(r => r.ReinvokeRequestOnServerAsync?>(TextBuffer, It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) + .Callback((textBuffer, method, clientName, completionParams, ct) => { Assert.Equal(Methods.TextDocumentCompletionName, method); Assert.Equal(RazorLSPConstants.RazorCSharpLanguageServerName, clientName); called = true; }) - .Returns(Task.FromResult(new ReinvokeResponse?>(_languageClient, new[] { expectedItem }))); + .Returns(Task.FromResult(new ReinvocationResponse?>(_languageClient, new[] { expectedItem }))); var projectionResult = new ProjectionResult() { @@ -1293,7 +1316,7 @@ namespace Microsoft.VisualStudio.LanguageServerClient.Razor.HtmlCSharp }; var documentManager = new TestDocumentManager(); - documentManager.AddDocument(Uri, new TestLSPDocumentSnapshot(new Uri("C:/path/file.razor"), 0)); + documentManager.AddDocument(Uri, new TestLSPDocumentSnapshot(new Uri("C:/path/file.razor"), 0, CSharpVirtualDocumentSnapshot)); var requestInvoker = new Mock(MockBehavior.Strict); @@ -1306,7 +1329,7 @@ namespace Microsoft.VisualStudio.LanguageServerClient.Razor.HtmlCSharp var completionHandler = new CompletionHandler(JoinableTaskContext, requestInvoker.Object, documentManager, projectionProvider.Object, TextStructureNavigatorSelectorService, CompletionRequestContextCache, FormattingOptionsProvider, LoggerProvider); // Act - var (succeeded, result) = await completionHandler.TryGetProvisionalCompletionsAsync(completionRequest, new TestLSPDocumentSnapshot(new Uri("C:/path/file.razor"), 0), projectionResult, CancellationToken.None).ConfigureAwait(false); + var (succeeded, result) = await completionHandler.TryGetProvisionalCompletionsAsync(completionRequest, new TestLSPDocumentSnapshot(new Uri("C:/path/file.razor"), 0, CSharpVirtualDocumentSnapshot), projectionResult, CancellationToken.None).ConfigureAwait(false); // Assert Assert.False(succeeded); @@ -1329,7 +1352,7 @@ namespace Microsoft.VisualStudio.LanguageServerClient.Razor.HtmlCSharp }; var documentManager = new TestDocumentManager(); - documentManager.AddDocument(Uri, new TestLSPDocumentSnapshot(new Uri("C:/path/file.razor"), 0)); + documentManager.AddDocument(Uri, new TestLSPDocumentSnapshot(new Uri("C:/path/file.razor"), 0, CSharpVirtualDocumentSnapshot)); var requestInvoker = new Mock(MockBehavior.Strict); @@ -1342,7 +1365,7 @@ namespace Microsoft.VisualStudio.LanguageServerClient.Razor.HtmlCSharp var completionHandler = new CompletionHandler(JoinableTaskContext, requestInvoker.Object, documentManager, projectionProvider.Object, TextStructureNavigatorSelectorService, CompletionRequestContextCache, FormattingOptionsProvider, LoggerProvider); // Act - var (succeeded, result) = await completionHandler.TryGetProvisionalCompletionsAsync(completionRequest, new TestLSPDocumentSnapshot(new Uri("C:/path/file.razor"), 0), projectionResult, CancellationToken.None).ConfigureAwait(false); + var (succeeded, result) = await completionHandler.TryGetProvisionalCompletionsAsync(completionRequest, new TestLSPDocumentSnapshot(new Uri("C:/path/file.razor"), 0, CSharpVirtualDocumentSnapshot), projectionResult, CancellationToken.None).ConfigureAwait(false); // Assert Assert.False(succeeded); @@ -1365,7 +1388,7 @@ namespace Microsoft.VisualStudio.LanguageServerClient.Razor.HtmlCSharp }; var documentManager = new TestDocumentManager(); - documentManager.AddDocument(Uri, new TestLSPDocumentSnapshot(new Uri("C:/path/file.razor"), 0)); + documentManager.AddDocument(Uri, new TestLSPDocumentSnapshot(new Uri("C:/path/file.razor"), 0, CSharpVirtualDocumentSnapshot)); var requestInvoker = new Mock(MockBehavior.Strict); @@ -1384,7 +1407,7 @@ namespace Microsoft.VisualStudio.LanguageServerClient.Razor.HtmlCSharp var completionHandler = new CompletionHandler(JoinableTaskContext, requestInvoker.Object, documentManager, projectionProvider.Object, TextStructureNavigatorSelectorService, CompletionRequestContextCache, FormattingOptionsProvider, LoggerProvider); // Act - var (succeeded, result) = await completionHandler.TryGetProvisionalCompletionsAsync(completionRequest, new TestLSPDocumentSnapshot(new Uri("C:/path/file.razor"), 0), projectionResult, CancellationToken.None).ConfigureAwait(false); + var (succeeded, result) = await completionHandler.TryGetProvisionalCompletionsAsync(completionRequest, new TestLSPDocumentSnapshot(new Uri("C:/path/file.razor"), 0, CSharpVirtualDocumentSnapshot), projectionResult, CancellationToken.None).ConfigureAwait(false); // Assert Assert.False(succeeded); @@ -1407,7 +1430,7 @@ namespace Microsoft.VisualStudio.LanguageServerClient.Razor.HtmlCSharp }; var documentManager = new TestDocumentManager(); - documentManager.AddDocument(Uri, new TestLSPDocumentSnapshot(new Uri("C:/path/file.razor"), 0)); + documentManager.AddDocument(Uri, new TestLSPDocumentSnapshot(new Uri("C:/path/file.razor"), 0, CSharpVirtualDocumentSnapshot)); var requestInvoker = new Mock(MockBehavior.Strict); @@ -1426,7 +1449,7 @@ namespace Microsoft.VisualStudio.LanguageServerClient.Razor.HtmlCSharp var completionHandler = new CompletionHandler(JoinableTaskContext, requestInvoker.Object, documentManager, projectionProvider.Object, TextStructureNavigatorSelectorService, CompletionRequestContextCache, FormattingOptionsProvider, LoggerProvider); // Act - var (succeeded, result) = await completionHandler.TryGetProvisionalCompletionsAsync(completionRequest, new TestLSPDocumentSnapshot(new Uri("C:/path/file.razor"), 0), projectionResult, CancellationToken.None).ConfigureAwait(false); + var (succeeded, result) = await completionHandler.TryGetProvisionalCompletionsAsync(completionRequest, new TestLSPDocumentSnapshot(new Uri("C:/path/file.razor"), 0, CSharpVirtualDocumentSnapshot), projectionResult, CancellationToken.None).ConfigureAwait(false); // Assert Assert.False(succeeded); @@ -1457,17 +1480,18 @@ namespace Microsoft.VisualStudio.LanguageServerClient.Razor.HtmlCSharp var requestInvoker = new Mock(MockBehavior.Strict); requestInvoker .Setup(r => r.ReinvokeRequestOnServerAsync?>( + TextBuffer, It.IsAny(), RazorLSPConstants.CSharpContentTypeName, It.IsAny(), It.IsAny())) - .Callback((method, clientName, completionParams, ct) => + .Callback((textBuffer, method, clientName, completionParams, ct) => { Assert.Equal(Methods.TextDocumentCompletionName, method); Assert.Equal(RazorLSPConstants.RazorCSharpLanguageServerName, clientName); languageServerCalled = true; }) - .Returns(Task.FromResult(new ReinvokeResponse?>(_languageClient, new[] { expectedItem }))); + .Returns(Task.FromResult(new ReinvocationResponse?>(_languageClient, new[] { expectedItem }))); var projectionResult = new ProjectionResult() { @@ -1488,7 +1512,7 @@ namespace Microsoft.VisualStudio.LanguageServerClient.Razor.HtmlCSharp var completionHandler = new CompletionHandler(JoinableTaskContext, requestInvoker.Object, documentManager, projectionProvider.Object, TextStructureNavigatorSelectorService, CompletionRequestContextCache, FormattingOptionsProvider, LoggerProvider); // Act - var (succeeded, result) = await completionHandler.TryGetProvisionalCompletionsAsync(completionRequest, new TestLSPDocumentSnapshot(new Uri("C:/path/file.razor"), 0), projectionResult, CancellationToken.None).ConfigureAwait(false); + var (succeeded, result) = await completionHandler.TryGetProvisionalCompletionsAsync(completionRequest, new TestLSPDocumentSnapshot(new Uri("C:/path/file.razor"), 0, CSharpVirtualDocumentSnapshot), projectionResult, CancellationToken.None).ConfigureAwait(false); // Assert Assert.False(succeeded); @@ -1521,17 +1545,18 @@ namespace Microsoft.VisualStudio.LanguageServerClient.Razor.HtmlCSharp var requestInvoker = new Mock(MockBehavior.Strict); requestInvoker .Setup(r => r.ReinvokeRequestOnServerAsync?>( + TextBuffer, It.IsAny(), RazorLSPConstants.RazorCSharpLanguageServerName, It.IsAny(), It.IsAny())) - .Callback((method, clientName, completionParams, ct) => + .Callback((textBuffer, method, clientName, completionParams, ct) => { Assert.Equal(Methods.TextDocumentCompletionName, method); Assert.Equal(RazorLSPConstants.RazorCSharpLanguageServerName, clientName); languageServerCalled = true; }) - .Returns(Task.FromResult(new ReinvokeResponse?>(_languageClient, new[] { expectedItem }))); + .Returns(Task.FromResult(new ReinvocationResponse?>(_languageClient, new[] { expectedItem }))); var projectionResult = new ProjectionResult() { @@ -1552,7 +1577,7 @@ namespace Microsoft.VisualStudio.LanguageServerClient.Razor.HtmlCSharp var completionHandler = new CompletionHandler(JoinableTaskContext, requestInvoker.Object, documentManager, projectionProvider.Object, TextStructureNavigatorSelectorService, CompletionRequestContextCache, FormattingOptionsProvider, LoggerProvider); // Act - var (succeeded, result) = await completionHandler.TryGetProvisionalCompletionsAsync(completionRequest, new TestLSPDocumentSnapshot(new Uri("C:/path/file.razor"), 0), projectionResult, CancellationToken.None).ConfigureAwait(false); + var (succeeded, result) = await completionHandler.TryGetProvisionalCompletionsAsync(completionRequest, new TestLSPDocumentSnapshot(new Uri("C:/path/file.razor"), 0, CSharpVirtualDocumentSnapshot), projectionResult, CancellationToken.None).ConfigureAwait(false); // Assert Assert.True(succeeded);