如何在 Roslyn 推荐符号中包含关键字和别名?

How to include keywords and aliases in Roslyn recommended symbols?

我正在使用 Roslyn 创建带有 IntelliSense 的 C# 脚本控件。

我对得到的结果总体上非常满意,但是,推荐的符号不包含 forif 等关键字,也不包含类型别名例如 int,当它包含 Int32.

更具体地说,我使用的是Microsoft.CodeAnalysis.Recommendations,即:

Recommender.GetRecommendedSymbolsAtPositionAsync(mySemanticModel, scriptPosition, myAdhocWorkspace);

我的 SemanticModel 对象是从 C# 编译中获得的,它至少总是引用 mscorlib.dll

在我脚本的所有位置,推荐的补全总是正确的。但是,我认为如果缺少 ifelsefor 等关键字,它们就不完整

我发现手动在我的 IntelliSense 中包含常见类型别名对我来说很容易。也就是说,如果 Int32 是一个可能的补全,那么我可以手动添加 int.

然而,if 语句或 for 语句甚至 is/as 在给定范围内是否合适则不太明显。

有没有办法在以这种方式获取推荐符号时包含这些关键字?

是否还有一种方法可以自动包含类型别名?

似乎Recommender.GetRecommendedSymbolsAtPositionAsync只提供符号补全。也就是说,方法、类型等(ISymbol 实现)。

如果想要keywords或者snippets补全,可以使用Microsoft.CodeAnalysis.Completion.CompletionService

void CompletionExample()
{
    var code = @"using System;

namespace NewConsoleApp
{
class NewClass
{
    void Method()
    {
fo // I want to get 'for' completion for this
    }
}
}";

    var completionIndex = code.LastIndexOf("fo") + 2;
    // Assume you have a method that create a workspace for you
    var workspace = CreateWorkspace("newSln", "newProj", code);
    var doc = workspace.CurrentSolution.Projects.First().Documents.First();

    var service = CompletionService.GetService(doc);
    var completionItems = service.GetCompletionsAsync(doc, completionIndex).Result.Items;

    foreach (var result in completionItems)
    {
        Console.WriteLine(result.DisplayText);
        Console.WriteLine(string.Join(",", result.Tags));
        Console.WriteLine();
    }
}

您可以尝试了解如何根据您的需要自定义它(规则、过滤器)。

请注意,每个结果都来自特定的完成提供程序 (item.Properties["Provider"]),您可以创建自定义 CompletionProvider(至少您应该能够)。

您也可以看看 C# for VS code (that powered with OmniSharp) 看看他们是如何完成这项工作的。