Search in sources :

Example 6 with CtTypeParameter

use of spoon.reflect.declaration.CtTypeParameter in project spoon by INRIA.

the class CtTypeParameterTest method testTypeSame.

@Test
public void testTypeSame() throws Exception {
    CtClass<?> ctModel = (CtClass<?>) ModelUtils.buildClass(ErasureModelA.class);
    CtTypeParameter tpA = ctModel.getFormalCtTypeParameters().get(0);
    CtTypeParameter tpB = ctModel.getFormalCtTypeParameters().get(1);
    CtTypeParameter tpC = ctModel.getFormalCtTypeParameters().get(2);
    CtTypeParameter tpD = ctModel.getFormalCtTypeParameters().get(3);
    CtConstructor<?> ctModelCons = ctModel.getConstructors().iterator().next();
    CtMethod<?> ctModelMethod = ctModel.getMethodsByName("method").get(0);
    CtMethod<?> ctModelMethod2 = ctModel.getMethodsByName("method2").get(0);
    CtClass<?> ctModelB = ctModel.filterChildren(new NamedElementFilter<>(CtClass.class, "ModelB")).first();
    CtTypeParameter tpA2 = ctModelB.getFormalCtTypeParameters().get(0);
    CtTypeParameter tpB2 = ctModelB.getFormalCtTypeParameters().get(1);
    CtTypeParameter tpC2 = ctModelB.getFormalCtTypeParameters().get(2);
    CtTypeParameter tpD2 = ctModelB.getFormalCtTypeParameters().get(3);
    CtConstructor<?> ctModelBCons = ctModelB.getConstructors().iterator().next();
    CtMethod<?> ctModelBMethod = ctModelB.getMethodsByName("method").get(0);
    // the type parameters of ErasureModelA and ErasureModelA$ModelB are same if they are on the same position.
    checkIsSame(ctModel.getFormalCtTypeParameters(), ctModelB.getFormalCtTypeParameters(), true);
    // the type parameters of ErasureModelA#constructor and ErasureModelA$ModelB constructor are same, because constructors has same formal type parameters
    // https://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.4.4
    checkIsSame(ctModelCons.getFormalCtTypeParameters(), ctModelBCons.getFormalCtTypeParameters(), true);
    // the type parameters of ctModel ErasureModelA#method and ErasureModelA$ModelB#method are same if they are on the same position.
    checkIsSame(ctModelMethod.getFormalCtTypeParameters(), ctModelBMethod.getFormalCtTypeParameters(), true);
    // the type parameters of ctModel ErasureModelA#constructor and ErasureModelA$ModelB#method are never same, because they have different type of scope (Method!=Constructor)
    checkIsSame(ctModelCons.getFormalCtTypeParameters(), ctModelBMethod.getFormalCtTypeParameters(), false);
    // the type parameters of ctModel ErasureModelA#method and ErasureModelA#method2 are same, because they have same formal type parameters
    // https://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.4.4
    checkIsSame(ctModelMethod.getFormalCtTypeParameters(), ctModelMethod2.getFormalCtTypeParameters(), true);
    CtClass<?> ctModelC = ctModel.filterChildren(new NamedElementFilter<>(CtClass.class, "ModelC")).first();
}
Also used : CtClass(spoon.reflect.declaration.CtClass) CtTypeParameter(spoon.reflect.declaration.CtTypeParameter) ErasureModelA(spoon.test.ctType.testclasses.ErasureModelA) NamedElementFilter(spoon.reflect.visitor.filter.NamedElementFilter) Test(org.junit.Test)

Example 7 with CtTypeParameter

use of spoon.reflect.declaration.CtTypeParameter in project spoon by INRIA.

the class GenericsTest method testIsGenericsMethod.

@Test
public void testIsGenericsMethod() throws Exception {
    CtType<Tacos> aTacos = buildNoClasspath(Tacos.class).Type().get(Tacos.class);
    CtTypeParameter typeParameter = aTacos.getFormalCtTypeParameters().get(0);
    assertTrue(typeParameter.isGenerics());
    assertTrue(typeParameter.getReference().isGenerics());
    CtTypeReference ctTypeReference = aTacos.getSuperInterfaces().toArray(new CtTypeReference[aTacos.getSuperInterfaces().size()])[0];
    assertFalse(aTacos.isGenerics());
    // this is a generic type reference spoon.test.generics.testclasses.ITacos<V>
    assertEquals("spoon.test.generics.testclasses.ITacos<V>", ctTypeReference.toString());
    assertTrue(ctTypeReference.isGenerics());
}
Also used : CtTypeParameter(spoon.reflect.declaration.CtTypeParameter) CtTypeReference(spoon.reflect.reference.CtTypeReference) Tacos(spoon.test.generics.testclasses.Tacos) MainTest(spoon.test.main.MainTest) Test(org.junit.Test)

Example 8 with CtTypeParameter

use of spoon.reflect.declaration.CtTypeParameter in project spoon by INRIA.

the class GenericsTest method testAccessToGenerics.

@Test
public void testAccessToGenerics() throws Exception {
    Launcher spoon = new Launcher();
    Factory factory = spoon.createFactory();
    SpoonModelBuilder compiler = spoon.createCompiler(factory, SpoonResourceHelper.resources("./src/test/java/spoon/test/generics/Foo.java", "./src/test/java/spoon/test/generics/Bar.java"));
    compiler.build();
    CtClass<?> foo = (CtClass<?>) factory.Type().get(Foo.class);
    CtInterface<?> bar = (CtInterface<?>) factory.Type().get(Bar.class);
    final CtNewClass<?> newAnonymousBar = foo.getElements(new AbstractFilter<CtNewClass<?>>(CtNewClass.class) {

        @Override
        public boolean matches(CtNewClass<?> element) {
            return element.getAnonymousClass() != null && element.getAnonymousClass().isAnonymous();
        }
    }).get(0);
    final List<CtTypeParameter> barTypeParamGenerics = bar.getFormalCtTypeParameters();
    final CtTypeReference<?> anonymousBar = newAnonymousBar.getType();
    assertEquals("Name of the first generic parameter in Bar interface must to be I.", "I", barTypeParamGenerics.get(0).getSimpleName());
    assertEquals("Name of the first generic parameter in Bar usage must to be K.", "K", anonymousBar.getActualTypeArguments().get(0).getSimpleName());
    assertEquals("Name of the second generic parameter in Bar interface must to be O.", "O", barTypeParamGenerics.get(1).getSimpleName());
    assertEquals("Name of the second generic parameter in Bar usage must to be V.", "V", anonymousBar.getActualTypeArguments().get(1).getSimpleName());
}
Also used : SpoonModelBuilder(spoon.SpoonModelBuilder) CtInterface(spoon.reflect.declaration.CtInterface) AbstractFilter(spoon.reflect.visitor.filter.AbstractFilter) CtTypeParameter(spoon.reflect.declaration.CtTypeParameter) ModelUtils.createFactory(spoon.testing.utils.ModelUtils.createFactory) Factory(spoon.reflect.factory.Factory) LikeCtClass(spoon.test.generics.testclasses2.LikeCtClass) CtClass(spoon.reflect.declaration.CtClass) CtNewClass(spoon.reflect.code.CtNewClass) Launcher(spoon.Launcher) MainTest(spoon.test.main.MainTest) Test(org.junit.Test)

Example 9 with CtTypeParameter

use of spoon.reflect.declaration.CtTypeParameter in project spoon by INRIA.

the class GenericsTest method testRecursiveTypeAdapting.

@Test
public void testRecursiveTypeAdapting() throws Exception {
    CtType<?> classOrange = buildClass(Orange.class);
    CtClass<?> classA = classOrange.getNestedType("A");
    CtTypeParameter typeParamO = classA.getFormalCtTypeParameters().get(0);
    CtTypeParameter typeParamM = classA.getFormalCtTypeParameters().get(1);
    assertEquals("O", typeParamO.getQualifiedName());
    assertEquals("M", typeParamM.getQualifiedName());
    assertEquals("K", typeParamO.getSuperclass().getQualifiedName());
    assertEquals("O", typeParamM.getSuperclass().getQualifiedName());
    assertEquals("K", typeParamM.getSuperclass().getSuperclass().getQualifiedName());
    CtClass<?> classB = classOrange.getNestedType("B");
    CtTypeParameter typeParamN = classB.getFormalCtTypeParameters().get(0);
    CtTypeParameter typeParamP = classB.getFormalCtTypeParameters().get(1);
    assertEquals("N", typeParamN.getQualifiedName());
    assertEquals("P", typeParamP.getQualifiedName());
    ClassTypingContext ctcB = new ClassTypingContext(classB);
    assertEquals("N", ctcB.adaptType(typeParamO).getQualifiedName());
    assertEquals("P", ctcB.adaptType(typeParamM).getQualifiedName());
    // contract: superClass of CtTypeParam is adapted too
    assertEquals("K", ctcB.adaptType(typeParamO).getSuperclass().getQualifiedName());
    assertEquals("N", ctcB.adaptType(typeParamM).getSuperclass().getQualifiedName());
    assertEquals("K", ctcB.adaptType(typeParamM).getSuperclass().getSuperclass().getQualifiedName());
    CtTypeReference<?> typeRef_list2m = classA.getField("list2m").getType();
    assertEquals("java.util.List<java.util.List<M>>", typeRef_list2m.toString());
    // contract: the CtTypeReference is adapted recursive including actual type arguments
    assertEquals("java.util.List<java.util.List<P>>", ctcB.adaptType(typeRef_list2m).toString());
    CtTypeReference<?> typeRef_ListQextendsM = classA.getMethodsByName("method").get(0).getParameters().get(0).getType();
    assertEquals("java.util.List<? extends M>", typeRef_ListQextendsM.toString());
    // contract: the CtTypeReference is adapted recursive including actual type arguments and their bounds
    assertEquals("java.util.List<? extends P>", ctcB.adaptType(typeRef_ListQextendsM).toString());
}
Also used : ClassTypingContext(spoon.support.visitor.ClassTypingContext) CtTypeParameter(spoon.reflect.declaration.CtTypeParameter) MainTest(spoon.test.main.MainTest) Test(org.junit.Test)

Example 10 with CtTypeParameter

use of spoon.reflect.declaration.CtTypeParameter in project spoon by INRIA.

the class GenericsTest method testTypeParameterDeclarer.

@Test
public void testTypeParameterDeclarer() throws Exception {
    // contract: one can lookup the declarer of a type parameter if it is in appropriate context (the declararer is in the parent hierarchy)
    CtClass<?> classThatDefinesANewTypeArgument = build("spoon.test.generics", "ClassThatDefinesANewTypeArgument");
    CtTypeParameter typeParam = classThatDefinesANewTypeArgument.getFormalCtTypeParameters().get(0);
    assertEquals("T", classThatDefinesANewTypeArgument.getFormalCtTypeParameters().get(0).getSimpleName());
    assertSame(classThatDefinesANewTypeArgument, typeParam.getTypeParameterDeclarer());
    CtTypeParameterReference typeParamReference = typeParam.getReference();
    assertSame(typeParam, typeParamReference.getDeclaration());
    // creating an appropriate context
    CtMethod m = classThatDefinesANewTypeArgument.getFactory().createMethod();
    m.setParent(classThatDefinesANewTypeArgument);
    // setting the return type of the method
    m.setType(typeParamReference);
    classThatDefinesANewTypeArgument.addMethod(m);
    // the final assertions
    assertSame(typeParam, typeParamReference.getDeclaration());
    assertSame(classThatDefinesANewTypeArgument, typeParamReference.getDeclaration().getParent());
    // now testing that the getDeclaration of a type parameter is actually a dynamic lookup
    CtClass<?> c2 = classThatDefinesANewTypeArgument.clone();
    c2.addMethod(m);
    assertSame(c2, typeParamReference.getDeclaration().getParent());
    // even if we rename it
    // renaming the reference
    typeParamReference.setSimpleName("R");
    // renaming the declaration
    c2.getFormalCtTypeParameters().get(0).setSimpleName("R");
    assertSame(c2, typeParamReference.getDeclaration().getParent());
}
Also used : CtTypeParameterReference(spoon.reflect.reference.CtTypeParameterReference) CtTypeParameter(spoon.reflect.declaration.CtTypeParameter) CtMethod(spoon.reflect.declaration.CtMethod) MainTest(spoon.test.main.MainTest) Test(org.junit.Test)

Aggregations

CtTypeParameter (spoon.reflect.declaration.CtTypeParameter)43 Test (org.junit.Test)25 MainTest (spoon.test.main.MainTest)12 Factory (spoon.reflect.factory.Factory)10 CtTypeParameterReference (spoon.reflect.reference.CtTypeParameterReference)10 Launcher (spoon.Launcher)9 CtClass (spoon.reflect.declaration.CtClass)9 CtTypeReference (spoon.reflect.reference.CtTypeReference)8 NamedElementFilter (spoon.reflect.visitor.filter.NamedElementFilter)7 ModelUtils.createFactory (spoon.testing.utils.ModelUtils.createFactory)7 ArrayList (java.util.ArrayList)6 CtMethod (spoon.reflect.declaration.CtMethod)6 CtType (spoon.reflect.declaration.CtType)5 LikeCtClass (spoon.test.generics.testclasses2.LikeCtClass)4 SpoonException (spoon.SpoonException)3 CtFormalTypeDeclarer (spoon.reflect.declaration.CtFormalTypeDeclarer)3 CtLambda (spoon.reflect.code.CtLambda)2 CtElement (spoon.reflect.declaration.CtElement)2 CtExecutable (spoon.reflect.declaration.CtExecutable)2 CtInterface (spoon.reflect.declaration.CtInterface)2