简体   繁体   中英

How do I create syntax nodes in Roslyn from scratch?

I would like to generate syntax nodes with the Roslyn API without having a pre-existing syntax node. That is, I cannot simply use the WithXYZ() methods on an existing object to modify it because there is no existing object.

For example, I would like to generate an InvocationExpressionSyntax object. Assuming a constructor was available, I could do something like

var invoke = new InvocationExpressionSyntax(expression, arguments);

But the constructor for InvocationExpressionSyntax seems to not be public.

http://www.philjhale.com/2012/10/getting-started-with-roslyn.html

this blog suggests that I can use an API such as

Syntax.InvocationExpression()

but I don't see what Syntax refers to, and I don't see anything that resembles it in the Roslyn API.

I did find Microsoft.CodeAnalysis.VisualBasic.SyntaxFactory that lets me do

var invoke = SyntaxFactory.InvocationExpression().WithExpression(expression);

And this works well enough for me. There is also Microsoft.CodeAnalysis.CSharp.SyntaxFactory for anyone wondering.

Is SyntaxFactory the proper way to create new syntax nodes?

The way I found SyntaxFactory.InvocationExpression was by looking at the PublicAPI.txt file in the roslyn source code ( https://github.com/dotnet/roslyn ) under the src/Compilers/VisualBasic/Portable directory. Otherwise, I don't see where SyntaxFactory is documented.

As the other answer stated, the SyntaxFactory is the correct class to use. As you have found there are two syntax factories available, Microsoft.CodeAnalysis.CSharp.SyntaxFactory and Microsoft.CodeAnalysis.VisualBasic.SyntaxFactory , depending on which language you are using.

Usually the calls into the SyntaxFactory are chained together, so you end up with many calls to the SytnaxFactory methods to generate even simple lines of code. For example, the code Console.WriteLine("A"); would be represented by the following calls to the Syntax Factory:

var console = SyntaxFactory.IdentifierName("Console");
var writeline = SyntaxFactory.IdentifierName("WriteLine");
var memberaccess = SyntaxFactory.MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, console, writeline);

var argument = SyntaxFactory.Argument(SyntaxFactory.LiteralExpression(SyntaxKind.StringLiteralExpression, SyntaxFactory.Literal("A")));
var argumentList = SyntaxFactory.SeparatedList(new[] { argument });

var writeLineCall =
    SyntaxFactory.ExpressionStatement(
    SyntaxFactory.InvocationExpression(memberaccess,
    SyntaxFactory.ArgumentList(argumentList)));

If you are unsure of how to generate nodes for some specific code, Kirill Osenkov created the Roslyn Quoter project on GitHub, which you can use to generate the SyntaxFactory code for you.

I recently did a blog post on this topic if you would like to read further.

是的, SyntaxFactory类型是从头开始创建语法节点的方法。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM