2015-09-14 9 views
5

Vorrei generare nodi di sintassi con l'API di Roslyn senza avere un nodo di sintassi preesistente. Cioè, non posso semplicemente usare i metodi WithXYZ() su un oggetto esistente per modificarlo perché non esiste alcun oggetto esistente.Come si creano nodi di sintassi in Roslyn da zero?

Ad esempio, vorrei generare un oggetto InvocationExpressionSyntax. Supponendo un costruttore era disponibile, ho potuto fare qualcosa di simile

var invoke = new InvocationExpressionSyntax(expression, arguments); 

Ma il costruttore di InvocationExpressionSyntax sembra non sono pubbliche.

http://www.philjhale.com/2012/10/getting-started-with-roslyn.html

questo blog suggerisce che posso usare un'API come

Syntax.InvocationExpression() 

ma non vedere ciò che si riferisce alla Syntax, e io non vedo nulla che assomiglia nel API di Roslyn.

ho trovato Microsoft.CodeAnalysis.VisualBasic.SyntaxFactory che mi permette di fare

var invoke = SyntaxFactory.InvocationExpression().WithExpression(expression); 

E questo funziona abbastanza bene per me. C'è anche lo Microsoft.CodeAnalysis.CSharp.SyntaxFactory per chi si chiede.

SyntaxFactory è il modo corretto per creare nuovi nodi di sintassi?

Il modo in cui ho trovato SyntaxFactory.InvocationExpression è stato esaminando il file PublicAPI.txt nel codice sorgente Roslyn (https://github.com/dotnet/roslyn) nella directory src/Compilers/VisualBasic/Portable. Altrimenti, non vedo dove sia documentato SyntaxFactory.

risposta

5

Sì, il tipo SyntaxFactory è il modo per creare nodi di sintassi da zero.

9

Come indicato nell'altra risposta, SyntaxFactory è la classe corretta da utilizzare. Come hai notato, sono disponibili due factory di sintassi, Microsoft.CodeAnalysis.CSharp.SyntaxFactory e Microsoft.CodeAnalysis.VisualBasic.SyntaxFactory, a seconda della lingua che stai utilizzando.

Di solito le chiamate nello SyntaxFactory sono concatenate insieme, quindi ci si ritrova con molte chiamate ai metodi SytnaxFactory per generare anche semplici righe di codice. Ad esempio, il codice Console.WriteLine("A"); sarebbe rappresentato dai seguenti chiamate alla sintassi di fabbrica:

var console = SyntaxFactory.IdentifierName("Console"); 
var writeline = SyntaxFactory.IdentifierName("WriteLine"); 
var memberaccess = SyntaxFactory.MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, console, writeline); 

var argument = SyntaxFactory.Argument(SyntaxFactory.LiteralExpression(SyntaxKind.StringLiteralExpression, SyntaxFactory.Literal("A"))); 
var argumentList = SyntaxFactory.SeparatedList(new[] { argument }); 

var writeLineCall = 
    SyntaxFactory.ExpressionStatement(
    SyntaxFactory.InvocationExpression(memberaccess, 
    SyntaxFactory.ArgumentList(argumentList))); 

Se non siete sicuri di come generare nodi per un po 'di codice specifico, Kirill Osenkov creato il Roslyn Quoter project su GitHub, che si può utilizzare per generare il codice SyntaxFactory per te.

Ho recentemente effettuato uno blog post su questo argomento per ulteriori informazioni.

Problemi correlati