зеркало из https://github.com/dotnet/razor.git
Fix HTML completion race when typing too quickly
- There was a race when typing too quickly our synchronization mechanism would try and reduce the work that was done to cancel pre-existing requests. So in the scenario when you were to type `<tr` what would happen is that 3 completion requests would fire: 1. Triggered completion for `<` 2. Typing completion for `t` 3. Typing completion for `r` Now when we sped things up we were able to process requests in parallel which meant that we could handle simultaneous requests for `<`, `t` and `r` all at the same time; however, this in turn results in an interesting behavior where if we ask for completion at `r` while `<` and `t` are still active our synchronization mechanism would aggressively cancel the older requests. For completion this is catastrohpic because it would result in a 0 length completion list because HTML does not respect completion requests beyond trigger characters and the beginning of the word. - To fix this issue I added a new mechanism for synchronization which takes a flag `rejectOnNewerParallelRequest` which states do not reject a synchronization request aggressively if this flag is `true`. Now this doesn't mean the requests never get rejected. If there's a batched document update or document close / open this will still reject the document; it just means that on the requesting of synchronization that older completion requests are not rejected eagerly. - Added tests to our projection and synchronization stack to account for this - Ensured that these changes are not breaking changes so marked some bits as virtual. ### Before ![before image](https://i.imgur.com/sZfGaub.gif) ### After ![after image](https://i.imgur.com/5EsJdDm.gif) Fixes #5743
This commit is contained in:
Родитель
4be2e4ce79
Коммит
e9cd763349
|
@ -38,6 +38,9 @@ namespace Microsoft.VisualStudio.LanguageServer.ContainedLanguage
|
|||
}
|
||||
|
||||
public override Task<bool> TrySynchronizeVirtualDocumentAsync(int requiredHostDocumentVersion, VirtualDocumentSnapshot virtualDocument, CancellationToken cancellationToken)
|
||||
=> TrySynchronizeVirtualDocumentAsync(requiredHostDocumentVersion, virtualDocument, rejectOnNewerParallelRequest: true, cancellationToken);
|
||||
|
||||
public override Task<bool> TrySynchronizeVirtualDocumentAsync(int requiredHostDocumentVersion, VirtualDocumentSnapshot virtualDocument, bool rejectOnNewerParallelRequest, CancellationToken cancellationToken)
|
||||
{
|
||||
if (virtualDocument is null)
|
||||
{
|
||||
|
@ -59,7 +62,7 @@ namespace Microsoft.VisualStudio.LanguageServer.ContainedLanguage
|
|||
}
|
||||
|
||||
// Currently tracked synchronizing context is not sufficient, need to update a new one.
|
||||
var onSynchronizedTask = documentContext.GetSynchronizationTaskAsync(requiredHostDocumentVersion, cancellationToken);
|
||||
var onSynchronizedTask = documentContext.GetSynchronizationTaskAsync(requiredHostDocumentVersion, rejectOnNewerParallelRequest, cancellationToken);
|
||||
return onSynchronizedTask;
|
||||
}
|
||||
}
|
||||
|
@ -192,14 +195,15 @@ namespace Microsoft.VisualStudio.LanguageServer.ContainedLanguage
|
|||
}
|
||||
}
|
||||
|
||||
public Task<bool> GetSynchronizationTaskAsync(int requiredHostDocumentVersion, CancellationToken cancellationToken)
|
||||
public Task<bool> GetSynchronizationTaskAsync(int requiredHostDocumentVersion, bool rejectOnNewerParallelRequest, CancellationToken cancellationToken)
|
||||
{
|
||||
// Cancel any out-of-date existing synchronizing contexts.
|
||||
|
||||
for (var i = _synchronizingContexts.Count - 1; i >= 0; i--)
|
||||
{
|
||||
var context = _synchronizingContexts[i];
|
||||
if (context.RequiredHostDocumentVersion < requiredHostDocumentVersion)
|
||||
if (context.RejectOnNewerParallelRequest &&
|
||||
context.RequiredHostDocumentVersion < requiredHostDocumentVersion)
|
||||
{
|
||||
// All of the existing synchronizations that are older than this version are no longer valid.
|
||||
context.SetSynchronized(result: false);
|
||||
|
@ -207,7 +211,7 @@ namespace Microsoft.VisualStudio.LanguageServer.ContainedLanguage
|
|||
}
|
||||
}
|
||||
|
||||
var synchronizingContext = new DocumentSynchronizingContext(requiredHostDocumentVersion, _synchronizingTimeout, cancellationToken);
|
||||
var synchronizingContext = new DocumentSynchronizingContext(requiredHostDocumentVersion, rejectOnNewerParallelRequest, _synchronizingTimeout, cancellationToken);
|
||||
_synchronizingContexts.Add(synchronizingContext);
|
||||
return synchronizingContext.OnSynchronizedAsync;
|
||||
}
|
||||
|
@ -230,10 +234,12 @@ namespace Microsoft.VisualStudio.LanguageServer.ContainedLanguage
|
|||
|
||||
public DocumentSynchronizingContext(
|
||||
int requiredHostDocumentVersion,
|
||||
bool rejectOnNewerParallelRequest,
|
||||
TimeSpan timeout,
|
||||
CancellationToken requestCancellationToken)
|
||||
{
|
||||
RequiredHostDocumentVersion = requiredHostDocumentVersion;
|
||||
RejectOnNewerParallelRequest = rejectOnNewerParallelRequest;
|
||||
_onSynchronizedSource = new TaskCompletionSource<bool>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
_cts = CancellationTokenSource.CreateLinkedTokenSource(requestCancellationToken);
|
||||
|
||||
|
@ -243,6 +249,8 @@ namespace Microsoft.VisualStudio.LanguageServer.ContainedLanguage
|
|||
_cts.CancelAfter(timeout);
|
||||
}
|
||||
|
||||
public bool RejectOnNewerParallelRequest { get; }
|
||||
|
||||
public int RequiredHostDocumentVersion { get; }
|
||||
|
||||
public Task<bool> OnSynchronizedAsync => _onSynchronizedSource.Task;
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
// 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.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
|
@ -9,5 +10,21 @@ namespace Microsoft.VisualStudio.LanguageServer.ContainedLanguage
|
|||
internal abstract class LSPDocumentSynchronizer : LSPDocumentChangeListener
|
||||
{
|
||||
public abstract Task<bool> TrySynchronizeVirtualDocumentAsync(int requiredHostDocumentVersion, VirtualDocumentSnapshot virtualDocument, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to synchronize a virtual document to a corresponding host document version.
|
||||
/// </summary>
|
||||
/// <param name="requiredHostDocumentVersion">The corresponding host document version required for the generated <paramref name="virtualDocument"/></param>
|
||||
/// <param name="virtualDocument">A generated document to correlate <paramref name="requiredHostDocumentVersion"/>'s for.</param>
|
||||
/// <param name="rejectOnNewerParallelRequest">
|
||||
/// When <c>true</c> if a second synchronization request for the same virtual document comes in with a newer required host document version all pending synchronization requests will be rejected.
|
||||
/// If <c>false</c>, active synchronization requests will be fulfilled as virtul document buffers get updated. Fulfillment could be a rejection or an approval.
|
||||
/// </param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns><c>true</c> if we were able to successfully synchronize; <c>false</c> otherwise.</returns>
|
||||
public virtual Task<bool> TrySynchronizeVirtualDocumentAsync(int requiredHostDocumentVersion, VirtualDocumentSnapshot virtualDocument, bool rejectOnNewerParallelRequest, CancellationToken cancellationToken)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -147,7 +147,7 @@ namespace Microsoft.VisualStudio.LanguageServerClient.Razor.HtmlCSharp
|
|||
return null;
|
||||
}
|
||||
|
||||
var projectionResult = await _projectionProvider.GetProjectionAsync(
|
||||
var projectionResult = await _projectionProvider.GetProjectionForCompletionAsync(
|
||||
documentSnapshot,
|
||||
request.Position,
|
||||
cancellationToken).ConfigureAwait(false);
|
||||
|
@ -532,7 +532,7 @@ namespace Microsoft.VisualStudio.LanguageServerClient.Razor.HtmlCSharp
|
|||
}
|
||||
|
||||
var previousCharacterPosition = new Position(projection.Position.Line, projection.Position.Character - 1);
|
||||
var previousCharacterProjection = await _projectionProvider.GetProjectionAsync(
|
||||
var previousCharacterProjection = await _projectionProvider.GetProjectionForCompletionAsync(
|
||||
documentSnapshot,
|
||||
previousCharacterPosition,
|
||||
cancellationToken).ConfigureAwait(false);
|
||||
|
|
|
@ -61,7 +61,13 @@ namespace Microsoft.VisualStudio.LanguageServerClient.Razor.HtmlCSharp
|
|||
_loggerProvider = loggerProvider;
|
||||
}
|
||||
|
||||
public override async Task<ProjectionResult?> GetProjectionAsync(LSPDocumentSnapshot documentSnapshot, Position position, CancellationToken cancellationToken)
|
||||
public override Task<ProjectionResult?> GetProjectionAsync(LSPDocumentSnapshot documentSnapshot, Position position, CancellationToken cancellationToken)
|
||||
=> GetProjectionCoreAsync(documentSnapshot, position, rejectOnNewerParallelRequest: true, cancellationToken);
|
||||
|
||||
public override Task<ProjectionResult?> GetProjectionForCompletionAsync(LSPDocumentSnapshot documentSnapshot, Position position, CancellationToken cancellationToken)
|
||||
=> GetProjectionCoreAsync(documentSnapshot, position, rejectOnNewerParallelRequest: false, cancellationToken);
|
||||
|
||||
private async Task<ProjectionResult?> GetProjectionCoreAsync(LSPDocumentSnapshot documentSnapshot, Position position, bool rejectOnNewerParallelRequest, CancellationToken cancellationToken)
|
||||
{
|
||||
if (documentSnapshot is null)
|
||||
{
|
||||
|
@ -126,7 +132,7 @@ namespace Microsoft.VisualStudio.LanguageServerClient.Razor.HtmlCSharp
|
|||
}
|
||||
else
|
||||
{
|
||||
var synchronized = await _documentSynchronizer.TrySynchronizeVirtualDocumentAsync(documentSnapshot.Version, virtualDocument, cancellationToken).ConfigureAwait(false);
|
||||
var synchronized = await _documentSynchronizer.TrySynchronizeVirtualDocumentAsync(documentSnapshot.Version, virtualDocument, rejectOnNewerParallelRequest, cancellationToken).ConfigureAwait(false);
|
||||
if (!synchronized)
|
||||
{
|
||||
_logHubLogger.LogInformation("Could not synchronize.");
|
||||
|
|
|
@ -13,5 +13,7 @@ namespace Microsoft.VisualStudio.LanguageServerClient.Razor.HtmlCSharp
|
|||
internal abstract class LSPProjectionProvider
|
||||
{
|
||||
public abstract Task<ProjectionResult?> GetProjectionAsync(LSPDocumentSnapshot documentSnapshot, Position position, CancellationToken cancellationToken);
|
||||
|
||||
public abstract Task<ProjectionResult?> GetProjectionForCompletionAsync(LSPDocumentSnapshot documentSnapshot, Position position, CancellationToken cancellationToken);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -175,6 +175,66 @@ namespace Microsoft.VisualStudio.LanguageServer.ContainedLanguage
|
|||
Assert.True(result2);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task TrySynchronizeVirtualDocumentAsync_NewerVersionRequested_CancelsActiveRequest()
|
||||
{
|
||||
// Arrange
|
||||
var (lspDocument, virtualDocument) = CreateDocuments(lspDocumentVersion: 124, virtualDocumentSyncVersion: 123);
|
||||
var fileUriProvider = CreateUriProviderFor(VirtualDocumentTextBuffer, virtualDocument.Uri);
|
||||
var synchronizer = new DefaultLSPDocumentSynchronizer(fileUriProvider)
|
||||
{
|
||||
_synchronizationTimeout = TimeSpan.FromMilliseconds(500)
|
||||
};
|
||||
NotifyLSPDocumentAdded(lspDocument, synchronizer);
|
||||
|
||||
// Act
|
||||
|
||||
// Start synchronization, this will hang until we notify the buffer versions been updated because the above virtual document expects host doc version 123 but the host doc is 124
|
||||
var synchronizeTask1 = synchronizer.TrySynchronizeVirtualDocumentAsync(lspDocument.Version, virtualDocument, CancellationToken.None);
|
||||
var (newLSPDocument, newVirtualDocument) = CreateDocuments(lspDocumentVersion: 125, virtualDocumentSyncVersion: 124);
|
||||
var synchronizeTask2 = synchronizer.TrySynchronizeVirtualDocumentAsync(newLSPDocument.Version, newVirtualDocument, CancellationToken.None);
|
||||
|
||||
NotifyBufferVersionUpdated(VirtualDocumentTextBuffer, lspDocument.Version);
|
||||
NotifyBufferVersionUpdated(VirtualDocumentTextBuffer, newLSPDocument.Version);
|
||||
|
||||
var result1 = await synchronizeTask1.ConfigureAwait(false);
|
||||
var result2 = await synchronizeTask2.ConfigureAwait(false);
|
||||
|
||||
// Assert
|
||||
Assert.False(result1);
|
||||
Assert.True(result2);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task TrySynchronizeVirtualDocumentAsync_RejectOnNewerParallelRequest_NewerVersionRequested_CancelsActiveRequest()
|
||||
{
|
||||
// Arrange
|
||||
var (lspDocument, virtualDocument) = CreateDocuments(lspDocumentVersion: 124, virtualDocumentSyncVersion: 123);
|
||||
var fileUriProvider = CreateUriProviderFor(VirtualDocumentTextBuffer, virtualDocument.Uri);
|
||||
var synchronizer = new DefaultLSPDocumentSynchronizer(fileUriProvider)
|
||||
{
|
||||
_synchronizationTimeout = TimeSpan.FromMilliseconds(500)
|
||||
};
|
||||
NotifyLSPDocumentAdded(lspDocument, synchronizer);
|
||||
|
||||
// Act
|
||||
|
||||
// Start synchronization, this will hang until we notify the buffer versions been updated because the above virtual document expects host doc version 123 but the host doc is 124
|
||||
var synchronizeTask1 = synchronizer.TrySynchronizeVirtualDocumentAsync(lspDocument.Version, virtualDocument, rejectOnNewerParallelRequest: false, CancellationToken.None);
|
||||
var (newLSPDocument, newVirtualDocument) = CreateDocuments(lspDocumentVersion: 125, virtualDocumentSyncVersion: 124);
|
||||
var synchronizeTask2 = synchronizer.TrySynchronizeVirtualDocumentAsync(newLSPDocument.Version, newVirtualDocument, CancellationToken.None);
|
||||
|
||||
NotifyBufferVersionUpdated(VirtualDocumentTextBuffer, lspDocument.Version);
|
||||
NotifyBufferVersionUpdated(VirtualDocumentTextBuffer, newLSPDocument.Version);
|
||||
|
||||
var result1 = await synchronizeTask1.ConfigureAwait(false);
|
||||
var result2 = await synchronizeTask2.ConfigureAwait(false);
|
||||
|
||||
// Assert
|
||||
Assert.True(result1);
|
||||
Assert.True(result2);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task TrySynchronizeVirtualDocumentAsync_DocumentRemoved_CancelsActiveRequests()
|
||||
{
|
||||
|
|
|
@ -357,6 +357,9 @@ $@"public class SomeRazorFile
|
|||
|
||||
return Task.FromResult(projectionResult);
|
||||
}
|
||||
|
||||
public override Task<ProjectionResult> GetProjectionForCompletionAsync(LSPDocumentSnapshot documentSnapshot, Position position, CancellationToken cancellationToken)
|
||||
=> GetProjectionAsync(documentSnapshot, position, cancellationToken);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -262,6 +262,9 @@ $@"public class SomeRazorFile
|
|||
|
||||
return Task.FromResult(projectionResult);
|
||||
}
|
||||
|
||||
public override Task<ProjectionResult> GetProjectionForCompletionAsync(LSPDocumentSnapshot documentSnapshot, Position position, CancellationToken cancellationToken)
|
||||
=> GetProjectionAsync(documentSnapshot, position, cancellationToken);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -86,7 +86,7 @@ namespace Microsoft.VisualStudio.LanguageServerClient.Razor.HtmlCSharp
|
|||
documentManager.AddDocument(Uri, new TestLSPDocumentSnapshot(new Uri("C:/path/file.razor"), 0, CSharpVirtualDocumentSnapshot));
|
||||
var requestInvoker = Mock.Of<LSPRequestInvoker>(MockBehavior.Strict);
|
||||
var projectionProvider = new Mock<LSPProjectionProvider>(MockBehavior.Strict).Object;
|
||||
Mock.Get(projectionProvider).Setup(projectionProvider => projectionProvider.GetProjectionAsync(It.IsAny<LSPDocumentSnapshot>(), It.IsAny<Position>(), CancellationToken.None))
|
||||
Mock.Get(projectionProvider).Setup(projectionProvider => projectionProvider.GetProjectionForCompletionAsync(It.IsAny<LSPDocumentSnapshot>(), It.IsAny<Position>(), CancellationToken.None))
|
||||
.Returns(Task.FromResult<ProjectionResult>(null));
|
||||
var completionHandler = new CompletionHandler(JoinableTaskContext, requestInvoker, documentManager, projectionProvider, TextStructureNavigatorSelectorService, CompletionRequestContextCache, FormattingOptionsProvider, LoggerProvider);
|
||||
var completionRequest = new CompletionParams()
|
||||
|
@ -137,7 +137,7 @@ namespace Microsoft.VisualStudio.LanguageServerClient.Razor.HtmlCSharp
|
|||
LanguageKind = RazorLanguageKind.Html,
|
||||
};
|
||||
var projectionProvider = new Mock<LSPProjectionProvider>(MockBehavior.Strict);
|
||||
projectionProvider.Setup(p => p.GetProjectionAsync(It.IsAny<LSPDocumentSnapshot>(), It.IsAny<Position>(), It.IsAny<CancellationToken>())).Returns(Task.FromResult(projectionResult));
|
||||
projectionProvider.Setup(p => p.GetProjectionForCompletionAsync(It.IsAny<LSPDocumentSnapshot>(), It.IsAny<Position>(), It.IsAny<CancellationToken>())).Returns(Task.FromResult(projectionResult));
|
||||
|
||||
var completionHandler = new CompletionHandler(JoinableTaskContext, requestInvoker.Object, documentManager, projectionProvider.Object, TextStructureNavigatorSelectorService, CompletionRequestContextCache, FormattingOptionsProvider, LoggerProvider);
|
||||
|
||||
|
@ -175,7 +175,7 @@ namespace Microsoft.VisualStudio.LanguageServerClient.Razor.HtmlCSharp
|
|||
LanguageKind = RazorLanguageKind.Html,
|
||||
};
|
||||
var projectionProvider = new Mock<LSPProjectionProvider>(MockBehavior.Strict);
|
||||
projectionProvider.Setup(p => p.GetProjectionAsync(It.IsAny<LSPDocumentSnapshot>(), It.IsAny<Position>(), It.IsAny<CancellationToken>())).Returns(Task.FromResult(projectionResult));
|
||||
projectionProvider.Setup(p => p.GetProjectionForCompletionAsync(It.IsAny<LSPDocumentSnapshot>(), It.IsAny<Position>(), It.IsAny<CancellationToken>())).Returns(Task.FromResult(projectionResult));
|
||||
|
||||
var completionHandler = new CompletionHandler(JoinableTaskContext, requestInvoker.Object, documentManager, projectionProvider.Object, TextStructureNavigatorSelectorService, CompletionRequestContextCache, FormattingOptionsProvider, LoggerProvider);
|
||||
|
||||
|
@ -221,7 +221,7 @@ namespace Microsoft.VisualStudio.LanguageServerClient.Razor.HtmlCSharp
|
|||
LanguageKind = RazorLanguageKind.CSharp,
|
||||
};
|
||||
var projectionProvider = new Mock<LSPProjectionProvider>(MockBehavior.Strict);
|
||||
projectionProvider.Setup(p => p.GetProjectionAsync(It.IsAny<LSPDocumentSnapshot>(), It.IsAny<Position>(), It.IsAny<CancellationToken>())).Returns(Task.FromResult(projectionResult));
|
||||
projectionProvider.Setup(p => p.GetProjectionForCompletionAsync(It.IsAny<LSPDocumentSnapshot>(), It.IsAny<Position>(), It.IsAny<CancellationToken>())).Returns(Task.FromResult(projectionResult));
|
||||
|
||||
var completionHandler = new CompletionHandler(JoinableTaskContext, requestInvoker.Object, documentManager, projectionProvider.Object, TextStructureNavigatorSelectorService, CompletionRequestContextCache, FormattingOptionsProvider, LoggerProvider);
|
||||
|
||||
|
@ -272,7 +272,7 @@ namespace Microsoft.VisualStudio.LanguageServerClient.Razor.HtmlCSharp
|
|||
LanguageKind = RazorLanguageKind.CSharp,
|
||||
};
|
||||
var projectionProvider = new Mock<LSPProjectionProvider>(MockBehavior.Strict);
|
||||
projectionProvider.Setup(p => p.GetProjectionAsync(It.IsAny<LSPDocumentSnapshot>(), It.IsAny<Position>(), It.IsAny<CancellationToken>())).Returns(Task.FromResult(projectionResult));
|
||||
projectionProvider.Setup(p => p.GetProjectionForCompletionAsync(It.IsAny<LSPDocumentSnapshot>(), It.IsAny<Position>(), It.IsAny<CancellationToken>())).Returns(Task.FromResult(projectionResult));
|
||||
|
||||
var completionHandler = new CompletionHandler(JoinableTaskContext, requestInvoker.Object, documentManager, projectionProvider.Object, TextStructureNavigatorSelectorService, CompletionRequestContextCache, FormattingOptionsProvider, LoggerProvider);
|
||||
|
||||
|
@ -352,7 +352,7 @@ namespace Microsoft.VisualStudio.LanguageServerClient.Razor.HtmlCSharp
|
|||
LanguageKind = RazorLanguageKind.CSharp,
|
||||
};
|
||||
var projectionProvider = new Mock<LSPProjectionProvider>(MockBehavior.Strict);
|
||||
projectionProvider.Setup(p => p.GetProjectionAsync(It.IsAny<LSPDocumentSnapshot>(), It.IsAny<Position>(), It.IsAny<CancellationToken>())).Returns(Task.FromResult(projectionResult));
|
||||
projectionProvider.Setup(p => p.GetProjectionForCompletionAsync(It.IsAny<LSPDocumentSnapshot>(), It.IsAny<Position>(), It.IsAny<CancellationToken>())).Returns(Task.FromResult(projectionResult));
|
||||
|
||||
var completionHandler = new CompletionHandler(JoinableTaskContext, requestInvoker.Object, documentManager, projectionProvider.Object, TextStructureNavigatorSelectorService, CompletionRequestContextCache, FormattingOptionsProvider, LoggerProvider);
|
||||
|
||||
|
@ -409,7 +409,7 @@ namespace Microsoft.VisualStudio.LanguageServerClient.Razor.HtmlCSharp
|
|||
LanguageKind = RazorLanguageKind.CSharp,
|
||||
};
|
||||
var projectionProvider = new Mock<LSPProjectionProvider>(MockBehavior.Strict);
|
||||
projectionProvider.Setup(p => p.GetProjectionAsync(It.IsAny<LSPDocumentSnapshot>(), It.IsAny<Position>(), It.IsAny<CancellationToken>())).Returns(Task.FromResult(projectionResult));
|
||||
projectionProvider.Setup(p => p.GetProjectionForCompletionAsync(It.IsAny<LSPDocumentSnapshot>(), It.IsAny<Position>(), It.IsAny<CancellationToken>())).Returns(Task.FromResult(projectionResult));
|
||||
|
||||
var completionHandler = new CompletionHandler(JoinableTaskContext, requestInvoker.Object, documentManager, projectionProvider.Object, TextStructureNavigatorSelectorService, CompletionRequestContextCache, FormattingOptionsProvider, LoggerProvider);
|
||||
|
||||
|
@ -468,7 +468,7 @@ namespace Microsoft.VisualStudio.LanguageServerClient.Razor.HtmlCSharp
|
|||
LanguageKind = RazorLanguageKind.CSharp,
|
||||
};
|
||||
var projectionProvider = new Mock<LSPProjectionProvider>(MockBehavior.Strict);
|
||||
projectionProvider.Setup(p => p.GetProjectionAsync(It.IsAny<LSPDocumentSnapshot>(), It.IsAny<Position>(), It.IsAny<CancellationToken>())).Returns(Task.FromResult(projectionResult));
|
||||
projectionProvider.Setup(p => p.GetProjectionForCompletionAsync(It.IsAny<LSPDocumentSnapshot>(), It.IsAny<Position>(), It.IsAny<CancellationToken>())).Returns(Task.FromResult(projectionResult));
|
||||
|
||||
var completionHandler = new CompletionHandler(JoinableTaskContext, requestInvoker.Object, documentManager, projectionProvider.Object, TextStructureNavigatorSelectorService, CompletionRequestContextCache, FormattingOptionsProvider, LoggerProvider);
|
||||
|
||||
|
@ -548,7 +548,7 @@ namespace Microsoft.VisualStudio.LanguageServerClient.Razor.HtmlCSharp
|
|||
LanguageKind = RazorLanguageKind.CSharp,
|
||||
};
|
||||
var projectionProvider = new Mock<LSPProjectionProvider>(MockBehavior.Strict);
|
||||
projectionProvider.Setup(p => p.GetProjectionAsync(It.IsAny<LSPDocumentSnapshot>(), It.IsAny<Position>(), It.IsAny<CancellationToken>())).Returns(Task.FromResult(projectionResult));
|
||||
projectionProvider.Setup(p => p.GetProjectionForCompletionAsync(It.IsAny<LSPDocumentSnapshot>(), It.IsAny<Position>(), It.IsAny<CancellationToken>())).Returns(Task.FromResult(projectionResult));
|
||||
|
||||
var completionHandler = new CompletionHandler(JoinableTaskContext, requestInvoker.Object, documentManager, projectionProvider.Object, navigatorSelector, CompletionRequestContextCache, FormattingOptionsProvider, LoggerProvider);
|
||||
|
||||
|
@ -624,7 +624,7 @@ namespace Microsoft.VisualStudio.LanguageServerClient.Razor.HtmlCSharp
|
|||
LanguageKind = RazorLanguageKind.CSharp,
|
||||
};
|
||||
var projectionProvider = new Mock<LSPProjectionProvider>(MockBehavior.Strict);
|
||||
projectionProvider.Setup(p => p.GetProjectionAsync(It.IsAny<LSPDocumentSnapshot>(), It.IsAny<Position>(), It.IsAny<CancellationToken>())).Returns(Task.FromResult(projectionResult));
|
||||
projectionProvider.Setup(p => p.GetProjectionForCompletionAsync(It.IsAny<LSPDocumentSnapshot>(), It.IsAny<Position>(), It.IsAny<CancellationToken>())).Returns(Task.FromResult(projectionResult));
|
||||
|
||||
var completionHandler = new CompletionHandler(JoinableTaskContext, requestInvoker.Object, documentManager, projectionProvider.Object, navigatorSelector, CompletionRequestContextCache, FormattingOptionsProvider, LoggerProvider);
|
||||
|
||||
|
@ -680,7 +680,7 @@ namespace Microsoft.VisualStudio.LanguageServerClient.Razor.HtmlCSharp
|
|||
LanguageKind = RazorLanguageKind.Html,
|
||||
};
|
||||
var projectionProvider = new Mock<LSPProjectionProvider>(MockBehavior.Strict);
|
||||
projectionProvider.Setup(p => p.GetProjectionAsync(It.IsAny<LSPDocumentSnapshot>(), It.IsAny<Position>(), It.IsAny<CancellationToken>())).Returns(Task.FromResult(projectionResult));
|
||||
projectionProvider.Setup(p => p.GetProjectionForCompletionAsync(It.IsAny<LSPDocumentSnapshot>(), It.IsAny<Position>(), It.IsAny<CancellationToken>())).Returns(Task.FromResult(projectionResult));
|
||||
|
||||
var completionHandler = new CompletionHandler(JoinableTaskContext, requestInvoker.Object, documentManager, projectionProvider.Object, TextStructureNavigatorSelectorService, CompletionRequestContextCache, FormattingOptionsProvider, LoggerProvider);
|
||||
|
||||
|
@ -712,7 +712,7 @@ namespace Microsoft.VisualStudio.LanguageServerClient.Razor.HtmlCSharp
|
|||
LanguageKind = RazorLanguageKind.CSharp,
|
||||
};
|
||||
var projectionProvider = new Mock<LSPProjectionProvider>(MockBehavior.Strict);
|
||||
projectionProvider.Setup(p => p.GetProjectionAsync(It.IsAny<LSPDocumentSnapshot>(), It.IsAny<Position>(), It.IsAny<CancellationToken>())).Returns(Task.FromResult(projectionResult));
|
||||
projectionProvider.Setup(p => p.GetProjectionForCompletionAsync(It.IsAny<LSPDocumentSnapshot>(), It.IsAny<Position>(), It.IsAny<CancellationToken>())).Returns(Task.FromResult(projectionResult));
|
||||
|
||||
var completionHandler = new CompletionHandler(JoinableTaskContext, requestInvoker.Object, documentManager, projectionProvider.Object, TextStructureNavigatorSelectorService, CompletionRequestContextCache, FormattingOptionsProvider, LoggerProvider);
|
||||
|
||||
|
@ -755,7 +755,7 @@ namespace Microsoft.VisualStudio.LanguageServerClient.Razor.HtmlCSharp
|
|||
LanguageKind = RazorLanguageKind.CSharp,
|
||||
};
|
||||
var projectionProvider = new Mock<LSPProjectionProvider>(MockBehavior.Strict);
|
||||
projectionProvider.Setup(p => p.GetProjectionAsync(It.IsAny<LSPDocumentSnapshot>(), It.IsAny<Position>(), It.IsAny<CancellationToken>())).Returns(Task.FromResult(projectionResult));
|
||||
projectionProvider.Setup(p => p.GetProjectionForCompletionAsync(It.IsAny<LSPDocumentSnapshot>(), It.IsAny<Position>(), It.IsAny<CancellationToken>())).Returns(Task.FromResult(projectionResult));
|
||||
|
||||
var completionHandler = new CompletionHandler(JoinableTaskContext, requestInvoker.Object, documentManager, projectionProvider.Object, TextStructureNavigatorSelectorService, CompletionRequestContextCache, FormattingOptionsProvider, LoggerProvider);
|
||||
|
||||
|
@ -802,7 +802,7 @@ namespace Microsoft.VisualStudio.LanguageServerClient.Razor.HtmlCSharp
|
|||
LanguageKind = RazorLanguageKind.CSharp,
|
||||
};
|
||||
var projectionProvider = new Mock<LSPProjectionProvider>(MockBehavior.Strict);
|
||||
projectionProvider.Setup(p => p.GetProjectionAsync(It.IsAny<LSPDocumentSnapshot>(), It.IsAny<Position>(), It.IsAny<CancellationToken>())).Returns(Task.FromResult(projectionResult));
|
||||
projectionProvider.Setup(p => p.GetProjectionForCompletionAsync(It.IsAny<LSPDocumentSnapshot>(), It.IsAny<Position>(), It.IsAny<CancellationToken>())).Returns(Task.FromResult(projectionResult));
|
||||
|
||||
var completionHandler = new CompletionHandler(JoinableTaskContext, requestInvoker.Object, documentManager, projectionProvider.Object, TextStructureNavigatorSelectorService, CompletionRequestContextCache, FormattingOptionsProvider, LoggerProvider);
|
||||
|
||||
|
@ -856,7 +856,7 @@ namespace Microsoft.VisualStudio.LanguageServerClient.Razor.HtmlCSharp
|
|||
LanguageKind = RazorLanguageKind.CSharp,
|
||||
};
|
||||
var projectionProvider = new Mock<LSPProjectionProvider>(MockBehavior.Strict);
|
||||
projectionProvider.Setup(p => p.GetProjectionAsync(It.IsAny<LSPDocumentSnapshot>(), It.IsAny<Position>(), It.IsAny<CancellationToken>())).Returns(Task.FromResult(projectionResult));
|
||||
projectionProvider.Setup(p => p.GetProjectionForCompletionAsync(It.IsAny<LSPDocumentSnapshot>(), It.IsAny<Position>(), It.IsAny<CancellationToken>())).Returns(Task.FromResult(projectionResult));
|
||||
|
||||
var completionHandler = new CompletionHandler(JoinableTaskContext, requestInvoker.Object, documentManager, projectionProvider.Object, TextStructureNavigatorSelectorService, CompletionRequestContextCache, FormattingOptionsProvider, LoggerProvider);
|
||||
|
||||
|
@ -940,7 +940,7 @@ namespace Microsoft.VisualStudio.LanguageServerClient.Razor.HtmlCSharp
|
|||
LanguageKind = RazorLanguageKind.CSharp,
|
||||
};
|
||||
var projectionProvider = new Mock<LSPProjectionProvider>(MockBehavior.Strict);
|
||||
projectionProvider.Setup(p => p.GetProjectionAsync(It.IsAny<LSPDocumentSnapshot>(), It.IsAny<Position>(), It.IsAny<CancellationToken>())).Returns(Task.FromResult(projectionResult));
|
||||
projectionProvider.Setup(p => p.GetProjectionForCompletionAsync(It.IsAny<LSPDocumentSnapshot>(), It.IsAny<Position>(), It.IsAny<CancellationToken>())).Returns(Task.FromResult(projectionResult));
|
||||
|
||||
var completionHandler = new CompletionHandler(JoinableTaskContext, requestInvoker.Object, documentManager, projectionProvider.Object, navigatorSelector, CompletionRequestContextCache, FormattingOptionsProvider, LoggerProvider);
|
||||
|
||||
|
@ -991,7 +991,7 @@ namespace Microsoft.VisualStudio.LanguageServerClient.Razor.HtmlCSharp
|
|||
LanguageKind = RazorLanguageKind.Html,
|
||||
};
|
||||
var projectionProvider = new Mock<LSPProjectionProvider>(MockBehavior.Strict);
|
||||
projectionProvider.Setup(p => p.GetProjectionAsync(It.IsAny<LSPDocumentSnapshot>(), It.IsAny<Position>(), It.IsAny<CancellationToken>())).Returns(Task.FromResult(projectionResult));
|
||||
projectionProvider.Setup(p => p.GetProjectionForCompletionAsync(It.IsAny<LSPDocumentSnapshot>(), It.IsAny<Position>(), It.IsAny<CancellationToken>())).Returns(Task.FromResult(projectionResult));
|
||||
|
||||
var completionHandler = new CompletionHandler(JoinableTaskContext, requestInvoker.Object, documentManager, projectionProvider.Object, TextStructureNavigatorSelectorService, CompletionRequestContextCache, FormattingOptionsProvider, LoggerProvider);
|
||||
|
||||
|
@ -1101,8 +1101,8 @@ namespace Microsoft.VisualStudio.LanguageServerClient.Razor.HtmlCSharp
|
|||
HostDocumentVersion = 1,
|
||||
};
|
||||
var projectionProvider = new Mock<LSPProjectionProvider>(MockBehavior.Strict);
|
||||
projectionProvider.Setup(p => p.GetProjectionAsync(It.IsAny<LSPDocumentSnapshot>(), new Position(1, 6), It.IsAny<CancellationToken>())).Returns(Task.FromResult(previousCharacterProjection));
|
||||
projectionProvider.Setup(p => p.GetProjectionAsync(It.IsAny<LSPDocumentSnapshot>(), completionRequest.Position, It.IsAny<CancellationToken>())).Returns(Task.FromResult(projectionResult));
|
||||
projectionProvider.Setup(p => p.GetProjectionForCompletionAsync(It.IsAny<LSPDocumentSnapshot>(), new Position(1, 6), It.IsAny<CancellationToken>())).Returns(Task.FromResult(previousCharacterProjection));
|
||||
projectionProvider.Setup(p => p.GetProjectionForCompletionAsync(It.IsAny<LSPDocumentSnapshot>(), completionRequest.Position, It.IsAny<CancellationToken>())).Returns(Task.FromResult(projectionResult));
|
||||
|
||||
var completionHandler = new CompletionHandler(JoinableTaskContext, requestInvoker.Object, documentManager, projectionProvider.Object, TextStructureNavigatorSelectorService, CompletionRequestContextCache, FormattingOptionsProvider, LoggerProvider);
|
||||
|
||||
|
@ -1202,7 +1202,7 @@ namespace Microsoft.VisualStudio.LanguageServerClient.Razor.HtmlCSharp
|
|||
HostDocumentVersion = 1,
|
||||
};
|
||||
var projectionProvider = new Mock<LSPProjectionProvider>(MockBehavior.Strict);
|
||||
projectionProvider.Setup(p => p.GetProjectionAsync(It.IsAny<LSPDocumentSnapshot>(), It.IsAny<Position>(), It.IsAny<CancellationToken>())).Returns(Task.FromResult(previousCharacterProjection));
|
||||
projectionProvider.Setup(p => p.GetProjectionForCompletionAsync(It.IsAny<LSPDocumentSnapshot>(), It.IsAny<Position>(), It.IsAny<CancellationToken>())).Returns(Task.FromResult(previousCharacterProjection));
|
||||
|
||||
var completionHandler = new CompletionHandler(JoinableTaskContext, requestInvoker.Object, documentManager, projectionProvider.Object, TextStructureNavigatorSelectorService, CompletionRequestContextCache, FormattingOptionsProvider, LoggerProvider);
|
||||
|
||||
|
@ -1282,7 +1282,7 @@ namespace Microsoft.VisualStudio.LanguageServerClient.Razor.HtmlCSharp
|
|||
LanguageKind = RazorLanguageKind.Html,
|
||||
};
|
||||
var projectionProvider = new Mock<LSPProjectionProvider>(MockBehavior.Strict);
|
||||
projectionProvider.Setup(p => p.GetProjectionAsync(It.IsAny<LSPDocumentSnapshot>(), It.IsAny<Position>(), It.IsAny<CancellationToken>())).Returns(Task.FromResult(previousCharacterProjection));
|
||||
projectionProvider.Setup(p => p.GetProjectionForCompletionAsync(It.IsAny<LSPDocumentSnapshot>(), It.IsAny<Position>(), It.IsAny<CancellationToken>())).Returns(Task.FromResult(previousCharacterProjection));
|
||||
|
||||
var completionHandler = new CompletionHandler(JoinableTaskContext, requestInvoker.Object, documentManager, projectionProvider.Object, TextStructureNavigatorSelectorService, CompletionRequestContextCache, FormattingOptionsProvider, LoggerProvider);
|
||||
|
||||
|
@ -1324,7 +1324,7 @@ namespace Microsoft.VisualStudio.LanguageServerClient.Razor.HtmlCSharp
|
|||
LanguageKind = RazorLanguageKind.CSharp,
|
||||
};
|
||||
var projectionProvider = new Mock<LSPProjectionProvider>(MockBehavior.Strict);
|
||||
projectionProvider.Setup(p => p.GetProjectionAsync(It.IsAny<LSPDocumentSnapshot>(), It.IsAny<Position>(), It.IsAny<CancellationToken>())).Returns(Task.FromResult(previousCharacterProjection));
|
||||
projectionProvider.Setup(p => p.GetProjectionForCompletionAsync(It.IsAny<LSPDocumentSnapshot>(), It.IsAny<Position>(), It.IsAny<CancellationToken>())).Returns(Task.FromResult(previousCharacterProjection));
|
||||
|
||||
var completionHandler = new CompletionHandler(JoinableTaskContext, requestInvoker.Object, documentManager, projectionProvider.Object, TextStructureNavigatorSelectorService, CompletionRequestContextCache, FormattingOptionsProvider, LoggerProvider);
|
||||
|
||||
|
@ -1387,7 +1387,7 @@ namespace Microsoft.VisualStudio.LanguageServerClient.Razor.HtmlCSharp
|
|||
HostDocumentVersion = null,
|
||||
};
|
||||
var projectionProvider = new Mock<LSPProjectionProvider>(MockBehavior.Strict);
|
||||
projectionProvider.Setup(p => p.GetProjectionAsync(It.IsAny<LSPDocumentSnapshot>(), It.IsAny<Position>(), It.IsAny<CancellationToken>())).Returns(Task.FromResult(previousCharacterProjection));
|
||||
projectionProvider.Setup(p => p.GetProjectionForCompletionAsync(It.IsAny<LSPDocumentSnapshot>(), It.IsAny<Position>(), It.IsAny<CancellationToken>())).Returns(Task.FromResult(previousCharacterProjection));
|
||||
|
||||
var completionHandler = new CompletionHandler(JoinableTaskContext, requestInvoker.Object, documentManager, projectionProvider.Object, TextStructureNavigatorSelectorService, CompletionRequestContextCache, FormattingOptionsProvider, LoggerProvider);
|
||||
|
||||
|
@ -1452,7 +1452,7 @@ namespace Microsoft.VisualStudio.LanguageServerClient.Razor.HtmlCSharp
|
|||
HostDocumentVersion = 1,
|
||||
};
|
||||
var projectionProvider = new Mock<LSPProjectionProvider>(MockBehavior.Strict);
|
||||
projectionProvider.Setup(p => p.GetProjectionAsync(It.IsAny<LSPDocumentSnapshot>(), It.IsAny<Position>(), It.IsAny<CancellationToken>())).Returns(Task.FromResult(previousCharacterProjection));
|
||||
projectionProvider.Setup(p => p.GetProjectionForCompletionAsync(It.IsAny<LSPDocumentSnapshot>(), It.IsAny<Position>(), It.IsAny<CancellationToken>())).Returns(Task.FromResult(previousCharacterProjection));
|
||||
|
||||
var completionHandler = new CompletionHandler(JoinableTaskContext, requestInvoker.Object, documentManager, projectionProvider.Object, TextStructureNavigatorSelectorService, CompletionRequestContextCache, FormattingOptionsProvider, LoggerProvider);
|
||||
|
||||
|
|
|
@ -88,7 +88,7 @@ namespace Microsoft.VisualStudio.LanguageServerClient.Razor.HtmlCSharp
|
|||
|
||||
var documentSynchronizer = new Mock<LSPDocumentSynchronizer>(MockBehavior.Strict);
|
||||
documentSynchronizer
|
||||
.Setup(d => d.TrySynchronizeVirtualDocumentAsync(DocumentSnapshot.Version, HtmlVirtualDocumentSnapshot, It.IsAny<CancellationToken>()))
|
||||
.Setup(d => d.TrySynchronizeVirtualDocumentAsync(DocumentSnapshot.Version, HtmlVirtualDocumentSnapshot, true, It.IsAny<CancellationToken>()))
|
||||
.Returns(Task.FromResult(true));
|
||||
|
||||
var projectionProvider = new DefaultLSPProjectionProvider(requestInvoker.Object, documentSynchronizer.Object, Mock.Of<RazorLogger>(MockBehavior.Strict), LoggerProvider);
|
||||
|
@ -127,7 +127,7 @@ namespace Microsoft.VisualStudio.LanguageServerClient.Razor.HtmlCSharp
|
|||
|
||||
var documentSynchronizer = new Mock<LSPDocumentSynchronizer>(MockBehavior.Strict);
|
||||
documentSynchronizer
|
||||
.Setup(d => d.TrySynchronizeVirtualDocumentAsync(DocumentSnapshot.Version, CSharpVirtualDocumentSnapshot, It.IsAny<CancellationToken>()))
|
||||
.Setup(d => d.TrySynchronizeVirtualDocumentAsync(DocumentSnapshot.Version, CSharpVirtualDocumentSnapshot, true, It.IsAny<CancellationToken>()))
|
||||
.Returns(Task.FromResult(true));
|
||||
|
||||
var projectionProvider = new DefaultLSPProjectionProvider(requestInvoker.Object, documentSynchronizer.Object, Mock.Of<RazorLogger>(MockBehavior.Strict), LoggerProvider);
|
||||
|
@ -166,7 +166,7 @@ namespace Microsoft.VisualStudio.LanguageServerClient.Razor.HtmlCSharp
|
|||
|
||||
var documentSynchronizer = new Mock<LSPDocumentSynchronizer>(MockBehavior.Strict);
|
||||
documentSynchronizer
|
||||
.Setup(d => d.TrySynchronizeVirtualDocumentAsync(DocumentSnapshot.Version, HtmlVirtualDocumentSnapshot, It.IsAny<CancellationToken>()))
|
||||
.Setup(d => d.TrySynchronizeVirtualDocumentAsync(DocumentSnapshot.Version, HtmlVirtualDocumentSnapshot, true, It.IsAny<CancellationToken>()))
|
||||
.Returns(Task.FromResult(true));
|
||||
|
||||
var logger = new Mock<RazorLogger>(MockBehavior.Strict);
|
||||
|
@ -183,6 +183,45 @@ namespace Microsoft.VisualStudio.LanguageServerClient.Razor.HtmlCSharp
|
|||
Assert.Equal(expectedPosition, result.Position);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task GetProjectionForCompletionAsync_CSharpProjection_ReturnsProjection()
|
||||
{
|
||||
// Arrange
|
||||
var expectedPosition = new Position(0, 0);
|
||||
var response = new RazorLanguageQueryResponse()
|
||||
{
|
||||
Kind = RazorLanguageKind.CSharp,
|
||||
HostDocumentVersion = 1,
|
||||
Position = new Position(expectedPosition.Line, expectedPosition.Character)
|
||||
};
|
||||
var requestInvoker = new Mock<LSPRequestInvoker>(MockBehavior.Strict);
|
||||
requestInvoker
|
||||
.Setup(r => r.ReinvokeRequestOnServerAsync<RazorLanguageQueryParams, RazorLanguageQueryResponse>(
|
||||
It.IsAny<ITextBuffer>(),
|
||||
It.IsAny<string>(),
|
||||
RazorLSPConstants.RazorLanguageServerName,
|
||||
It.IsAny<Func<JToken, bool>>(),
|
||||
It.IsAny<RazorLanguageQueryParams>(),
|
||||
It.IsAny<CancellationToken>()))
|
||||
.Returns(Task.FromResult(new ReinvocationResponse<RazorLanguageQueryResponse>("LanguageClient", response)));
|
||||
|
||||
var documentSynchronizer = new Mock<LSPDocumentSynchronizer>(MockBehavior.Strict);
|
||||
documentSynchronizer
|
||||
.Setup(d => d.TrySynchronizeVirtualDocumentAsync(DocumentSnapshot.Version, CSharpVirtualDocumentSnapshot, false, It.IsAny<CancellationToken>()))
|
||||
.Returns(Task.FromResult(true));
|
||||
|
||||
var projectionProvider = new DefaultLSPProjectionProvider(requestInvoker.Object, documentSynchronizer.Object, Mock.Of<RazorLogger>(MockBehavior.Strict), LoggerProvider);
|
||||
|
||||
// Act
|
||||
var result = await projectionProvider.GetProjectionForCompletionAsync(DocumentSnapshot, new Position(), CancellationToken.None).ConfigureAwait(false);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(result);
|
||||
Assert.Equal(CSharpVirtualDocumentSnapshot.Uri, result.Uri);
|
||||
Assert.Equal(RazorLanguageKind.CSharp, result.LanguageKind);
|
||||
Assert.Equal(expectedPosition, result.Position);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task GetProjectionAsync_SynchronizationFails_ReturnsNull()
|
||||
{
|
||||
|
@ -207,7 +246,7 @@ namespace Microsoft.VisualStudio.LanguageServerClient.Razor.HtmlCSharp
|
|||
|
||||
var documentSynchronizer = new Mock<LSPDocumentSynchronizer>(MockBehavior.Strict);
|
||||
documentSynchronizer
|
||||
.Setup(d => d.TrySynchronizeVirtualDocumentAsync(DocumentSnapshot.Version, CSharpVirtualDocumentSnapshot, It.IsAny<CancellationToken>()))
|
||||
.Setup(d => d.TrySynchronizeVirtualDocumentAsync(DocumentSnapshot.Version, CSharpVirtualDocumentSnapshot, true, It.IsAny<CancellationToken>()))
|
||||
.Returns(Task.FromResult(false));
|
||||
|
||||
var projectionProvider = new DefaultLSPProjectionProvider(requestInvoker.Object, documentSynchronizer.Object, Mock.Of<RazorLogger>(MockBehavior.Strict), LoggerProvider);
|
||||
|
|
Загрузка…
Ссылка в новой задаче