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