在 Roslyn 中从类型 string/ITypeSymbol 创建语法树

Creating a syntax tree from a type string/ITypeSymbol in Roslyn

Roslyn 是否提供了为任意有效类型字符串或 ITypeSymbol 生成语法树的方法?

例如System.Threading.Task解析为

的树
QualifiedName(
    QualifiedName(
        IdentifierName("System"),
        IdentifierName("Threading")),
    IdentifierName("Task"))

System.Threading.Task<int> 解析为

的树
QualifiedName(
    QualifiedName(
        IdentifierName("System"),
        IdentifierName("Threading")),
    GenericName(
        Identifier("Task"))
    .WithTypeArgumentList(
        TypeArgumentList(
            SingletonSeparatedList<TypeSyntax>(
                PredefinedType(
                    Token(SyntaxKind.IntKeyword))))))

最后System.Threading.Task<,>解析为

的树
QualifiedName(
    QualifiedName(
        IdentifierName("System"),
        IdentifierName("Threading")),
    GenericName(
        Identifier("Task"))
    .WithTypeArgumentList(
        TypeArgumentList(
            SeparatedList<TypeSyntax>(
                new SyntaxNodeOrToken[]{
                    OmittedTypeArgument(),
                    Token(SyntaxKind.CommaToken),
                    OmittedTypeArgument()}))))

虽然我正在为此用例编写轻量级词法分析器,但我想知道 Roslyn 是否已经提供了它。

更新 #1: 基于 Tamas 描述的方法最小化解析的最终变体:

public static async Task<TypeSyntax> CreateTypeSyntax(string typeName)
{
    var options = new CSharpParseOptions(kind: SourceCodeKind.Script);
    var parsedTree = CSharpSyntaxTree.ParseText($"typeof({typeName})", options);
    var treeRoot = await parsedTree.GetRootAsync();
    var typeNameNode = treeRoot.DescendantNodes().OfType<TypeSyntax>().FirstOrDefault();
    return typeNameNode;
}

您可以使用 CSharpSyntaxTree.ParseText 从任何输入生成树。如果你给它一个你可以控制的输入,那么你就可以找到你感兴趣的子树。例如,现在你想要一个类型的语法。您可以将输入放在一起:

@"class MyClass
{
  TYPE_THAT_INTERESTS_ME field;
}"

然后获取它的树,导航到该字段,并从其 VariableDeclarationSyntax 中获取 TypeSyntax