예제 #1
0
        public async Task <Hover?> HandleRequestAsync(TextDocumentPositionParams request, RequestContext context, CancellationToken cancellationToken)
        {
            var document = context.Document;

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

            var position = await document.GetPositionFromLinePositionAsync(ProtocolConversions.PositionToLinePosition(request.Position), cancellationToken).ConfigureAwait(false);

            var quickInfoService = document.Project.LanguageServices.GetService <IXamlQuickInfoService>();

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

            var info = await quickInfoService.GetQuickInfoAsync(document, position, cancellationToken).ConfigureAwait(false);

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

            var descriptionBuilder = new List <TaggedText>(info.Description);

            if (info.Symbol != null)
            {
                var options     = _globalOptions.GetSymbolDescriptionOptions(document.Project.Language);
                var description = await info.Symbol.GetDescriptionAsync(document, options, cancellationToken).ConfigureAwait(false);

                if (description.Any())
                {
                    if (descriptionBuilder.Any())
                    {
                        descriptionBuilder.AddLineBreak();
                    }

                    descriptionBuilder.AddRange(description);
                }
            }

            var text = await document.GetTextAsync(cancellationToken).ConfigureAwait(false);

            return(new VSInternalHover
            {
                Range = ProtocolConversions.TextSpanToRange(info.Span, text),
                Contents = new MarkupContent
                {
                    Kind = MarkupKind.Markdown,
                    Value = GetMarkdownString(descriptionBuilder)
                },
                RawContent = new ClassifiedTextElement(descriptionBuilder.Select(tp => new ClassifiedTextRun(tp.Tag.ToClassificationTypeName(), tp.Text)))
            });
            public async Task <IntellisenseQuickInfoItem> GetQuickInfoItemAsync(IAsyncQuickInfoSession session, CancellationToken cancellationToken)
            {
                var triggerPoint = session.GetTriggerPoint(_subjectBuffer.CurrentSnapshot);

                if (!triggerPoint.HasValue)
                {
                    return(null);
                }

                var snapshot = triggerPoint.Value.Snapshot;
                var document = snapshot.GetOpenDocumentInCurrentContextWithChanges();

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

                var service = QuickInfoService.GetService(document);

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

                try
                {
                    using (Logger.LogBlock(FunctionId.Get_QuickInfo_Async, cancellationToken))
                    {
                        cancellationToken.ThrowIfCancellationRequested();

                        var options = _globalOptions.GetSymbolDescriptionOptions(document.Project.Language);
                        var item    = await service.GetQuickInfoAsync(document, triggerPoint.Value, options, cancellationToken).ConfigureAwait(false);

                        if (item != null)
                        {
                            var textVersion           = snapshot.Version;
                            var trackingSpan          = textVersion.CreateTrackingSpan(item.Span.ToSpan(), SpanTrackingMode.EdgeInclusive);
                            var classificationOptions = _globalOptions.GetClassificationOptions(document.Project.Language);

                            return(await IntellisenseQuickInfoBuilder.BuildItemAsync(
                                       trackingSpan, item, document, classificationOptions,
                                       _threadingContext, _operationExecutor,
                                       _asyncListener, _streamingPresenter, cancellationToken).ConfigureAwait(false));
                        }

                        return(null);
                    }
                }
                catch (Exception e) when(FatalError.ReportAndPropagateUnlessCanceled(e, cancellationToken, ErrorSeverity.Critical))
                {
                    throw ExceptionUtilities.Unreachable;
                }
            }
예제 #3
0
        public async Task <LSP.CompletionItem> HandleRequestAsync(LSP.CompletionItem completionItem, RequestContext context, CancellationToken cancellationToken)
        {
            Contract.ThrowIfNull(context.Solution);

            if (completionItem is not VSInternalCompletionItem vsCompletionItem)
            {
                return(completionItem);
            }

            CompletionResolveData?data;

            if (completionItem.Data is JToken token)
            {
                data = token.ToObject <CompletionResolveData>();
                Assumes.Present(data);
            }
            else
            {
                return(completionItem);
            }

            var documentId = DocumentId.CreateFromSerialized(ProjectId.CreateFromSerialized(data.ProjectGuid), data.DocumentGuid);
            var document   = context.Solution.GetDocument(documentId) ?? context.Solution.GetAdditionalDocument(documentId);

            if (document == null)
            {
                return(completionItem);
            }

            var offset = await document.GetPositionFromLinePositionAsync(ProtocolConversions.PositionToLinePosition(data.Position), cancellationToken).ConfigureAwait(false);

            var completionService = document.Project.LanguageServices.GetRequiredService <IXamlCompletionService>();
            var symbol            = await completionService.GetSymbolAsync(new XamlCompletionContext(document, offset), completionItem.Label, cancellationToken : cancellationToken).ConfigureAwait(false);

            if (symbol == null)
            {
                return(completionItem);
            }

            var options     = _globalOptions.GetSymbolDescriptionOptions(document.Project.Language);
            var description = await symbol.GetDescriptionAsync(document, options, cancellationToken).ConfigureAwait(false);

            vsCompletionItem.Description = new ClassifiedTextElement(description.Select(tp => new ClassifiedTextRun(tp.Tag.ToClassificationTypeName(), tp.Text)));
            return(vsCompletionItem);
        }
예제 #4
0
        public async Task <Hover?> HandleRequestAsync(TextDocumentPositionParams request, RequestContext context, CancellationToken cancellationToken)
        {
            var document = context.Document;

            Contract.ThrowIfNull(document);

            var position = await document.GetPositionFromLinePositionAsync(ProtocolConversions.PositionToLinePosition(request.Position), cancellationToken).ConfigureAwait(false);

            var quickInfoService = document.Project.LanguageServices.GetRequiredService <QuickInfoService>();
            var options          = _globalOptions.GetSymbolDescriptionOptions(document.Project.Language);
            var info             = await quickInfoService.GetQuickInfoAsync(document, position, options, cancellationToken).ConfigureAwait(false);

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

            var classificationOptions = _globalOptions.GetClassificationOptions(document.Project.Language);
            var text = await document.GetTextAsync(cancellationToken).ConfigureAwait(false);

            return(await GetHoverAsync(info, text, document.Project.Language, document, classificationOptions, context.ClientCapabilities, cancellationToken).ConfigureAwait(false));
        }
예제 #5
0
        public async Task <LSP.CompletionItem> HandleRequestAsync(LSP.CompletionItem completionItem, RequestContext context, CancellationToken cancellationToken)
        {
            var document = context.Document;

            Contract.ThrowIfNull(document);

            var completionService = document.Project.LanguageServices.GetRequiredService <CompletionService>();
            var cacheEntry        = GetCompletionListCacheEntry(completionItem);

            if (cacheEntry == null)
            {
                // Don't have a cache associated with this completion item, cannot resolve.
                context.TraceInformation("No cache entry found for the provided completion item at resolve time.");
                return(completionItem);
            }

            var list = cacheEntry.CompletionList;

            // Find the matching completion item in the completion list
            var selectedItem = list.Items.FirstOrDefault(cachedCompletionItem => MatchesLSPCompletionItem(completionItem, cachedCompletionItem));

            if (selectedItem == null)
            {
                return(completionItem);
            }

            var completionOptions = _globalOptions.GetCompletionOptions(document.Project.Language);
            var displayOptions    = _globalOptions.GetSymbolDescriptionOptions(document.Project.Language);
            var description       = await completionService.GetDescriptionAsync(document, selectedItem, completionOptions, displayOptions, cancellationToken).ConfigureAwait(false) !;

            if (description != null)
            {
                var supportsVSExtensions = context.ClientCapabilities.HasVisualStudioLspCapability();
                if (supportsVSExtensions)
                {
                    var vsCompletionItem = (LSP.VSInternalCompletionItem)completionItem;
                    vsCompletionItem.Description = new ClassifiedTextElement(description.TaggedParts
                                                                             .Select(tp => new ClassifiedTextRun(tp.Tag.ToClassificationTypeName(), tp.Text)));
                }
                else
                {
                    var clientSupportsMarkdown = context.ClientCapabilities.TextDocument?.Completion?.CompletionItem?.DocumentationFormat.Contains(LSP.MarkupKind.Markdown) == true;
                    completionItem.Documentation = ProtocolConversions.GetDocumentationMarkupContent(description.TaggedParts, document, clientSupportsMarkdown);
                }
            }

            // We compute the TextEdit resolves for complex text edits (e.g. override and partial
            // method completions) here. Lazily resolving TextEdits is technically a violation of
            // the LSP spec, but is currently supported by the VS client anyway. Once the VS client
            // adheres to the spec, this logic will need to change and VS will need to provide
            // official support for TextEdit resolution in some form.
            if (selectedItem.IsComplexTextEdit)
            {
                Contract.ThrowIfTrue(completionItem.InsertText != null);
                Contract.ThrowIfTrue(completionItem.TextEdit != null);

                var snippetsSupported = context.ClientCapabilities.TextDocument?.Completion?.CompletionItem?.SnippetSupport ?? false;

                completionItem.TextEdit = await GenerateTextEditAsync(
                    document, completionService, selectedItem, snippetsSupported, cancellationToken).ConfigureAwait(false);
            }

            return(completionItem);
        }