private AutoCompleteItem MakeAutoCompleteResponse(WantsType wants, ISymbol symbol, string completionText, bool includeOptionalParams = true) { var displayNameGenerator = new SnippetGenerator(); displayNameGenerator.IncludeMarkers = false; displayNameGenerator.IncludeOptionalParameters = includeOptionalParams; var response = new AutoCompleteItem(); response.CompletionText = completionText; // TODO: Do something more intelligent here response.DisplayText = displayNameGenerator.Generate(symbol); if ((wants & WantsType.WantDocumentationForEveryCompletionResult) == WantsType.WantDocumentationForEveryCompletionResult) { response.Description = DocumentationConverter.ConvertDocumentation(symbol.GetDocumentationCommentXml(), "\n" /*_formattingOptions.NewLine*/); } if ((wants & WantsType.WantReturnType) == WantsType.WantReturnType) { response.ReturnType = ReturnTypeFormatter.GetReturnType(symbol); } if ((wants & WantsType.WantKind) == WantsType.WantKind) { response.Kind = symbol.GetKind(); } // if (request.WantSnippet) // { // var snippetGenerator = new SnippetGenerator(); // snippetGenerator.IncludeMarkers = true; // snippetGenerator.IncludeOptionalParameters = includeOptionalParams; // response.Snippet = snippetGenerator.Generate(symbol); // } // if (request.WantMethodHeader) // { // response.MethodHeader = displayNameGenerator.Generate(symbol); // } return(response); }
public async Task <object> Handle(DesignHub hub, InvokeArgs args) { int type = args.GetInt32(); //TODO: remove it string fileName = args.GetString(); int line = args.GetInt32() - 1; //注意:前端传过来的值需要-1 int column = args.GetInt32() - 1; string wordToComplete = args.GetString(); WantsType wants = WantsType.WantDocumentationForEveryCompletionResult | WantsType.WantKind | WantsType.WantReturnType; //暂默认 var completions = new HashSet <AutoCompleteItem>(); var document = hub.TypeSystem.Workspace.GetOpenedDocumentByName(fileName); if (document == null) { throw new Exception($"Cannot find opened document: {fileName}"); } var sourceText = await document.GetTextAsync(); var position = sourceText.Lines.GetPosition(new LinePosition(line, column)); var service = CompletionService.GetService(document); var completionList = await service.GetCompletionsAsync(document, position); if (completionList != null) { // Only trigger on space if Roslyn has object creation items //if (request.TriggerCharacter == " " && !completionList.Items.Any(i => i.IsObjectCreationCompletionItem())) //{ // return completions; //} // get recommened symbols to match them up later with SymbolCompletionProvider var semanticModel = await document.GetSemanticModelAsync(); var recommendedSymbols = await Recommender.GetRecommendedSymbolsAtPositionAsync(semanticModel, position, hub.TypeSystem.Workspace); foreach (var item in completionList.Items) { var completionText = item.DisplayText; if (completionText.IsValidCompletionFor(wordToComplete)) { var symbols = await item.GetCompletionSymbolsAsync(recommendedSymbols, document); if (symbols.Any()) { foreach (var symbol in symbols) { if (item.UseDisplayTextAsCompletionText()) { completionText = item.DisplayText; } else if (item.TryGetInsertionText(out var insertionText)) { completionText = insertionText; } else { completionText = symbol.Name; } if (symbol != null) { if ((wants & WantsType.WantSnippet) == WantsType.WantSnippet) { // foreach (var completion in MakeSnippetedResponses(request, symbol, completionText)) // { // completions.Add(completion); // } } else { completions.Add(MakeAutoCompleteResponse(wants, symbol, completionText)); } } } // if we had any symbols from the completion, we can continue, otherwise it means // the completion didn't have an associated symbol so we'll add it manually continue; } // for other completions, i.e. keywords, create a simple AutoCompleteResponse // we'll just assume that the completion text is the same // as the display text. var response = new AutoCompleteItem() { CompletionText = item.DisplayText, DisplayText = item.DisplayText, Snippet = item.DisplayText, Kind = (wants & WantsType.WantKind) == WantsType.WantKind ? item.Tags.First() : null }; completions.Add(response); } } } //todo: 处理overloads return(completions .OrderByDescending(c => c.CompletionText.IsValidCompletionStartsWithExactCase(wordToComplete)) .ThenByDescending(c => c.CompletionText.IsValidCompletionStartsWithIgnoreCase(wordToComplete)) .ThenByDescending(c => c.CompletionText.IsCamelCaseMatch(wordToComplete)) .ThenByDescending(c => c.CompletionText.IsSubsequenceMatch(wordToComplete)) .ThenBy(c => c.DisplayText, StringComparer.OrdinalIgnoreCase) .ThenBy(c => c.CompletionText, StringComparer.OrdinalIgnoreCase) .ToArray()); }