/**
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/
package net.sourceforge.pmd.lang.apex.rule.performance;
import net.sourceforge.pmd.lang.apex.ast.ASTDmlDeleteStatement;
import net.sourceforge.pmd.lang.apex.ast.ASTDmlInsertStatement;
import net.sourceforge.pmd.lang.apex.ast.ASTDmlMergeStatement;
import net.sourceforge.pmd.lang.apex.ast.ASTDmlUndeleteStatement;
import net.sourceforge.pmd.lang.apex.ast.ASTDmlUpdateStatement;
import net.sourceforge.pmd.lang.apex.ast.ASTDmlUpsertStatement;
import net.sourceforge.pmd.lang.apex.ast.ASTDoLoopStatement;
import net.sourceforge.pmd.lang.apex.ast.ASTForEachStatement;
import net.sourceforge.pmd.lang.apex.ast.ASTForLoopStatement;
import net.sourceforge.pmd.lang.apex.ast.ASTWhileLoopStatement;
import net.sourceforge.pmd.lang.apex.rule.AbstractApexRule;
import net.sourceforge.pmd.lang.ast.AbstractNode;
import net.sourceforge.pmd.lang.ast.Node;
public class AvoidDmlStatementsInLoopsRule extends AbstractApexRule {
public AvoidDmlStatementsInLoopsRule() {
setProperty(CODECLIMATE_CATEGORIES, new String[] { "Performance" });
// Note: Often more complicated as just moving the SOQL a few lines.
// Involves Maps...
setProperty(CODECLIMATE_REMEDIATION_MULTIPLIER, 150);
setProperty(CODECLIMATE_BLOCK_HIGHLIGHTING, false);
}
@Override
public Object visit(ASTDmlDeleteStatement node, Object data) {
if (insideLoop(node)) {
addViolation(data, node);
}
return data;
}
@Override
public Object visit(ASTDmlInsertStatement node, Object data) {
if (insideLoop(node)) {
addViolation(data, node);
}
return data;
}
@Override
public Object visit(ASTDmlMergeStatement node, Object data) {
if (insideLoop(node)) {
addViolation(data, node);
}
return data;
}
@Override
public Object visit(ASTDmlUndeleteStatement node, Object data) {
if (insideLoop(node)) {
addViolation(data, node);
}
return data;
}
@Override
public Object visit(ASTDmlUpdateStatement node, Object data) {
if (insideLoop(node)) {
addViolation(data, node);
}
return data;
}
@Override
public Object visit(ASTDmlUpsertStatement node, Object data) {
if (insideLoop(node)) {
addViolation(data, node);
}
return data;
}
private boolean insideLoop(AbstractNode node) {
Node n = node.jjtGetParent();
while (n != null) {
if (n instanceof ASTDoLoopStatement || n instanceof ASTWhileLoopStatement
|| n instanceof ASTForLoopStatement || n instanceof ASTForEachStatement) {
return true;
}
n = n.jjtGetParent();
}
return false;
}
}