2013-10-01 14 views
6

Sto utilizzando la libreria Roslyn. Voglio aggiungere le istruzioni dopo la riga corrispondente: Ecco il requisito. Prima di tutto voglio trovare la linea di seguito:Roslyn - come aggiungere istruzioni dopo la corrispondenza InvocationExpressionSyntax

_container.RegisterInstance(NavigationService); 

E poi voglio aggiungere di seguito le dichiarazioni dopo la linea di cui sopra:

_container.RegisterInstance<ISessionStateService>(SessionStateService); 
_container.RegisterInstance<IFlyoutService>(FlyoutService); 

Qualsiasi aiuto sarebbe molto apprezzato.

EDIT:? (Ho creato le espressioni, ma ora come aggiungere quei due experssions alla mia targetExpression

string strContent = File.ReadAllText(strPath); 
     SyntaxTree tree = SyntaxTree.ParseText(strContent); 
     var targetExpression = tree.GetRoot().DescendantNodes().OfType<InvocationExpressionSyntax>() 
       .FirstOrDefault(
        x => x.Expression.ToString().Contains("_container.RegisterInstance") && x.ArgumentList.ToString().Contains("NavigationService")); 

     InvocationExpressionSyntax replacementNode1 = 
      Syntax.InvocationExpression(Syntax.ParseExpression(@"_container.RegisterInstance<ISessionStateService>(SessionStateService);")); 

     InvocationExpressionSyntax replacementNode2 = 
      Syntax.InvocationExpression(Syntax.ParseExpression(@"_container.RegisterInstance<IFlyoutService>(FlyoutService);")); 

     MethodDeclarationSyntax targetMethod = (MethodDeclarationSyntax)targetExpression.Parent.Parent.Parent; 

     List<InvocationExpressionSyntax> list = targetMethod.DescendantNodes().OfType<InvocationExpressionSyntax>().ToList(); 
     int index = list.IndexOf(targetExpression); 

     list.Insert(index + 1, replacementNode1); 
     list.Insert(index + 1, replacementNode2); 

ora il problema è come ottenere il mio albero aggiornato ?? Significa come aggiornare la mia lista e ottenere l'albero con questi cambiamenti

Edit:. Ora sono in grado di generare aggiungere i nodi, ma unico problema è la formattazione .. la distanza non è corretta qui è il codice:.

string strContent = File.ReadAllText(strPath); 
     SyntaxTree tree = SyntaxTree.ParseText(strContent); 

     ExpressionStatementSyntax expressionStatementSyntax = 
      Syntax.ExpressionStatement(Syntax.ParseExpression("_container.RegisterInstance(NavigationService);")); 

     var targetBlock = 
      tree.GetRoot() 
       .DescendantNodes() 
       .OfType<BlockSyntax>() 
       .FirstOrDefault(x => x.Statements.Any(y => y.ToString().Contains("_container.RegisterInstance"))); 

     StatementSyntax syn1 = 
      Syntax.ParseStatement(@"_container.RegisterInstance<ISessionStateService>(SessionStateService);"); 
     StatementSyntax syn2 = Syntax.ParseStatement(@"_container.RegisterInstance<ISessionStateService>(SessionStateService2);"); 

     List<StatementSyntax> newSynList = new List<StatementSyntax> { syn1, syn2 }; 

     SyntaxList<StatementSyntax> blockWithNewStatements = targetBlock.Statements; 

     foreach (var syn in newSynList) 
     { 
      blockWithNewStatements = blockWithNewStatements.Insert(1, syn); 
     } 

     BlockSyntax newBlock = Syntax.Block(blockWithNewStatements); 

     var newRoot = tree.GetRoot().ReplaceNode(targetBlock, newBlock); 

genera l'output con tutte le linee allineate a sinistra .. qualche suggerimento?

+2

Cosa hai finora? –

+0

Sono solo in grado di trovare la mia linea di destinazione ... ma non sono sicuro di come aggiungere le dichiarazioni dopo la mia linea di destinazione. string strContent = File.ReadAllText (strPath); SyntaxTree tree = SyntaxTree.ParseText (strContent); var targetMethod = tree.GetRoot(). DescendantNodes(). OfType () .FirstOrDefault ( x => x.Expression.ToString(). Contains ("_ container.RegisterInstance") && x.ArgumentList.ToString() .Contains ("NavigationService")); –

+0

Ho modificato il thread .. Sono in grado di ottenere il targetExpression e ho anche creato due nodi che voglio aggiungere al mio targetExpression ... Qualche suggerimento? –

risposta

6

Dopo la modifica, sembra che la principale domanda rimanente riguardi la gestione della formattazione della linea. In entrambi i casi, una volta ottenuta la root finale, è possibile richiamare un formattatore per ripulirlo. Sono disponibili due opzioni:

  1. È possibile chiamare l'estensione NormalizeWhitespace() sui nodi, una volta che hai finito, che riformatta molto scortesemente tutti i nodi in qualcosa di remoto "ragionevole". Se non ti interessa conservare la formattazione che hai, e vuoi solo che l'output non sembri terribile, questa è l'opzione semplice.
  2. È possibile fare riferimento all'assembly Roslyn.Services e quindi aggiungere "utilizzando Roslyn.Services" in alto se non lo si è già. Da lì, c'è un metodo Format() che è un formattatore molto più elaborato che tenta di mantenere il rientro così com'è, rispetta ciò che l'utente ha già, ecc. Ecc. Se si configura un'annotazione di sintassi sui nodi creati, è possibile passa quell'annotazione a questo formattatore in modo che sappia lasciare il resto del file inalterato.
+0

sei fantastico ... grazie mille Jason .... –

Problemi correlati