/// <summary> /// 取得光标位置的可用智能感知项目 /// </summary> /// <param name="bodytext">代码</param> /// <param name="logic">对应项目</param> /// <param name="index">光标所在位置</param> /// <returns>可能智能感知项目</returns> public IEnumerable <ISymbol> GetRecommendedSymbolsAtPositionAsync(string bodytext, IDocumentProvider logic, int index) { if (logic is IPartCodeProvider) { var doc = Documents[logic.GetDocumentGuid()]; bodytext = (logic as IPartCodeProvider).ReplaceNewCode(doc.GetTextAsync().Result.ToString(), bodytext); //var doc = Documents[method.BusinessObject.Oid]; //var newText = method.ReplaceNewCode(doc.GetTextAsync().Result.ToString(), bodytext); //UpdateText(newText, method.BusinessObject); //var semanticModel = SemanticModels[method.BusinessObject.Oid]; //return Recommender.GetRecommendedSymbolsAtPositionAsync(semanticModel, pos, Workspace).Result; } UpdateText(bodytext, logic); if (logic is IPartCodeProvider) { var define = (logic as IPartCodeProvider).DefaultLocation; index = bodytext.IndexOf(define) + define.Length + index + 1; } var semanticModel = SemanticModels[logic.GetDocumentGuid()]; return(Recommender.GetRecommendedSymbolsAtPositionAsync(semanticModel, index, Workspace).Result); }
public IReadOnlyList <ISymbol> GetRecommendedSymbols(DocumentId documentId, int position) { var document = CurrentSolution.GetDocument(documentId); var semanticModel = document.GetSemanticModelAsync().Result; return(Recommender.GetRecommendedSymbolsAtPositionAsync(semanticModel, position, this).Result.ToArray()); }
private async Task <IEnumerable <CompletionItem> > GetCompletionList( string code, int cursorPosition) { var(document, offset) = GetDocumentWithOffsetFromCode(code); var absolutePosition = cursorPosition + offset; var service = CompletionService.GetService(document); var completionList = await service.GetCompletionsAsync(document, absolutePosition); if (completionList is null) { return(Enumerable.Empty <CompletionItem>()); } var semanticModel = await document.GetSemanticModelAsync(); var symbols = await Recommender.GetRecommendedSymbolsAtPositionAsync(semanticModel, absolutePosition, document.Project.Solution.Workspace); var symbolToSymbolKey = new Dictionary <(string, int), ISymbol>(); foreach (var symbol in symbols) { var key = (symbol.Name, (int)symbol.Kind); if (!symbolToSymbolKey.ContainsKey(key)) { symbolToSymbolKey[key] = symbol; } } var items = completionList.Items.Select(item => item.ToModel(symbolToSymbolKey, document)).ToArray(); return(items); }
public async Task <CompletionResult> GetCompletionList(WorkspaceRequest request, Budget budget) { budget ??= new TimeBudget(TimeSpan.FromSeconds(defaultBudgetInSeconds)); var package = await _packageFinder.Find <ICreateWorkspace>(request.Workspace.WorkspaceType); var workspace = await request.Workspace.InlineBuffersAsync(); var sourceFiles = workspace.GetSourceFiles(); var(_, documents) = await package.GetCompilationForLanguageServices( sourceFiles, GetSourceCodeKind(request), GetUsings(request.Workspace), budget); var file = workspace.GetFileFromBufferId(request.ActiveBufferId); var(_, _, absolutePosition) = workspace.GetTextLocation(request.ActiveBufferId); var selectedDocument = documents.First(doc => doc.IsMatch(file)); var service = CompletionService.GetService(selectedDocument); var completionList = await service.GetCompletionsAsync(selectedDocument, absolutePosition); var semanticModel = await selectedDocument.GetSemanticModelAsync(); var diagnostics = DiagnosticsExtractor.ExtractSerializableDiagnosticsFromSemanticModel(request.ActiveBufferId, budget, semanticModel, workspace); var symbols = await Recommender.GetRecommendedSymbolsAtPositionAsync( semanticModel, absolutePosition, selectedDocument.Project.Solution.Workspace); var symbolToSymbolKey = new Dictionary <(string, int), ISymbol>(); foreach (var symbol in symbols) { var key = (symbol.Name, (int)symbol.Kind); if (!symbolToSymbolKey.ContainsKey(key)) { symbolToSymbolKey[key] = symbol; } } if (completionList == null) { return(new CompletionResult(requestId: request.RequestId, diagnostics: diagnostics)); } var completionItems = completionList.Items .Where(i => i != null) .Select(item => item.ToModel(symbolToSymbolKey, selectedDocument)); return(new CompletionResult(completionItems .Deduplicate() .ToArray(), requestId: request.RequestId, diagnostics: diagnostics)); }
public static IEnumerable <ICompletionData> Resolve(string code, int position, string[] references = null, IEnumerable <Tuple <string, string> > includes = null) { var completions = new List <ICompletionData>(); var pos = position - 1; var workspace = new AdhocWorkspace(); var document = InitWorkspace(workspace, code, null, AgregateRefs(references), includes); var model = document.GetSemanticModelAsync().Result; var symbols = Recommender.GetRecommendedSymbolsAtPositionAsync(model, position, workspace).Result.ToArray(); var data = symbols.Select(s => s.ToCompletionData()).ToArray(); foreach (var group in data.GroupBy(x => x.DisplayText)) { var item = group.First(); if (group.Count() > 1) { foreach (var overload in group) { item.AddOverload(overload); //item.HasOverloads = true; } } completions.Add(item); } return(completions); }
private async Task <IEnumerable <CompletionItem> > GetCompletionList(string code, int cursorPosition, ScriptState scriptState) { var metadataReferences = ImmutableArray <MetadataReference> .Empty; var forcedState = false; if (scriptState == null) { scriptState = await CSharpScript.RunAsync(string.Empty, ScriptOptions); forcedState = true; } var compilation = scriptState.Script.GetCompilation(); metadataReferences = metadataReferences.AddRange(compilation.References); var originalCode = forcedState ? string.Empty : scriptState.Script.Code ?? string.Empty; var buffer = new StringBuilder(originalCode); if (!string.IsNullOrWhiteSpace(originalCode) && !originalCode.EndsWith(Environment.NewLine)) { buffer.AppendLine(); } buffer.AppendLine(code); var fullScriptCode = buffer.ToString(); var offset = fullScriptCode.LastIndexOf(code, StringComparison.InvariantCulture); var absolutePosition = Math.Max(offset, 0) + cursorPosition; if (_fixture == null || _metadataReferences != metadataReferences) { _fixture = new WorkspaceFixture(compilation.Options, metadataReferences); _metadataReferences = metadataReferences; } var document = _fixture.ForkDocument(fullScriptCode); var service = CompletionService.GetService(document); var completionList = await service.GetCompletionsAsync(document, absolutePosition); var semanticModel = await document.GetSemanticModelAsync(); var symbols = await Recommender.GetRecommendedSymbolsAtPositionAsync(semanticModel, absolutePosition, document.Project.Solution.Workspace); var symbolToSymbolKey = new Dictionary <(string, int), ISymbol>(); foreach (var symbol in symbols) { var key = (symbol.Name, (int)symbol.Kind); if (!symbolToSymbolKey.ContainsKey(key)) { symbolToSymbolKey[key] = symbol; } } var items = completionList.Items.Select(item => item.ToModel(symbolToSymbolKey, document).ToDomainObject()).ToArray(); return(items); }
public Task <IReadOnlyList <ISymbol> > GetRecommendedSymbolsAsync(DocumentId documentId, int position, CancellationToken cancellationToken) { return(Task.Run(async() => { var document = CurrentSolution.GetDocument(documentId); var semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); var symbols = await Recommender.GetRecommendedSymbolsAtPositionAsync(semanticModel, position, this, null, cancellationToken).ConfigureAwait(false); return (IReadOnlyList <ISymbol>)symbols.ToArray(); }, cancellationToken)); }
public async Task <IEnumerable <string> > GetCompletionStringsAsync(string code, int position, CancellationToken token) { Workspace workspace = new AdhocWorkspace(); var compilation = await runner.GetCompilationAsync(code); var tree = compilation.CompilationObject.SyntaxTrees.Single(); SemanticModel sm = compilation.CompilationObject.GetSemanticModel(tree); var symbols = await Recommender.GetRecommendedSymbolsAtPositionAsync(sm, position, workspace, cancellationToken : token); return(symbols.OrderBy(s => s.Name).Select(s => s.Name).Distinct()); }
public async Task <IEnumerable <CompletionData> > GetCompletionListAsync(int position, string code) { CompileScript(code); var semanticModel = await document.GetSemanticModelAsync(); var items = await Recommender.GetRecommendedSymbolsAtPositionAsync( semanticModel, position, workspace); return(items.Select(symbol => new CompletionData() { Content = symbol.Name.EndsWith("Attribute") ? symbol.Name.Substring(0, symbol.Name.Length - "Attribute".Length) : symbol.Name, Text = symbol.Name.EndsWith("Attribute") ? symbol.Name.Substring(0, symbol.Name.Length - "Attribute".Length) : symbol.Name, Description = symbol.ToMinimalDisplayString(semanticModel, position) })); }
public async Task <IEnumerable <CompletionData> > GetCompletionListAsync(int position, string code) { CompileScript(code); if (_semanticModel == null || _workspace == null) { return(Enumerable.Empty <CompletionData>()); } var items = await Recommender.GetRecommendedSymbolsAtPositionAsync(_semanticModel, position, _workspace); return(items.Select(symbol => new CompletionData() { Content = symbol.Name, Text = symbol.Name, Description = symbol.ToMinimalDisplayString(_semanticModel, position) })); }
public IEnumerable <ISymbol> GetRecommendedSymbols(string code, int index) { SyntaxTree syntaxTree = CSharpSyntaxTree.ParseText(code, this.cSharpParseOptions); var syntaxTrees = new[] { syntaxTree }; CSharpCompilation compilation = CSharpCompilation.Create(assemblyName: this.ConsoleAssemblyName, syntaxTrees: syntaxTrees, references: this.references.Where(r => r.Display != this.dummyConsoleAssembly.Location), options: this.compilationOptions); var workspace = new AdhocWorkspace(); string projName = "NewProject"; var projectId = ProjectId.CreateNewId(); var versionStamp = VersionStamp.Create(); var projectInfo = ProjectInfo.Create(projectId, versionStamp, projName, projName, LanguageNames.CSharp); var newProject = workspace.AddProject(projectInfo); var sourceText = SourceText.From(code); var newDocument = workspace.AddDocument(newProject.Id, "NewFile.cs", sourceText); var recommendedSymblos = Recommender.GetRecommendedSymbolsAtPositionAsync(compilation.GetSemanticModel(syntaxTree), index, workspace).Result; return(recommendedSymblos); }
static void Main() { var project = _Solution.Projects.Single(p => p.Name == "ConfigureAwaitTest"); var fooCs = project.Documents.Single(d => d.Name == "Foo.cs"); // Find the 'dot' token in the first Console.WriteLine member access expression. var tree = fooCs.GetSyntaxTreeAsync().Result; var model = project.GetCompilationAsync().Result.GetSemanticModel(tree); var consoleDot = tree.GetRoot().DescendantNodes().OfType <MemberAccessExpressionSyntax>().First().OperatorToken; // Get recommendations at the indicated cursor position. if (_Solution.Workspace != null) { var result = Recommender.GetRecommendedSymbolsAtPositionAsync(model, consoleDot.GetLocation().SourceSpan.Start + 1, _Solution.Workspace).Result; foreach (var symbol in result) { Console.WriteLine(symbol); } } }
public static async Task <(CompletionList, string)> GetCompletion(string source, string language, int position) { var description = string.Empty; if (language == "csharp") { if (!CSharpEditorProject.Current.IsInitialised()) { return(null, null); } var document = CSharpEditorProject.Current.GetCurrentDocument(source); var completionService = Microsoft.CodeAnalysis.Completion.CompletionService.GetService(document); var items = await completionService.GetCompletionsAsync(document, position); var semanticModel = await document.GetSemanticModelAsync(); var recommendedSymbols = await Recommender.GetRecommendedSymbolsAtPositionAsync(semanticModel, position, CSharpEditorProject.Current.Workspace); if (items != null && items.Items.Length == 1) { var documentDescription = await completionService.GetDescriptionAsync(document, items.Items[0]); description = documentDescription.Text; } return(items, description); } else if (language == "vb") { } return(null, null); }
public async Task <IEnumerable <AutoCompleteResponse> > Handle(AutoCompleteRequest request) { var documents = _workspace.GetDocuments(request.FileName); var wordToComplete = request.WordToComplete; var completions = new HashSet <AutoCompleteResponse>(); foreach (var document in documents) { var sourceText = await document.GetTextAsync(); var position = sourceText.Lines.GetPosition(new LinePosition(request.Line, request.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 recommended symbols to match them up later with SymbolCompletionProvider var semanticModel = await document.GetSemanticModelAsync(); var recommendedSymbols = (await Recommender.GetRecommendedSymbolsAtPositionAsync(semanticModel, position, _workspace)).ToArray(); var isSuggestionMode = completionList.SuggestionModeItem != null; foreach (var item in completionList.Items) { var completionText = item.DisplayText; var preselect = item.Rules.MatchPriority == MatchPriority.Preselect; 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 (request.WantSnippet) { foreach (var completion in MakeSnippetedResponses(request, symbol, completionText, preselect, isSuggestionMode)) { completions.Add(completion); } } else { completions.Add(MakeAutoCompleteResponse(request, symbol, completionText, preselect, isSuggestionMode)); } } } // 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 AutoCompleteResponse() { CompletionText = item.DisplayText, DisplayText = item.DisplayText, Snippet = item.DisplayText, Kind = request.WantKind ? item.Tags.First() : null, IsSuggestionMode = isSuggestionMode, Preselect = preselect }; completions.Add(response); } } } } 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)); }
public async Task <IEnumerable <AutoCompleteResponse> > Handle(AutoCompleteRequest request) { var documents = _workspace.GetDocuments(request.FileName); var wordToComplete = request.WordToComplete; var completions = new HashSet <AutoCompleteResponse>(); foreach (var document in documents) { var sourceText = await document.GetTextAsync(); var position = sourceText.Lines.GetPosition(new LinePosition(request.Line, request.Column)); var service = CompletionService.GetService(document); var completionList = await service.GetCompletionsAsync(document, position); // Add keywords from the completion list. We'll use the recommender service to get symbols // to create snippets from. foreach (var item in completionList.Items) { if (item.Tags.Contains(CompletionTags.Keyword)) { // Note: For keywords, we'll just assume that the completion text is the same // as the display text. var keyword = item.DisplayText; if (keyword.IsValidCompletionFor(wordToComplete)) { var response = new AutoCompleteResponse() { CompletionText = item.DisplayText, DisplayText = item.DisplayText, Snippet = item.DisplayText, Kind = request.WantKind ? "Keyword" : null }; completions.Add(response); } } } var model = await document.GetSemanticModelAsync(); var symbols = await Recommender.GetRecommendedSymbolsAtPositionAsync(model, position, _workspace); foreach (var symbol in symbols.Where(s => s.Name.IsValidCompletionFor(wordToComplete))) { if (request.WantSnippet) { foreach (var completion in MakeSnippetedResponses(request, symbol)) { completions.Add(completion); } } else { completions.Add(MakeAutoCompleteResponse(request, symbol)); } } } 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.CompletionText)); }
protected override async Task <IEnumerable <CompletionData> > GetItemsWorkerAsync(CompletionResult completionResult, CompletionEngine engine, CompletionContext completionContext, CompletionTriggerInfo info, SyntaxContext ctx, CancellationToken cancellationToken) { var semanticModel = ctx.SemanticModel; var result = new List <CompletionData> (); if (info.TriggerCharacter == ' ') { var newExpression = ObjectCreationContextHandler.GetObjectCreationNewExpression(ctx.SyntaxTree, completionContext.Position, cancellationToken); if (newExpression == null && info.CompletionTriggerReason == CompletionTriggerReason.CharTyped && !ctx.LeftToken.IsKind(SyntaxKind.EqualsToken) && !ctx.LeftToken.IsKind(SyntaxKind.EqualsEqualsToken)) { return(Enumerable.Empty <CompletionData> ()); } completionResult.AutoCompleteEmptyMatch = false; } var parent = ctx.TargetToken.Parent; bool isInAttribute = ctx.CSharpSyntaxContext.IsAttributeNameContext; bool isInBaseList = parent != null && parent.IsKind(SyntaxKind.BaseList); bool isInUsingDirective = parent != null && parent.Parent != null && parent.Parent.IsKind(SyntaxKind.UsingDirective) && !parent.IsKind(SyntaxKind.QualifiedName); var isInQuery = ctx.CSharpSyntaxContext.IsInQuery; var completionDataLookup = new Dictionary <Tuple <string, SymbolKind>, ISymbolCompletionData> (); bool isInCatchTypeExpression = parent != null && parent.IsKind(SyntaxKind.CatchDeclaration) || parent.IsKind(SyntaxKind.QualifiedName) && parent.Parent != null && parent.Parent.IsKind(SyntaxKind.CatchDeclaration); Action <ISymbolCompletionData> addData = d => { var key = Tuple.Create(d.DisplayText, d.Symbol.Kind); ISymbolCompletionData data; if (completionDataLookup.TryGetValue(key, out data)) { data.AddOverload(d); return; } completionDataLookup.Add(key, d); result.Add(d); }; var completionCategoryLookup = new Dictionary <string, CompletionCategory> (); foreach (var symbol in await Recommender.GetRecommendedSymbolsAtPositionAsync(semanticModel, completionContext.Position, engine.Workspace, null, cancellationToken)) { if (symbol.Kind == SymbolKind.NamedType) { if (isInAttribute) { var type = (ITypeSymbol)symbol; if (type.IsAttribute()) { var v = type.Name.Substring(0, type.Name.Length - "Attribute".Length); var needsEscaping = SyntaxFacts.GetKeywordKind(v) != SyntaxKind.None; needsEscaping = needsEscaping || (isInQuery && SyntaxFacts.IsQueryContextualKeyword(SyntaxFacts.GetContextualKeywordKind(v))); if (!needsEscaping) { addData(engine.Factory.CreateSymbolCompletionData(this, symbol, v)); continue; } } } if (isInBaseList) { var type = (ITypeSymbol)symbol; if (type.IsSealed || type.IsStatic) { continue; } } if (isInCatchTypeExpression) { var type = (ITypeSymbol)symbol; if (!IsException(type)) { continue; } } } if (isInUsingDirective && symbol.Kind != SymbolKind.Namespace) { continue; } var newData = engine.Factory.CreateSymbolCompletionData(this, symbol, symbol.Name.EscapeIdentifier(isInQuery)); ISymbol categorySymbol; var method = symbol as IMethodSymbol; if (method != null) { if (method.IsReducedExtension()) { categorySymbol = method.ReceiverType; } else { categorySymbol = (ISymbol)symbol.ContainingType; } } else { categorySymbol = (ISymbol)symbol.ContainingType ?? symbol.ContainingNamespace; } if (categorySymbol != null) { CompletionCategory category; var key = categorySymbol.ToDisplayString(); if (!completionCategoryLookup.TryGetValue(key, out category)) { completionCategoryLookup [key] = category = engine.Factory.CreateCompletionDataCategory(categorySymbol); } newData.CompletionCategory = category; } addData(newData); } return((IEnumerable <CompletionData>)result); }
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()); }
protected override Task <IEnumerable <ISymbol> > GetSymbolsWorker(AbstractSyntaxContext context, int position, OptionSet options, CancellationToken cancellationToken) { return(Recommender.GetRecommendedSymbolsAtPositionAsync(context.SemanticModel, position, context.Workspace, options, cancellationToken)); }
public async Task <IEnumerable <NeedContextItemsArgs.ContextItem> > GetCompletionItemsAsync(string code, int offset) { UpdateDocument(code); Document[] documents = new Document[1] { document }; string wordToComplete = GetPartialWord(code, offset); var completions = new List <NeedContextItemsArgs.ContextItem>(); foreach (Document document in documents) { SourceText source = await document.GetTextAsync(); CompletionService service = CompletionService.GetService(document); CompletionList completionList = await service.GetCompletionsAsync(document, offset); if (completionList != null) { // get recommended symbols to match them up later with SymbolCompletionProvider SemanticModel semanticModel = await document.GetSemanticModelAsync(); ISymbol[] recommendedSymbols = (await Recommender.GetRecommendedSymbolsAtPositionAsync(semanticModel, offset, workspace)).ToArray(); bool isSuggestionMode = completionList.SuggestionModeItem != null; foreach (CompletionItem item in completionList.Items) { string completionText = item.DisplayText; bool preselect = item.Rules.MatchPriority == MatchPriority.Preselect; if (completionText.IsValidCompletionFor(wordToComplete)) { var symbols = await item.GetCompletionSymbolsAsync(recommendedSymbols, document); if (symbols.Any()) { foreach (ISymbol 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 (request.WantSnippet) //{ // foreach (var completion in MakeSnippetedResponses(request, symbol, completionText, preselect, isSuggestionMode)) // { // completions.Add(completion); // } //} //else { //completions.Add(MakeAutoCompleteResponse(request, symbol, completionText, preselect, isSuggestionMode)); completions.Add(new NeedContextItemsArgs.ContextItem() { Name = symbol.Name, Descr = symbol.ToDisplayString(), IsMethod = symbol.Kind == SymbolKind.Method, IsProperty = symbol.Kind == SymbolKind.Property, IsEvent = symbol.Kind == SymbolKind.Event }); if (symbol is IPropertySymbol property) { completions.Last().IsWriteable = !property.IsReadOnly; } } } } // 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 AutoCompleteResponse() //{ // CompletionText = item.DisplayText, // DisplayText = item.DisplayText, // Snippet = item.DisplayText, // Kind = request.WantKind ? item.Tags.First() : null, // IsSuggestionMode = isSuggestionMode, // Preselect = preselect //}; completions.Add(new NeedContextItemsArgs.ContextItem() { Name = item.DisplayText, Descr = item.Tags.First(), }); } } } } return(completions .OrderByDescending(c => c.Name.IsValidCompletionStartsWithExactCase(wordToComplete)) .ThenByDescending(c => c.Name.IsValidCompletionStartsWithIgnoreCase(wordToComplete)) .ThenByDescending(c => c.Name.IsCamelCaseMatch(wordToComplete)) .ThenByDescending(c => c.Name.IsSubsequenceMatch(wordToComplete)) .ThenBy(c => c.Name, StringComparer.OrdinalIgnoreCase) .ThenBy(c => c.Name, StringComparer.OrdinalIgnoreCase)); }
public async Task <CompletionResult[]> GetCompletionsAsync(CompletionRequest request, Source source) { if (source == null) { throw new ArgumentNullException(nameof(source)); } // We need to ensure all dependencies have been downloaded and located. ResolveReferences() gets a // firm reference for each reference and any additional dependencies. var references = _metadataProvider.ResolveReferences(source.Dependencies); var referenceAssemblies = references.Select(r => Assembly.LoadFrom(r.Display)).ToArray(); var compositionContext = new ContainerConfiguration() .WithAssemblies(MefHostServices.DefaultAssemblies .Concat(new[] { // These assemblies are necessary to enable language services. Assembly.Load("Microsoft.CodeAnalysis.Features"), Assembly.Load("Microsoft.CodeAnalysis.CSharp.Features") }) .Concat(referenceAssemblies)) .CreateContainer(); var host = MefHostServices.Create(compositionContext); // Setup a workspace for this code file, since we aren't actively managing a project or solutions. var workspace = new AdhocWorkspace(host); var projectName = RandomString(6, "Project"); var assemblyName = RandomString(6, "Assembly"); var documentName = RandomString(6, "Document"); var document = workspace.CurrentSolution .AddProject(projectName, assemblyName, LanguageNames.CSharp) .WithMetadataReferences(references) .AddDocument(documentName, SourceText.From(source.Code)); // Determine position of cursor so we know which symbols to recommend. var text = await document.GetTextAsync(); var position = text.Lines.GetPosition(new LinePosition(request.Line, request.Character)); // The code analysis libraries have rolled in all the intellisense code // so all we need to do is get a reference to the CompletionService and // request completions for the given character position. var service = CompletionService.GetService(document); var completions = await service.GetCompletionsAsync(document, position); var completionResults = new List <CompletionResult>(); // We'll handle special cases for keywords, and determine whether the // completions we received are valid for the given text position. if (completions != null) { foreach (var item in completions.Items) { if (item.Tags.Contains(CompletionTags.Keyword)) { // For keywords we'll assume the completion text is the same as the display text. var keyword = item.DisplayText; if (keyword.IsValidCompletionFor(request.WordToComplete)) { var response = new CompletionResult() { CompletionText = item.DisplayText, DisplayText = item.DisplayText, Snippet = item.DisplayText, Kind = request.WantKind ? "Keyword" : null }; completionResults.Add(response); } } } } // Now we'll add completions based on the semantics model and referenced assemblies. var model = await document.GetSemanticModelAsync(); var symbols = await Recommender.GetRecommendedSymbolsAtPositionAsync(model, position, workspace); foreach (var symbol in symbols.Where(s => s.Name.IsValidCompletionFor(request.WordToComplete))) { if (request.WantSnippet) { foreach (var completion in MakeSnippetedResponses(request, symbol)) { completionResults.Add(completion); } } else { completionResults.Add(MakeAutoCompleteResponse(request, symbol)); } } // Order the list to the most appropriate completions first. return(completionResults .OrderByDescending(c => c.CompletionText.IsValidCompletionStartsWithExactCase(request.WordToComplete)) .ThenByDescending(c => c.CompletionText.IsValidCompletionStartsWithIgnoreCase(request.WordToComplete)) .ThenByDescending(c => c.CompletionText.IsCamelCaseMatch(request.WordToComplete)) .ThenByDescending(c => c.CompletionText.IsSubsequenceMatch(request.WordToComplete)) .ThenBy(c => c.CompletionText) .ToArray()); }