2014-04-28 17 views
5

Cercando con un diagnostico e un CodeFix per fare un codice che trasformazione che:Roslyn C cambiamento # incrementazione

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

Into:

variable++; 
otherVariable--; 

già fatto la diagnostica (funziona):

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

Edit: ho fatto qualche cambiamento. Ora l'incremento viene sempre riconosciuto. Il programma va nel CodeFix, ma il mio ReplaceToken con SyntaxFactory non funziona. (E 'ora solo per "++" e non "-"):

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

Si dovrebbe analizzare l'albero di sintassi, non controllare la rappresentazione di stringa. 'ToString()' probabilmente non restituisce ciò che ti aspetti. – SLaks

+0

Ho trovato la strada e ora va nel CodeFix. Ma non cambia nulla ... Ho un CodeAction, ma non viene eseguita alcuna azione. Quando eseguo il debug passo dopo passo, posso vedere che il nuovoIncrementationClause è esattamente lo stesso di IncrementationClause. Forse puoi aiutarmi :) – Maloz

+0

Stai sostituendo un nuovo nodo appena creato, che per definizione non è nell'albero. Non dovresti mai lavorare con 'node.ToString()'; utilizzare sempre le API del nodo direttamente. – SLaks

risposta

0

Okey, trovo da solo la strada! Ecco il 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

provare a utilizzare il lasso fonte della diagnostica e non l'argomento arco. Inoltre, il genitore del primo token nello span non sarà necessariamente l'espressione binaria che stai cercando. Dovrai cercare la catena principale usando .AncestorsAndSelf() o usare FindNode() per trovare il nodo che meglio corrisponde allo span.

Inoltre, stai controllando un token per vedere se ha il tipo di nodo. Di norma tutti i tipi di token terminano in Token o Keyword. Devi trovare il nodo che ha SyntaxKind.