Search in sources :

Example 1 with CtForEach

use of spoon.reflect.code.CtForEach in project spoon by INRIA.

the class DefaultCoreFactory method createForEach.

public CtForEach createForEach() {
    CtForEach e = new CtForEachImpl();
    e.setFactory(getMainFactory());
    return e;
}
Also used : CtForEachImpl(spoon.support.reflect.code.CtForEachImpl) CtForEach(spoon.reflect.code.CtForEach)

Example 2 with CtForEach

use of spoon.reflect.code.CtForEach 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 3 with CtForEach

use of spoon.reflect.code.CtForEach in project spoon by INRIA.

the class AccessibleVariablesFinder method getVariable.

private List<CtVariable> getVariable(final CtElement parent) {
    final List<CtVariable> variables = new ArrayList<>();
    if (parent == null) {
        return variables;
    }
    class VariableScanner extends CtInheritanceScanner {

        @Override
        public void visitCtStatementList(CtStatementList e) {
            for (int i = 0; i < e.getStatements().size(); i++) {
                CtStatement ctStatement = e.getStatements().get(i);
                if (ctStatement.getPosition() == null) {
                }
                if (ctStatement.getPosition() != null && ctStatement.getPosition().getSourceStart() > expression.getPosition().getSourceEnd()) {
                    break;
                }
                if (ctStatement instanceof CtVariable) {
                    variables.add((CtVariable) ctStatement);
                }
            }
            super.visitCtStatementList(e);
        }

        @Override
        public <T> void scanCtType(CtType<T> type) {
            List<CtField<?>> fields = type.getFields();
            for (int i = 0; i < fields.size(); i++) {
                CtField<?> ctField = fields.get(i);
                if (ctField.hasModifier(ModifierKind.PUBLIC) || ctField.hasModifier(ModifierKind.PROTECTED)) {
                    variables.add(ctField);
                } else if (ctField.hasModifier(ModifierKind.PRIVATE)) {
                    if (expression.hasParent(type)) {
                        variables.add(ctField);
                    }
                } else if (expression.getParent(CtPackage.class).equals(type.getParent(CtPackage.class))) {
                    // default visibility
                    variables.add(ctField);
                }
            }
            CtTypeReference<?> superclass = type.getSuperclass();
            if (superclass != null) {
                variables.addAll(getVariable(superclass.getTypeDeclaration()));
            }
            Set<CtTypeReference<?>> superInterfaces = type.getSuperInterfaces();
            for (Iterator<CtTypeReference<?>> iterator = superInterfaces.iterator(); iterator.hasNext(); ) {
                CtTypeReference<?> typeReference = iterator.next();
                variables.addAll(getVariable(typeReference.getTypeDeclaration()));
            }
            super.scanCtType(type);
        }

        @Override
        public void visitCtTryWithResource(CtTryWithResource e) {
            variables.addAll(e.getResources());
            super.visitCtTryWithResource(e);
        }

        @Override
        public void scanCtExecutable(CtExecutable e) {
            variables.addAll(e.getParameters());
            super.scanCtExecutable(e);
        }

        @Override
        public void visitCtFor(CtFor e) {
            for (CtStatement ctStatement : e.getForInit()) {
                this.scan(ctStatement);
            }
            super.visitCtFor(e);
        }

        @Override
        public void visitCtForEach(CtForEach e) {
            variables.add(e.getVariable());
            super.visitCtForEach(e);
        }

        @Override
        public void visitCtMethod(CtMethod e) {
            this.scan(e.getBody());
            super.visitCtMethod(e);
        }

        @Override
        public void visitCtLocalVariable(CtLocalVariable e) {
            variables.add(e);
            super.visitCtLocalVariable(e);
        }

        @Override
        public void visitCtCatch(CtCatch e) {
            variables.add(e.getParameter());
            super.visitCtCatch(e);
        }
    }
    new VariableScanner().scan(parent);
    return variables;
}
Also used : ArrayList(java.util.ArrayList) CtLocalVariable(spoon.reflect.code.CtLocalVariable) CtExecutable(spoon.reflect.declaration.CtExecutable) CtForEach(spoon.reflect.code.CtForEach) CtType(spoon.reflect.declaration.CtType) CtStatement(spoon.reflect.code.CtStatement) CtField(spoon.reflect.declaration.CtField) CtTypeReference(spoon.reflect.reference.CtTypeReference) CtVariable(spoon.reflect.declaration.CtVariable) CtStatementList(spoon.reflect.code.CtStatementList) CtPackage(spoon.reflect.declaration.CtPackage) CtTryWithResource(spoon.reflect.code.CtTryWithResource) CtCatch(spoon.reflect.code.CtCatch) CtFor(spoon.reflect.code.CtFor) CtMethod(spoon.reflect.declaration.CtMethod)

Example 4 with CtForEach

use of spoon.reflect.code.CtForEach in project spoon by INRIA.

the class LoopTest method testAnnotationInForLoop.

@Test
public void testAnnotationInForLoop() throws Exception {
    CtType<?> aFoo = ModelUtils.build(new File("./src/test/resources/spoon/test/loop/testclasses/")).Type().get("spoon.test.loop.testclasses.Foo");
    CtFor aFor = aFoo.getMethod("m").getElements(new TypeFilter<>(CtFor.class)).get(0);
    assertEquals(1, ((CtLocalVariable) aFor.getForInit().get(0)).getType().getAnnotations().size());
    assertEquals(1, ((CtLocalVariable) aFor.getForInit().get(1)).getType().getAnnotations().size());
    CtForEach aForEach = aFoo.getMethod("m").getElements(new TypeFilter<>(CtForEach.class)).get(0);
    assertEquals(1, aForEach.getVariable().getType().getAnnotations().size());
}
Also used : TypeFilter(spoon.reflect.visitor.filter.TypeFilter) File(java.io.File) CtFor(spoon.reflect.code.CtFor) CtForEach(spoon.reflect.code.CtForEach) Test(org.junit.Test)

Aggregations

CtForEach (spoon.reflect.code.CtForEach)4 Test (org.junit.Test)2 CtFor (spoon.reflect.code.CtFor)2 File (java.io.File)1 ArrayList (java.util.ArrayList)1 IdentityHashMap (java.util.IdentityHashMap)1 Launcher (spoon.Launcher)1 CtBlock (spoon.reflect.code.CtBlock)1 CtCatch (spoon.reflect.code.CtCatch)1 CtLocalVariable (spoon.reflect.code.CtLocalVariable)1 CtStatement (spoon.reflect.code.CtStatement)1 CtStatementList (spoon.reflect.code.CtStatementList)1 CtTryWithResource (spoon.reflect.code.CtTryWithResource)1 CtElement (spoon.reflect.declaration.CtElement)1 CtExecutable (spoon.reflect.declaration.CtExecutable)1 CtField (spoon.reflect.declaration.CtField)1 CtMethod (spoon.reflect.declaration.CtMethod)1 CtPackage (spoon.reflect.declaration.CtPackage)1 CtType (spoon.reflect.declaration.CtType)1 CtTypeMember (spoon.reflect.declaration.CtTypeMember)1