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 <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;
                }

                // 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);

                if (!RazorLSPConventions.IsRazorCSharpFile(referenceItem.Location.Uri) &&
                    !RazorLSPConventions.IsRazorHtmlFile(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.IsRazorCSharpFile(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 <(LSPDocumentSnapshot, TextEdit[])> RemapTextEditsCoreAsync(
            Uri uri,
            TextEdit[] edits,
            CancellationToken cancellationToken,
            bool shouldFormat = false,
            FormattingOptions formattingOptions = null)
        {
            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 mapToDocumentEditsParams = new RazorMapToDocumentEditsParams()
            {
                Kind               = languageKind,
                RazorDocumentUri   = razorDocumentUri,
                ProjectedTextEdits = edits,
                ShouldFormat       = shouldFormat,
                FormattingOptions  = formattingOptions
            };

            var mappingResult = await _requestInvoker.ReinvokeRequestOnServerAsync <RazorMapToDocumentEditsParams, RazorMapToDocumentEditsResponse>(
                LanguageServerConstants.RazorMapToDocumentEditsEndpoint,
                RazorLSPConstants.RazorLSPContentTypeName,
                mapToDocumentEditsParams,
                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);
            }

            return(documentSnapshot, mappingResult.TextEdits);
        }
Esempio n. 4
0
        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());
        }
        public async override Task<TextEdit[]> RemapFormattedTextEditsAsync(Uri uri, TextEdit[] edits, FormattingOptions options, CancellationToken cancellationToken)
        {
            if (uri is null)
            {
                throw new ArgumentNullException(nameof(uri));
            }

            if (edits is null)
            {
                throw new ArgumentNullException(nameof(edits));
            }

            if (!RazorLSPConventions.IsRazorCSharpFile(uri) && !RazorLSPConventions.IsRazorHtmlFile(uri))
            {
                // This is not a virtual razor file. No need to remap.
                return edits;
            }

            var (_, remappedEdits) = await RemapTextEditsCoreAsync(uri, edits, cancellationToken, shouldFormat: true, formattingOptions: options).ConfigureAwait(false);
            return remappedEdits;
        }
        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();
        }
 private static bool CanRemap(Uri uri)
 {
     return RazorLSPConventions.IsRazorCSharpFile(uri) || RazorLSPConventions.IsRazorHtmlFile(uri);
 }