2013-10-01 10 views
6

Używam biblioteki Roslyn. Chcę dodać wyciągi po dopasowaniu linii: Oto wymóg. najpierw chcę znaleźć poniższy wiersz:Roslyn - jak dodać wyciągi po dopasowaniu InvocationExpressionSyntax

_container.RegisterInstance(NavigationService); 

A potem chcę dodać poniżej wypowiedzi po powyższej linii:

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

Każda pomoc będzie mile widziana.

EDIT: (I stworzyli wyrażeń, ale teraz, jak dodać te dwa experssions do mojego 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); 

teraz problem jest jak zdobyć mój zaktualizowany drzewa ?? czyli jak zaktualizować listę i dostać się na drzewo z tymi zmianami

Edit. teraz jestem w stanie wygenerować dodać węzły, ale jedynym problemem jest formatowanie .. odstęp nie jest poprawna oto kod:.

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); 

generuje dane wyjściowe ze wszystkimi liniami wyrównanymi do lewej .. Jakieś sugestie?

+2

Co masz do tej pory? –

+0

Po prostu mogę znaleźć moją linię docelową ... ale nie jestem pewien Jak dodać wyciągi po mojej linii docelowej. string strContent = File.ReadAllText (strPath); SyntaxTree tree = SyntaxTree.ParseText (strContent); var targetMethod = tree.GetRoot(). DescendantNodes(). OfType () .FirstOrDefault ( X => x.Expression.ToString(). Zawiera ("_") container.RegisterInstance && x.ArgumentList.ToString() .Contains ("NavigationService")); –

+0

Edytowałem wątek .. Jestem w stanie uzyskać targetExpression, a także utworzone dwa węzły, które chcę dodać do mojej targetExpression ... Wszelkie sugestie? –

Odpowiedz

6

Po zakończeniu edycji wygląda na to, że główne pytanie pozostało do rozwiązania w kwestii formatowania linii. W obu przypadkach, gdy już masz swój ostatni katalog główny, możesz wywołać formatator, aby go wyczyścić. Masz dwie opcje:

  1. Można wywołać NormalizeWhitespace extension() na węzłach raz skończysz, który bardzo niegrzecznie formatuje wszystkie węzły w coś zdalnie „rozsądne”. Jeśli nie dbasz o zachowanie jakiegokolwiek formatowania, które masz, i po prostu chcesz, aby wyjście nie wyglądało strasznie, jest to prosta opcja.
  2. Możesz odwołać się do montażu Roslyn.Services, a następnie dodać "używając Roslyn.Services" na górze, jeśli jeszcze tego nie zrobiłeś. Stamtąd istnieje metoda Format(), która jest znacznie bardziej wyszukanym formaterem, który stara się zachować wcięcia w takiej formie, respektuje to, co już posiadał użytkownik itp. Jeśli wstawisz adnotację składni do utworzonych węzłów, możesz wtedy przekaż tę adnotację do tego formatera, aby wiedział, że pozostawi resztę pliku nietkniętą.
+0

jesteś niesamowity ... dziękuję bardzo Jason .... –