[java] Qualify references to inner classes of imports

- Given an import on `a.Foo`, references to `Foo.Inner` should be qualified
    as `a.Foo.Inner`.
 - This fixes a couple of wrong missing classes.
 - The test also brought to light another issue with resolvers that would fail
    to resolve even a qualified inner class if not explicitly imported under
    certain circumstances.
This commit is contained in:
Juan Martín Sotuyo Dodero
2017-01-31 01:40:07 -03:00
committed by Andreas Dangel
parent ac03b2e9d6
commit ac2eedf4dd
3 changed files with 34 additions and 3 deletions

View File

@ -381,6 +381,15 @@ public class ClassScope extends AbstractJavaScope {
return qualified;
}
// Is it an inner class of an explicit import?
int dotIndex = typeImage.indexOf('.');
if (dotIndex != -1) {
qualified = findQualifiedName(typeImage.substring(0, dotIndex), fileScope.getExplicitImports());
if (qualified != null) {
return qualified.concat(typeImage.substring(dotIndex));
}
}
return typeImage;
}

View File

@ -437,6 +437,18 @@ public class TypeSet {
return c;
}
@Override
public boolean couldResolve(String name) {
/*
* We can always try!
* If a file used an explicit import on A.Inner, the class loader will register
* A.Inner can't be resolved even if A$Inner can.
* If a second file used A.Inner without an explicit import, we would end here,
* super.couldResolve("A.Inner") will return false, but we CAN resolve it as A$Inner.
*/
return true;
}
}
public void setASTCompilationUnitPackage(String pkg) {

View File

@ -169,6 +169,14 @@ public class ClassScopeTest extends STBBaseTst {
assertEquals("(String,String...)", mnd.getParameterDisplaySignature());
}
@Test
public void testNestedClassesOfImportResolution() {
parseCode(NESTED_CLASSES_OF_IMPORT);
final ASTClassOrInterfaceDeclaration n = acu.findDescendantsOfType(ASTClassOrInterfaceDeclaration.class).get(0);
final ClassScope c = (ClassScope) n.getScope();
assertEquals(EnumTest.class, c.resolveType("TheInnerClass.EnumTest"));
}
@Test
public void testNestedClassesResolution() {
parseForClass(InnerClass.class);
@ -423,7 +431,9 @@ public class ClassScopeTest extends STBBaseTst {
" public EnumTest e;" + PMD.EOL +
"}" + PMD.EOL;
public static junit.framework.Test suite() {
return new junit.framework.JUnit4TestAdapter(ClassScopeTest.class);
}
private static final String NESTED_CLASSES_OF_IMPORT =
"import net.sourceforge.pmd.lang.java.symboltable.testdata.InnerClass.TheInnerClass;" + PMD.EOL
+ "public class Foo {" + PMD.EOL
+ " public TheInnerClass.EnumTest e;" + PMD.EOL
+ "}" + PMD.EOL;
}