/**
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/
package net.sourceforge.pmd.lang.java.rule.basic;
import java.math.BigDecimal;
import java.math.BigInteger;
import net.sourceforge.pmd.RuleContext;
import net.sourceforge.pmd.lang.LanguageRegistry;
import net.sourceforge.pmd.lang.ast.Node;
import net.sourceforge.pmd.lang.java.JavaLanguageModule;
import net.sourceforge.pmd.lang.java.ast.ASTAllocationExpression;
import net.sourceforge.pmd.lang.java.ast.ASTArguments;
import net.sourceforge.pmd.lang.java.ast.ASTArrayDimsAndInits;
import net.sourceforge.pmd.lang.java.ast.ASTClassOrInterfaceType;
import net.sourceforge.pmd.lang.java.ast.ASTLiteral;
import net.sourceforge.pmd.lang.java.rule.AbstractJavaRule;
import net.sourceforge.pmd.lang.java.typeresolution.TypeHelper;
/**
* Rule that marks instantiations of new {@link BigInteger} or
* {@link BigDecimal} objects, when there is a well-known constant available,
* such as {@link BigInteger#ZERO}.
*/
public class BigIntegerInstantiationRule extends AbstractJavaRule {
@Override
public Object visit(ASTAllocationExpression node, Object data) {
Node type = node.jjtGetChild(0);
if (!(type instanceof ASTClassOrInterfaceType)) {
return super.visit(node, data);
}
boolean jdk15 = ((RuleContext) data).getLanguageVersion()
.compareTo(LanguageRegistry.getLanguage(JavaLanguageModule.NAME).getVersion("1.5")) >= 0;
if ((TypeHelper.isA((ASTClassOrInterfaceType) type, BigInteger.class)
|| jdk15 && TypeHelper.isA((ASTClassOrInterfaceType) type, BigDecimal.class))
&& !node.hasDescendantOfType(ASTArrayDimsAndInits.class)) {
ASTArguments args = node.getFirstChildOfType(ASTArguments.class);
if (args.getArgumentCount() == 1) {
ASTLiteral literal = node.getFirstDescendantOfType(ASTLiteral.class);
if (literal == null
|| literal.jjtGetParent().jjtGetParent().jjtGetParent().jjtGetParent().jjtGetParent() != args) {
return super.visit(node, data);
}
String img = literal.getImage();
if (literal.isStringLiteral()) {
img = img.substring(1, img.length() - 1);
}
if ("0".equals(img) || "1".equals(img) || jdk15 && "10".equals(img)) {
addViolation(data, node);
return data;
}
}
}
return super.visit(node, data);
}
}