/**
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/
package net.sourceforge.pmd.lang.java.rule.controversial;
import net.sourceforge.pmd.PropertySource;
import net.sourceforge.pmd.lang.ast.Node;
import net.sourceforge.pmd.lang.java.ast.ASTAssignmentOperator;
import net.sourceforge.pmd.lang.java.ast.ASTExpression;
import net.sourceforge.pmd.lang.java.ast.ASTForStatement;
import net.sourceforge.pmd.lang.java.ast.ASTIfStatement;
import net.sourceforge.pmd.lang.java.ast.ASTPostfixExpression;
import net.sourceforge.pmd.lang.java.ast.ASTPreDecrementExpression;
import net.sourceforge.pmd.lang.java.ast.ASTPreIncrementExpression;
import net.sourceforge.pmd.lang.java.ast.ASTWhileStatement;
import net.sourceforge.pmd.lang.java.rule.AbstractJavaRule;
import net.sourceforge.pmd.lang.rule.properties.BooleanProperty;
/**
*
*
*/
public class AssignmentInOperandRule extends AbstractJavaRule {
private static final BooleanProperty ALLOW_IF_DESCRIPTOR = new BooleanProperty("allowIf",
"Allow assignment within the conditional expression of an if statement", false, 1.0f);
private static final BooleanProperty ALLOW_FOR_DESCRIPTOR = new BooleanProperty("allowFor",
"Allow assignment within the conditional expression of a for statement", false, 2.0f);
private static final BooleanProperty ALLOW_WHILE_DESCRIPTOR = new BooleanProperty("allowWhile",
"Allow assignment within the conditional expression of a while statement", false, 3.0f);
private static final BooleanProperty ALLOW_INCREMENT_DECREMENT_DESCRIPTOR = new BooleanProperty(
"allowIncrementDecrement",
"Allow increment or decrement operators within the conditional expression of an if, for, or while statement",
false, 4.0f);
public AssignmentInOperandRule() {
definePropertyDescriptor(ALLOW_IF_DESCRIPTOR);
definePropertyDescriptor(ALLOW_FOR_DESCRIPTOR);
definePropertyDescriptor(ALLOW_WHILE_DESCRIPTOR);
definePropertyDescriptor(ALLOW_INCREMENT_DECREMENT_DESCRIPTOR);
}
@Override
public Object visit(ASTExpression node, Object data) {
Node parent = node.jjtGetParent();
if ((parent instanceof ASTIfStatement && !getProperty(ALLOW_IF_DESCRIPTOR)
|| parent instanceof ASTWhileStatement && !getProperty(ALLOW_WHILE_DESCRIPTOR)
|| parent instanceof ASTForStatement && parent.jjtGetChild(1) == node
&& !getProperty(ALLOW_FOR_DESCRIPTOR))
&& (node.hasDescendantOfType(ASTAssignmentOperator.class)
|| !getProperty(ALLOW_INCREMENT_DECREMENT_DESCRIPTOR)
&& (node.hasDecendantOfAnyType(ASTPreIncrementExpression.class,
ASTPreDecrementExpression.class, ASTPostfixExpression.class)))) {
addViolation(data, node);
return data;
}
return super.visit(node, data);
}
public boolean allowsAllAssignments() {
return getProperty(ALLOW_IF_DESCRIPTOR) && getProperty(ALLOW_FOR_DESCRIPTOR)
&& getProperty(ALLOW_WHILE_DESCRIPTOR) && getProperty(ALLOW_INCREMENT_DECREMENT_DESCRIPTOR);
}
/**
* @see PropertySource#dysfunctionReason()
*/
@Override
public String dysfunctionReason() {
return allowsAllAssignments() ? "All assignment types allowed, no checks performed" : null;
}
}