从Roslyn中的类型字符串/ ITypeSymbol创建语法树

时间:2016-04-22 08:56:29

标签: .net abstract-syntax-tree 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;
}

1 个答案:

答案 0 :(得分:1)

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

@"class MyClass
{
  TYPE_THAT_INTERESTS_ME field;
}"

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