зеркало из https://github.com/dotnet/razor.git
Simplified provisional completion implementation (#1749)
This commit is contained in:
Родитель
4c8dbd0beb
Коммит
43850ca22f
|
@ -3,7 +3,6 @@
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
|
||||||
using Microsoft.CodeAnalysis.Text;
|
using Microsoft.CodeAnalysis.Text;
|
||||||
using Microsoft.VisualStudio.Text;
|
using Microsoft.VisualStudio.Text;
|
||||||
|
|
||||||
|
@ -12,11 +11,8 @@ namespace Microsoft.VisualStudio.LanguageServerClient.Razor
|
||||||
internal class CSharpVirtualDocument : VirtualDocument
|
internal class CSharpVirtualDocument : VirtualDocument
|
||||||
{
|
{
|
||||||
private long? _hostDocumentSyncVersion;
|
private long? _hostDocumentSyncVersion;
|
||||||
private CSharpVirtualDocumentSnapshot _previousSnapshot;
|
|
||||||
private CSharpVirtualDocumentSnapshot _currentSnapshot;
|
private CSharpVirtualDocumentSnapshot _currentSnapshot;
|
||||||
|
|
||||||
private bool _hasProvisionalChanges = false;
|
|
||||||
|
|
||||||
public CSharpVirtualDocument(Uri uri, ITextBuffer textBuffer)
|
public CSharpVirtualDocument(Uri uri, ITextBuffer textBuffer)
|
||||||
{
|
{
|
||||||
if (uri is null)
|
if (uri is null)
|
||||||
|
@ -31,7 +27,6 @@ namespace Microsoft.VisualStudio.LanguageServerClient.Razor
|
||||||
|
|
||||||
Uri = uri;
|
Uri = uri;
|
||||||
TextBuffer = textBuffer;
|
TextBuffer = textBuffer;
|
||||||
_previousSnapshot = null;
|
|
||||||
_currentSnapshot = UpdateSnapshot();
|
_currentSnapshot = UpdateSnapshot();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,7 +38,7 @@ namespace Microsoft.VisualStudio.LanguageServerClient.Razor
|
||||||
|
|
||||||
public override VirtualDocumentSnapshot CurrentSnapshot => _currentSnapshot;
|
public override VirtualDocumentSnapshot CurrentSnapshot => _currentSnapshot;
|
||||||
|
|
||||||
public override VirtualDocumentSnapshot Update(IReadOnlyList<TextChange> changes, long hostDocumentVersion, bool provisional = false)
|
public override VirtualDocumentSnapshot Update(IReadOnlyList<TextChange> changes, long hostDocumentVersion)
|
||||||
{
|
{
|
||||||
if (changes is null)
|
if (changes is null)
|
||||||
{
|
{
|
||||||
|
@ -52,16 +47,13 @@ namespace Microsoft.VisualStudio.LanguageServerClient.Razor
|
||||||
|
|
||||||
_hostDocumentSyncVersion = hostDocumentVersion;
|
_hostDocumentSyncVersion = hostDocumentVersion;
|
||||||
|
|
||||||
TryRevertProvisionalChanges();
|
|
||||||
_hasProvisionalChanges = provisional;
|
|
||||||
|
|
||||||
if (changes.Count == 0)
|
if (changes.Count == 0)
|
||||||
{
|
{
|
||||||
_currentSnapshot = UpdateSnapshot();
|
_currentSnapshot = UpdateSnapshot();
|
||||||
return _currentSnapshot;
|
return _currentSnapshot;
|
||||||
}
|
}
|
||||||
|
|
||||||
using var edit = TextBuffer.CreateEdit();
|
using var edit = TextBuffer.CreateEdit(EditOptions.None, reiteratedVersionNumber: null, InviolableEditTag.Instance);
|
||||||
for (var i = 0; i < changes.Count; i++)
|
for (var i = 0; i < changes.Count; i++)
|
||||||
{
|
{
|
||||||
var change = changes[i];
|
var change = changes[i];
|
||||||
|
@ -90,42 +82,6 @@ namespace Microsoft.VisualStudio.LanguageServerClient.Razor
|
||||||
return _currentSnapshot;
|
return _currentSnapshot;
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool TryRevertProvisionalChanges()
|
private CSharpVirtualDocumentSnapshot UpdateSnapshot() => new CSharpVirtualDocumentSnapshot(Uri, TextBuffer.CurrentSnapshot, HostDocumentSyncVersion);
|
||||||
{
|
|
||||||
if (!_hasProvisionalChanges)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
Debug.Assert(_previousSnapshot != null);
|
|
||||||
|
|
||||||
using var revertEdit = TextBuffer.CreateEdit(EditOptions.None, _previousSnapshot.Snapshot.Version.VersionNumber, InviolableEditTag.Instance);
|
|
||||||
var previousChanges = _previousSnapshot.Snapshot.Version.Changes;
|
|
||||||
for (var i = 0; i < previousChanges.Count; i++)
|
|
||||||
{
|
|
||||||
var change = previousChanges[i];
|
|
||||||
revertEdit.Replace(change.NewSpan, change.OldText);
|
|
||||||
}
|
|
||||||
|
|
||||||
revertEdit.Apply();
|
|
||||||
|
|
||||||
_hasProvisionalChanges = false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private CSharpVirtualDocumentSnapshot UpdateSnapshot()
|
|
||||||
{
|
|
||||||
_previousSnapshot = _currentSnapshot;
|
|
||||||
return new CSharpVirtualDocumentSnapshot(Uri, TextBuffer.CurrentSnapshot, HostDocumentSyncVersion);
|
|
||||||
}
|
|
||||||
|
|
||||||
// This indicates that no other entity should respond to the edit event associated with this tag.
|
|
||||||
private class InviolableEditTag : IInviolableEditTag
|
|
||||||
{
|
|
||||||
private InviolableEditTag() { }
|
|
||||||
|
|
||||||
public readonly static IInviolableEditTag Instance = new InviolableEditTag();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,14 +58,14 @@ namespace Microsoft.VisualStudio.LanguageServerClient.Razor
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override LSPDocumentSnapshot UpdateVirtualDocument<TVirtualDocument>(IReadOnlyList<TextChange> changes, long hostDocumentVersion, bool provisional = false)
|
public override LSPDocumentSnapshot UpdateVirtualDocument<TVirtualDocument>(IReadOnlyList<TextChange> changes, long hostDocumentVersion)
|
||||||
{
|
{
|
||||||
if (!TryGetVirtualDocument<TVirtualDocument>(out var virtualDocument))
|
if (!TryGetVirtualDocument<TVirtualDocument>(out var virtualDocument))
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException($"Cannot update virtual document of type {typeof(TVirtualDocument)} because LSP document {Uri} does not contain a virtual document of that type.");
|
throw new InvalidOperationException($"Cannot update virtual document of type {typeof(TVirtualDocument)} because LSP document {Uri} does not contain a virtual document of that type.");
|
||||||
}
|
}
|
||||||
|
|
||||||
virtualDocument.Update(changes, hostDocumentVersion, provisional);
|
virtualDocument.Update(changes, hostDocumentVersion);
|
||||||
|
|
||||||
_currentSnapshot = UpdateSnapshot();
|
_currentSnapshot = UpdateSnapshot();
|
||||||
|
|
||||||
|
|
|
@ -101,8 +101,7 @@ namespace Microsoft.VisualStudio.LanguageServerClient.Razor
|
||||||
public override void UpdateVirtualDocument<TVirtualDocument>(
|
public override void UpdateVirtualDocument<TVirtualDocument>(
|
||||||
Uri hostDocumentUri,
|
Uri hostDocumentUri,
|
||||||
IReadOnlyList<TextChange> changes,
|
IReadOnlyList<TextChange> changes,
|
||||||
long hostDocumentVersion,
|
long hostDocumentVersion)
|
||||||
bool provisional = false)
|
|
||||||
{
|
{
|
||||||
if (hostDocumentUri is null)
|
if (hostDocumentUri is null)
|
||||||
{
|
{
|
||||||
|
@ -133,7 +132,7 @@ namespace Microsoft.VisualStudio.LanguageServerClient.Razor
|
||||||
|
|
||||||
var old = lspDocument.CurrentSnapshot;
|
var old = lspDocument.CurrentSnapshot;
|
||||||
var oldVirtual = virtualDocument.CurrentSnapshot;
|
var oldVirtual = virtualDocument.CurrentSnapshot;
|
||||||
var @new = lspDocument.UpdateVirtualDocument<TVirtualDocument>(changes, hostDocumentVersion, provisional);
|
var @new = lspDocument.UpdateVirtualDocument<TVirtualDocument>(changes, hostDocumentVersion);
|
||||||
|
|
||||||
if (old == @new)
|
if (old == @new)
|
||||||
{
|
{
|
||||||
|
|
|
@ -78,37 +78,40 @@ namespace Microsoft.VisualStudio.LanguageServerClient.Razor.HtmlCSharp
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
var completionParams = new CompletionParams()
|
|
||||||
{
|
|
||||||
Context = request.Context,
|
|
||||||
Position = projectionResult.Position,
|
|
||||||
TextDocument = new TextDocumentIdentifier()
|
|
||||||
{
|
|
||||||
Uri = projectionResult.Uri
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
var serverKind = projectionResult.LanguageKind == RazorLanguageKind.CSharp ? LanguageServerKind.CSharp : LanguageServerKind.Html;
|
var serverKind = projectionResult.LanguageKind == RazorLanguageKind.CSharp ? LanguageServerKind.CSharp : LanguageServerKind.Html;
|
||||||
|
|
||||||
var provisionalCompletionParams = await GetProvisionalCompletionParamsAsync(request, documentSnapshot, projectionResult, cancellationToken).ConfigureAwait(false);
|
var (succeeded, result) = await TryGetProvisionalCompletionsAsync(request, documentSnapshot, projectionResult, cancellationToken).ConfigureAwait(false);
|
||||||
if (provisionalCompletionParams != null)
|
if (succeeded)
|
||||||
{
|
{
|
||||||
// This means the user has just typed a dot after some identifier such as (cursor is pipe): "DateTime.| "
|
// This means the user has just typed a dot after some identifier such as (cursor is pipe): "DateTime.| "
|
||||||
// In this case Razor interprets after the dot as Html and before it as C#.
|
// In this case Razor interprets after the dot as Html and before it as C#.
|
||||||
// We use this criteria to provide a better completion experience for what we call provisional changes.
|
// We use this criteria to provide a better completion experience for what we call provisional changes.
|
||||||
completionParams = provisionalCompletionParams;
|
|
||||||
serverKind = LanguageServerKind.CSharp;
|
|
||||||
}
|
}
|
||||||
else if (!TriggerAppliesToProjection(request.Context, projectionResult.LanguageKind))
|
else if (!TriggerAppliesToProjection(request.Context, projectionResult.LanguageKind))
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// This is a valid non-provisional completion request.
|
||||||
|
var completionParams = new CompletionParams()
|
||||||
|
{
|
||||||
|
Context = request.Context,
|
||||||
|
Position = projectionResult.Position,
|
||||||
|
TextDocument = new TextDocumentIdentifier()
|
||||||
|
{
|
||||||
|
Uri = projectionResult.Uri
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
var result = await _requestInvoker.RequestServerAsync<CompletionParams, SumType<CompletionItem[], CompletionList>?>(
|
result = await _requestInvoker.RequestServerAsync<CompletionParams, SumType<CompletionItem[], CompletionList>?>(
|
||||||
Methods.TextDocumentCompletionName,
|
Methods.TextDocumentCompletionName,
|
||||||
serverKind,
|
serverKind,
|
||||||
completionParams,
|
completionParams,
|
||||||
cancellationToken).ConfigureAwait(false);
|
cancellationToken).ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
|
||||||
if (result.HasValue)
|
if (result.HasValue)
|
||||||
{
|
{
|
||||||
|
@ -119,43 +122,43 @@ namespace Microsoft.VisualStudio.LanguageServerClient.Razor.HtmlCSharp
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal async Task<CompletionParams> GetProvisionalCompletionParamsAsync(CompletionParams request, LSPDocumentSnapshot documentSnapshot, ProjectionResult projection, CancellationToken cancellationToken)
|
internal async Task<(bool, SumType<CompletionItem[], CompletionList>?)> TryGetProvisionalCompletionsAsync(CompletionParams request, LSPDocumentSnapshot documentSnapshot, ProjectionResult projection, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
|
SumType<CompletionItem[], CompletionList>? result = null;
|
||||||
if (projection.LanguageKind != RazorLanguageKind.Html ||
|
if (projection.LanguageKind != RazorLanguageKind.Html ||
|
||||||
request.Context.TriggerKind != CompletionTriggerKind.TriggerCharacter ||
|
request.Context.TriggerKind != CompletionTriggerKind.TriggerCharacter ||
|
||||||
request.Context.TriggerCharacter != ".")
|
request.Context.TriggerCharacter != ".")
|
||||||
{
|
{
|
||||||
return null;
|
return (false, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (projection.Position.Character == 0)
|
if (projection.Position.Character == 0)
|
||||||
{
|
{
|
||||||
// We're at the start of line. Can't have provisional completions here.
|
// We're at the start of line. Can't have provisional completions here.
|
||||||
return null;
|
return (false, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
var previousCharacterPosition = new Position(projection.Position.Line, projection.Position.Character - 1);
|
var previousCharacterPosition = new Position(projection.Position.Line, projection.Position.Character - 1);
|
||||||
var previousCharacterProjection = await _projectionProvider.GetProjectionAsync(documentSnapshot, previousCharacterPosition, cancellationToken).ConfigureAwait(false);
|
var previousCharacterProjection = await _projectionProvider.GetProjectionAsync(documentSnapshot, previousCharacterPosition, cancellationToken).ConfigureAwait(false);
|
||||||
if (previousCharacterProjection == null || previousCharacterProjection.LanguageKind != RazorLanguageKind.CSharp)
|
if (previousCharacterProjection == null || previousCharacterProjection.LanguageKind != RazorLanguageKind.CSharp)
|
||||||
{
|
{
|
||||||
return null;
|
return (false, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(_documentManager is TrackingLSPDocumentManager trackingDocumentManager))
|
if (!(_documentManager is TrackingLSPDocumentManager trackingDocumentManager))
|
||||||
{
|
{
|
||||||
return null;
|
return (false, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Edit the CSharp projected document to contain a '.'. This allows C# completion to provide valid
|
// Edit the CSharp projected document to contain a '.'. This allows C# completion to provide valid
|
||||||
// completion items for moments when a user has typed a '.' that's typically interpreted as Html.
|
// completion items for moments when a user has typed a '.' that's typically interpreted as Html.
|
||||||
var changes = new[]
|
var addProvisionalDot = new TextChange(
|
||||||
{
|
TextSpan.FromBounds(previousCharacterProjection.PositionIndex, previousCharacterProjection.PositionIndex),
|
||||||
new TextChange(TextSpan.FromBounds(previousCharacterProjection.PositionIndex, previousCharacterProjection.PositionIndex), "."),
|
".");
|
||||||
};
|
|
||||||
|
|
||||||
await _joinableTaskFactory.SwitchToMainThreadAsync();
|
await _joinableTaskFactory.SwitchToMainThreadAsync();
|
||||||
|
|
||||||
trackingDocumentManager.UpdateVirtualDocument<CSharpVirtualDocument>(documentSnapshot.Uri, changes, previousCharacterProjection.HostDocumentVersion, provisional: true);
|
trackingDocumentManager.UpdateVirtualDocument<CSharpVirtualDocument>(documentSnapshot.Uri, new[] { addProvisionalDot }, previousCharacterProjection.HostDocumentVersion);
|
||||||
|
|
||||||
var provisionalCompletionParams = new CompletionParams()
|
var provisionalCompletionParams = new CompletionParams()
|
||||||
{
|
{
|
||||||
|
@ -164,7 +167,20 @@ namespace Microsoft.VisualStudio.LanguageServerClient.Razor.HtmlCSharp
|
||||||
TextDocument = new TextDocumentIdentifier() { Uri = previousCharacterProjection.Uri }
|
TextDocument = new TextDocumentIdentifier() { Uri = previousCharacterProjection.Uri }
|
||||||
};
|
};
|
||||||
|
|
||||||
return provisionalCompletionParams;
|
result = await _requestInvoker.RequestServerAsync<CompletionParams, SumType<CompletionItem[], CompletionList>?>(
|
||||||
|
Methods.TextDocumentCompletionName,
|
||||||
|
LanguageServerKind.CSharp,
|
||||||
|
provisionalCompletionParams,
|
||||||
|
cancellationToken).ConfigureAwait(true);
|
||||||
|
|
||||||
|
// We have now obtained the necessary completion items. We no longer need the provisional change. Revert.
|
||||||
|
var removeProvisionalDot = new TextChange(
|
||||||
|
TextSpan.FromBounds(previousCharacterProjection.PositionIndex, previousCharacterProjection.PositionIndex + 1),
|
||||||
|
string.Empty);
|
||||||
|
|
||||||
|
trackingDocumentManager.UpdateVirtualDocument<CSharpVirtualDocument>(documentSnapshot.Uri, new[] { removeProvisionalDot }, previousCharacterProjection.HostDocumentVersion);
|
||||||
|
|
||||||
|
return (true, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Internal for testing
|
// Internal for testing
|
||||||
|
|
|
@ -38,7 +38,7 @@ namespace Microsoft.VisualStudio.LanguageServerClient.Razor
|
||||||
|
|
||||||
public override VirtualDocumentSnapshot CurrentSnapshot => _currentSnapshot;
|
public override VirtualDocumentSnapshot CurrentSnapshot => _currentSnapshot;
|
||||||
|
|
||||||
public override VirtualDocumentSnapshot Update(IReadOnlyList<TextChange> changes, long hostDocumentVersion, bool provisional = false)
|
public override VirtualDocumentSnapshot Update(IReadOnlyList<TextChange> changes, long hostDocumentVersion)
|
||||||
{
|
{
|
||||||
if (changes is null)
|
if (changes is null)
|
||||||
{
|
{
|
||||||
|
@ -53,7 +53,7 @@ namespace Microsoft.VisualStudio.LanguageServerClient.Razor
|
||||||
return _currentSnapshot;
|
return _currentSnapshot;
|
||||||
}
|
}
|
||||||
|
|
||||||
using var edit = TextBuffer.CreateEdit();
|
using var edit = TextBuffer.CreateEdit(EditOptions.None, reiteratedVersionNumber: null, InviolableEditTag.Instance);
|
||||||
for (var i = 0; i < changes.Count; i++)
|
for (var i = 0; i < changes.Count; i++)
|
||||||
{
|
{
|
||||||
var change = changes[i];
|
var change = changes[i];
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
// Copyright (c) .NET Foundation. All rights reserved.
|
||||||
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
using Microsoft.VisualStudio.Text;
|
||||||
|
|
||||||
|
namespace Microsoft.VisualStudio.LanguageServerClient.Razor
|
||||||
|
{
|
||||||
|
// Used to indicate that no other entity should respond to the edit event associated with this tag.
|
||||||
|
internal class InviolableEditTag : IInviolableEditTag
|
||||||
|
{
|
||||||
|
private InviolableEditTag() { }
|
||||||
|
|
||||||
|
public readonly static IInviolableEditTag Instance = new InviolableEditTag();
|
||||||
|
}
|
||||||
|
}
|
|
@ -20,7 +20,7 @@ namespace Microsoft.VisualStudio.LanguageServerClient.Razor
|
||||||
|
|
||||||
public abstract IReadOnlyList<VirtualDocument> VirtualDocuments { get; }
|
public abstract IReadOnlyList<VirtualDocument> VirtualDocuments { get; }
|
||||||
|
|
||||||
public abstract LSPDocumentSnapshot UpdateVirtualDocument<TVirtualDocument>(IReadOnlyList<TextChange> changes, long hostDocumentVersion, bool provisional = false) where TVirtualDocument : VirtualDocument;
|
public abstract LSPDocumentSnapshot UpdateVirtualDocument<TVirtualDocument>(IReadOnlyList<TextChange> changes, long hostDocumentVersion) where TVirtualDocument : VirtualDocument;
|
||||||
|
|
||||||
public bool TryGetVirtualDocument<TVirtualDocument>(out TVirtualDocument virtualDocument) where TVirtualDocument : VirtualDocument
|
public bool TryGetVirtualDocument<TVirtualDocument>(out TVirtualDocument virtualDocument) where TVirtualDocument : VirtualDocument
|
||||||
{
|
{
|
||||||
|
|
|
@ -17,7 +17,6 @@ namespace Microsoft.VisualStudio.LanguageServerClient.Razor
|
||||||
public abstract void UpdateVirtualDocument<TVirtualDocument>(
|
public abstract void UpdateVirtualDocument<TVirtualDocument>(
|
||||||
Uri hostDocumentUri,
|
Uri hostDocumentUri,
|
||||||
IReadOnlyList<TextChange> changes,
|
IReadOnlyList<TextChange> changes,
|
||||||
long hostDocumentVersion,
|
long hostDocumentVersion) where TVirtualDocument : VirtualDocument;
|
||||||
bool provisional = false) where TVirtualDocument : VirtualDocument;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,6 @@ namespace Microsoft.VisualStudio.LanguageServerClient.Razor
|
||||||
|
|
||||||
public abstract long? HostDocumentSyncVersion { get; }
|
public abstract long? HostDocumentSyncVersion { get; }
|
||||||
|
|
||||||
public abstract VirtualDocumentSnapshot Update(IReadOnlyList<TextChange> changes, long hostDocumentVersion, bool provisional = false);
|
public abstract VirtualDocumentSnapshot Update(IReadOnlyList<TextChange> changes, long hostDocumentVersion);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -119,7 +119,7 @@ namespace Microsoft.VisualStudio.LanguageServerClient.Razor
|
||||||
edit.Setup(e => e.Replace(replace.Span.Start, replace.Span.Length, replace.NewText));
|
edit.Setup(e => e.Replace(replace.Span.Start, replace.Span.Length, replace.NewText));
|
||||||
var textBuffer = new Mock<ITextBuffer>();
|
var textBuffer = new Mock<ITextBuffer>();
|
||||||
var textBufferSnapshot = Mock.Of<ITextSnapshot>();
|
var textBufferSnapshot = Mock.Of<ITextSnapshot>();
|
||||||
textBuffer.Setup(buffer => buffer.CreateEdit())
|
textBuffer.Setup(buffer => buffer.CreateEdit(EditOptions.None, null, It.IsAny<IInviolableEditTag>()))
|
||||||
.Returns(edit.Object);
|
.Returns(edit.Object);
|
||||||
textBuffer.Setup(buffer => buffer.CurrentSnapshot)
|
textBuffer.Setup(buffer => buffer.CurrentSnapshot)
|
||||||
.Returns(() => textBufferSnapshot);
|
.Returns(() => textBufferSnapshot);
|
||||||
|
@ -138,55 +138,9 @@ namespace Microsoft.VisualStudio.LanguageServerClient.Razor
|
||||||
Assert.Same(editedSnapshot, document.CurrentSnapshot.Snapshot);
|
Assert.Same(editedSnapshot, document.CurrentSnapshot.Snapshot);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
public static ITextBuffer CreateTextBuffer(ITextEdit edit)
|
||||||
public void Update_Provisional_AppliesAndRevertsProvisionalChanges()
|
|
||||||
{
|
{
|
||||||
// Arrange
|
var textBuffer = Mock.Of<ITextBuffer>(buffer => buffer.CreateEdit(EditOptions.None, null, It.IsAny<IInviolableEditTag>()) == edit && buffer.CurrentSnapshot == Mock.Of<ITextSnapshot>());
|
||||||
var insert = new TextChange(new TextSpan(123, 0), ".");
|
|
||||||
var edit = new Mock<ITextEdit>();
|
|
||||||
edit.Setup(e => e.Insert(insert.Span.Start, insert.NewText)).Verifiable();
|
|
||||||
edit.Setup(e => e.Apply()).Verifiable();
|
|
||||||
|
|
||||||
var revertEdit = new Mock<ITextEdit>();
|
|
||||||
revertEdit.Setup(e => e.Replace(new Span(123, 1), string.Empty)).Verifiable();
|
|
||||||
revertEdit.Setup(e => e.Apply()).Verifiable();
|
|
||||||
|
|
||||||
var textBuffer = CreateTextBuffer(edit.Object, revertEdit.Object, new[] { insert });
|
|
||||||
var document = new CSharpVirtualDocument(Uri, textBuffer);
|
|
||||||
|
|
||||||
// Make a provisional edit followed by another edit.
|
|
||||||
|
|
||||||
// Act 1
|
|
||||||
document.Update(new[] { insert }, hostDocumentVersion: 1, provisional: true);
|
|
||||||
|
|
||||||
// Assert 1
|
|
||||||
edit.VerifyAll();
|
|
||||||
|
|
||||||
// Act 2
|
|
||||||
document.Update(new[] { new TextChange(new TextSpan(125, 0), "Some other edit") }, hostDocumentVersion: 2, provisional: false);
|
|
||||||
|
|
||||||
// Assert 2
|
|
||||||
revertEdit.VerifyAll();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static ITextBuffer CreateTextBuffer(ITextEdit edit, ITextEdit revertEdit = null, TextChange[] provisionalChanges = null)
|
|
||||||
{
|
|
||||||
var changes = new TestTextChangeCollection();
|
|
||||||
if (provisionalChanges != null)
|
|
||||||
{
|
|
||||||
foreach (var provisionalChange in provisionalChanges)
|
|
||||||
{
|
|
||||||
var change = new Mock<ITextChange>();
|
|
||||||
change.SetupGet(c => c.NewSpan).Returns(new Span(provisionalChange.Span.Start, provisionalChange.NewText.Length));
|
|
||||||
change.SetupGet(c => c.OldText).Returns(string.Empty);
|
|
||||||
changes.Add(change.Object);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var textBuffer = Mock.Of<ITextBuffer>(
|
|
||||||
buffer => buffer.CreateEdit() == edit &&
|
|
||||||
buffer.CreateEdit(EditOptions.None, It.IsAny<int?>(), It.IsAny<IInviolableEditTag>()) == revertEdit &&
|
|
||||||
buffer.CurrentSnapshot == Mock.Of<ITextSnapshot>(s => s.Version.Changes == changes));
|
|
||||||
return textBuffer;
|
return textBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,7 @@ namespace Microsoft.VisualStudio.LanguageServerClient.Razor
|
||||||
document.Uri == Uri &&
|
document.Uri == Uri &&
|
||||||
document.CurrentSnapshot == LSPDocumentSnapshot &&
|
document.CurrentSnapshot == LSPDocumentSnapshot &&
|
||||||
document.VirtualDocuments == new[] { new TestVirtualDocument() } &&
|
document.VirtualDocuments == new[] { new TestVirtualDocument() } &&
|
||||||
document.UpdateVirtualDocument<TestVirtualDocument>(It.IsAny<IReadOnlyList<TextChange>>(), It.IsAny<long>(), It.IsAny<bool>()) == Mock.Of<LSPDocumentSnapshot>());
|
document.UpdateVirtualDocument<TestVirtualDocument>(It.IsAny<IReadOnlyList<TextChange>>(), It.IsAny<long>()) == Mock.Of<LSPDocumentSnapshot>());
|
||||||
LSPDocumentFactory = Mock.Of<LSPDocumentFactory>(factory => factory.Create(TextBuffer) == LSPDocument);
|
LSPDocumentFactory = Mock.Of<LSPDocumentFactory>(factory => factory.Create(TextBuffer) == LSPDocument);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -146,7 +146,7 @@ namespace Microsoft.VisualStudio.LanguageServerClient.Razor
|
||||||
var changes = new[] { new TextChange(new TextSpan(1, 1), string.Empty) };
|
var changes = new[] { new TextChange(new TextSpan(1, 1), string.Empty) };
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
manager.UpdateVirtualDocument<TestVirtualDocument>(Uri, changes, 123, provisional: true);
|
manager.UpdateVirtualDocument<TestVirtualDocument>(Uri, changes, 123);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.True(changedCalled);
|
Assert.True(changedCalled);
|
||||||
|
@ -207,7 +207,7 @@ namespace Microsoft.VisualStudio.LanguageServerClient.Razor
|
||||||
|
|
||||||
public override long? HostDocumentSyncVersion => 123;
|
public override long? HostDocumentSyncVersion => 123;
|
||||||
|
|
||||||
public override VirtualDocumentSnapshot Update(IReadOnlyList<TextChange> changes, long hostDocumentVersion, bool provisional)
|
public override VirtualDocumentSnapshot Update(IReadOnlyList<TextChange> changes, long hostDocumentVersion)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,12 +31,11 @@ namespace Microsoft.VisualStudio.LanguageServerClient.Razor
|
||||||
var originalSnapshot = document.CurrentSnapshot;
|
var originalSnapshot = document.CurrentSnapshot;
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
document.UpdateVirtualDocument<TestVirtualDocument>(changes, hostDocumentVersion: 1337, provisional: true);
|
document.UpdateVirtualDocument<TestVirtualDocument>(changes, hostDocumentVersion: 1337);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.Equal(1337, virtualDocument.HostDocumentSyncVersion);
|
Assert.Equal(1337, virtualDocument.HostDocumentSyncVersion);
|
||||||
Assert.Same(changes, virtualDocument.Changes);
|
Assert.Same(changes, virtualDocument.Changes);
|
||||||
Assert.True(virtualDocument.Provisional);
|
|
||||||
Assert.NotEqual(originalSnapshot, document.CurrentSnapshot);
|
Assert.NotEqual(originalSnapshot, document.CurrentSnapshot);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,8 +45,6 @@ namespace Microsoft.VisualStudio.LanguageServerClient.Razor
|
||||||
|
|
||||||
public IReadOnlyList<TextChange> Changes { get; private set; }
|
public IReadOnlyList<TextChange> Changes { get; private set; }
|
||||||
|
|
||||||
public bool Provisional { get; private set; }
|
|
||||||
|
|
||||||
public override Uri Uri => throw new NotImplementedException();
|
public override Uri Uri => throw new NotImplementedException();
|
||||||
|
|
||||||
public override ITextBuffer TextBuffer => throw new NotImplementedException();
|
public override ITextBuffer TextBuffer => throw new NotImplementedException();
|
||||||
|
@ -56,11 +53,10 @@ namespace Microsoft.VisualStudio.LanguageServerClient.Razor
|
||||||
|
|
||||||
public override long? HostDocumentSyncVersion => _hostDocumentVersion;
|
public override long? HostDocumentSyncVersion => _hostDocumentVersion;
|
||||||
|
|
||||||
public override VirtualDocumentSnapshot Update(IReadOnlyList<TextChange> changes, long hostDocumentVersion, bool provisional)
|
public override VirtualDocumentSnapshot Update(IReadOnlyList<TextChange> changes, long hostDocumentVersion)
|
||||||
{
|
{
|
||||||
_hostDocumentVersion = hostDocumentVersion;
|
_hostDocumentVersion = hostDocumentVersion;
|
||||||
Changes = changes;
|
Changes = changes;
|
||||||
Provisional = provisional;
|
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,7 +53,7 @@ namespace Microsoft.VisualStudio.LanguageServerClient.Razor
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var documentManager = new Mock<TrackingLSPDocumentManager>();
|
var documentManager = new Mock<TrackingLSPDocumentManager>();
|
||||||
documentManager.Setup(manager => manager.UpdateVirtualDocument<CSharpVirtualDocument>(It.IsAny<Uri>(), It.IsAny<IReadOnlyList<TextChange>>(), 1337, false /* UpdateCSharpBuffer request should never be provisional */))
|
documentManager.Setup(manager => manager.UpdateVirtualDocument<CSharpVirtualDocument>(It.IsAny<Uri>(), It.IsAny<IReadOnlyList<TextChange>>(), 1337))
|
||||||
.Verifiable();
|
.Verifiable();
|
||||||
var target = new DefaultRazorLanguageServerCustomMessageTarget(documentManager.Object);
|
var target = new DefaultRazorLanguageServerCustomMessageTarget(documentManager.Object);
|
||||||
var request = new UpdateBufferRequest()
|
var request = new UpdateBufferRequest()
|
||||||
|
|
|
@ -343,7 +343,7 @@ namespace Microsoft.VisualStudio.LanguageServerClient.Razor.HtmlCSharp
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task GetProvisionalCompletionParamsAsync_CSharpProjection_ReturnsNull()
|
public async Task TryGetProvisionalCompletionsAsync_CSharpProjection_ReturnsFalse()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var completionRequest = new CompletionParams()
|
var completionRequest = new CompletionParams()
|
||||||
|
@ -371,14 +371,15 @@ namespace Microsoft.VisualStudio.LanguageServerClient.Razor.HtmlCSharp
|
||||||
var completionHandler = new CompletionHandler(JoinableTaskContext, requestInvoker.Object, documentManager, projectionProvider.Object);
|
var completionHandler = new CompletionHandler(JoinableTaskContext, requestInvoker.Object, documentManager, projectionProvider.Object);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var result = await completionHandler.GetProvisionalCompletionParamsAsync(completionRequest, Mock.Of<LSPDocumentSnapshot>(), projectionResult, CancellationToken.None).ConfigureAwait(false);
|
var (succeeded, result) = await completionHandler.TryGetProvisionalCompletionsAsync(completionRequest, Mock.Of<LSPDocumentSnapshot>(), projectionResult, CancellationToken.None).ConfigureAwait(false);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
|
Assert.False(succeeded);
|
||||||
Assert.Null(result);
|
Assert.Null(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task GetProvisionalCompletionParamsAsync_TriggerCharacterNotDot_ReturnsNull()
|
public async Task TryGetProvisionalCompletionsAsync_TriggerCharacterNotDot_ReturnsFalse()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var completionRequest = new CompletionParams()
|
var completionRequest = new CompletionParams()
|
||||||
|
@ -406,14 +407,15 @@ namespace Microsoft.VisualStudio.LanguageServerClient.Razor.HtmlCSharp
|
||||||
var completionHandler = new CompletionHandler(JoinableTaskContext, requestInvoker.Object, documentManager, projectionProvider.Object);
|
var completionHandler = new CompletionHandler(JoinableTaskContext, requestInvoker.Object, documentManager, projectionProvider.Object);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var result = await completionHandler.GetProvisionalCompletionParamsAsync(completionRequest, Mock.Of<LSPDocumentSnapshot>(), projectionResult, CancellationToken.None).ConfigureAwait(false);
|
var (succeeded, result) = await completionHandler.TryGetProvisionalCompletionsAsync(completionRequest, Mock.Of<LSPDocumentSnapshot>(), projectionResult, CancellationToken.None).ConfigureAwait(false);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
|
Assert.False(succeeded);
|
||||||
Assert.Null(result);
|
Assert.Null(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task GetProvisionalCompletionParamsAsync_PreviousCharacterHtml_ReturnsNull()
|
public async Task TryGetProvisionalCompletionsAsync_PreviousCharacterHtml_ReturnsFalse()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var completionRequest = new CompletionParams()
|
var completionRequest = new CompletionParams()
|
||||||
|
@ -447,14 +449,15 @@ namespace Microsoft.VisualStudio.LanguageServerClient.Razor.HtmlCSharp
|
||||||
var completionHandler = new CompletionHandler(JoinableTaskContext, requestInvoker.Object, documentManager, projectionProvider.Object);
|
var completionHandler = new CompletionHandler(JoinableTaskContext, requestInvoker.Object, documentManager, projectionProvider.Object);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var result = await completionHandler.GetProvisionalCompletionParamsAsync(completionRequest, Mock.Of<LSPDocumentSnapshot>(), projectionResult, CancellationToken.None).ConfigureAwait(false);
|
var (succeeded, result) = await completionHandler.TryGetProvisionalCompletionsAsync(completionRequest, Mock.Of<LSPDocumentSnapshot>(), projectionResult, CancellationToken.None).ConfigureAwait(false);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
|
Assert.False(succeeded);
|
||||||
Assert.Null(result);
|
Assert.Null(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task GetProvisionalCompletionParamsAsync_ProjectionAtStartOfLine_ReturnsNull()
|
public async Task TryGetProvisionalCompletionsAsync_ProjectionAtStartOfLine_ReturnsFalse()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var completionRequest = new CompletionParams()
|
var completionRequest = new CompletionParams()
|
||||||
|
@ -488,14 +491,15 @@ namespace Microsoft.VisualStudio.LanguageServerClient.Razor.HtmlCSharp
|
||||||
var completionHandler = new CompletionHandler(JoinableTaskContext, requestInvoker.Object, documentManager, projectionProvider.Object);
|
var completionHandler = new CompletionHandler(JoinableTaskContext, requestInvoker.Object, documentManager, projectionProvider.Object);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var result = await completionHandler.GetProvisionalCompletionParamsAsync(completionRequest, Mock.Of<LSPDocumentSnapshot>(), projectionResult, CancellationToken.None).ConfigureAwait(false);
|
var (succeeded, result) = await completionHandler.TryGetProvisionalCompletionsAsync(completionRequest, Mock.Of<LSPDocumentSnapshot>(), projectionResult, CancellationToken.None).ConfigureAwait(false);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
|
Assert.False(succeeded);
|
||||||
Assert.Null(result);
|
Assert.Null(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task GetProvisionalCompletionParamsAsync_AtCorrectProvisionalCompletionPoint_ReturnsCorrectParams()
|
public async Task TryGetProvisionalCompletionsAsync_AtCorrectProvisionalCompletionPoint_ReturnsExpectedResult()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var completionRequest = new CompletionParams()
|
var completionRequest = new CompletionParams()
|
||||||
|
@ -513,7 +517,18 @@ namespace Microsoft.VisualStudio.LanguageServerClient.Razor.HtmlCSharp
|
||||||
|
|
||||||
var documentManager = new TestDocumentManager();
|
var documentManager = new TestDocumentManager();
|
||||||
|
|
||||||
var requestInvoker = new Mock<LSPRequestInvoker>();
|
var languageServerCalled = false;
|
||||||
|
var expectedItem = new CompletionItem() { InsertText = "DateTime" };
|
||||||
|
var requestInvoker = new Mock<LSPRequestInvoker>(MockBehavior.Strict);
|
||||||
|
requestInvoker
|
||||||
|
.Setup(r => r.RequestServerAsync<CompletionParams, SumType<CompletionItem[], CompletionList>?>(It.IsAny<string>(), LanguageServerKind.CSharp, It.IsAny<CompletionParams>(), It.IsAny<CancellationToken>()))
|
||||||
|
.Callback<string, LanguageServerKind, CompletionParams, CancellationToken>((method, serverKind, completionParams, ct) =>
|
||||||
|
{
|
||||||
|
Assert.Equal(Methods.TextDocumentCompletionName, method);
|
||||||
|
Assert.Equal(LanguageServerKind.CSharp, serverKind);
|
||||||
|
languageServerCalled = true;
|
||||||
|
})
|
||||||
|
.Returns(Task.FromResult<SumType<CompletionItem[], CompletionList>?>(new[] { expectedItem }));
|
||||||
|
|
||||||
var projectionResult = new ProjectionResult()
|
var projectionResult = new ProjectionResult()
|
||||||
{
|
{
|
||||||
|
@ -533,15 +548,15 @@ namespace Microsoft.VisualStudio.LanguageServerClient.Razor.HtmlCSharp
|
||||||
var completionHandler = new CompletionHandler(JoinableTaskContext, requestInvoker.Object, documentManager, projectionProvider.Object);
|
var completionHandler = new CompletionHandler(JoinableTaskContext, requestInvoker.Object, documentManager, projectionProvider.Object);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var result = await completionHandler.GetProvisionalCompletionParamsAsync(completionRequest, Mock.Of<LSPDocumentSnapshot>(), projectionResult, CancellationToken.None).ConfigureAwait(false);
|
var (succeeded, result) = await completionHandler.TryGetProvisionalCompletionsAsync(completionRequest, Mock.Of<LSPDocumentSnapshot>(), projectionResult, CancellationToken.None).ConfigureAwait(false);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.True(documentManager.UpdateVirtualDocumentCalled);
|
Assert.True(succeeded);
|
||||||
|
Assert.True(languageServerCalled);
|
||||||
|
Assert.Equal(2, documentManager.UpdateVirtualDocumentCallCount);
|
||||||
Assert.NotNull(result);
|
Assert.NotNull(result);
|
||||||
Assert.Same(completionRequest.Context, result.Context);
|
var item = Assert.Single((CompletionItem[])result.Value);
|
||||||
Assert.Equal(virtualDocumentUri, result.TextDocument.Uri);
|
Assert.Equal(expectedItem.InsertText, item.InsertText);
|
||||||
Assert.Equal(previousCharacterProjection.Position.Line, result.Position.Line);
|
|
||||||
Assert.Equal(previousCharacterProjection.Position.Character + 1, result.Position.Character);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private class TestDocumentManager : TrackingLSPDocumentManager
|
private class TestDocumentManager : TrackingLSPDocumentManager
|
||||||
|
@ -550,7 +565,7 @@ namespace Microsoft.VisualStudio.LanguageServerClient.Razor.HtmlCSharp
|
||||||
|
|
||||||
public override event EventHandler<LSPDocumentChangeEventArgs> Changed;
|
public override event EventHandler<LSPDocumentChangeEventArgs> Changed;
|
||||||
|
|
||||||
public bool UpdateVirtualDocumentCalled { get; private set; }
|
public int UpdateVirtualDocumentCallCount { get; private set; }
|
||||||
|
|
||||||
public override bool TryGetDocument(Uri uri, out LSPDocumentSnapshot lspDocumentSnapshot)
|
public override bool TryGetDocument(Uri uri, out LSPDocumentSnapshot lspDocumentSnapshot)
|
||||||
{
|
{
|
||||||
|
@ -574,9 +589,9 @@ namespace Microsoft.VisualStudio.LanguageServerClient.Razor.HtmlCSharp
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void UpdateVirtualDocument<TVirtualDocument>(Uri hostDocumentUri, IReadOnlyList<TextChange> changes, long hostDocumentVersion, bool provisional = false)
|
public override void UpdateVirtualDocument<TVirtualDocument>(Uri hostDocumentUri, IReadOnlyList<TextChange> changes, long hostDocumentVersion)
|
||||||
{
|
{
|
||||||
UpdateVirtualDocumentCalled = true;
|
UpdateVirtualDocumentCallCount++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -118,7 +118,7 @@ namespace Microsoft.VisualStudio.LanguageServerClient.Razor
|
||||||
edit.Setup(e => e.Replace(replace.Span.Start, replace.Span.Length, replace.NewText));
|
edit.Setup(e => e.Replace(replace.Span.Start, replace.Span.Length, replace.NewText));
|
||||||
var textBuffer = new Mock<ITextBuffer>();
|
var textBuffer = new Mock<ITextBuffer>();
|
||||||
var textBufferSnapshot = Mock.Of<ITextSnapshot>();
|
var textBufferSnapshot = Mock.Of<ITextSnapshot>();
|
||||||
textBuffer.Setup(buffer => buffer.CreateEdit())
|
textBuffer.Setup(buffer => buffer.CreateEdit(EditOptions.None, null, It.IsAny<IInviolableEditTag>()))
|
||||||
.Returns(edit.Object);
|
.Returns(edit.Object);
|
||||||
textBuffer.Setup(buffer => buffer.CurrentSnapshot)
|
textBuffer.Setup(buffer => buffer.CurrentSnapshot)
|
||||||
.Returns(() => textBufferSnapshot);
|
.Returns(() => textBufferSnapshot);
|
||||||
|
@ -139,7 +139,7 @@ namespace Microsoft.VisualStudio.LanguageServerClient.Razor
|
||||||
|
|
||||||
public static ITextBuffer CreateTextBuffer(ITextEdit edit)
|
public static ITextBuffer CreateTextBuffer(ITextEdit edit)
|
||||||
{
|
{
|
||||||
var textBuffer = Mock.Of<ITextBuffer>(buffer => buffer.CreateEdit() == edit && buffer.CurrentSnapshot == Mock.Of<ITextSnapshot>());
|
var textBuffer = Mock.Of<ITextBuffer>(buffer => buffer.CreateEdit(EditOptions.None, null, It.IsAny<IInviolableEditTag>()) == edit && buffer.CurrentSnapshot == Mock.Of<ITextSnapshot>());
|
||||||
return textBuffer;
|
return textBuffer;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,7 +58,7 @@ namespace Microsoft.VisualStudio.LanguageServerClient.Razor
|
||||||
|
|
||||||
public override VirtualDocumentSnapshot CurrentSnapshot => throw new NotImplementedException();
|
public override VirtualDocumentSnapshot CurrentSnapshot => throw new NotImplementedException();
|
||||||
|
|
||||||
public override VirtualDocumentSnapshot Update(IReadOnlyList<TextChange> changes, long hostDocumentVersion, bool provisional)
|
public override VirtualDocumentSnapshot Update(IReadOnlyList<TextChange> changes, long hostDocumentVersion)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
Загрузка…
Ссылка в новой задаче