Parsing expression names in Roslyn

I am trying to do something with nameof expressions in CSharpSyntaxWalker , however I noticed that AST does not have NameOfExpressionSyntax . Instead, I get InvocationExpressionSyntax , for which SemanticModel.GetSymbolInfo does not return matching characters, and the call expression is IdentifierNameSyntax containing the identifier token "nameof" .

So, in order to recognize nameof expressions, I would add a special case to VisitInvocationExpression , looking to see if GetSymbolInfo returns anything, and if not, then looking for the nameof identifier. However, this sounds a bit uncomfortable for me. Is there a better way, perhaps that transfers such detection logic to the parser?

(PS: I know this is probably being parsed, as it is for backward compatibility reasons, just wondering if an API exists to distinguish between nameof and regular calls.)

+5
source share
2 answers

Now I really used the following snippet:

 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 } } 

I decided not to use a constant value for detection only if C # 8 or so adds another statement in this vein, which can also have a constant value, but not nameof . Detection pretty much determines what the specification says is used to define a call, which is a nameof expression:

Since nameof not a reserved keyword, the expression nameof always syntactically ambiguous with the simple nameof . For compatibility reasons, if the search for the name nameof is successful, the expression is treated as the expression invocation_expression - regardless of whether the call is legal. Otherwise, it is a name_expression expression.

+1
source

nameof expressions are a compile-time constant. You can use this fact to distinguish it from ordinary calls. You can call SematicModel.GetConstantValue() on InvocationExpressionSyntax . In case a nameof , you will return the string / name inside Optional<object>.Value ( HasValue also returns true).

+3
source

All Articles