public Task <LinkedEditingRanges?> GetLinkedEditingRangesAsync(LinkedEditingRangeParams renameParams, CancellationToken cancellationToken) { Contract.ThrowIfNull(_clientCapabilities, $"{nameof(InitializeAsync)} has not been called."); return(RequestDispatcher.ExecuteRequestAsync <LinkedEditingRangeParams, LinkedEditingRanges?>(Queue, Methods.TextDocumentLinkedEditingRangeName, renameParams, _clientCapabilities, ClientName, cancellationToken)); }
public Task <LinkedEditingRanges> OnLinkedEditingRangeAsync(LinkedEditingRangeParams request, CancellationToken cancellationToken) { if (request is null) { throw new ArgumentNullException(nameof(request)); } return(ExecuteRequestAsync <LinkedEditingRangeParams, LinkedEditingRanges>(Methods.TextDocumentLinkedEditingRangeName, request, ClientCapabilities, cancellationToken)); }
#pragma warning disable CS8613 // Nullability of reference types in return type doesn't match implicitly implemented member. // The return type of the handler should be nullable. O# tracking issue: // https://github.com/OmniSharp/csharp-language-server-protocol/issues/644 public async Task <LinkedEditingRanges?> Handle( #pragma warning restore CS8613 // Nullability of reference types in return type doesn't match implicitly implemented member. LinkedEditingRangeParams request, CancellationToken cancellationToken) { var uri = request.TextDocument.Uri.GetAbsoluteOrUNCPath(); var document = await _projectSnapshotManagerDispatcher.RunOnDispatcherThreadAsync(() => { if (!_documentResolver.TryResolveDocument(uri, out var documentSnapshot)) { _logger.LogWarning("Unable to resolve document for {Uri}", uri); return(null); } return(documentSnapshot); }, cancellationToken).ConfigureAwait(false); if (document is null || cancellationToken.IsCancellationRequested) { _logger.LogWarning("Unable to resolve document for {Uri} or cancellation was requested.", uri); return(null); } var codeDocument = await document.GetGeneratedOutputAsync(); if (codeDocument.IsUnsupported()) { _logger.LogWarning("FileKind {FileKind} is unsupported", codeDocument.GetFileKind()); return(null); } var location = await GetSourceLocation(request, document).ConfigureAwait(false); // We only care if the user is within a TagHelper or HTML tag with a valid start and end tag. if (TryGetNearestMarkupNameTokens(codeDocument, location, out var startTagNameToken, out var endTagNameToken) && (startTagNameToken.Span.Contains(location.AbsoluteIndex) || endTagNameToken.Span.Contains(location.AbsoluteIndex) || startTagNameToken.Span.End == location.AbsoluteIndex || endTagNameToken.Span.End == location.AbsoluteIndex)) { var startSpan = startTagNameToken.GetLinePositionSpan(codeDocument.Source); var endSpan = endTagNameToken.GetLinePositionSpan(codeDocument.Source); var ranges = new Range[2] { startSpan.AsRange(), endSpan.AsRange() }; return(new LinkedEditingRanges { Ranges = ranges, WordPattern = WordPattern }); } _logger.LogInformation("LinkedEditingRange request was null at {location} for {uri}", location, uri); return(null);
static async Task <SourceLocation> GetSourceLocation( LinkedEditingRangeParams request, DocumentSnapshot document) { var sourceText = await document.GetTextAsync().ConfigureAwait(false); var linePosition = new LinePosition(request.Position.Line, request.Position.Character); var hostDocumentIndex = sourceText.Lines.GetPosition(linePosition); var location = new SourceLocation(hostDocumentIndex, request.Position.Line, request.Position.Character); return(location); }
public async Task Handle_TagHelperStartTag_ReturnsCorrectRange_EndSpan() { // Arrange var txt = $"@addTagHelper *, TestAssembly{Environment.NewLine}<test1></test1>"; var codeDocument = CreateCodeDocument(txt, DefaultTagHelpers); var uri = new Uri("file://path/test.razor"); var documentResolver = CreateDocumentResolver(uri.GetAbsoluteOrUNCPath(), codeDocument); var endpoint = new LinkedEditingRangeEndpoint(LegacyDispatcher, documentResolver, LoggerFactory); var request = new LinkedEditingRangeParams { TextDocument = new TextDocumentIdentifier(uri), Position = new Position { Line = 1, Character = 6 } // <test1[||]></test1> }; var expectedRanges = new Range[] { new Range { Start = new Position { Line = 1, Character = 1 }, End = new Position { Line = 1, Character = 6 } }, new Range { Start = new Position { Line = 1, Character = 9 }, End = new Position { Line = 1, Character = 14 } } }; // Act var result = await endpoint.Handle(request, CancellationToken.None); // Assert Assert.Equal(expectedRanges, result.Ranges); Assert.Equal(LinkedEditingRangeEndpoint.WordPattern, result.WordPattern); }
public async Task Handle_SelfClosingHTMLTag_ReturnsNull() { // Arrange var txt = $"@addTagHelper *, TestAssembly{Environment.NewLine}<body />"; var codeDocument = CreateCodeDocument(txt, DefaultTagHelpers); var uri = new Uri("file://path/test.razor"); var documentResolver = CreateDocumentResolver(uri.GetAbsoluteOrUNCPath(), codeDocument); var endpoint = new LinkedEditingRangeEndpoint(LegacyDispatcher, documentResolver, LoggerFactory); var request = new LinkedEditingRangeParams { TextDocument = new TextDocumentIdentifier(uri), Position = new Position { Line = 1, Character = 3 } // <bo[||]dy /> }; // Act var result = await endpoint.Handle(request, CancellationToken.None); // Assert Assert.Null(result); }