2016-09-05 15 views
5

Próbuję coś zrobić z wyrażeniami nameof w CSharpSyntaxWalker, jednak zauważyłem, że nie ma NameOfExpressionSyntax w AST. Zamiast tego otrzymuję InvocationExpressionSyntax, dla którego SemanticModel.GetSymbolInfo nie zwraca żadnych pasujących symboli, a wyrażenie wywołania to IdentifierNameSyntax zawierające token identyfikatora "nameof".Parsowanie wyrażeń nameof w Roslyn

więc rozpoznać nameof wyrażenia bym dodał do VisitInvocationExpression szczególny przypadek, szukając czy GetSymbolInfo zwraca niczego, a jeśli nie, szukając tego, czy identyfikator jest nameof. Jednak dla mnie to brzmi trochę niepewnie. Czy istnieje lepszy sposób, który może przesunąć tego rodzaju logikę wykrywania do analizatora składni?

(P.S .: Wiem, że to jest prawdopodobnie analizowany tak ze względu na kompatybilność wstecz;. Po prostu zastanawiasz się, czy istnieje API dla odróżnienia nameof i normalne inwokacje)

+4

[Ktoś inny też to zauważył] (https://joshvarty.wordpress.com/2015/02/16/lrn-quick-tips-working-with-nameof/). – Rawling

+1

Ciągle nie ma formalnej specyfikacji dla C# 6, ale [ten szkic] (https://github.com/ljw1004/csharpspec/blob/f12213c4ffe77a51dbc5412250bef6af75333f32/expressions.md#nameof-expressions) wydaje się potwierdzać, że jest to niejednoznaczna analiza, a więc dodatkowe uzasadnienie jest wymagane. –

+1

@Damien_The_Unbeliever: Rzeczywiście próbowałem znaleźć to miejsce w kodzie źródłowym Roslyn, gdzie to określa, ale nie mógł w pobieżnym wyszukiwaniu. Może powinienem znów spojrzeć. – Joey

Odpowiedz

1

I teraz rzeczywiście używany następujący fragment:

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

Zdecydowałem nie wykorzystać stałą wartość do wykrywania tylko w przypadku C# 8 lub więc dodaje jeszcze inny operator w tym duchu, że może mieć również stała wartość, ale nie jest to nameof. Wykrycie prawie wykrywa właśnie specyfikacja mówi służy do określania inwokację bycia nameof wyrażenie:

Ponieważ nameof nie jest zarezerwowanym słowo kluczowe, wyrażenie nameof jest zawsze składniowo niejednoznaczne z wezwaniem prostą nazwę nameof . Ze względu na kompatybilność, jeśli wyszukiwanie nazwy o nazwie nameof powiedzie się, wyrażenie traktowane jest jako Wywołanie inwokacji - niezależnie od tego, czy wywołanie jest legalne. W przeciwnym razie jest to nameof_expression.

3

nameof wyrażenia są stałe w czasie kompilacji. Możesz użyć tego faktu, aby odróżnić go od normalnych inwokacji. Możesz zadzwonić pod numer SematicModel.GetConstantValue() na InvocationExpressionSyntax. W przypadku, gdy jest to nameof, otrzymasz z powrotem ciąg/nazwa wewnątrz Optional<object>.Value (HasValue również zwraca wartość true).

+1

GetConstantValue nie pomoże mi w tym przypadku, ponieważ muszę zamapować symbol na niestandardową nazwę, ale przyznaję, że to prawdopodobnie dobry sposób na jej odróżnienie. z innych wywołań, które zwykle nie są stałymi. – Joey