private async Task<Dictionary<string, TextEdit[]>> RemapDocumentEditsAsync(Dictionary<string, TextEdit[]> changes, CancellationToken cancellationToken) { var remappedChanges = new Dictionary<string, TextEdit[]>(); foreach (var entry in changes) { var uri = new Uri(entry.Key); var edits = entry.Value; if (!CanRemap(uri)) { // This location doesn't point to a background razor file. No need to remap. remappedChanges[entry.Key] = entry.Value; continue; } var (_, remappedEdits) = await RemapTextEditsCoreAsync(uri, edits, cancellationToken).ConfigureAwait(false); if (remappedEdits == null || remappedEdits.Length == 0) { // Nothing to do. continue; } var razorDocumentUri = RazorLSPConventions.GetRazorDocumentUri(uri); remappedChanges[razorDocumentUri.AbsoluteUri] = remappedEdits; } return remappedChanges; }
private async Task <(LSPDocumentSnapshot?, TextEdit[])> RemapTextEditsCoreAsync( Uri uri, TextEdit[] edits, TextEditKind textEditKind, CancellationToken cancellationToken, FormattingOptions?formattingOptions = null) { var languageKind = RazorLanguageKind.Razor; if (RazorLSPConventions.IsVirtualCSharpFile(uri)) { languageKind = RazorLanguageKind.CSharp; } else if (RazorLSPConventions.IsVirtualHtmlFile(uri)) { languageKind = RazorLanguageKind.Html; } else { Debug.Fail("This method should only be called for Razor background files."); } var razorDocumentUri = RazorLSPConventions.GetRazorDocumentUri(uri); var mapToDocumentEditsParams = new RazorMapToDocumentEditsParams() { Kind = languageKind, RazorDocumentUri = razorDocumentUri, ProjectedTextEdits = edits, TextEditKind = textEditKind, FormattingOptions = formattingOptions }; if (!_lazyDocumentManager.Value.TryGetDocument(razorDocumentUri, out var documentSnapshot)) { return(null, s_emptyEdits); } var response = await _requestInvoker.ReinvokeRequestOnServerAsync <RazorMapToDocumentEditsParams, RazorMapToDocumentEditsResponse>( documentSnapshot.Snapshot.TextBuffer, LanguageServerConstants.RazorMapToDocumentEditsEndpoint, RazorLSPConstants.RazorLanguageServerName, CheckRazorEditMappingCapability, mapToDocumentEditsParams, cancellationToken).ConfigureAwait(false); var mappingResult = response?.Response; if (mappingResult is null || (_lazyDocumentManager.Value.TryGetDocument(razorDocumentUri, out documentSnapshot) && mappingResult.HostDocumentVersion != documentSnapshot.Version)) { // Couldn't remap the location or the document changed in the meantime. Discard these ranges. return(null, s_emptyEdits); } return(documentSnapshot, mappingResult.TextEdits); }
private async Task <(LSPDocumentSnapshot, TextEdit[])> RemapTextEditsCoreAsync(Uri uri, TextEdit[] edits, CancellationToken cancellationToken) { var languageKind = RazorLanguageKind.Razor; if (RazorLSPConventions.IsRazorCSharpFile(uri)) { languageKind = RazorLanguageKind.CSharp; } else if (RazorLSPConventions.IsRazorHtmlFile(uri)) { languageKind = RazorLanguageKind.Html; } else { Debug.Fail("This method should only be called for Razor background files."); } var razorDocumentUri = RazorLSPConventions.GetRazorDocumentUri(uri); var rangesToMap = edits.Select(e => e.Range).ToArray(); var mappingResult = await MapToDocumentRangesAsync( languageKind, razorDocumentUri, rangesToMap, cancellationToken).ConfigureAwait(false); if (mappingResult == null || (_lazyDocumentManager.Value.TryGetDocument(razorDocumentUri, out var documentSnapshot) && mappingResult.HostDocumentVersion != documentSnapshot.Version)) { // Couldn't remap the location or the document changed in the meantime. Discard these ranges. return(null, EmptyEdits); } var remappedEdits = new List <TextEdit>(); for (var i = 0; i < edits.Length; i++) { var edit = edits[i]; var range = mappingResult.Ranges[i]; if (range.IsUndefined()) { // Couldn't remap the range correctly. Discard this range. continue; } var remappedEdit = new TextEdit() { Range = range, NewText = edit.NewText }; remappedEdits.Add(remappedEdit); } return(documentSnapshot, remappedEdits.ToArray()); }
private async Task <VSInternalReferenceItem[]> RemapReferenceItemsAsync(VSInternalReferenceItem[] result, CancellationToken cancellationToken) { var remappedLocations = new List <VSInternalReferenceItem>(); foreach (var referenceItem in result) { if (referenceItem?.Location is null || referenceItem.Text is null) { continue; } // Temporary fix for codebehind leaking through // Revert when https://github.com/dotnet/aspnetcore/issues/22512 is resolved referenceItem.DefinitionText = FilterReferenceDisplayText(referenceItem.DefinitionText); referenceItem.Text = FilterReferenceDisplayText(referenceItem.Text); // Indicates the reference item is directly available in the code referenceItem.Origin = VSInternalItemOrigin.Exact; if (!RazorLSPConventions.IsVirtualCSharpFile(referenceItem.Location.Uri) && !RazorLSPConventions.IsVirtualHtmlFile(referenceItem.Location.Uri)) { // This location doesn't point to a virtual cs file. No need to remap. remappedLocations.Add(referenceItem); continue; } var razorDocumentUri = RazorLSPConventions.GetRazorDocumentUri(referenceItem.Location.Uri); var languageKind = RazorLSPConventions.IsVirtualCSharpFile(referenceItem.Location.Uri) ? RazorLanguageKind.CSharp : RazorLanguageKind.Html; var mappingResult = await _documentMappingProvider.MapToDocumentRangesAsync( languageKind, razorDocumentUri, new[] { referenceItem.Location.Range }, cancellationToken).ConfigureAwait(false); if (mappingResult == null || mappingResult.Ranges[0].IsUndefined() || (_documentManager.TryGetDocument(razorDocumentUri, out var mappedDocumentSnapshot) && mappingResult.HostDocumentVersion != mappedDocumentSnapshot.Version)) { // Couldn't remap the location or the document changed in the meantime. Discard this location. continue; } referenceItem.Location.Uri = razorDocumentUri; referenceItem.DisplayPath = razorDocumentUri.AbsolutePath; referenceItem.Location.Range = mappingResult.Ranges[0]; remappedLocations.Add(referenceItem); } return(remappedLocations.ToArray()); }
private async Task <VSReferenceItem[]> RemapReferenceItemsAsync(VSReferenceItem[] result, CancellationToken cancellationToken) { var remappedLocations = new List <VSReferenceItem>(); foreach (var referenceItem in result) { if (referenceItem?.Location is null || referenceItem.Text is null) { continue; } if (!RazorLSPConventions.IsRazorCSharpFile(referenceItem.Location.Uri)) { // This location doesn't point to a virtual cs file. No need to remap. remappedLocations.Add(referenceItem); continue; } var razorDocumentUri = RazorLSPConventions.GetRazorDocumentUri(referenceItem.Location.Uri); var mappingResult = await _documentMappingProvider.MapToDocumentRangesAsync( RazorLanguageKind.CSharp, razorDocumentUri, new[] { referenceItem.Location.Range }, cancellationToken).ConfigureAwait(false); if (mappingResult == null || mappingResult.Ranges[0].IsUndefined() || (_documentManager.TryGetDocument(razorDocumentUri, out var mappedDocumentSnapshot) && mappingResult.HostDocumentVersion != mappedDocumentSnapshot.Version)) { // Couldn't remap the location or the document changed in the meantime. Discard this location. continue; } referenceItem.Location.Uri = razorDocumentUri; referenceItem.DisplayPath = razorDocumentUri.AbsolutePath; referenceItem.Location.Range = mappingResult.Ranges[0]; remappedLocations.Add(referenceItem); } return(remappedLocations.ToArray()); }
private async Task <TextDocumentEdit[]> RemapVersionedDocumentEditsAsync(TextDocumentEdit[] documentEdits, CancellationToken cancellationToken) { var remappedDocumentEdits = new List <TextDocumentEdit>(); foreach (var entry in documentEdits) { var uri = entry.TextDocument.Uri; if (!CanRemap(uri)) { // This location doesn't point to a background razor file. No need to remap. remappedDocumentEdits.Add(entry); continue; } var edits = entry.Edits; var(documentSnapshot, remappedEdits) = await RemapTextEditsCoreAsync(uri, edits, cancellationToken).ConfigureAwait(false); if (remappedEdits == null || remappedEdits.Length == 0) { // Nothing to do. continue; } var razorDocumentUri = RazorLSPConventions.GetRazorDocumentUri(uri); remappedDocumentEdits.Add(new TextDocumentEdit() { TextDocument = new VersionedTextDocumentIdentifier() { Uri = razorDocumentUri, Version = documentSnapshot?.Version }, Edits = remappedEdits }); } return(remappedDocumentEdits.ToArray()); }
public async override Task<Location[]> RemapLocationsAsync(Location[] locations, CancellationToken cancellationToken) { if (locations is null) { throw new ArgumentNullException(nameof(locations)); } var remappedLocations = new List<Location>(); foreach (var location in locations) { var uri = location.Uri; RazorLanguageKind languageKind; if (RazorLSPConventions.IsRazorCSharpFile(uri)) { languageKind = RazorLanguageKind.CSharp; } else if (RazorLSPConventions.IsRazorHtmlFile(uri)) { languageKind = RazorLanguageKind.Html; } else { // This location doesn't point to a virtual razor file. No need to remap. remappedLocations.Add(location); continue; } var razorDocumentUri = RazorLSPConventions.GetRazorDocumentUri(uri); var mappingResult = await MapToDocumentRangesAsync( languageKind, razorDocumentUri, new[] { location.Range }, cancellationToken).ConfigureAwait(false); cancellationToken.ThrowIfCancellationRequested(); if (mappingResult == null || (_lazyDocumentManager.Value.TryGetDocument(razorDocumentUri, out var documentSnapshot) && mappingResult.HostDocumentVersion != documentSnapshot.Version)) { // Couldn't remap the location or the document changed in the meantime. Discard these ranges. continue; } var remappedRange = mappingResult.Ranges[0]; if (remappedRange.IsUndefined()) { // Couldn't remap the range correctly. Discard this range. continue; } var remappedLocation = new Location() { Uri = razorDocumentUri, Range = remappedRange, }; remappedLocations.Add(remappedLocation); } return remappedLocations.ToArray(); }