我想使用Roslyn API生成语法节点,而不需要预先存在的语法节点。也就是说,我不能简单地在现有对象上使用WithXYZ()方法来修改它,因为没有现有对象。
例如,我想生成一个InvocationExpressionSyntax对象。假设有一个构造函数,我可以做类似的事情
select_item()
但var invoke = new InvocationExpressionSyntax(expression, arguments);
的构造函数似乎不公开。
http://www.philjhale.com/2012/10/getting-started-with-roslyn.html
此博客建议我可以使用
等APIInvocationExpressionSyntax
但是我没有看到Syntax.InvocationExpression()
引用的内容,我在Roslyn API中看不到任何与它类似的内容。
我确实找到了允许我这样做的Microsoft.CodeAnalysis.VisualBasic.SyntaxFactory
Syntax
这对我来说效果很好。任何想知道的人都有var invoke = SyntaxFactory.InvocationExpression().WithExpression(expression);
。
Microsoft.CodeAnalysis.CSharp.SyntaxFactory
是创建新语法节点的正确方法吗?
我找到SyntaxFactory.InvocationExpression的方法是查看src / Compilers / VisualBasic / Portable目录下的roslyn源代码(https://github.com/dotnet/roslyn)中的PublicAPI.txt文件。否则,我没有看到记录SyntaxFactory
的位置。
答案 0 :(得分:15)
正如另一个答案所述,SyntaxFactory
是正确使用的类。正如您所发现的,有两个语法工厂可用,Microsoft.CodeAnalysis.CSharp.SyntaxFactory
和Microsoft.CodeAnalysis.VisualBasic.SyntaxFactory
,具体取决于您使用的语言。
通常,对SyntaxFactory
的调用被链接在一起,因此您最终会调用SytnaxFactory
方法来生成更简单的代码行。例如,代码Console.WriteLine("A");
将由以下对语法工厂的调用表示:
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)));
如果您不确定如何为某些特定代码生成节点,Kirill Osenkov在GitHub上创建了Roslyn Quoter project,您可以使用该代码为您生成SyntaxFactory
代码。
如果您想进一步阅读,我最近就此主题做了blog post。
答案 1 :(得分:7)
是的,SyntaxFactory
类型是从头开始创建语法节点的方法。