Merge branch 'pr-741'

This commit is contained in:
Andreas Dangel
2017-11-24 11:45:10 +01:00
5 changed files with 44 additions and 87 deletions

View File

@ -347,6 +347,7 @@ a warning will now be produced suggesting users to adopt it for better performan
* [#534](https://github.com/pmd/pmd/issues/534): \[java] NPE in MethodTypeResolution for static methods
* [#603](https://github.com/pmd/pmd/issues/603): \[core] incremental analysis should invalidate upon Java rule plugin changes
* [#650](https://github.com/pmd/pmd/issues/650): \[java] ProcesingError analyzing code under 5.8.1
* [#732](https://github.com/pmd/pmd/issues/732): \[java] LinkageError with aux classpath
* java-basic
* [#565](https://github.com/pmd/pmd/pull/565): \[java] False negative on DontCallThreadRun when extending Thread
* java-comments

View File

@ -22,42 +22,14 @@ import net.sourceforge.pmd.lang.java.typeresolution.TypeHelper;
public abstract class AbstractJUnitRule extends AbstractJavaRule {
public static final Class<?> JUNIT3_CLASS;
private static final String JUNIT3_CLASS_NAME = "junit.framework.TestCase";
public static final Class<?> JUNIT4_CLASS;
private static final String JUNIT4_CLASS_NAME = "org.junit.Test";
public static final Class<?> JUNIT5_CLASS;
private static final String JUNIT5_CLASS_NAME = "org.junit.jupiter.api.Test";
protected static final String JUNIT3_CLASS_NAME = "junit.framework.TestCase";
protected static final String JUNIT4_CLASS_NAME = "org.junit.Test";
protected static final String JUNIT5_CLASS_NAME = "org.junit.jupiter.api.Test";
private boolean isJUnit3Class;
private boolean isJUnit4Class;
private boolean isJUnit5Class;
static {
Class<?> c;
try {
c = Class.forName(JUNIT3_CLASS_NAME);
} catch (ClassNotFoundException | NoClassDefFoundError t) {
c = null;
}
JUNIT3_CLASS = c;
try {
c = Class.forName(JUNIT4_CLASS_NAME);
} catch (ClassNotFoundException | NoClassDefFoundError t) {
c = null;
}
JUNIT4_CLASS = c;
try {
c = Class.forName(JUNIT5_CLASS_NAME);
} catch (ClassNotFoundException | NoClassDefFoundError t) {
c = null;
}
JUNIT5_CLASS = c;
}
@Override
public Object visit(ASTCompilationUnit node, Object data) {
@ -112,11 +84,11 @@ public abstract class AbstractJUnitRule extends AbstractJavaRule {
}
private boolean isJUnit4Method(ASTMethodDeclaration method) {
return doesNodeContainJUnitAnnotation(method.jjtGetParent(), JUNIT4_CLASS, JUNIT4_CLASS_NAME);
return doesNodeContainJUnitAnnotation(method.jjtGetParent(), JUNIT4_CLASS_NAME);
}
private boolean isJUnit5Method(ASTMethodDeclaration method) {
return doesNodeContainJUnitAnnotation(method.jjtGetParent(), JUNIT5_CLASS, JUNIT5_CLASS_NAME);
return doesNodeContainJUnitAnnotation(method.jjtGetParent(), JUNIT5_CLASS_NAME);
}
private boolean isJUnit3Method(ASTMethodDeclaration method) {
@ -133,7 +105,7 @@ public abstract class AbstractJUnitRule extends AbstractJavaRule {
return false;
}
if (node.getType() != null && TypeHelper.isA(node, JUNIT3_CLASS)) {
if (node.getType() != null && TypeHelper.isA(node, JUNIT3_CLASS_NAME)) {
return true;
} else if (node.getType() == null) {
ASTExtendsList extendsList = cid.getFirstChildOfType(ASTExtendsList.class);
@ -152,14 +124,14 @@ public abstract class AbstractJUnitRule extends AbstractJavaRule {
}
private boolean isJUnit4Class(ASTCompilationUnit node) {
return doesNodeContainJUnitAnnotation(node, JUNIT4_CLASS, JUNIT4_CLASS_NAME);
return doesNodeContainJUnitAnnotation(node, JUNIT4_CLASS_NAME);
}
private boolean isJUnit5Class(ASTCompilationUnit node) {
return doesNodeContainJUnitAnnotation(node, JUNIT5_CLASS, JUNIT5_CLASS_NAME);
return doesNodeContainJUnitAnnotation(node, JUNIT5_CLASS_NAME);
}
private boolean doesNodeContainJUnitAnnotation(Node node, Class<?> annotationTypeClass, String annotationTypeClassName) {
private boolean doesNodeContainJUnitAnnotation(Node node, String annotationTypeClassName) {
List<ASTAnnotation> annotations = node.findDescendantsOfType(ASTAnnotation.class);
for (ASTAnnotation annotation : annotations) {
Node annotationTypeNode = annotation.jjtGetChild(0);
@ -169,7 +141,7 @@ public abstract class AbstractJUnitRule extends AbstractJavaRule {
if (name != null && (name.hasImageEqualTo("Test") || name.hasImageEqualTo(annotationTypeClassName))) {
return true;
}
} else if (annotationType.getType().equals(annotationTypeClass)) {
} else if (TypeHelper.isA(annotationType, annotationTypeClassName)) {
return true;
}
}

View File

@ -20,6 +20,7 @@ import net.sourceforge.pmd.lang.java.ast.ASTPrimaryExpression;
import net.sourceforge.pmd.lang.java.ast.ASTReferenceType;
import net.sourceforge.pmd.lang.java.ast.ASTStatementExpression;
import net.sourceforge.pmd.lang.java.rule.AbstractJUnitRule;
import net.sourceforge.pmd.lang.java.typeresolution.TypeHelper;
import net.sourceforge.pmd.lang.symboltable.NameDeclaration;
import net.sourceforge.pmd.lang.symboltable.NameOccurrence;
import net.sourceforge.pmd.lang.symboltable.Scope;
@ -106,7 +107,7 @@ public class JUnitTestsShouldIncludeAssertRule extends AbstractJUnitRule {
for (ASTNormalAnnotation annotation : annotations) {
ASTName name = annotation.getFirstChildOfType(ASTName.class);
if (name != null && ("Test".equals(name.getImage())
|| name.getType() != null && name.getType().equals(JUNIT4_CLASS))) {
|| name.getType() != null && TypeHelper.isA(name, JUNIT4_CLASS_NAME))) {
List<ASTMemberValuePair> memberValues = annotation.findDescendantsOfType(ASTMemberValuePair.class);
for (ASTMemberValuePair pair : memberValues) {
if ("expected".equals(pair.getImage())) {

View File

@ -16,37 +16,14 @@ import net.sourceforge.pmd.lang.java.ast.ASTType;
import net.sourceforge.pmd.lang.java.ast.ASTVariableDeclarator;
import net.sourceforge.pmd.lang.java.ast.JavaNode;
import net.sourceforge.pmd.lang.java.rule.AbstractJavaRule;
import net.sourceforge.pmd.lang.java.typeresolution.TypeHelper;
import net.sourceforge.pmd.util.NumericConstants;
public class MoreThanOneLoggerRule extends AbstractJavaRule {
private static final Class<?> LOG4J_LOGGER;
private static final Class<?> JAVA_LOGGER;
private static final Class<?> SLF4J_LOGGER;
static {
Class<?> c;
try {
c = Class.forName("org.apache.log4j.Logger");
} catch (Throwable t) {
c = null;
}
LOG4J_LOGGER = c;
try {
c = Class.forName("java.util.logging.Logger");
} catch (Throwable t) {
c = null;
}
JAVA_LOGGER = c;
try {
c = Class.forName("org.slf4j.Logger");
} catch (Throwable t) {
c = null;
}
SLF4J_LOGGER = c;
}
private static final String LOG4J_LOGGER_NAME = "org.apache.log4j.Logger";
private static final String JAVA_LOGGER_NAME = "java.util.logging.Logger";
private static final String SLF4J_LOGGER_NAME = "org.slf4j.Logger";
private Stack<Integer> stack = new Stack<>();
@ -94,8 +71,9 @@ public class MoreThanOneLoggerRule extends AbstractJavaRule {
if (classOrIntType instanceof ASTClassOrInterfaceType) {
Class<?> clazzType = ((ASTClassOrInterfaceType) classOrIntType).getType();
if (clazzType != null
&& (clazzType.equals(LOG4J_LOGGER) || clazzType.equals(JAVA_LOGGER)
|| clazzType.equals(SLF4J_LOGGER))
&& (TypeHelper.isA((ASTClassOrInterfaceType) classOrIntType, LOG4J_LOGGER_NAME)
|| TypeHelper.isA((ASTClassOrInterfaceType) classOrIntType, JAVA_LOGGER_NAME)
|| TypeHelper.isA((ASTClassOrInterfaceType) classOrIntType, SLF4J_LOGGER_NAME))
|| clazzType == null && "Logger".equals(classOrIntType.getImage())) {
++count;
}

View File

@ -4,9 +4,6 @@
package net.sourceforge.pmd.lang.java.typeresolution;
import java.util.Arrays;
import java.util.List;
import net.sourceforge.pmd.lang.ast.Node;
import net.sourceforge.pmd.lang.java.ast.TypeNode;
import net.sourceforge.pmd.lang.java.symboltable.TypedNameDeclaration;
@ -17,6 +14,29 @@ public final class TypeHelper {
// utility class
}
public static boolean isA(final TypeNode n, final String clazzName) {
if (n.getType() != null) {
try {
ClassLoader classLoader = n.getType().getClassLoader();
if (classLoader == null) {
// Using the system classloader then
classLoader = ClassLoader.getSystemClassLoader();
}
// If the requested type is in the classpath, using the same classloader should work
final Class<?> clazz = classLoader.loadClass(clazzName);
if (clazz != null) {
return isA(n, clazz);
}
} catch (final ClassNotFoundException e) {
// The requested type is not on the auxclasspath
}
}
return clazzName.equals(n.getImage()) || clazzName.endsWith("." + n.getImage());
}
public static boolean isA(TypeNode n, Class<?> clazz) {
return subclasses(n, clazz);
}
@ -45,21 +65,6 @@ public final class TypeHelper {
return clazz.getSimpleName().equals(((Node) n).getImage()) || clazz.getName().equals(((Node) n).getImage());
}
if (type.equals(clazz)) {
return true;
}
List<Class<?>> implementors = Arrays.asList(type.getInterfaces());
if (implementors.contains(clazz)) {
return true;
}
Class<?> superC = type.getSuperclass();
while (superC != null && !superC.equals(Object.class)) {
if (superC.equals(clazz)) {
return true;
}
superC = superC.getSuperclass();
}
return false;
return clazz.isAssignableFrom(type);
}
}