View Javadoc

    1   package net.sourceforge.pmd.rules.optimization;
    2
    3   import net.sourceforge.pmd.AbstractRule;
    4   import net.sourceforge.pmd.ast.ASTArgumentList;
    5   import net.sourceforge.pmd.ast.ASTAssignmentOperator;
    6   import net.sourceforge.pmd.ast.ASTLocalVariableDeclaration;
    7   import net.sourceforge.pmd.ast.ASTName;
    8   import net.sourceforge.pmd.ast.ASTPrimaryExpression;
    9   import net.sourceforge.pmd.ast.ASTStatementExpression;
    10  import net.sourceforge.pmd.ast.ASTVariableDeclaratorId;
    11  import net.sourceforge.pmd.ast.Node;
    12  import net.sourceforge.pmd.ast.SimpleNode;
    13  import net.sourceforge.pmd.symboltable.NameOccurrence;
    14  import net.sourceforge.pmd.typeresolution.TypeHelper;
    15
    16  public class UseStringBufferForStringAppends extends AbstractRule {
    17
    18      @Override
    19      public Object visit(ASTVariableDeclaratorId node, Object data) {
    20          if (!TypeHelper.isA(node, String.class) || node.isArray()) {
    21              return data;
    22          }
    23          Node parent = node.jjtGetParent().jjtGetParent();
    24          if (!parent.getClass().equals(ASTLocalVariableDeclaration.class)) {
    25              return data;
    26          }
    27          for (NameOccurrence no: node.getUsages()) {
    28              SimpleNode name = no.getLocation();
    29              ASTStatementExpression statement = name.getFirstParentOfType(ASTStatementExpression.class);
    30              if (statement == null) {
    31                  continue;
    32              }
    33              ASTArgumentList argList = name.getFirstParentOfType(ASTArgumentList.class);
    34              if (argList != null && argList.getFirstParentOfType(ASTStatementExpression.class) == statement) {
    35                  // used in method call
    36                  continue;
    37              }
    38              if (statement.jjtGetNumChildren() > 0 && statement.jjtGetChild(0).getClass().equals(ASTPrimaryExpression.class)) {
    39                  ASTName astName = ((SimpleNode) statement.jjtGetChild(0)).getFirstChildOfType(ASTName.class);
    40                  if(astName != null){
    41                      if (astName.equals(name)) {
    42                          ASTAssignmentOperator assignmentOperator = statement.getFirstChildOfType(ASTAssignmentOperator.class);
    43                          if (assignmentOperator != null && assignmentOperator.isCompound()) {
    44                              addViolation(data, assignmentOperator);
    45                          }
    46                      } else if(astName.getImage().equals(name.getImage())){
    47                          ASTAssignmentOperator assignmentOperator = statement.getFirstChildOfType(ASTAssignmentOperator.class);
    48                          if (assignmentOperator != null && !assignmentOperator.isCompound()) {
    49                              addViolation(data, astName);
    50                          }
    51                      }
    52                  }
    53              }
    54          }
    55          return data;
    56      }
    57  }