public override async Task <LSP.CompletionItem[]> HandleRequestAsync(LSP.CompletionParams request, LSP.ClientCapabilities clientCapabilities, string?clientName, CancellationToken cancellationToken) { var document = SolutionProvider.GetDocument(request.TextDocument, clientName); if (document == null) { return(Array.Empty <LSP.CompletionItem>()); } var position = await document.GetPositionFromLinePositionAsync(ProtocolConversions.PositionToLinePosition(request.Position), cancellationToken).ConfigureAwait(false); // Filter out unimported types for now as there are two issues with providing them: // 1. LSP client does not currently provide a way to provide detail text on the completion item to show the namespace. // https://dev.azure.com/devdiv/DevDiv/_workitems/edit/1076759 // 2. We need to figure out how to provide the text edits along with the completion item or provide them in the resolve request. // https://devdiv.visualstudio.com/DevDiv/_workitems/edit/985860/ // 3. LSP client should support completion filters / expanders var documentOptions = await document.GetOptionsAsync(cancellationToken).ConfigureAwait(false); var completionOptions = documentOptions .WithChangedOption(CompletionOptions.ShowItemsFromUnimportedNamespaces, false) .WithChangedOption(CompletionServiceOptions.IsExpandedCompletion, false); var completionService = document.Project.LanguageServices.GetRequiredService <CompletionService>(); var list = await completionService.GetCompletionsAsync(document, position, options : completionOptions, cancellationToken : cancellationToken).ConfigureAwait(false); if (list == null) { return(Array.Empty <LSP.CompletionItem>()); } var lspVSClientCapability = clientCapabilities?.HasVisualStudioLspCapability() == true; return(list.Items.Select(item => CreateLSPCompletionItem(request, item, lspVSClientCapability)).ToArray());
public async Task <object> HandleRequestAsync(Solution solution, LSP.CompletionParams request, LSP.ClientCapabilities clientCapabilities, CancellationToken cancellationToken) { var document = solution.GetDocumentFromURI(request.TextDocument.Uri); if (document == null) { return(Array.Empty <LSP.CompletionItem>()); } var position = await document.GetPositionFromLinePositionAsync(ProtocolConversions.PositionToLinePosition(request.Position), cancellationToken).ConfigureAwait(false); var completionService = document.Project.LanguageServices.GetService <CompletionService>(); var list = await completionService.GetCompletionsAsync(document, position, cancellationToken : cancellationToken).ConfigureAwait(false); if (list == null) { return(Array.Empty <LSP.CompletionItem>()); } var lspVSClientCapability = clientCapabilities?.HasVisualStudioLspCapability() == true; return(list.Items.Select(item => CreateLSPCompletionItem(request, item, lspVSClientCapability)).ToArray());
public async Task <object> HandleRequestAsync(Solution solution, LSP.TextDocumentPositionParams request, LSP.ClientCapabilities clientCapabilities, CancellationToken cancellationToken) { var locations = ArrayBuilder <LSP.Location> .GetInstance(); var document = solution.GetDocumentFromURI(request.TextDocument.Uri); if (document == null) { return(locations.ToArrayAndFree()); } var findUsagesService = document.Project.LanguageServices.GetService <IFindUsagesService>(); var position = await document.GetPositionFromLinePositionAsync(ProtocolConversions.PositionToLinePosition(request.Position), cancellationToken).ConfigureAwait(false); var context = new SimpleFindUsagesContext(cancellationToken); await FindImplementationsAsync(findUsagesService, document, position, context).ConfigureAwait(false); foreach (var definition in context.GetDefinitions()) { var text = definition.GetClassifiedText(); foreach (var sourceSpan in context.GetDefinitions().SelectMany(definition => definition.SourceSpans)) { if (clientCapabilities?.HasVisualStudioLspCapability() == true) { locations.Add(await ProtocolConversions.DocumentSpanToLocationWithTextAsync(sourceSpan, text, cancellationToken).ConfigureAwait(false)); } else { locations.Add(await ProtocolConversions.DocumentSpanToLocationAsync(sourceSpan, cancellationToken).ConfigureAwait(false)); } } } return(locations.ToArrayAndFree()); }
public override async Task <LSP.CompletionItem> HandleRequestAsync(LSP.CompletionItem completionItem, LSP.ClientCapabilities clientCapabilities, string?clientName, CancellationToken cancellationToken) { CompletionResolveData data; if (completionItem.Data is CompletionResolveData) { data = (CompletionResolveData)completionItem.Data; } else { data = ((JToken)completionItem.Data).ToObject <CompletionResolveData>(); } var document = SolutionProvider.GetDocument(data.TextDocument, clientName); if (document == null) { return(completionItem); } var position = await document.GetPositionFromLinePositionAsync(ProtocolConversions.PositionToLinePosition(data.Position), cancellationToken).ConfigureAwait(false); var completionService = document.Project.LanguageServices.GetRequiredService <CompletionService>(); var list = await completionService.GetCompletionsAsync(document, position, cancellationToken : cancellationToken).ConfigureAwait(false); if (list == null) { return(completionItem); } var selectedItem = list.Items.FirstOrDefault(i => i.DisplayText == data.DisplayText); if (selectedItem == null) { return(completionItem); } var description = await completionService.GetDescriptionAsync(document, selectedItem, cancellationToken).ConfigureAwait(false); var lspVSClientCapability = clientCapabilities?.HasVisualStudioLspCapability() == true; LSP.CompletionItem resolvedCompletionItem; if (lspVSClientCapability) { resolvedCompletionItem = CloneVSCompletionItem(completionItem); ((LSP.VSCompletionItem)resolvedCompletionItem).Description = new ClassifiedTextElement(description.TaggedParts .Select(tp => new ClassifiedTextRun(tp.Tag.ToClassificationTypeName(), tp.Text))); } else { resolvedCompletionItem = RoslynCompletionItem.From(completionItem); ((RoslynCompletionItem)resolvedCompletionItem).Description = description.TaggedParts.Select( tp => new RoslynTaggedText { Tag = tp.Tag, Text = tp.Text }).ToArray(); } resolvedCompletionItem.Detail = description.TaggedParts.GetFullText(); return(resolvedCompletionItem); }
public async Task <LSP.SignatureHelp> HandleRequestAsync(Solution solution, LSP.TextDocumentPositionParams request, LSP.ClientCapabilities clientCapabilities, CancellationToken cancellationToken, bool keepThreadContext = false) { var document = solution.GetDocumentFromURI(request.TextDocument.Uri); if (document == null) { return(new LSP.SignatureHelp()); } var position = await document.GetPositionFromLinePositionAsync(ProtocolConversions.PositionToLinePosition(request.Position), cancellationToken).ConfigureAwait(keepThreadContext); var providers = _allProviders.Where(p => p.Metadata.Language == document.Project.Language); var triggerInfo = new SignatureHelpTriggerInfo(SignatureHelpTriggerReason.InvokeSignatureHelpCommand); foreach (var provider in providers) { var items = await provider.Value.GetItemsAsync(document, position, triggerInfo, cancellationToken).ConfigureAwait(keepThreadContext); if (items != null) { var sigInfos = new ArrayBuilder <LSP.SignatureInformation>(); foreach (var item in items.Items) { LSP.SignatureInformation sigInfo; if (clientCapabilities?.HasVisualStudioLspCapability() == true) { sigInfo = new LSP.VSSignatureInformation { ColorizedLabel = GetSignatureClassifiedText(item) }; } else { sigInfo = new LSP.SignatureInformation(); } sigInfo.Label = GetSignatureText(item); sigInfo.Documentation = new LSP.MarkupContent { Kind = LSP.MarkupKind.PlainText, Value = item.DocumentationFactory(cancellationToken).GetFullText() }; sigInfo.Parameters = item.Parameters.Select(p => new LSP.ParameterInformation { Label = p.Name, Documentation = new LSP.MarkupContent { Kind = LSP.MarkupKind.PlainText, Value = p.DocumentationFactory(cancellationToken).GetFullText() } }).ToArray(); sigInfos.Add(sigInfo); } var sigHelp = new LSP.SignatureHelp { ActiveSignature = GetActiveSignature(items), ActiveParameter = items.ArgumentIndex, Signatures = sigInfos.ToArrayAndFree() }; return(sigHelp); } } return(new LSP.SignatureHelp()); }