2014-04-28 3 views
5

Essayer avec un diagnostic et un CodeFix pour faire un code qui transform que:Roslyn C# incrémenter changement

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

en:

variable++; 
otherVariable--; 

déjà fait le diagnostic (cela fonctionne):

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

Modifier: J'ai fait quelques changements. Maintenant, l'incrémentation est toujours reconnue. Le programme va dans le CodeFix, mais mon ReplaceToken avec une SyntaxFactory ne fonctionne pas. (Il est maintenant seulement pour "++" et 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

Vous devez analyser l'arbre de syntaxe, pas vérifier la représentation de la chaîne. 'ToString()' ne retourne probablement pas ce que vous attendez. – SLaks

+0

J'ai trouvé le chemin et maintenant il va dans le CodeFix. Mais rien ne change ... J'ai un CodeAction, mais aucune action n'est faite. Quand je débogue pas à pas, je peux voir que newIncrementationClause est exactement la même chose que IncrementationClause. Peut-être pouvez-vous m'aider :) – Maloz

+0

Vous remplacez un nouveau nœud que vous venez de créer et qui, par définition, n'est pas dans l'arborescence. Vous ne devriez jamais travailler avec 'node.ToString()'; utilisez toujours les API Node directement. – SLaks

Répondre

0

Okey, je trouve le chemin par moi-même! Voici le 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

Essayez d'utiliser la durée source du diagnostic et non l'argument span. En outre, le parent du premier jeton de la plage ne sera pas nécessairement l'expression binaire que vous recherchez. Vous devrez rechercher la chaîne parente en utilisant .AncestorsAndSelf() ou utiliser FindNode() pour trouver le nœud qui correspond le mieux à l'intervalle.

Vous vérifiez également un jeton pour voir s'il a le type d'un nœud. En règle générale, tous les types de jetons se terminent par un jeton ou un mot clé. Vous devez trouver le noeud qui a ce SyntaxKind.