Search in sources :

Example 61 with CtMethod

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

the class IntercessionTest method testSettersAreAllGood.

@Test
public void testSettersAreAllGood() throws Exception {
    ArrayList classpath = new ArrayList();
    for (String classpathEntry : System.getProperty("java.class.path").split(File.pathSeparator)) {
        if (!classpathEntry.contains("test-classes")) {
            classpath.add(classpathEntry);
        }
    }
    final Launcher launcher = new Launcher();
    launcher.addInputResource("./src/main/java/spoon/reflect/");
    launcher.addInputResource("./src/main/java/spoon/support/");
    launcher.getModelBuilder().setSourceClasspath((String[]) classpath.toArray(new String[] {}));
    launcher.buildModel();
    final Factory factory = launcher.getFactory();
    final List<CtMethod<?>> setters = Query.getElements(factory, new AbstractFilter<CtMethod<?>>(CtMethod.class) {

        @Override
        public boolean matches(CtMethod<?> element) {
            CtType<?> declaringType = element.getDeclaringType();
            if (declaringType.getPackage() != null && (declaringType.getPackage().getQualifiedName().startsWith("spoon.support.visitor") || declaringType.getPackage().getQualifiedName().startsWith("spoon.reflect.visitor"))) {
                return false;
            }
            return declaringType.isInterface() && declaringType.getSimpleName().startsWith("Ct") && (element.getSimpleName().startsWith("set") || element.getSimpleName().startsWith("add"));
        }
    });
    for (CtMethod<?> setter : setters) {
        final String methodLog = setter.getSimpleName() + " in " + setter.getDeclaringType().getSimpleName();
        if (setter.getFormalCtTypeParameters().size() <= 0) {
            fail("Your setter " + methodLog + " don't have a generic type for its return type.");
        }
        boolean isMatch = false;
        // New type parameter declaration.
        for (CtTypeParameter typeParameter : setter.getFormalCtTypeParameters()) {
            if (setter.getType().getSimpleName().equals(typeParameter.getSimpleName())) {
                isMatch = true;
                if (setter.getAnnotation(Override.class) != null) {
                    // interface. So the return type can't be the declaring interface.
                    continue;
                }
                if (!setter.getDeclaringType().getSimpleName().equals(typeParameter.getSuperclass().getSimpleName())) {
                    fail("Your setter " + methodLog + " has a type reference who don't extends " + setter.getDeclaringType().getSimpleName());
                }
            }
        }
        assertTrue("The type of " + methodLog + " don't match with generic types.", isMatch);
    }
}
Also used : CtType(spoon.reflect.declaration.CtType) CtTypeParameter(spoon.reflect.declaration.CtTypeParameter) ArrayList(java.util.ArrayList) Launcher(spoon.Launcher) ModelUtils.createFactory(spoon.testing.utils.ModelUtils.createFactory) Factory(spoon.reflect.factory.Factory) CtMethod(spoon.reflect.declaration.CtMethod) Test(org.junit.Test)

Example 62 with CtMethod

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

the class IntercessionTest method testResetCollectionInSetters.

@Test
// interesting but too fragile with conventions
@Ignore
public void testResetCollectionInSetters() throws Exception {
    final Launcher launcher = new Launcher();
    launcher.setArgs(new String[] { "--output-type", "nooutput" });
    final Factory factory = launcher.getFactory();
    launcher.getEnvironment().setNoClasspath(true);
    // interfaces.
    launcher.addInputResource("./src/main/java/spoon/reflect/code");
    launcher.addInputResource("./src/main/java/spoon/reflect/declaration");
    launcher.addInputResource("./src/main/java/spoon/reflect/reference");
    // implementations.
    launcher.addInputResource("./src/main/java/spoon/support/reflect/code");
    launcher.addInputResource("./src/main/java/spoon/support/reflect/declaration");
    launcher.addInputResource("./src/main/java/spoon/support/reflect/reference");
    launcher.buildModel();
    new IntercessionScanner(factory) {

        @Override
        protected boolean isToBeProcessed(CtMethod<?> candidate) {
            return // 
            candidate.getSimpleName().startsWith("set") && // 
            candidate.hasModifier(ModifierKind.PUBLIC) && // 
            takeSetterCollection(candidate) && // 
            avoidInterfaces(candidate) && // && avoidSpecificMethods(candidate) //
            avoidThrowUnsupportedOperationException(candidate);
        }

        private boolean takeSetterCollection(CtMethod<?> candidate) {
            final CtTypeReference<?> type = candidate.getParameters().get(0).getType();
            final List<CtTypeReference<?>> actualTypeArguments = type.getActualTypeArguments();
            return COLLECTIONS.contains(type) && actualTypeArguments.size() == 1 && actualTypeArguments.get(0).isSubtypeOf(CTELEMENT_REFERENCE);
        }

        @Override
        protected void process(CtMethod<?> element) {
            if (element.getAnnotation(UnsettableProperty.class) != null) {
                // we don't check the contracts for unsettable setters
                return;
            }
            final CtStatement statement = element.getBody().getStatement(0);
            if (!(statement instanceof CtIf)) {
                fail(log(element, "First statement should be an if to check the parameter of the setter"));
            }
            final CtIf anIf = (CtIf) statement;
            if (!createCheckNull(element.getParameters().get(0)).equals(anIf.getCondition())) {
                fail(log(element, "Condition should test if the parameter is null.\nThe condition was " + anIf.getCondition()));
            }
            if (!(anIf.getThenStatement() instanceof CtBlock)) {
                fail(log(element, "Should have a block in the if condition to have the initialization and the return."));
            }
            if (element.getParameters().get(0).getType().equals(SET_REFERENCE)) {
                if (!hasCallEmptyInv(anIf.getThenStatement(), SET_REFERENCE)) {
                    fail(log(element, "Should initilize the list with CtElementImpl#emptySet()."));
                }
            } else {
                if (!hasCallEmptyInv(anIf.getThenStatement(), LIST_REFERENCE)) {
                    fail(log(element, "Should initilize the list with CtElementImpl#emptyList()."));
                }
            }
        }

        private boolean hasCallEmptyInv(CtBlock thenStatement, CtTypeReference<? extends Collection> collectionReference) {
            if (!(thenStatement.getStatement(0) instanceof CtAssignment)) {
                return false;
            }
            final CtExpression assignment = ((CtAssignment) thenStatement.getStatement(0)).getAssignment();
            if (!(assignment instanceof CtInvocation)) {
                return false;
            }
            final CtInvocation inv = (CtInvocation) assignment;
            if (collectionReference.equals(SET_REFERENCE)) {
                if (!inv.getExecutable().getSimpleName().equals("emptySet")) {
                    return false;
                }
            } else if (collectionReference.equals(LIST_REFERENCE)) {
                if (!inv.getExecutable().getSimpleName().equals("emptyList")) {
                    return false;
                }
            }
            return true;
        }

        /**
         * Creates <code>list == null && list.isEmpty()</code>.
         *
         * @param ctParameter <code>list</code>
         */
        private CtBinaryOperator<Boolean> createCheckNull(CtParameter<?> ctParameter) {
            final CtVariableAccess<?> variableRead = factory.Code().createVariableRead(ctParameter.getReference(), true);
            final CtLiteral nullLiteral = factory.Code().createLiteral(null);
            nullLiteral.setType(factory.Type().nullType());
            final CtBinaryOperator<Boolean> checkNull = factory.Code().createBinaryOperator(variableRead, nullLiteral, BinaryOperatorKind.EQ);
            checkNull.setType(factory.Type().BOOLEAN_PRIMITIVE);
            final CtMethod<Boolean> isEmptyMethod = ctParameter.getType().getTypeDeclaration().getMethod(factory.Type().booleanPrimitiveType(), "isEmpty");
            final CtInvocation<Boolean> isEmpty = factory.Code().createInvocation(variableRead, isEmptyMethod.getReference());
            final CtBinaryOperator<Boolean> condition = factory.Code().createBinaryOperator(checkNull, isEmpty, BinaryOperatorKind.OR);
            return condition.setType(factory.Type().booleanPrimitiveType());
        }

        private String log(CtMethod<?> element, String message) {
            return message + "\nin " + element.getSignature() + "\ndeclared in " + element.getDeclaringType().getQualifiedName();
        }
    }.scan(factory.getModel().getUnnamedModule());
}
Also used : CtVariableAccess(spoon.reflect.code.CtVariableAccess) CtAssignment(spoon.reflect.code.CtAssignment) CtExpression(spoon.reflect.code.CtExpression) CtBinaryOperator(spoon.reflect.code.CtBinaryOperator) ModelUtils.createFactory(spoon.testing.utils.ModelUtils.createFactory) Factory(spoon.reflect.factory.Factory) CtIf(spoon.reflect.code.CtIf) CtInvocation(spoon.reflect.code.CtInvocation) CtBlock(spoon.reflect.code.CtBlock) CtLiteral(spoon.reflect.code.CtLiteral) CtStatement(spoon.reflect.code.CtStatement) CtTypeReference(spoon.reflect.reference.CtTypeReference) Launcher(spoon.Launcher) ArrayList(java.util.ArrayList) List(java.util.List) CtMethod(spoon.reflect.declaration.CtMethod) Ignore(org.junit.Ignore) Test(org.junit.Test)

Example 63 with CtMethod

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

the class IntercessionTest method testInsertIfIntercession.

@Test
public void testInsertIfIntercession() {
    String ifCode = "if (1 == 0)\n" + "    return 1;\n" + "else\n" + "    return 0;\n" + "";
    CtClass<?> clazz = factory.Code().createCodeSnippetStatement("" + "class X {" + "public int bar() {" + ifCode + "}" + "};").compile();
    CtMethod<?> foo = (CtMethod<?>) clazz.getMethods().toArray()[0];
    CtBlock<?> body = foo.getBody();
    assertEquals(1, body.getStatements().size());
    CtIf ifStmt = (CtIf) foo.getBody().getStatements().get(0);
    String s = ifStmt.toString().replace("\r", "");
    assertEquals(ifCode, s);
    CtBlock<?> r1 = ifStmt.getThenStatement();
    CtBlock<?> r2 = ifStmt.getElseStatement();
    assertTrue(r1.isImplicit());
    assertTrue(r2.isImplicit());
    ifStmt.setThenStatement(r2);
    assertSame(r2, ifStmt.getThenStatement());
    ifStmt.setElseStatement(r1);
    assertSame(r1, ifStmt.getElseStatement());
    s = ifStmt.toString().replace("\r", "");
    String ifCodeNew = "if (1 == 0)\n" + "    return 0;\n" + "else\n" + "    return 1;\n" + "";
    assertEquals(ifCodeNew, s);
}
Also used : CtMethod(spoon.reflect.declaration.CtMethod) CtIf(spoon.reflect.code.CtIf) Test(org.junit.Test)

Example 64 with CtMethod

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

the class RemoveTest method testRemoveAllStatements.

@Test
public void testRemoveAllStatements() {
    Factory factory = createFactory();
    CtClass<?> clazz = factory.Code().createCodeSnippetStatement("" + "class X {" + "public void foo() {" + " int x=0;int y=0;" + "}};").compile();
    CtMethod<?> foo = (CtMethod<?>) clazz.getMethods().toArray()[0];
    CtBlock<?> body = foo.getBody();
    assertEquals(2, body.getStatements().size());
    for (CtStatement s : body) {
        body.removeStatement(s);
    }
    assertEquals(0, body.getStatements().size());
}
Also used : CtStatement(spoon.reflect.code.CtStatement) Factory(spoon.reflect.factory.Factory) ModelUtils.createFactory(spoon.testing.utils.ModelUtils.createFactory) CtMethod(spoon.reflect.declaration.CtMethod) Test(org.junit.Test)

Example 65 with CtMethod

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

the class SpoonMetaModel method addFieldsOfType.

/**
 * adds all {@link MetamodelProperty}s of `ctType`
 * @param mmConcept the owner of to be created fields
 * @param ctType to be scanned {@link CtType}
 */
private void addFieldsOfType(MetamodelConcept mmConcept, CtType<?> ctType) {
    ctType.getTypeMembers().forEach(typeMember -> {
        if (typeMember instanceof CtMethod<?>) {
            CtMethod<?> method = (CtMethod<?>) typeMember;
            CtRole role = getRoleOfMethod(method);
            if (role != null) {
                MetamodelProperty field = mmConcept.getOrCreateMMField(role);
                field.addMethod(method);
            } else {
                mmConcept.otherMethods.add(method);
            }
        }
    });
    addFieldsOfSuperType(mmConcept, ctType.getSuperclass());
    ctType.getSuperInterfaces().forEach(superIfaceRef -> addFieldsOfSuperType(mmConcept, superIfaceRef));
}
Also used : CtRole(spoon.reflect.path.CtRole) CtMethod(spoon.reflect.declaration.CtMethod)

Aggregations

CtMethod (spoon.reflect.declaration.CtMethod)240 Test (org.junit.Test)163 Factory (spoon.reflect.factory.Factory)77 Launcher (spoon.Launcher)73 CtClass (spoon.reflect.declaration.CtClass)47 TypeFilter (spoon.reflect.visitor.filter.TypeFilter)47 CtType (spoon.reflect.declaration.CtType)45 AbstractTest (fr.inria.AbstractTest)36 ArrayList (java.util.ArrayList)35 List (java.util.List)33 CtTypeReference (spoon.reflect.reference.CtTypeReference)31 CtInvocation (spoon.reflect.code.CtInvocation)26 CtStatement (spoon.reflect.code.CtStatement)26 AmplificationHelper (fr.inria.diversify.utils.AmplificationHelper)19 Collectors (java.util.stream.Collectors)19 CtLiteral (spoon.reflect.code.CtLiteral)18 CtElement (spoon.reflect.declaration.CtElement)18 CtIf (spoon.reflect.code.CtIf)16 CtAnnotation (spoon.reflect.declaration.CtAnnotation)16 CtField (spoon.reflect.declaration.CtField)16