2014-04-28 20 views
5

Próbując z diagnostyki i CodeFix aby kod, który przekształcać że:Roslyn C# zmiany przyrostu

variable = variable + 1; 
otherVariable = otherVariable -1; 

Into:

variable++; 
otherVariable--; 

Już zrobione diagnostyki (działa):

var incrementing = node as BinaryExpressionSyntax; 
if (incrementing != null) 
{ 
    string right = incrementing .Right.ToString(); 
    string left = incrementing .Left.ToString(); 

    if (right == left + " - 1" || right == left + " + 1") 
    { 
     addDiagnostic(Diagnostic.Create(Rule, incrementation.GetLocation(), "Use the shorter way")); 
    } 
} 

Edytuj: Wprowadziłem trochę zmian. Teraz inkrementacja jest zawsze rozpoznawana. Program przechodzi do CodeFix, ale mój ReplaceToken z SyntaxFactory nie działa. (To teraz tylko dla "++", a nie "-"):

if (node.IsKind(SyntaxKind.SimpleAssignmentExpression)) //I use a node instead of a token 
{ 
    var IncrementationClause = (BinaryExpressionSyntax)node; 

     string left = IncrementationClause.Left.ToString(); 
     left = left + "++"; 
     string rigt = IncrementationClause.Right.ToString(); 

     var newIncrementationClause = IncrementationClause.ReplaceToken(SyntaxFactory.Identifier(IncrementationClause.Left.ToString()), SyntaxFactory.Identifier(left)); 
     newIncrementationClause = IncrementationClause.ReplaceToken(SyntaxFactory.Identifier(IncrementationClause.Right.ToString()), SyntaxFactory.Identifier(String.Empty)); 
     newIncrementationClause = IncrementationClause.ReplaceToken(SyntaxFactory.Identifier(IncrementationClause.OperatorToken.ToString()), SyntaxFactory.Identifier(String.Empty)); 

     var newRoot = root.ReplaceNode(IncrementationClause, newIncrementationClause); 

     return new[] { CodeAction.Create("Changer la mise en forme", document.WithSyntaxRoot(newRoot)) }; 
} 
+2

Powinieneś przeanalizować drzewo składniowe, a nie sprawdzać reprezentację napisów. 'ToString()' prawdopodobnie nie zwraca tego, czego się spodziewasz. – SLaks

+0

Znaleźliśmy drogę, a teraz jest w CodeFix. Ale nic się nie zmieniło ... Mam CodeAction, ale nie podejmuję żadnych działań. Kiedy debuguję krok po kroku, widzę, że newIncrementationClause jest dokładnie taki sam jak IncrementationClause. Może możesz mi pomóc :) – Maloz

+0

Wymieniasz nowy węzeł, który właśnie utworzyłeś, który z definicji nie znajduje się w drzewie. Nigdy nie powinieneś pracować z 'node.ToString()'; zawsze korzystaj bezpośrednio z API Node. – SLaks

Odpowiedz

0

Okey, sam znajduję drogę! Oto CodeFix:

if (node.IsKind(SyntaxKind.SimpleAssignmentExpression)) 
{ 
     var IncrementationClause = (BinaryExpressionSyntax)node; 
     var IncrementionClauseExpressionStatement = IncrementationClause.Parent; 

     string right = IncrementationClause.Right.ToString(); 
     string left = IncrementationClause.Left.ToString(); 

     var ExpressionNew = SyntaxFactory.ExpressionStatement(IncrementationClause); 

     if (right == left + " - 1") 
     { 
      var BonneIncrementation = SyntaxFactory.PostfixUnaryExpression(SyntaxKind.PostDecrementExpression, IncrementationClause.Left); 
      ExpressionNew = SyntaxFactory.ExpressionStatement(BonneIncrementation).WithAdditionalAnnotations(Formatter.Annotation).WithLeadingTrivia(leading).WithTrailingTrivia(trailing); 
      } 
      else 
      { 
      var BonneIncrementation = SyntaxFactory.PostfixUnaryExpression(SyntaxKind.PostIncrementExpression, IncrementationClause.Left); 
      ExpressionNew = SyntaxFactory.ExpressionStatement(BonneIncrementation).WithAdditionalAnnotations(Formatter.Annotation).WithLeadingTrivia(leading).WithTrailingTrivia(trailing); 
      } 

      var newRoot = root.ReplaceNode(IncrementionClauseExpressionStatement, ExpressionNew); 

      return new[] { CodeAction.Create("Convert in the good way of incrementing", document.WithSyntaxRoot(newRoot)) }; 


} 
2

Spróbuj użyć zakresu źródłowego argumentu diagnostycznego, a nie rozpiętości. Ponadto rodzic pierwszego tokenu w zakresie nie musi być binarnym wyrażeniem, którego szukasz. Będziesz musiał przeszukać macierzysty łańcuch przy użyciu .AncestorsAndSelf() lub użyć FindNode(), aby znaleźć węzeł, który najlepiej pasuje do zakresu.

Sprawdzasz również token, aby sprawdzić, czy ma on węzeł. Z reguły wszystkie rodzaje tokenów kończą się Tokenem lub słowem kluczowym. Musisz znaleźć węzeł, który ma ten skrypt składniowy.

Powiązane problemy