在Roslyn中解析表达式的名称

Joe*_*oey 7 c# roslyn nameof

我试图用a中的nameof表达式做一些事情CSharpSyntaxWalker,但是,我注意到NameOfExpressionSyntaxAST中没有.相反,我得到一个没有匹配符号的InvocationExpressionSyntaxfor SemanticModel.GetSymbolInfo,并且调用的表达式IdentifierNameSyntax包含一个标识符标记"nameof".

因此,要识别nameof表达式,我会添加一个特殊情况VisitInvocationExpression,查找是否GetSymbolInfo返回任何内容,如果没有,则查找标识符是否为nameof.然而,这对我来说听起来有点不合时宜.有没有更好的方法可能将那种检测逻辑转移到解析器?

(PS:我知道这可能是出于向后兼容性原因而解析的;只是想知道是否有用于区分nameof和正常调用的API .)

m0s*_*0sa 5

nameof表达式是编译时常量。您可以使用该事实将其与正常调用区分开来。你可以叫SematicModel.GetConstantValue()InvocationExpressionSyntax。如果它是nameof,您将返回Optional<object>.Value(HasValue也返回 true) 中的字符串/名称。


Joe*_*oey 2

我现在确实使用了以下代码片段:

\n\n
if (symbolInfo.Symbol == null &&\n    symbolInfo.CandidateSymbols.IsEmpty &&\n    symbolInfo.CandidateReason == CandidateReason.None) {\n  var identifier = node.Expression as IdentifierNameSyntax;\n  if (identifier != null && identifier.Identifier.Kind() == SyntaxKind.IdentifierToken && identifier.Identifier.Text == "nameof") {\n    // We have a nameof expression\n  }\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

我选择不利用常量值进行检测,以防 C# 8 左右添加了一个不同的运算符,该运算符也可能有一个常量值,但不是nameof。该检测几乎准确地检测了规范中所说的用于确定调用是否为表达式的内容nameof

\n\n
\n

因为nameof不是保留关键字,所以nameof表达式在调用简单名称时在语法上总是不明确的nameof。出于兼容性原因,如果名称的名称查找成功,则无论调用是否合法,该表达式nameof都将被视为调用表达式\xe2\x80\x93。否则它是一个nameof_expression

\n
\n