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