我试图用常规C#SyntaxFactory
从零开始构造nameof
表达式。不幸的是,出于某种原因,Roslyn未能将我的InvocationExpressionSyntax
识别为上下文nameof
关键字,并在Emit
命令后引发错误诊断。通过SyntaxFactory(Roslyn)构造NameOf表达式
在找出错误的过程中,我试着给Roslyn一些有效的代码进行解析,希望能够找到我的语法构造和“正确解析的”之间的一些区别。我在实验上能够很快地追踪到“nameof”标识符标记的差异,但那是我卡住的地方。我找不到在我的nameof
令牌和解析的令牌之间有什么不同,但它们仍然有些不同。
当我使用“解析的人”时,一切正常,Emit
按预期工作,没有错误。另一方面,当我使用我自己的nameof
令牌时,它编译失败,并且Emit
抛出错误诊断。
这里是我的代码,我与测试它:
var CODE = "class X { void Q() { var q = nameof(Q); } }";
var correctSyntaxTree = CSharpSyntaxTree.ParseText(CODE);
var correctRoot = correctSyntaxTree.GetRoot();
var correctNameOf = correctRoot.DescendantNodes().OfType<InvocationExpressionSyntax>().First();
var correctExpression = (IdentifierNameSyntax)correctNameOf.Expression;
var myNameOf = SyntaxFactory.InvocationExpression
(
correctExpression, //Works
//SyntaxFactory.IdentifierName("nameof"), //Doesn't work
//SyntaxFactory.IdentifierName(SyntaxFactory.Token(SyntaxKind.NameOfKeyword)), //System.ArgumentException: 'identifier'
//SyntaxFactory.IdentifierName(correctExpression.Identifier), //Works
//SyntaxFactory.IdentifierName(correctExpression.Identifier.ValueText), //Doesn't work
//correctExpression.WithIdentifier(SyntaxFactory.Identifier("nameof")), //Doesn't work
//correctExpression.WithIdentifier(SyntaxFactory.Identifier(correctExpression.Identifier.ValueText)), //Doesn't work
//SyntaxFactory.IdentifierName("nameof").WithTriviaFrom(correctExpression), //Doesn't work
//correctExpression.CopyAnnotationsTo(SyntaxFactory.IdentifierName("nameof")), //Doesn't work
//SyntaxFactory.IdentifierName(correctExpression.Identifier.WithoutAnnotations().WithoutTrivia()), //Works
SyntaxFactory.ArgumentList
(
SyntaxFactory.SingletonSeparatedList
(
SyntaxFactory.Argument
(
SyntaxFactory.IdentifierName("Q")
)
)
)
);
var newRoot = correctRoot.ReplaceNode(correctNameOf, myNameOf);
var newTree = CSharpSyntaxTree.Create((CSharpSyntaxNode)newRoot);
var compilation = CSharpCompilation.Create
(
"Compilation",
new[] { newTree },
references: MsCorLib,
options: new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)
);
var compilationResult = compilation.Emit(new MemoryStream());
如果有人能指出任何区别解析令牌和我的令牌这是造成罗斯林到(正确地)不能绑定nameof
表达式到任何“in-code”符号,但不会将其视为上下文关键字,这真的会帮助我。
编译错误:(1,30):错误CS0103:名称 'nameof' 不在当前情况下存在
编译#LanguageVersion: CSharp7
罗斯林版本: (Nuget最新)Microsoft.CodeAnalysis.CSharp v2.3.2
哦,非常感谢你。这使得伎俩。 我一直在'RawKind'周围嗅探,期待一些背景差异,但没有运气。由于它不是公有财产,我不知道另一个“ContextualKind”的存在。你向我展示了另一个我不知道的罗斯林原则。 还有一件事。我可以以某种方式从标记(非反射方式)读取'ContextualKind',或者是我通过'SyntaxFacts.GetContextualKeywordKind(Token.ValueText)'猜测的唯一机会吗? – WELLCZECH
据我所知,没有办法(没有使用反射)。 'Microsoft.CodeAnalysis.CSharpExtensions'中有一个'ContextualKind'方法,但也是内部的。在我看来,这并没有被曝光。 – nejcs