Search in sources :

Example 1 with CtTypeMember

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

the class CtTypeParameterTest method checkType.

private void checkType(CtType<?> type) throws NoSuchFieldException, SecurityException {
    List<CtTypeParameter> formalTypeParameters = type.getFormalCtTypeParameters();
    for (CtTypeParameter ctTypeParameter : formalTypeParameters) {
        checkTypeParamErasureOfType(ctTypeParameter, type.getActualClass());
    }
    for (CtTypeMember member : type.getTypeMembers()) {
        if (member instanceof CtFormalTypeDeclarer) {
            CtFormalTypeDeclarer ftDecl = (CtFormalTypeDeclarer) member;
            formalTypeParameters = ftDecl.getFormalCtTypeParameters();
            if (member instanceof CtExecutable<?>) {
                CtExecutable<?> exec = (CtExecutable<?>) member;
                for (CtTypeParameter ctTypeParameter : formalTypeParameters) {
                    checkTypeParamErasureOfExecutable(ctTypeParameter);
                }
                for (CtParameter<?> param : exec.getParameters()) {
                    checkParameterErasureOfExecutable(param);
                }
            } else if (member instanceof CtType<?>) {
                CtType<?> nestedType = (CtType<?>) member;
                // recursive call for nested type
                checkType(nestedType);
            }
        }
    }
}
Also used : CtTypeParameter(spoon.reflect.declaration.CtTypeParameter) CtTypeMember(spoon.reflect.declaration.CtTypeMember) CtType(spoon.reflect.declaration.CtType) CtFormalTypeDeclarer(spoon.reflect.declaration.CtFormalTypeDeclarer) CtExecutable(spoon.reflect.declaration.CtExecutable)

Example 2 with CtTypeMember

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

the class GenericsTest method testMethodTypingContextAdaptMethod.

@Test
public void testMethodTypingContextAdaptMethod() throws Exception {
    // core contracts of MethodTypingContext#adaptMethod
    Factory factory = build(new File("src/test/java/spoon/test/generics/testclasses"));
    CtClass<?> ctClassLunch = factory.Class().get(Lunch.class);
    // represents <C> void eatMe(A paramA, B paramB, C paramC){}
    CtMethod<?> trLunch_eatMe = ctClassLunch.filterChildren(new NamedElementFilter<>(CtMethod.class, "eatMe")).first();
    CtClass<?> ctClassWeddingLunch = factory.Class().get(WeddingLunch.class);
    ClassTypingContext ctcWeddingLunch = new ClassTypingContext(ctClassWeddingLunch);
    // we all analyze new methods
    final MethodTypingContext methodSTH = new MethodTypingContext().setClassTypingContext(ctcWeddingLunch);
    // contract: method can be adapted only using MethodTypingContext
    methodSTH.setMethod(trLunch_eatMe);
    CtMethod<?> adaptedLunchEatMe = (CtMethod<?>) methodSTH.getAdaptationScope();
    // contract: adapting of method declared in different scope, returns new method
    assertTrue(adaptedLunchEatMe != trLunch_eatMe);
    // check that new method is adapted correctly
    // is declared in correct class
    assertSame(ctClassWeddingLunch, adaptedLunchEatMe.getDeclaringType());
    // is not member of the same class (WeddingLunch)
    for (CtTypeMember typeMember : ctClassWeddingLunch.getTypeMembers()) {
        assertFalse(adaptedLunchEatMe == typeMember);
    }
    // the name is the same
    assertEquals("eatMe", adaptedLunchEatMe.getSimpleName());
    // it has the same number of of formal type parameters
    assertEquals(1, adaptedLunchEatMe.getFormalCtTypeParameters().size());
    assertEquals("C", adaptedLunchEatMe.getFormalCtTypeParameters().get(0).getQualifiedName());
    // parameters are correct
    assertEquals(3, adaptedLunchEatMe.getParameters().size());
    // "A paramA" becomes "X paramA" becomes Lunch%A corresponds to X in WeddingLunch
    assertEquals("X", adaptedLunchEatMe.getParameters().get(0).getType().getQualifiedName());
    // B paramB becomes Tacos becomes Lunch%B corresponds to Tacos in WeddingLunch (class WeddingLunch<X> extends CelebrationLunch<Tacos, Paella, X>)
    assertEquals(Tacos.class.getName(), adaptedLunchEatMe.getParameters().get(1).getType().getQualifiedName());
    // "C paramC" stays "C paramC"
    assertEquals("C", adaptedLunchEatMe.getParameters().get(2).getType().getQualifiedName());
    // contract: adapting of adapted method returns input method
    methodSTH.setMethod(adaptedLunchEatMe);
    assertSame(adaptedLunchEatMe, methodSTH.getAdaptationScope());
}
Also used : ClassTypingContext(spoon.support.visitor.ClassTypingContext) CtTypeMember(spoon.reflect.declaration.CtTypeMember) MethodTypingContext(spoon.support.visitor.MethodTypingContext) Tacos(spoon.test.generics.testclasses.Tacos) NamedElementFilter(spoon.reflect.visitor.filter.NamedElementFilter) ModelUtils.createFactory(spoon.testing.utils.ModelUtils.createFactory) Factory(spoon.reflect.factory.Factory) File(java.io.File) CtMethod(spoon.reflect.declaration.CtMethod) MainTest(spoon.test.main.MainTest) Test(org.junit.Test)

Example 3 with CtTypeMember

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

the class TemplateTest method testTemplateInheritance.

@Test
public void testTemplateInheritance() throws Exception {
    Launcher spoon = new Launcher();
    Factory factory = spoon.getFactory();
    spoon.getEnvironment().setCommentEnabled(true);
    spoon.createCompiler(factory, SpoonResourceHelper.resources("./src/test/java/spoon/test/template/testclasses/inheritance/SubClass.java", "./src/test/java/spoon/test/template/testclasses/inheritance/SuperClass.java"), SpoonResourceHelper.resources("./src/test/java/spoon/test/template/testclasses/inheritance/SubTemplate.java", "./src/test/java/spoon/test/template/testclasses/inheritance/SuperTemplate.java")).build();
    // Collects type members which should contain generated by comment
    final Map<CtElement, String> elementToGeneratedByMember = new IdentityHashMap<>();
    CtClass<?> superc = factory.Class().get(SuperClass.class);
    new SuperTemplate().addGeneratedBy(true).apply(superc);
    CtMethod<?> addedMethod = superc.getElements(new NamedElementFilter<>(CtMethod.class, "toBeOverriden")).get(0);
    assertEquals("toBeOverriden", addedMethod.getSimpleName());
    elementToGeneratedByMember.put(addedMethod, "#toBeOverriden");
    CtClass<?> subc = factory.Class().get(SubClass.class);
    SubTemplate template = new SubTemplate();
    template.addGeneratedBy(true);
    template.params = new ArrayList<>();
    CtParameter<Integer> parameter = factory.Core().createParameter();
    parameter.setSimpleName("x");
    parameter.setType(factory.Type().createReference(int.class));
    template.params.add(parameter);
    // templating the invocation
    template.invocation = factory.Code().createInvocation(null, addedMethod.getReference());
    // templating the foreach
    template.intValues = new CtExpression[2];
    template.intValues[0] = factory.Code().createLiteral(0);
    template.intValues[1] = factory.Code().createLiteral(1);
    // we apply the extension template to subc
    template.apply(subc);
    CtMethod<?> addedMethod2 = subc.getElements(new NamedElementFilter<>(CtMethod.class, "toBeOverriden")).get(0);
    assertEquals("toBeOverriden", addedMethod2.getSimpleName());
    assertEquals("super.toBeOverriden()", addedMethod2.getBody().getStatements().get(0).toString());
    elementToGeneratedByMember.put(addedMethod2, "#toBeOverriden");
    // contract; method parameter templates are handled
    CtMethod<?> methodWithTemplatedParameters = subc.getElements(new NamedElementFilter<>(CtMethod.class, "methodWithTemplatedParameters")).get(0);
    assertEquals("methodWithTemplatedParameters", methodWithTemplatedParameters.getSimpleName());
    assertEquals("x", methodWithTemplatedParameters.getParameters().get(0).getSimpleName());
    assertEquals("int x", methodWithTemplatedParameters.getParameters().get(0).toString());
    elementToGeneratedByMember.put(methodWithTemplatedParameters, "#methodWithTemplatedParameters");
    // contract: nested types of the templates are copied
    assertEquals(1, subc.getNestedTypes().size());
    elementToGeneratedByMember.put(subc.getNestedTypes().iterator().next(), "$InnerClass");
    // contract: methods are renamed
    assertEquals(1, subc.getMethodsByName("newVarName").size());
    CtMethod<?> varMethod = subc.getMethodsByName("newVarName").get(0);
    elementToGeneratedByMember.put(varMethod, "#var");
    // contract: parameters are replaced in comments too. The Class parameter value is converted to String
    assertEquals("newVarName", varMethod.getComments().get(0).getContent().split("[\\n\\r]+")[0]);
    assertEquals("{@link LinkedList}", varMethod.getComments().get(1).getContent());
    assertEquals("{@link SuperClass#toBeOverriden()}", varMethod.getComments().get(2).getContent());
    // contract: variable are renamed
    assertEquals("java.util.List newVarName = null", methodWithTemplatedParameters.getBody().getStatement(0).toString());
    // contract: types are replaced by other types
    assertEquals("java.util.LinkedList l = null", methodWithTemplatedParameters.getBody().getStatement(1).toString());
    // contract: casts are replaced by substitution types
    assertEquals("java.util.List o = ((java.util.LinkedList) (new java.util.LinkedList()))", methodWithTemplatedParameters.getBody().getStatement(2).toString());
    // contract: invocations are replaced by actual invocations
    assertEquals("toBeOverriden()", methodWithTemplatedParameters.getBody().getStatement(3).toString());
    // contract: foreach in block is inlined into that wrapping block
    CtBlock templatedForEach = methodWithTemplatedParameters.getBody().getStatement(4);
    assertEquals("java.lang.System.out.println(0)", templatedForEach.getStatement(0).toString());
    assertEquals("java.lang.System.out.println(1)", templatedForEach.getStatement(1).toString());
    // contract: foreach with single body block are inlined without extra block
    assertEquals("java.lang.System.out.println(0)", methodWithTemplatedParameters.getBody().getStatement(5).toString());
    assertEquals("java.lang.System.out.println(1)", methodWithTemplatedParameters.getBody().getStatement(6).toString());
    // contract: foreach with double body block are inlined with one extra block for each inlined statement
    assertEquals("java.lang.System.out.println(0)", ((CtBlock) methodWithTemplatedParameters.getBody().getStatement(7)).getStatement(0).toString());
    assertEquals("java.lang.System.out.println(1)", ((CtBlock) methodWithTemplatedParameters.getBody().getStatement(8)).getStatement(0).toString());
    // contract: foreach with statement are inlined without extra (implicit) block
    assertFalse(methodWithTemplatedParameters.getBody().getStatement(9) instanceof CtBlock);
    assertEquals("java.lang.System.out.println(0)", methodWithTemplatedParameters.getBody().getStatement(9).toString());
    assertFalse(methodWithTemplatedParameters.getBody().getStatement(10) instanceof CtBlock);
    assertEquals("java.lang.System.out.println(1)", methodWithTemplatedParameters.getBody().getStatement(10).toString());
    // contract: for each whose expression is not a template parameter is not inlined
    assertTrue(methodWithTemplatedParameters.getBody().getStatement(11) instanceof CtForEach);
    // contract: local variable write are replaced by local variable write with modified local variable name
    assertEquals("newVarName = o", methodWithTemplatedParameters.getBody().getStatement(12).toString());
    // contract: local variable read are replaced by local variable read with modified local variable name
    assertEquals("l = ((java.util.LinkedList) (newVarName))", methodWithTemplatedParameters.getBody().getStatement(13).toString());
    // contract; field access is handled same like local variable access
    CtMethod<?> methodWithFieldAccess = subc.getElements(new NamedElementFilter<>(CtMethod.class, "methodWithFieldAccess")).get(0);
    elementToGeneratedByMember.put(methodWithFieldAccess, "#methodWithFieldAccess");
    elementToGeneratedByMember.put(subc.getField("newVarName"), "#var");
    // contract: field write are replaced by field write with modified field name
    assertEquals("newVarName = o", methodWithFieldAccess.getBody().getStatement(2).toString());
    // contract: field read are replaced by field read with modified field name
    assertEquals("l = ((java.util.LinkedList) (newVarName))", methodWithFieldAccess.getBody().getStatement(3).toString());
    class Context {

        int nrTypeMembers = 0;

        int nrOthers = 0;
    }
    final Context ctx = new Context();
    // contract: each CtTypeMember has `Generated by ` with appropriate template class name, member name and line number
    superc.filterChildren(null).forEach((CtElement e) -> {
        if (e instanceof CtTypeMember) {
            ctx.nrTypeMembers++;
            assertCommentHasGeneratedBy(e, SuperTemplate.class.getName(), elementToGeneratedByMember);
        } else {
            ctx.nrOthers++;
            assertTrue(e.getDocComment() == null || e.getDocComment().indexOf("Generated by") == -1);
        }
    });
    assertTrue(ctx.nrTypeMembers > 0);
    assertTrue(ctx.nrOthers > 0);
    ctx.nrTypeMembers = 0;
    ctx.nrOthers = 0;
    subc.filterChildren(null).forEach((CtElement e) -> {
        if (e instanceof CtTypeMember) {
            ctx.nrTypeMembers++;
            assertCommentHasGeneratedBy(e, SubTemplate.class.getName(), elementToGeneratedByMember);
        } else {
            ctx.nrOthers++;
            assertTrue(e.getDocComment() == null || e.getDocComment().indexOf("Generated by") == -1);
        }
    });
    assertTrue(ctx.nrTypeMembers > 0);
    assertTrue(ctx.nrOthers > 0);
}
Also used : SubTemplate(spoon.test.template.testclasses.inheritance.SubTemplate) CtElement(spoon.reflect.declaration.CtElement) IdentityHashMap(java.util.IdentityHashMap) Factory(spoon.reflect.factory.Factory) CtForEach(spoon.reflect.code.CtForEach) CtBlock(spoon.reflect.code.CtBlock) CtTypeMember(spoon.reflect.declaration.CtTypeMember) SuperTemplate(spoon.test.template.testclasses.inheritance.SuperTemplate) NamedElementFilter(spoon.reflect.visitor.filter.NamedElementFilter) Launcher(spoon.Launcher) Test(org.junit.Test)

Example 4 with CtTypeMember

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

the class ImportScannerImpl method visitCtClass.

@Override
public <T> void visitCtClass(CtClass<T> ctClass) {
    addClassImport(ctClass.getReference());
    for (CtTypeMember t : ctClass.getTypeMembers()) {
        if (!(t instanceof CtType)) {
            continue;
        }
        addClassImport(((CtType) t).getReference());
    }
    super.visitCtClass(ctClass);
}
Also used : CtTypeMember(spoon.reflect.declaration.CtTypeMember) CtType(spoon.reflect.declaration.CtType)

Example 5 with CtTypeMember

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

the class AllTypeMembersFunction method apply.

@Override
public void apply(CtTypeInformation input, final CtConsumer<Object> outputConsumer) {
    final CtQuery q = ((CtQueryable) input).map(new SuperInheritanceHierarchyFunction(distinctSet == null ? new HashSet<String>() : distinctSet).includingSelf(true));
    q.forEach(new CtConsumer<CtType<?>>() {

        @Override
        public void accept(CtType<?> type) {
            for (CtTypeMember typeMember : type.getTypeMembers()) {
                if (memberClass == null || memberClass.isInstance(typeMember)) {
                    outputConsumer.accept(typeMember);
                }
                if (query.isTerminated()) {
                    q.terminate();
                }
            }
        }
    });
}
Also used : CtType(spoon.reflect.declaration.CtType) CtTypeMember(spoon.reflect.declaration.CtTypeMember) CtQueryable(spoon.reflect.visitor.chain.CtQueryable) CtQuery(spoon.reflect.visitor.chain.CtQuery) HashSet(java.util.HashSet)

Aggregations

CtTypeMember (spoon.reflect.declaration.CtTypeMember)22 CtType (spoon.reflect.declaration.CtType)9 CtField (spoon.reflect.declaration.CtField)6 CtConstructor (spoon.reflect.declaration.CtConstructor)5 CtMethod (spoon.reflect.declaration.CtMethod)5 Factory (spoon.reflect.factory.Factory)5 ArrayList (java.util.ArrayList)4 Test (org.junit.Test)4 Launcher (spoon.Launcher)3 CtBlock (spoon.reflect.code.CtBlock)3 CtElement (spoon.reflect.declaration.CtElement)3 NamedElementFilter (spoon.reflect.visitor.filter.NamedElementFilter)3 ClassTypingContext (spoon.support.visitor.ClassTypingContext)3 File (java.io.File)2 Annotation (java.lang.annotation.Annotation)2 Comparator (java.util.Comparator)2 HashSet (java.util.HashSet)2 List (java.util.List)2 CtAnnotation (spoon.reflect.declaration.CtAnnotation)2 CtAnnotationType (spoon.reflect.declaration.CtAnnotationType)2