在 Roslyn 中解析 nameof 表达式
Parsing nameof expressions in Roslyn
我试图用 CSharpSyntaxWalker
中的 nameof
表达式做一些事情,但是,我注意到 AST 中没有 NameOfExpressionSyntax
。相反,我得到一个 InvocationExpressionSyntax
SemanticModel.GetSymbolInfo
returns 没有匹配的符号,并且调用的表达式是一个 IdentifierNameSyntax
包含标识符标记 "nameof"
.
所以为了识别 nameof
表达式,我会在 VisitInvocationExpression
中添加一个特例,寻找是否 GetSymbolInfo
returns 任何东西,如果没有,寻找是否标识符是 nameof
。但是,这对我来说听起来有点不确定。是否有更好的方法将这种检测逻辑转移到解析器?
(P.S.: 我知道出于向后兼容性的原因,这可能是这样解析的;只是想知道是否有 API 来区分 nameof
和正常调用。)
nameof
表达式是编译时常量。您可以使用该事实将其与正常调用区分开来。您可以在 InvocationExpressionSyntax
上调用 SematicModel.GetConstantValue()
。如果它是 nameof
,您将返回 Optional<object>.Value
中的字符串/名称(HasValue
也 returns true)。
我现在确实使用了以下片段:
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
}
}
我选择不利用常量值进行检测,以防万一 C# 8 左右添加了一个不同的运算符,它可能也有一个常量值,但不是 nameof
。检测几乎准确地检测到规范所说的用于确定调用是 nameof
表达式的内容:
Because nameof
is not a reserved keyword, a nameof
expression is always syntactically ambiguous with an invocation of the simple name nameof
. For compatibility reasons, if a name lookup of the name nameof
succeeds, the expression is treated as an invocation_expression – regardless of whether the invocation is legal. Otherwise it is a nameof_expression.
我试图用 CSharpSyntaxWalker
中的 nameof
表达式做一些事情,但是,我注意到 AST 中没有 NameOfExpressionSyntax
。相反,我得到一个 InvocationExpressionSyntax
SemanticModel.GetSymbolInfo
returns 没有匹配的符号,并且调用的表达式是一个 IdentifierNameSyntax
包含标识符标记 "nameof"
.
所以为了识别 nameof
表达式,我会在 VisitInvocationExpression
中添加一个特例,寻找是否 GetSymbolInfo
returns 任何东西,如果没有,寻找是否标识符是 nameof
。但是,这对我来说听起来有点不确定。是否有更好的方法将这种检测逻辑转移到解析器?
(P.S.: 我知道出于向后兼容性的原因,这可能是这样解析的;只是想知道是否有 API 来区分 nameof
和正常调用。)
nameof
表达式是编译时常量。您可以使用该事实将其与正常调用区分开来。您可以在 InvocationExpressionSyntax
上调用 SematicModel.GetConstantValue()
。如果它是 nameof
,您将返回 Optional<object>.Value
中的字符串/名称(HasValue
也 returns true)。
我现在确实使用了以下片段:
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
}
}
我选择不利用常量值进行检测,以防万一 C# 8 左右添加了一个不同的运算符,它可能也有一个常量值,但不是 nameof
。检测几乎准确地检测到规范所说的用于确定调用是 nameof
表达式的内容:
Because
nameof
is not a reserved keyword, anameof
expression is always syntactically ambiguous with an invocation of the simple namenameof
. For compatibility reasons, if a name lookup of the namenameof
succeeds, the expression is treated as an invocation_expression – regardless of whether the invocation is legal. Otherwise it is a nameof_expression.