c# - 如何从头开始在 Roslyn 中创建语法节点?

标签 c# vb.net roslyn

我想在没有预先存在的语法节点的情况下使用 Roslyn API 生成语法节点。也就是说,我不能简单地对现有对象使用 WithXYZ() 方法来修改它,因为不存在现有对象。

例如,我想生成一个 InvocationExpressionSyntax 对象。假设构造函数可用,我可以做类似的事情

var invoke = new InvocationExpressionSyntax(expression, arguments);

但是 InvocationExpressionSyntax 的构造函数似乎不公开。

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

这篇博客建议我可以使用一个 API,例如

Syntax.InvocationExpression()

但我没有看到 Syntax 指的是什么,我在 Roslyn API 中也没有看到任何类似的东西。

我确实找到了可以让我做的 Microsoft.CodeAnalysis.VisualBasic.SyntaxFactory

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

这对我来说效果很好。对于任何想知道的人,还有 Microsoft.CodeAnalysis.CSharp.SyntaxFactory

SyntaxFactory 是创建新语法节点的正确方法吗?

我找到 SyntaxFactory.InvocationExpression 的方法是查看 src/Compilers/VisualBasic/Portable 目录下 roslyn 源代码 ( https://github.com/dotnet/roslyn ) 中的 PublicAPI.txt 文件。否则,我看不到 SyntaxFactory 的记录位置。

最佳答案

正如其他答案所述,SyntaxFactory 是要使用的正确类。正如您所发现的,有两个可用的语法工厂,Microsoft.CodeAnalysis.CSharp.SyntaxFactoryMicrosoft.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 创建了 Roslyn Quoter project在 GitHub 上,您可以使用它为您生成 SyntaxFactory 代码。

我最近做了一个blog post关于这个主题,如果你想进一步阅读。

关于c# - 如何从头开始在 Roslyn 中创建语法节点?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32572761/

相关文章:

c# - 获取错误 foreach statement cannot operate on variables of type '' because '' does not contain a public definition for 'GetEnumerator'

c# - 带项目符号的 RTF 列表在第一行的缩进方式不同

vb.net - 如何在 Visual Basic 中遍历字母表?

c# - 安装 Roslyn 会对我的 VS 安装产生什么影响

C# "validate"绑定(bind)到表单的对象的最佳方法

c# - ContainsKey线程安全

ruby-on-rails - VB .NET 中有 Rails partials 的类似物吗?

c# - Roslyn 源生成器能否发现 IDE 的间距/等首选项?

c# - CodeDomProvider.CompileAssemblyFromSource - 找不到 Roslyn (csc.exe)

c# - 如何将参数对象[i]传递给C#中的模板函数