private static async Task <ISymbol?> TryRehydrateAsync(Document document, CompletionItem item, CancellationToken cancellationToken) { // If we're need to rehydrate the conversion, pull out the necessary parts. if (item.Properties.ContainsKey(RehydrateName)) { var symbols = await SymbolCompletionItem.GetSymbolsAsync(item, document, cancellationToken).ConfigureAwait(false); if (symbols.Length == 3 && symbols[0] is INamedTypeSymbol containingType && symbols[1] is ITypeSymbol fromType && symbols[2] is ITypeSymbol toType) { return(CodeGenerationSymbolFactory.CreateConversionSymbol( toType: toType, fromType: CodeGenerationSymbolFactory.CreateParameterSymbol(fromType, "value"), containingType: containingType, documentationCommentXml: item.Properties[DocumentationCommentXmlName])); } return(null); } else { // Otherwise, just go retrieve the conversion directly. var symbols = await SymbolCompletionItem.GetSymbolsAsync(item, document, cancellationToken).ConfigureAwait(false); return(symbols.Length == 1 ? symbols.Single() : null); } }
public override async Task <TextChange?> GetTextChangeAsync(Document document, CompletionItem selectedItem, char?ch, CancellationToken cancellationToken) { if (ch.HasValue && ch.Value == '(') { var symbols = await SymbolCompletionItem.GetSymbolsAsync(selectedItem, document, cancellationToken).ConfigureAwait(false); if (symbols.Length > 0) { return(new TextChange(selectedItem.Span, symbols[0].Name)); } } return(new TextChange(selectedItem.Span, selectedItem.DisplayText)); }
/// <summary> /// Filter currentCompletionList according to the current filter text. Roslyn's completion does not /// handle this automatically. /// </summary> static async Task <CompletionModel> FilterModelAsync( RoslynCompilationWorkspace compilationWorkspace, SourceText sourceText, CompletionModel model, CompletionHelper helper, CancellationToken ct) { if (model == null) { return(null); } CompletionItem bestFilterMatch = null; var bestFilterMatchIndex = 0; var document = compilationWorkspace.GetSubmissionDocument(sourceText.Container); var newFilteredCompletions = new List <CompletionItem> (); foreach (var item in model.TotalItems) { var completion = item; // TODO: Better range checking on delete before queuing up filtering (see TODO in HandleChange) if (completion.Span.Start > sourceText.Length) { continue; } var filterText = GetFilterText(sourceText, completion); // CompletionRules.MatchesFilterText seems to always return false when filterText is // empty. if (filterText != String.Empty && !helper.MatchesPattern( completion.FilterText, filterText, CultureInfo.CurrentCulture)) { continue; } var itemDetail = String.Empty; var symbols = await SymbolCompletionItem.GetSymbolsAsync(completion, document, ct) .ConfigureAwait(false); var overloads = symbols.OfType <IMethodSymbol> ().ToArray(); if (overloads.Length > 0) { itemDetail = overloads [0].ToMonacoSignatureString(); if (overloads.Length > 1) { itemDetail += $" (+ {overloads.Length - 1} overload(s))"; } } completion = completion.AddProperty(itemDetailPropertyName, itemDetail); newFilteredCompletions.Add(completion); if (bestFilterMatch == null || helper.CompareItems( completion, bestFilterMatch, filterText, CultureInfo.CurrentCulture) > 0) { bestFilterMatch = completion; bestFilterMatchIndex = newFilteredCompletions.Count - 1; } } if (newFilteredCompletions.Count == 0) { return(null); } return(model .WithFilteredItems(newFilteredCompletions) .WithSelectedItem(bestFilterMatch, bestFilterMatchIndex) .WithText(sourceText)); }