public async Task <DocumentOnTypeRenameResponseItem> HandleRequestAsync(DocumentOnTypeRenameParams request, ClientCapabilities clientCapabilities, CancellationToken cancellationToken)
        {
            if (request is null)
            {
                throw new ArgumentNullException(nameof(request));
            }

            cancellationToken.ThrowIfCancellationRequested();

            if (!_documentManager.TryGetDocument(request.TextDocument.Uri, out var documentSnapshot))
            {
                return(null);
            }

            var projectionResult = await _projectionProvider.GetProjectionAsync(documentSnapshot, request.Position, cancellationToken).ConfigureAwait(false);

            if (projectionResult is null || projectionResult.LanguageKind != RazorLanguageKind.Html)
            {
                return(null);
            }

            var onTypeRenameParams = new DocumentOnTypeRenameParams()
            {
                Position     = projectionResult.Position,
                TextDocument = new TextDocumentIdentifier()
                {
                    Uri = projectionResult.Uri
                }
            };

            var contentType = projectionResult.LanguageKind.ToContainedLanguageContentType();
            var response    = await _requestInvoker.ReinvokeRequestOnServerAsync <DocumentOnTypeRenameParams, DocumentOnTypeRenameResponseItem>(
                MSLSPMethods.OnTypeRenameName,
                contentType,
                onTypeRenameParams,
                cancellationToken).ConfigureAwait(false);

            if (response is null)
            {
                return(null);
            }

            var mappingResult = await _documentMappingProvider.MapToDocumentRangesAsync(
                projectionResult.LanguageKind,
                request.TextDocument.Uri,
                response.Ranges,
                cancellationToken).ConfigureAwait(false);

            if (mappingResult is null ||
                (_documentManager.TryGetDocument(request.TextDocument.Uri, out var mappedDocumentSnapshot) &&
                 mappingResult.HostDocumentVersion != mappedDocumentSnapshot.Version))
            {
                // Couldn't remap the range or the document changed in the meantime. Discard this result.
                return(null);
            }

            response.Ranges = mappingResult.Ranges;
            return(response);
        }
        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());
        }
        public async Task <DocumentHighlight[]> HandleRequestAsync(DocumentHighlightParams request, ClientCapabilities clientCapabilities, CancellationToken cancellationToken)
        {
            if (request is null)
            {
                throw new ArgumentNullException(nameof(request));
            }

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

            _logger.LogInformation($"Starting request for {request.TextDocument.Uri}.");

            if (!_documentManager.TryGetDocument(request.TextDocument.Uri, out var documentSnapshot))
            {
                _logger.LogWarning($"Failed to find document {request.TextDocument.Uri}.");
                return(null);
            }

            var projectionResult = await _projectionProvider.GetProjectionAsync(
                documentSnapshot,
                request.Position,
                cancellationToken).ConfigureAwait(false);

            if (projectionResult == null)
            {
                return(null);
            }

            var serverKind = projectionResult.LanguageKind == RazorLanguageKind.CSharp ? LanguageServerKind.CSharp : LanguageServerKind.Html;

            cancellationToken.ThrowIfCancellationRequested();

            var documentHighlightParams = new DocumentHighlightParams()
            {
                Position     = projectionResult.Position,
                TextDocument = new TextDocumentIdentifier()
                {
                    Uri = projectionResult.Uri
                }
            };

            _logger.LogInformation($"Requesting highlights for {projectionResult.Uri} at ({projectionResult.Position?.Line}, {projectionResult.Position?.Character}).");

            var highlights = await _requestInvoker.ReinvokeRequestOnServerAsync <DocumentHighlightParams, DocumentHighlight[]>(
                Methods.TextDocumentDocumentHighlightName,
                serverKind.ToContentType(),
                documentHighlightParams,
                cancellationToken).ConfigureAwait(false);

            if (highlights == null || highlights.Length == 0)
            {
                _logger.LogInformation("Received no results.");
                return(highlights);
            }

            _logger.LogInformation($"Received {highlights.Length} results, remapping.");

            var remappedHighlights = new List <DocumentHighlight>();

            var rangesToMap   = highlights.Select(r => r.Range).ToArray();
            var mappingResult = await _documentMappingProvider.MapToDocumentRangesAsync(
                projectionResult.LanguageKind,
                request.TextDocument.Uri,
                rangesToMap,
                cancellationToken).ConfigureAwait(false);

            if (mappingResult == null || mappingResult.HostDocumentVersion != documentSnapshot.Version)
            {
                // Couldn't remap the range or the document changed in the meantime. Discard this highlight.
                _logger.LogInformation($"Mapping failed. Versions: {documentSnapshot.Version} -> {mappingResult?.HostDocumentVersion}.");
                return(Array.Empty <DocumentHighlight>());
            }

            for (var i = 0; i < highlights.Length; i++)
            {
                var highlight = highlights[i];
                var range     = mappingResult.Ranges[i];
                if (range.IsUndefined())
                {
                    // Couldn't remap the range correctly. Discard this range.
                    continue;
                }

                var remappedHighlight = new DocumentHighlight()
                {
                    Range = range,
                    Kind  = highlight.Kind
                };

                remappedHighlights.Add(remappedHighlight);
            }

            _logger.LogInformation($"Returning {remappedHighlights.Count} highlights.");
            return(remappedHighlights.ToArray());
        }
Exemple #4
0
        public async Task <Hover> HandleRequestAsync(TextDocumentPositionParams request, ClientCapabilities clientCapabilities, CancellationToken cancellationToken)
        {
            if (request is null)
            {
                throw new ArgumentNullException(nameof(request));
            }

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

            if (!_documentManager.TryGetDocument(request.TextDocument.Uri, out var documentSnapshot))
            {
                return(null);
            }

            var projectionResult = await _projectionProvider.GetProjectionAsync(documentSnapshot, request.Position, cancellationToken).ConfigureAwait(false);

            if (projectionResult == null)
            {
                return(null);
            }

            var contentType = projectionResult.LanguageKind.ToContainedLanguageContentType();

            cancellationToken.ThrowIfCancellationRequested();

            var textDocumentPositionParams = new TextDocumentPositionParams()
            {
                Position     = projectionResult.Position,
                TextDocument = new TextDocumentIdentifier()
                {
                    Uri = projectionResult.Uri
                }
            };

            var result = await _requestInvoker.ReinvokeRequestOnServerAsync <TextDocumentPositionParams, Hover>(
                Methods.TextDocumentHoverName,
                contentType,
                textDocumentPositionParams,
                cancellationToken).ConfigureAwait(false);

            if (result?.Range == null || result?.Contents == null)
            {
                return(null);
            }

            var mappingResult = await _documentMappingProvider.MapToDocumentRangesAsync(projectionResult.LanguageKind, request.TextDocument.Uri, new[] { result.Range }, cancellationToken).ConfigureAwait(false);

            if (mappingResult == null || mappingResult.Ranges[0].IsUndefined())
            {
                // Couldn't remap the edits properly. Returning hover at initial request position.
                return(CreateHover(result, new Range
                {
                    Start = request.Position,
                    End = request.Position
                }));
            }
            else if (mappingResult.HostDocumentVersion != documentSnapshot.Version)
            {
                // Discard hover if document has changed.
                return(null);
            }

            return(CreateHover(result, mappingResult.Ranges[0]));
        }
        public async Task <DocumentOnTypeRenameResponseItem> HandleRequestAsync(DocumentOnTypeRenameParams request, ClientCapabilities clientCapabilities, CancellationToken cancellationToken)
        {
            if (request is null)
            {
                throw new ArgumentNullException(nameof(request));
            }

            cancellationToken.ThrowIfCancellationRequested();

            _logger.LogInformation($"Starting request for {request.TextDocument.Uri}.");

            if (!_documentManager.TryGetDocument(request.TextDocument.Uri, out var documentSnapshot))
            {
                _logger.LogWarning($"Failed to find document {request.TextDocument.Uri}.");
                return(null);
            }

            var projectionResult = await _projectionProvider.GetProjectionAsync(
                documentSnapshot,
                request.Position,
                cancellationToken).ConfigureAwait(false);

            if (projectionResult is null)
            {
                return(null);
            }
            else if (projectionResult.LanguageKind != RazorLanguageKind.Html)
            {
                _logger.LogInformation($"Unsupported language kind {projectionResult.LanguageKind:G}.");
                return(null);
            }

            var onTypeRenameParams = new DocumentOnTypeRenameParams()
            {
                Position     = projectionResult.Position,
                TextDocument = new TextDocumentIdentifier()
                {
                    Uri = projectionResult.Uri
                }
            };

            _logger.LogInformation($"Requesting OnTypeRename for {projectionResult.Uri}.");

            var contentType = projectionResult.LanguageKind.ToContainedLanguageContentType();
            var response    = await _requestInvoker.ReinvokeRequestOnServerAsync <DocumentOnTypeRenameParams, DocumentOnTypeRenameResponseItem>(
                MSLSPMethods.OnTypeRenameName,
                contentType,
                onTypeRenameParams,
                cancellationToken).ConfigureAwait(false);

            if (response is null)
            {
                _logger.LogInformation("Received no results.");
                return(null);
            }

            _logger.LogInformation($"Received response, remapping.");

            var mappingResult = await _documentMappingProvider.MapToDocumentRangesAsync(
                projectionResult.LanguageKind,
                request.TextDocument.Uri,
                response.Ranges,
                cancellationToken).ConfigureAwait(false);

            if (mappingResult is null ||
                (_documentManager.TryGetDocument(request.TextDocument.Uri, out var mappedDocumentSnapshot) &&
                 mappingResult.HostDocumentVersion != mappedDocumentSnapshot.Version))
            {
                // Couldn't remap the range or the document changed in the meantime. Discard this result.
                _logger.LogInformation($"Mapping failed. Versions: {documentSnapshot.Version} -> {mappingResult?.HostDocumentVersion}.");
                return(null);
            }

            response.Ranges = mappingResult.Ranges;
            _logger.LogInformation("Returned remapped result.");
            return(response);
        }
Exemple #6
0
        public async Task <Hover?> HandleRequestAsync(TextDocumentPositionParams request, ClientCapabilities clientCapabilities, CancellationToken cancellationToken)
        {
            if (request is null)
            {
                throw new ArgumentNullException(nameof(request));
            }

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

            _logger.LogInformation($"Starting request for {request.TextDocument.Uri}.");

            if (!_documentManager.TryGetDocument(request.TextDocument.Uri, out var documentSnapshot))
            {
                _logger.LogWarning($"Failed to find document {request.TextDocument.Uri}.");
                return(null);
            }

            var projectionResult = await _projectionProvider.GetProjectionAsync(
                documentSnapshot,
                request.Position,
                cancellationToken).ConfigureAwait(false);

            if (projectionResult is null)
            {
                return(null);
            }

            var languageServerName = projectionResult.LanguageKind.ToContainedLanguageServerName();

            cancellationToken.ThrowIfCancellationRequested();

            var textDocumentPositionParams = new TextDocumentPositionParams()
            {
                Position     = projectionResult.Position,
                TextDocument = new TextDocumentIdentifier()
                {
                    Uri = projectionResult.Uri
                }
            };

            _logger.LogInformation($"Requesting hovers for {projectionResult.Uri}.");

            var serverKind = projectionResult.LanguageKind.ToLanguageServerKind();
            var textBuffer = serverKind.GetTextBuffer(documentSnapshot);
            var response   = await _requestInvoker.ReinvokeRequestOnServerAsync <TextDocumentPositionParams, Hover>(
                textBuffer,
                Methods.TextDocumentHoverName,
                languageServerName,
                textDocumentPositionParams,
                cancellationToken).ConfigureAwait(false);

            if (!ReinvocationResponseHelper.TryExtractResultOrLog(response, _logger, languageServerName, out var result))
            {
                return(null);
            }

            if (result.Range is null)
            {
                _logger.LogInformation("Received no results.");
                return(null);
            }

            _logger.LogInformation("Received result, remapping.");

            var mappingResult = await _documentMappingProvider.MapToDocumentRangesAsync(
                projectionResult.LanguageKind,
                request.TextDocument.Uri,
                new[] { result.Range },
                cancellationToken).ConfigureAwait(false);

            if (mappingResult is null || mappingResult.Ranges[0].IsUndefined())
            {
                // Couldn't remap the edits properly. Returning hover at initial request position.
                _logger.LogInformation("Mapping failed");
                return(CreateHover(result, new Range
                {
                    Start = request.Position,
                    End = request.Position
                }));
            }
Exemple #7
0
        public async Task <DocumentHighlight[]> HandleRequestAsync(DocumentHighlightParams request, ClientCapabilities clientCapabilities, CancellationToken cancellationToken)
        {
            if (request is null)
            {
                throw new ArgumentNullException(nameof(request));
            }

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

            if (!_documentManager.TryGetDocument(request.TextDocument.Uri, out var documentSnapshot))
            {
                return(null);
            }

            var projectionResult = await _projectionProvider.GetProjectionAsync(documentSnapshot, request.Position, cancellationToken).ConfigureAwait(false);

            if (projectionResult == null || projectionResult.LanguageKind != RazorLanguageKind.CSharp)
            {
                return(null);
            }

            cancellationToken.ThrowIfCancellationRequested();

            var serverKind = LanguageServerKind.CSharp;
            var documentHighlightParams = new DocumentHighlightParams()
            {
                Position     = projectionResult.Position,
                TextDocument = new TextDocumentIdentifier()
                {
                    Uri = projectionResult.Uri
                }
            };

            var highlights = await _requestInvoker.ReinvokeRequestOnServerAsync <DocumentHighlightParams, DocumentHighlight[]>(
                Methods.TextDocumentDocumentHighlightName,
                serverKind,
                documentHighlightParams,
                cancellationToken).ConfigureAwait(false);

            if (highlights == null || highlights.Length == 0)
            {
                return(highlights);
            }

            var remappedHighlights = new List <DocumentHighlight>();

            var rangesToMap   = highlights.Select(r => r.Range).ToArray();
            var mappingResult = await _documentMappingProvider.MapToDocumentRangesAsync(
                projectionResult.LanguageKind,
                request.TextDocument.Uri,
                rangesToMap,
                cancellationToken).ConfigureAwait(false);

            if (mappingResult == null || mappingResult.HostDocumentVersion != documentSnapshot.Version)
            {
                // Couldn't remap the range or the document changed in the meantime. Discard this highlight.
                return(Array.Empty <DocumentHighlight>());
            }

            for (var i = 0; i < highlights.Length; i++)
            {
                var highlight = highlights[i];
                var range     = mappingResult.Ranges[i];
                if (range.IsUndefined())
                {
                    // Couldn't remap the range correctly. Discard this range.
                    continue;
                }

                var remappedHighlight = new DocumentHighlight()
                {
                    Range = range,
                    Kind  = highlight.Kind
                };

                remappedHighlights.Add(remappedHighlight);
            }

            return(remappedHighlights.ToArray());
        }