roaster
roaster copied to clipboard
Qualified name of inner classes missing the enclosing type
If you reference an inner class (or interface) in the extends clause / implements clause / field / return type of method / parameter of method, the parent types are missing. I provided a small example:
import org.jboss.forge.roaster.Roaster;
import org.jboss.forge.roaster.model.source.JavaClassSource;
import org.jboss.forge.roaster.model.source.JavaInterfaceSource;
import org.jboss.forge.roaster.model.source.JavaSource;
import org.junit.jupiter.api.Test;
public class InnerClassesTest {
private String testClass = """
package alpha.beta.gamma;
public class Foo {
public class Bar extends Bar2 implements BarInterface {
private Huu h;
public Huu getHuu(Huu huu) throws BarException {return null;}
public class Huu {
}
}
public class Bar2 {}
public interface BarInterface {}
}
""";
@Test
public void test() {
JavaClassSource foo = (JavaClassSource) Roaster.parse(JavaSource.class, testClass);
JavaClassSource bar = (JavaClassSource) foo.getNestedTypes().get(0);
JavaClassSource bar2 = (JavaClassSource) foo.getNestedTypes().get(1);
JavaInterfaceSource bar2Interface = (JavaInterfaceSource) foo.getNestedTypes().get(2);
JavaClassSource huu = (JavaClassSource) bar.getNestedTypes().get(0);
System.out.println(bar.getSuperType()+" should be "+bar2.getQualifiedName());
System.out.println(bar.getInterfaces().get(0)+" should be "+bar2Interface.getQualifiedName());
System.out.println(bar.getFields().get(0).getType().getQualifiedNameWithGenerics() +" should be "+huu.getQualifiedName());
System.out.println(bar.getMethods().get(0).getReturnType().getQualifiedNameWithGenerics()+" should be "+huu.getQualifiedName());
System.out.println(bar.getMethods().get(0).getParameters().get(0).getType().getQualifiedNameWithGenerics()+" should be "+huu.getQualifiedName());
System.out.println(bar.getMethods().get(0).getParameters().get(0).getType().getQualifiedNameWithGenerics()+" should be "+huu.getQualifiedName());
}
}
Produced output:
alpha.beta.gamma.Bar2 should be alpha.beta.gamma.Foo$Bar2
alpha.beta.gamma.BarInterface should be alpha.beta.gamma.Foo$BarInterface
alpha.beta.gamma.Huu should be alpha.beta.gamma.Foo$Bar$Huu
alpha.beta.gamma.Huu should be alpha.beta.gamma.Foo$Bar$Huu
alpha.beta.gamma.Huu should be alpha.beta.gamma.Foo$Bar$Huu
alpha.beta.gamma.Huu should be alpha.beta.gamma.Foo$Bar$Huu
Here is a test using assertions based on your report:
package org.jboss.forge.test.roaster.model;
import org.jboss.forge.roaster.Roaster;
import org.jboss.forge.roaster.model.source.JavaClassSource;
import org.jboss.forge.roaster.model.source.JavaInterfaceSource;
import org.jboss.forge.roaster.model.source.JavaSource;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
public class InnerClassesTest
{
private static final String CONTENTS =
"package alpha.beta.gamma;"
+ "public class Outer {"
+ " public class InnerExtendsClass extends InnerClass implements InnerInterface {"
+ " private InnerInnerExtendsClass h;"
+ " public InnerInnerExtendsClass getInnerInnerExtendsClass(InnerInnerExtendsClass huu) throws Exception {return null;}"
+ " public class InnerInnerExtendsClass {}"
+ " }"
+ " public class InnerClass {}"
+ " public interface InnerInterface {}"
+ "}";
private static JavaClassSource innerExtendsClass;
private static JavaClassSource innerClass;
private static JavaInterfaceSource innerInterface;
private static JavaClassSource innerInnerExtendsClass;
@BeforeAll
static void setUp()
{
JavaClassSource outer = Roaster.parse(JavaClassSource.class, CONTENTS);
List<JavaSource<?>> nestedTypes = outer.getNestedTypes();
innerExtendsClass = (JavaClassSource) nestedTypes.get(0);
innerClass = (JavaClassSource) nestedTypes.get(1);
innerInterface = (JavaInterfaceSource) nestedTypes.get(2);
innerInnerExtendsClass = (JavaClassSource) innerExtendsClass.getNestedTypes().get(0);
}
@Test
void test_super_type_should_match_qualified_name()
{
assertThat(innerExtendsClass.getSuperType()).isEqualTo(innerClass.getQualifiedName());
}
@Test
void test_interface_should_match_qualified_name()
{
assertThat(innerExtendsClass.getInterfaces().get(0)).isEqualTo(innerInterface.getQualifiedName());
}
@Test
void test_field_type_should_match_qualified_name() {
assertThat(innerExtendsClass.getFields().get(0).getType().getQualifiedNameWithGenerics()).isEqualTo(
innerInnerExtendsClass.getQualifiedName());
}
@Test
void test_method_return_type_should_match_qualified_name() {
assertThat(innerExtendsClass.getMethods().get(0).getReturnType().getQualifiedNameWithGenerics())
.isEqualTo(innerInnerExtendsClass.getQualifiedName());
}
@Test
void test_method_parameter_type_should_match_qualified_name() {
assertThat(innerExtendsClass.getMethods().get(0).getParameters().get(0).getType().getQualifiedNameWithGenerics())
.isEqualTo(innerInnerExtendsClass.getQualifiedName());
}
}