Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Qualified name of inner classes missing the enclosing type #218

Open
thorstengross opened this issue Nov 14, 2021 · 1 comment
Open

Qualified name of inner classes missing the enclosing type #218

thorstengross opened this issue Nov 14, 2021 · 1 comment

Comments

@thorstengross
Copy link

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
@gastaldi
Copy link
Member

gastaldi commented May 13, 2022

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());
   }

}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants