[java] Fix typehelper fallback for simple class name
If there is no auxclasspath, then we still can use imports to check the full name before we fallback to simple name only. Also improve RuleTst to actually test without auxclasspath
This commit is contained in:
@ -6,6 +6,7 @@ package net.sourceforge.pmd.lang.java.typeresolution;
|
||||
|
||||
import java.lang.reflect.Array;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
@ -16,6 +17,7 @@ import net.sourceforge.pmd.lang.java.ast.ASTClassOrInterfaceDeclaration;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTClassOrInterfaceType;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTEnumDeclaration;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTImplementsList;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTImportDeclaration;
|
||||
import net.sourceforge.pmd.lang.java.ast.TypeNode;
|
||||
import net.sourceforge.pmd.lang.java.symboltable.TypedNameDeclaration;
|
||||
import net.sourceforge.pmd.lang.java.typeresolution.internal.NullableClassLoader;
|
||||
@ -85,6 +87,18 @@ public final class TypeHelper {
|
||||
}
|
||||
|
||||
private static boolean fallbackIsA(TypeNode n, String clazzName) {
|
||||
if (n.getImage() != null && !n.getImage().contains(".")) {
|
||||
// simple name detected, check the imports to get the full name and use that for fallback
|
||||
List<ASTImportDeclaration> imports = n.getRoot().findChildrenOfType(ASTImportDeclaration.class);
|
||||
for (ASTImportDeclaration importDecl : imports) {
|
||||
if (n.hasImageEqualTo(importDecl.getImportedSimpleName())) {
|
||||
// found the import, compare the full names
|
||||
return clazzName.equals(importDecl.getImportedName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// fall back on using the simple name of the class only
|
||||
if (clazzName.equals(n.getImage()) || clazzName.endsWith("." + n.getImage())) {
|
||||
return true;
|
||||
}
|
||||
|
@ -18,6 +18,8 @@ import org.junit.rules.ExpectedException;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTAnnotationTypeDeclaration;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTClassOrInterfaceDeclaration;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTEnumDeclaration;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTMarkerAnnotation;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTName;
|
||||
import net.sourceforge.pmd.lang.java.ast.TypeNode;
|
||||
import net.sourceforge.pmd.lang.java.symboltable.BaseNonParserTest;
|
||||
import net.sourceforge.pmd.lang.java.typeresolution.internal.NullableClassLoader;
|
||||
@ -78,6 +80,22 @@ public class TypeHelperTest extends BaseNonParserTest {
|
||||
assertIsA(klass, Object.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* If we don't have the annotation on the classpath,
|
||||
* we should resolve the full name via the import, if possible
|
||||
* and compare then. Only after that, we should compare the
|
||||
* simple names.
|
||||
*/
|
||||
@Test
|
||||
public void testIsAFallbackAnnotationSimpleNameImport() {
|
||||
ASTName annotation = java.parse("package org; import foo.Stuff; @Stuff public class FooBar {}")
|
||||
.getFirstDescendantOfType(ASTMarkerAnnotation.class).getFirstChildOfType(ASTName.class);
|
||||
|
||||
Assert.assertNull(annotation.getType());
|
||||
Assert.assertTrue(TypeHelper.isA(annotation, "foo.Stuff"));
|
||||
Assert.assertFalse(TypeHelper.isA(annotation, "other.Stuff"));
|
||||
}
|
||||
|
||||
private void assertIsA(TypeNode node, Class<?> type) {
|
||||
Assert.assertTrue("TypeHelper::isA with class arg: " + type.getCanonicalName(),
|
||||
TypeHelper.isA(node, type));
|
||||
|
@ -150,41 +150,63 @@ public class MethodNamingConventions implements SomeInterface {
|
||||
]]>
|
||||
</code>
|
||||
</test-code>
|
||||
|
||||
<test-code>
|
||||
<description>JUnit 4 test detection</description>
|
||||
<rule-property name="junit4TestPattern">[a-z][A-Za-z]*Test</rule-property>
|
||||
<expected-problems>2</expected-problems>
|
||||
<expected-linenumbers>12,16</expected-linenumbers>
|
||||
<expected-linenumbers>8,12</expected-linenumbers>
|
||||
<expected-messages>
|
||||
<message>The JUnit 4 test method name 'testGetBestTeam' doesn't match '[a-z][A-Za-z]*Test'</message>
|
||||
<message>The JUnit 4 test method name 'getBestTeam' doesn't match '[a-z][A-Za-z]*Test'</message>
|
||||
</expected-messages>
|
||||
<code><![CDATA[
|
||||
import junit.framework.Assert;
|
||||
import junit.framework.TestCase;
|
||||
import junit.framework.TestCase;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.junit.Test;
|
||||
public class TournamentTest extends TestCase {
|
||||
Tournament tournament;
|
||||
|
||||
@Test // note that this is also a junit 3 test, but the junit4 rule applies
|
||||
public void testGetBestTeam() {
|
||||
}
|
||||
|
||||
public class TournamentTest extends TestCase {
|
||||
Tournament tournament;
|
||||
@Test // this is just a junit 4 test
|
||||
public void getBestTeam() {
|
||||
}
|
||||
|
||||
// this is ok
|
||||
@Test
|
||||
public void getBestTeamTest() {
|
||||
}
|
||||
}
|
||||
]]></code>
|
||||
</test-code>
|
||||
|
||||
@Test // note that this is also a junit 3 test, but the junit4 rule applies
|
||||
public void testGetBestTeam() {
|
||||
}
|
||||
<test-code useAuxClasspath="false">
|
||||
<description>JUnit 4 test detection without proper auxclasspath</description>
|
||||
<expected-problems>1</expected-problems>
|
||||
<expected-linenumbers>8</expected-linenumbers>
|
||||
<expected-messages>
|
||||
<message>The JUnit 4 test method name 'get_best_team' doesn't match '[a-z][a-zA-Z0-9]*'</message>
|
||||
</expected-messages>
|
||||
<code><![CDATA[
|
||||
import org.junit.Test; // note: test case uses "useAuxClasspath=false"!!
|
||||
|
||||
@Test // this is just a junit 4 test
|
||||
public void getBestTeam() {
|
||||
}
|
||||
public class TournamentTest {
|
||||
Tournament tournament;
|
||||
|
||||
// this is ok
|
||||
@Test
|
||||
public void getBestTeamTest() {
|
||||
}
|
||||
}
|
||||
]]>
|
||||
</code>
|
||||
// wrong test name pattern
|
||||
@Test
|
||||
public void get_best_team() {
|
||||
}
|
||||
|
||||
// this is ok
|
||||
@Test
|
||||
public void getBestTeam() {
|
||||
}
|
||||
}
|
||||
]]></code>
|
||||
</test-code>
|
||||
|
||||
<test-code>
|
||||
|
Reference in New Issue
Block a user