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,
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
70
71 @Override
72 public String dysfunctionReason() {
73 return allowsAllAssignments() ? "All assignment types allowed, no checks performed" : null;
74 }
75 }