/**
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/
package net.sourceforge.pmd.lang.apex.rule.complexity;
import static apex.jorje.semantic.symbol.type.ModifierTypeInfos.FINAL;
import static apex.jorje.semantic.symbol.type.ModifierTypeInfos.STATIC;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import net.sourceforge.pmd.lang.apex.ast.ASTField;
import net.sourceforge.pmd.lang.apex.ast.ASTUserClass;
import net.sourceforge.pmd.lang.apex.rule.AbstractApexRule;
import net.sourceforge.pmd.lang.ast.Node;
import net.sourceforge.pmd.lang.rule.properties.IntegerProperty;
import net.sourceforge.pmd.util.NumericConstants;
public class TooManyFieldsRule extends AbstractApexRule {
private static final int DEFAULT_MAXFIELDS = 15;
private Map<String, Integer> stats;
private Map<String, ASTUserClass> nodes;
private static final IntegerProperty MAX_FIELDS_DESCRIPTOR = new IntegerProperty("maxfields",
"Max allowable fields", 1, 300, DEFAULT_MAXFIELDS, 1.0f);
public TooManyFieldsRule() {
definePropertyDescriptor(MAX_FIELDS_DESCRIPTOR);
setProperty(CODECLIMATE_CATEGORIES, new String[] { "Complexity" });
setProperty(CODECLIMATE_REMEDIATION_MULTIPLIER, 200);
setProperty(CODECLIMATE_BLOCK_HIGHLIGHTING, false);
}
@Override
public Object visit(ASTUserClass node, Object data) {
int maxFields = getProperty(MAX_FIELDS_DESCRIPTOR);
stats = new HashMap<>(5);
nodes = new HashMap<>(5);
List<ASTField> l = node.findDescendantsOfType(ASTField.class);
for (ASTField fd : l) {
if (fd.getNode().getModifierInfo().all(FINAL, STATIC)) {
continue;
}
ASTUserClass clazz = fd.getFirstParentOfType(ASTUserClass.class);
if (clazz != null) {
bumpCounterFor(clazz);
}
}
for (Map.Entry<String, Integer> entry : stats.entrySet()) {
int val = entry.getValue();
Node n = nodes.get(entry.getKey());
if (val > maxFields) {
addViolation(data, n);
}
}
return data;
}
private void bumpCounterFor(ASTUserClass clazz) {
String key = clazz.getImage();
if (!stats.containsKey(key)) {
stats.put(key, NumericConstants.ZERO);
nodes.put(key, clazz);
}
Integer i = Integer.valueOf(stats.get(key) + 1);
stats.put(key, i);
}
}