1
2
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, ASTPostfixExpression.class))))) {
55
56 addViolation(data, node);
57 return data;
58 }
59 return super.visit(node, data);
60 }
61
62
63 public boolean allowsAllAssignments() {
64 return
65 getProperty(ALLOW_IF_DESCRIPTOR) &&
66 getProperty(ALLOW_FOR_DESCRIPTOR) &&
67 getProperty(ALLOW_WHILE_DESCRIPTOR) &&
68 getProperty(ALLOW_INCREMENT_DECREMENT_DESCRIPTOR);
69 }
70
71
72
73
74 @Override
75 public String dysfunctionReason() {
76 return allowsAllAssignments() ? "All assignment types allowed, no checks performed" : null;
77 }
78 }