我正在尝试使用nameof
中的CSharpSyntaxWalker
表达式执行某些操作,但是,我注意到AST中没有NameOfExpressionSyntax
。相反,我得到一个InvocationExpressionSyntax
SemanticModel.GetSymbolInfo
没有返回匹配的符号,并且调用的表达式是包含标识符标记IdentifierNameSyntax
的{{1}}。
因此,为了识别"nameof"
表达式,我会向nameof
添加一个特殊情况,查找VisitInvocationExpression
是否返回任何内容,如果没有,则查找标识符是否为{{1} }。然而,这对我来说听起来有点不合时宜。是否有更好的方法可以将那种检测逻辑转移到解析器?
(P.S。:我知道这可能是出于向后兼容性原因而解析的;只是想知道是否有用于区分GetSymbolInfo
和普通调用的API。)
答案 0 :(得分:4)
nameof
表达式是编译时常量。您可以使用该事实将其与正常调用区分开来。您可以在SematicModel.GetConstantValue()
上致电InvocationExpressionSyntax
。如果它是nameof
,您可以在Optional<object>.Value
内找回字符串/名称(HasValue
也返回true)。
答案 1 :(得分:1)
我现在确实使用了以下代码段:
console.log("function was called");
我选择不使用常量值进行检测,只是在C#8左右添加了另一个不同的运算符,可能也有一个常量值,但不是if (symbolInfo.Symbol == null &&
symbolInfo.CandidateSymbols.IsEmpty &&
symbolInfo.CandidateReason == CandidateReason.None) {
var identifier = node.Expression as IdentifierNameSyntax;
if (identifier != null && identifier.Identifier.Kind() == SyntaxKind.IdentifierToken && identifier.Identifier.Text == "nameof") {
// We have a nameof expression
}
}
。检测几乎完全检测到规范所说的用于确定调用为nameof
表达式的内容:
因为
nameof
不是保留关键字,所以nameof
表达式在语法上总是不明确,并且调用简单名称nameof
。出于兼容性原因,如果名称nameof
的名称查找成功,则表达式将被视为 invocation_expression - 无论调用是否合法。否则它是 nameof_expression 。