Merge branch 'bug-1436' into pmd/5.4.x

This commit is contained in:
Andreas Dangel
2015-11-20 11:23:18 +01:00
6 changed files with 97 additions and 18 deletions

View File

@ -8,8 +8,6 @@ import net.sourceforge.pmd.lang.java.rule.AbstractJavaRule;
public class DontImportJavaLangRule extends AbstractJavaRule {
private static final Package JAVA_LANG_PACKAGE = Package.getPackage("java.lang");
@Override
public Object visit(ASTImportDeclaration node, Object data) {
@ -17,22 +15,16 @@ public class DontImportJavaLangRule extends AbstractJavaRule {
return data;
}
if (node.getPackage() != null) {
if (node.getPackage().equals(JAVA_LANG_PACKAGE)) {
addViolation(data, node);
}
} else {
String img = node.jjtGetChild(0).getImage();
if (img.startsWith("java.lang")) {
if (img.startsWith("java.lang.ref") || img.startsWith("java.lang.reflect")
|| img.startsWith("java.lang.annotation") || img.startsWith("java.lang.instrument")
|| img.startsWith("java.lang.management") || img.startsWith("java.lang.Thread.")
|| img.startsWith("java.lang.ProcessBuilder.")) {
return data;
}
addViolation(data, node);
}
String img = node.jjtGetChild(0).getImage();
if (img.startsWith("java.lang")) {
if (img.startsWith("java.lang.ref") || img.startsWith("java.lang.reflect")
|| img.startsWith("java.lang.annotation") || img.startsWith("java.lang.instrument")
|| img.startsWith("java.lang.management") || img.startsWith("java.lang.Thread.")
|| img.startsWith("java.lang.ProcessBuilder.")) {
return data;
}
addViolation(data, node);
}
return data;
}
}

View File

@ -18,6 +18,8 @@ public class UnnecessaryFullyQualifiedNameRule extends AbstractJavaRule {
private List<ASTImportDeclaration> imports = new ArrayList<ASTImportDeclaration>();
private List<ASTImportDeclaration> matches = new ArrayList<ASTImportDeclaration>();
private List<PotentialViolation> violations = new ArrayList<PotentialViolation>();
private List<PotentialViolation> enumViolations = new ArrayList<PotentialViolation>();
public UnnecessaryFullyQualifiedNameRule() {
super.addRuleChainVisit(ASTCompilationUnit.class);
@ -29,6 +31,13 @@ public class UnnecessaryFullyQualifiedNameRule extends AbstractJavaRule {
@Override
public Object visit(ASTCompilationUnit node, Object data) {
imports.clear();
violations.clear();
enumViolations.clear();
super.visit(node, data);
filterPotentialViolations();
reportViolations(data);
return data;
}
@ -118,9 +127,49 @@ public class UnnecessaryFullyQualifiedNameRule extends AbstractJavaRule {
ASTImportDeclaration firstMatch = matches.get(0);
String importStr = firstMatch.getImportedName() + (matches.get(0).isImportOnDemand() ? ".*" : "");
String type = firstMatch.isStatic() ? "static " : "";
addViolation(data, node, new Object[] { node.getImage(), importStr, type });
PotentialViolation v = new PotentialViolation(node, importStr, type);
violations.add(v);
if (isEnum(firstMatch.getType())) {
enumViolations.add(v);
}
}
matches.clear();
}
private static class PotentialViolation {
private JavaNode node;
private String importStr;
private String importType;
public PotentialViolation(JavaNode node, String importStr, String importType) {
this.node = node;
this.importStr = importStr;
this.importType = importType;
}
public void addViolation(UnnecessaryFullyQualifiedNameRule rule, Object data) {
rule.addViolation(data, node, new Object[] { node.getImage(), importStr, importType });
}
}
private void filterPotentialViolations() {
if (enumViolations.size() > 1) {
violations.removeAll(enumViolations);
}
}
private void reportViolations(Object data) {
for (PotentialViolation v : violations) {
v.addViolation(this, data);
}
}
private boolean isEnum(Class<?> type) {
if (type != null && Enum.class.isAssignableFrom(type)) {
return true;
}
return false;
}
}

View File

@ -662,6 +662,16 @@ public class ClassTypeResolver extends JavaParserVisitorAdapter {
}
}
}
if (myType == null && qualifiedName != null && qualifiedName.contains(".")) {
// try if the last part defines a inner class
String qualifiedNameInner = qualifiedName.substring(0, qualifiedName.lastIndexOf('.'))
+ "$" + qualifiedName.substring(qualifiedName.lastIndexOf('.') + 1);
try {
myType = pmdClassLoader.loadClass(qualifiedNameInner);
} catch (Exception e) {
// ignored
}
}
if (myType == null && qualifiedName != null && !qualifiedName.contains(".")) {
// try again with java.lang....
try {

View File

@ -30,4 +30,14 @@ public class ImportsRulesTest extends SimpleAggregatorTst {
System.out.println(message);
}
}
// Do not delete these two enums - it is needed for a test case
// see: /pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/imports/xml/UnnecessaryFullyQualifiedName.xml
// #1436 UnnecessaryFullyQualifiedName false positive on clashing static imports with enums
public enum ENUM1 {
A, B;
}
public enum ENUM2 {
C, D;
}
}

View File

@ -315,6 +315,22 @@ public class InitialPageComponent extends BaseExecutionCourseComponent {
.sorted(Comparator.comparing(Professorship::isResponsibleFor).reversed()
.thenComparing(Professorship.COMPARATOR_BY_PERSON_NAME)).collect(Collectors.toList()));
}
}
]]></code>
</test-code>
<test-code>
<description>#1436 UnnecessaryFullyQualifiedName false positive on clashing static imports with enums</description>
<expected-problems>0</expected-problems>
<code><![CDATA[
import static net.sourceforge.pmd.lang.java.rule.imports.ImportsRulesTest.ENUM1.*;
import static net.sourceforge.pmd.lang.java.rule.imports.ImportsRulesTest.ENUM2.*;
public class UnnecessaryFullyQualifiedName {
public static void main(String[] args) {
System.out.println(ENUM1.values());
System.out.println(ENUM2.values());
}
}
]]></code>
</test-code>