View Javadoc
1   /**
2    * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
3    */
4   package net.sourceforge.pmd.lang.java.rule.controversial;
5   
6   import net.sourceforge.pmd.PropertySource;
7   import net.sourceforge.pmd.lang.ast.Node;
8   import net.sourceforge.pmd.lang.java.ast.ASTAssignmentOperator;
9   import net.sourceforge.pmd.lang.java.ast.ASTExpression;
10  import net.sourceforge.pmd.lang.java.ast.ASTForStatement;
11  import net.sourceforge.pmd.lang.java.ast.ASTIfStatement;
12  import net.sourceforge.pmd.lang.java.ast.ASTPostfixExpression;
13  import net.sourceforge.pmd.lang.java.ast.ASTPreDecrementExpression;
14  import net.sourceforge.pmd.lang.java.ast.ASTPreIncrementExpression;
15  import net.sourceforge.pmd.lang.java.ast.ASTWhileStatement;
16  import net.sourceforge.pmd.lang.java.rule.AbstractJavaRule;
17  import net.sourceforge.pmd.lang.rule.properties.BooleanProperty;
18  
19  /**
20   *
21   *
22   */
23  public class AssignmentInOperandRule extends AbstractJavaRule {
24  
25      private static final BooleanProperty ALLOW_IF_DESCRIPTOR = new BooleanProperty("allowIf",
26              "Allow assignment within the conditional expression of an if statement", false, 1.0f);
27  
28      private static final BooleanProperty ALLOW_FOR_DESCRIPTOR = new BooleanProperty("allowFor",
29              "Allow assignment within the conditional expression of a for statement", false, 2.0f);
30  
31      private static final BooleanProperty ALLOW_WHILE_DESCRIPTOR = new BooleanProperty("allowWhile",
32              "Allow assignment within the conditional expression of a while statement", false, 3.0f);
33  
34      private static final BooleanProperty ALLOW_INCREMENT_DECREMENT_DESCRIPTOR = new BooleanProperty(
35              "allowIncrementDecrement",
36              "Allow increment or decrement operators within the conditional expression of an if, for, or while statement",
37              false, 4.0f);
38  
39      public AssignmentInOperandRule() {
40          definePropertyDescriptor(ALLOW_IF_DESCRIPTOR);
41          definePropertyDescriptor(ALLOW_FOR_DESCRIPTOR);
42          definePropertyDescriptor(ALLOW_WHILE_DESCRIPTOR);
43          definePropertyDescriptor(ALLOW_INCREMENT_DECREMENT_DESCRIPTOR);
44      }
45  
46      @Override
47      public Object visit(ASTExpression node, Object data) {
48          Node parent = node.jjtGetParent();
49          if ((parent instanceof ASTIfStatement && !getProperty(ALLOW_IF_DESCRIPTOR)
50                  || parent instanceof ASTWhileStatement && !getProperty(ALLOW_WHILE_DESCRIPTOR)
51                  || parent instanceof ASTForStatement && parent.jjtGetChild(1) == node && !getProperty(ALLOW_FOR_DESCRIPTOR))
52                  && (node.hasDescendantOfType(ASTAssignmentOperator.class)
53                          || !getProperty(ALLOW_INCREMENT_DECREMENT_DESCRIPTOR)
54                                  && (node.hasDecendantOfAnyType(ASTPreIncrementExpression.class, ASTPreDecrementExpression.class,
55                                  ASTPostfixExpression.class)))) {
56  
57              addViolation(data, node);
58              return data;
59          }
60          return super.visit(node, data);
61      }
62  
63      public boolean allowsAllAssignments() {
64          return getProperty(ALLOW_IF_DESCRIPTOR) && getProperty(ALLOW_FOR_DESCRIPTOR)
65                  && getProperty(ALLOW_WHILE_DESCRIPTOR) && getProperty(ALLOW_INCREMENT_DECREMENT_DESCRIPTOR);
66      }
67  
68      /**
69       * @see PropertySource#dysfunctionReason()
70       */
71      @Override
72      public String dysfunctionReason() {
73          return allowsAllAssignments() ? "All assignment types allowed, no checks performed" : null;
74      }
75  }