C# 在使用CSharp.SyntaxFactory时,如何正确地将nameof的SyntaxNodes指定给Roslyn?
我目前正在编写一个包含Roslyn的代码生成器,但我一直在研究如何为C# 在使用CSharp.SyntaxFactory时,如何正确地将nameof的SyntaxNodes指定给Roslyn?,c#,code-generation,abstract-syntax-tree,roslyn,C#,Code Generation,Abstract Syntax Tree,Roslyn,我目前正在编写一个包含Roslyn的代码生成器,但我一直在研究如何为nameof操作符正确创建C#语法节点。作为MCVE,我想为以下代码构建语法树,然后对其进行编译: 使用系统; 命名空间编译测试 { 公开课Foo { public const string Bar=nameof(Array.Length); } } 使用、名称空间和类声明都没有问题,但我无法正确获取调用表达式。根据Syntax Visualizer和Roslyn Quoter的说法,nameof只是一个IdentifierN
nameof
操作符正确创建C#语法节点。作为MCVE,我想为以下代码构建语法树,然后对其进行编译:
使用系统;
命名空间编译测试
{
公开课Foo
{
public const string Bar=nameof(Array.Length);
}
}
使用、名称空间和类声明都没有问题,但我无法正确获取调用表达式。根据Syntax Visualizer和Roslyn Quoter的说法,nameof
只是一个IdentifierName(“nameof”)
表达式,Array.Length
是一个SimpleMemberAccessExpression
:
然后,我尝试使用以下代码构建字段的语法节点:
字段声明(
VariableDeclaration(预定义类型(标记(SyntaxKind.StringKeyword)))
.带变量(
单音分隔列表(
VariableDeclarator(标识符(“条”))
.使用初始值设定项(
等值条款(
调用表达式(标识符名称(“名称”))
.WithArgumentList(
论据列表(
单音分隔列表(
论据(
MemberAccessExpression(
SyntaxKind.SimpleMemberAccessExpression,
标识符名称(“数组”),
标识符名称(“长度”()()()())
.带修饰语(
令牌列表(令牌(SyntaxKind.PublicKeyword)、令牌(SyntaxKind.ConstKeyword)))
但是,当我创建编译并将其发送到流时,它无法解析nameof
和Aray.Length
,从而提供以下编译器诊断:
(8,35): error CS0103: The name 'nameof' does not exist in the current context
(8,42): error CS0120: An object reference is required for the non-static field, method, or property 'Array.Length'
但是当我只是将源代码传递给CSharpSyntaxTree.Parse作为字符串而不是自己创建语法树时,一切都很顺利。
我的问题是:如何正确地为nameof(Array.Length)
创建语法节点?还是在创建语法树时缺少一些选项?
为了完整起见,这里是完整的MCVE,只需将它粘贴到一个xunit测试项目中,该项目也引用了Microsoft.CodeAnalysiss.CSharp(在撰写本文时为3.6.0)
使用系统;
使用System.IO;
使用Microsoft.CodeAnalysis;
使用Microsoft.CodeAnalysis.CSharp;
使用Microsoft.CodeAnalysis.CSharp.Syntax;
使用Xunit;
使用Xunit.抽象;
使用静态Microsoft.CodeAnalysis.CSharp.SyntaxFactory;
命名空间编译测试
{
公共密封类CSharp编译测试
{
私有只读ITestOutputHelper\u输出;
公共CSharpCompilementTests(ITestOutputHelper输出)=>\u输出=输出;
[事实]
public void Compile()
{
var根节点=
编译单元()
.使用(单音表(使用指令(IdentifierName(“系统”)))
.与成员(
单音表(
名称空间声明(IdentifierName(“编译测试”))
.与成员(
单音表(
类别声明(“Foo”)
.与成员(
单音表(
字段声明(
VariableDeclaration(预定义类型(标记(SyntaxKind.StringKeyword)))
.带变量(
单音分隔列表(
VariableDeclarator(标识符(“条”))
.使用初始值设定项(
等值条款(
调用表达式(标识符名称(“名称”))
.WithArgumentList(
论据列表(
单音分隔列表(
论据(
MemberAccessExpression(
SyntaxKind.SimpleMemberAccessExpression,
标识符名称(“数组”),
标识符名称(“长度”()()()())
.带修饰语(
令牌列表(令牌(SyntaxKind.PublicKeyword)、令牌
.whitespace();
var compilation=csharpcomilation.Create(
“我的大会”,
新建[]{CSharpSyntaxTree.Create(rootNode,csharpsparseoptions.Defa
IdentifierName("nameof")
IdentifierName(Identifier(TriviaList(),
SyntaxKind.NameOfKeyword,
"nameof",
"nameof",
TriviaList()));
SyntaxFactory.InvocationExpression(
SyntaxFactory.IdentifierName("nameof")
)
.WithArgumentList(
SyntaxFactory.ArgumentList(
SyntaxFactory.SingletonSeparatedList(
SyntaxFactory.Argument(
SyntaxFactory.MemberAccessExpression(
SyntaxKind.SimpleMemberAccessExpression,
SyntaxFactory.IdentifierName("Array"),
SyntaxFactory.IdentifierName("Length")
)
)
)
)
)