ThatRA
ThatRA

Reputation: 79

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

Does Roslyn provide a way to generate a syntax tree for an arbitrary valid type string or ITypeSymbol?

For example, System.Threading.Task parses to a tree of

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

While System.Threading.Task<int> parses to a tree of

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

and finally System.Threading.Task<,> parses to a tree of

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

While I am in the process of writing a lightweight lexer for this use case, I wanted to know if this was provided by Roslyn already.

Update #1: Final variant to minimize parsing based on the approach described by 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;
}

Upvotes: 2

Views: 902

Answers (1)

Tamas
Tamas

Reputation: 6420

You can use CSharpSyntaxTree.ParseText to generate a tree from any input. If you give it an input which you have control over, then you can get to the subtree that interests you. So for example now you want to have the syntax for a type. You can put together an input like:

@"class MyClass
{
  TYPE_THAT_INTERESTS_ME field;
}"

Then get the tree of it, and navigate to the field, and get the TypeSyntax from its VariableDeclarationSyntax.

Upvotes: 1

Related Questions