Search in sources :

Example 1 with CtBinaryOperator

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

the class SnippetTest method testCompileSnippetSeveralTimes.

@Test
public void testCompileSnippetSeveralTimes() throws Exception {
    // contract: a snippet object can be reused several times
    final Factory factory = createFactory();
    final CtCodeSnippetExpression<Object> snippet = factory.Code().createCodeSnippetExpression("1 > 2");
    // Compile a first time the snippet.
    final CtExpression<Object> compile = snippet.compile();
    // Compile a second time the same snippet.
    final CtExpression<Object> secondCompile = snippet.compile();
    assertTrue(compile instanceof CtBinaryOperator);
    assertEquals("1 > 2", compile.toString());
    assertTrue(secondCompile instanceof CtBinaryOperator);
    assertEquals("1 > 2", secondCompile.toString());
    // Compile a third time a snippet but with an expression set.
    snippet.setValue("1 > 3");
    final CtExpression<Object> thirdCompile = snippet.compile();
    assertTrue(thirdCompile instanceof CtBinaryOperator);
    assertEquals("1 > 3", thirdCompile.toString());
}
Also used : CtBinaryOperator(spoon.reflect.code.CtBinaryOperator) Factory(spoon.reflect.factory.Factory) ModelUtils.createFactory(spoon.testing.utils.ModelUtils.createFactory) Test(org.junit.Test)

Example 2 with CtBinaryOperator

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

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

the class ParentTest method testParentSetInSetter.

@Test
// too fragile because of conventions
@Ignore
public void testParentSetInSetter() throws Exception {
    // contract: Check that all setters protect their parameter.
    final Launcher launcher = new Launcher();
    final Factory factory = launcher.getFactory();
    launcher.setArgs(new String[] { "--output-type", "nooutput" });
    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");
    // Utils.
    launcher.addInputResource("./src/test/java/spoon/reflect/ast/");
    launcher.buildModel();
    // Asserts.
    new IntercessionScanner(launcher.getFactory()) {

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

        @Override
        public void process(CtMethod<?> element) {
            if (element.getAnnotation(UnsettableProperty.class) != null) {
                // we don't check the contracts for unsettable setters
                return;
            }
            if (element.getSimpleName().startsWith("add")) {
                checkAddStrategy(element);
            } else {
                checkSetStrategy(element);
            }
        }

        private void checkAddStrategy(CtMethod<?> element) {
            final CtStatement statement = element.getBody().getStatement(0);
            if (!(statement instanceof CtIf)) {
                fail("First statement should be an if to check the parameter of the setter." + element.getSignature() + " declared in " + element.getDeclaringType().getQualifiedName());
            }
            if (!createCheckNull(element.getParameters().get(0)).equals(((CtIf) statement).getCondition())) {
                fail("Condition should test if the parameter is null. The condition was " + ((CtIf) statement).getCondition() + "in " + element.getSignature() + " declared in " + element.getDeclaringType().getQualifiedName());
            }
        }

        private void checkSetStrategy(CtMethod<?> element) {
            final CtTypeReference<?> type = element.getParameters().get(0).getType();
            if (!COLLECTIONS.contains(type) && !(type instanceof CtArrayTypeReference)) {
                CtInvocation<?> setParent = searchSetParent(element.getBody());
                if (setParent == null) {
                    return;
                }
                try {
                    if (setParent.getParent(CtIf.class) == null) {
                        fail("Missing condition in " + element.getSignature() + " declared in the class " + element.getDeclaringType().getQualifiedName());
                    }
                } catch (ParentNotInitializedException e) {
                    fail("Missing parent condition in " + element.getSignature() + " declared in the class " + element.getDeclaringType().getQualifiedName());
                }
            }
        }

        /**
         * Creates <code>parameter == null</code>.
         *
         * @param ctParameter <code>parameter</code>
         */
        private CtBinaryOperator<Boolean> createCheckNull(CtParameter<?> ctParameter) {
            final CtLiteral nullLiteral = factory.Code().createLiteral(null);
            nullLiteral.setType(factory.Type().NULL_TYPE.clone());
            final CtBinaryOperator<Boolean> operator = // 
            factory.Code().createBinaryOperator(// 
            factory.Code().createVariableRead(ctParameter.getReference(), true), nullLiteral, BinaryOperatorKind.EQ);
            operator.setType(factory.Type().BOOLEAN_PRIMITIVE);
            return operator;
        }

        private CtInvocation<?> searchSetParent(CtBlock<?> body) {
            final List<CtInvocation<?>> ctInvocations = body.getElements(new TypeFilter<CtInvocation<?>>(CtInvocation.class) {

                @Override
                public boolean matches(CtInvocation<?> element) {
                    return "setParent".equals(element.getExecutable().getSimpleName()) && super.matches(element);
                }
            });
            return ctInvocations.size() > 0 ? ctInvocations.get(0) : null;
        }
    }.scan(launcher.getModel().getRootPackage());
}
Also used : ParentNotInitializedException(spoon.reflect.declaration.ParentNotInitializedException) CtBinaryOperator(spoon.reflect.code.CtBinaryOperator) Factory(spoon.reflect.factory.Factory) TypeFilter(spoon.reflect.visitor.filter.TypeFilter) ReferenceTypeFilter(spoon.reflect.visitor.filter.ReferenceTypeFilter) CtIf(spoon.reflect.code.CtIf) CtInvocation(spoon.reflect.code.CtInvocation) CtLiteral(spoon.reflect.code.CtLiteral) CtStatement(spoon.reflect.code.CtStatement) CtTypeReference(spoon.reflect.reference.CtTypeReference) Launcher(spoon.Launcher) CtStatementList(spoon.reflect.code.CtStatementList) List(java.util.List) CtArrayTypeReference(spoon.reflect.reference.CtArrayTypeReference) IntercessionScanner(spoon.test.intercession.IntercessionScanner) Ignore(org.junit.Ignore) Test(org.junit.Test)

Example 4 with CtBinaryOperator

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

the class TypeTest method testTypeAccessOfArrayObjectInFullyQualifiedName.

@Test
public void testTypeAccessOfArrayObjectInFullyQualifiedName() throws Exception {
    // contract: A type access in fully qualified name must to rewrite well.
    final String target = "./target/type";
    final Launcher launcher = new Launcher();
    launcher.addInputResource("./src/test/java/spoon/test/type/testclasses");
    launcher.setSourceOutputDirectory(target);
    launcher.getEnvironment().setNoClasspath(true);
    launcher.run();
    final CtClass<Pozole> aPozole = launcher.getFactory().Class().get(Pozole.class);
    final CtMethod<?> season = aPozole.getMethodsByName("season").get(0);
    final List<CtTypeAccess<?>> typeAccesses = season.getElements(new TypeFilter<CtTypeAccess<?>>(CtTypeAccess.class));
    assertEquals(2, typeAccesses.size());
    assertTrue(typeAccesses.get(0).getParent() instanceof CtBinaryOperator);
    assertEquals(BinaryOperatorKind.INSTANCEOF, ((CtBinaryOperator) typeAccesses.get(0).getParent()).getKind());
    assertEquals("a instanceof java.lang.@spoon.test.annotation.testclasses.TypeAnnotation(integer = 1)" + System.lineSeparator() + "Object[]", typeAccesses.get(0).getParent().toString());
    assertTrue(typeAccesses.get(1).getParent() instanceof CtBinaryOperator);
    assertEquals(BinaryOperatorKind.INSTANCEOF, ((CtBinaryOperator) typeAccesses.get(1).getParent()).getKind());
    assertEquals("a instanceof java.lang.Object[]", typeAccesses.get(1).getParent().toString());
    canBeBuilt(target, 8, true);
}
Also used : Pozole(spoon.test.type.testclasses.Pozole) CtBinaryOperator(spoon.reflect.code.CtBinaryOperator) Launcher(spoon.Launcher) CtTypeAccess(spoon.reflect.code.CtTypeAccess) Test(org.junit.Test)

Example 5 with CtBinaryOperator

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

the class VisibilityTest method testFullyQualifiedNameOfTypeReferenceWithGeneric.

@Test
public void testFullyQualifiedNameOfTypeReferenceWithGeneric() throws Exception {
    // contract: Generics are written when there are specified in the return type of a method.
    final String target = "./target/spooned/spoon/test/visibility_generics/testclasses/";
    final SpoonAPI launcher = new Launcher();
    launcher.addInputResource("./src/test/java/spoon/test/visibility/testclasses/A.java");
    launcher.addInputResource("./src/test/java/spoon/test/visibility/testclasses/A2.java");
    launcher.addInputResource("./src/test/java/spoon/test/visibility/testclasses/Foo.java");
    launcher.setSourceOutputDirectory(target);
    launcher.run();
    final CtClass<A> aClass = launcher.getFactory().Class().get(A.class);
    CtType<?> nestedB = aClass.getNestedType("B");
    List<CtFieldAccess> elements = nestedB.getElements(new TypeFilter<>(CtFieldAccess.class));
    assertEquals(1, elements.size());
    assertEquals("(spoon.test.visibility.testclasses.A.B.i)", elements.get(0).toString());
    CtMethod<?> instanceOf = aClass.getMethodsByName("instanceOf").get(0);
    List<CtBinaryOperator> elements1 = instanceOf.getElements(new TypeFilter<>(CtBinaryOperator.class));
    assertEquals(1, elements1.size());
    assertEquals("spoon.test.visibility.testclasses.A.B", elements1.get(0).getRightHandOperand().toString());
    CtMethod<?> returnType = aClass.getMethodsByName("returnType").get(0);
    assertEquals("spoon.test.visibility.testclasses.A<T>.C<T>", returnType.getType().toString());
    final CtClass<A2> secondClass = launcher.getFactory().Class().get(A2.class);
    nestedB = secondClass.getNestedType("B");
    elements = nestedB.getElements(new TypeFilter<>(CtFieldAccess.class));
    assertEquals(1, elements.size());
    assertEquals("(spoon.test.visibility.testclasses.A2.B.i)", elements.get(0).toString());
    instanceOf = secondClass.getMethodsByName("instanceOf").get(0);
    elements1 = instanceOf.getElements(new TypeFilter<>(CtBinaryOperator.class));
    assertEquals(1, elements1.size());
    assertEquals("spoon.test.visibility.testclasses.A2.B", elements1.get(0).getRightHandOperand().toString());
    returnType = secondClass.getMethodsByName("returnType").get(0);
    assertEquals("spoon.test.visibility.testclasses.A2.C<java.lang.String>", returnType.getType().toString());
    returnType = secondClass.getMethodsByName("returnType2").get(0);
    assertEquals("spoon.test.visibility.testclasses.Foo<java.lang.String>.Bar<java.lang.String>", returnType.getType().toString());
    canBeBuilt(target, 8);
}
Also used : A(spoon.test.visibility.testclasses.A) CtFieldAccess(spoon.reflect.code.CtFieldAccess) CtBinaryOperator(spoon.reflect.code.CtBinaryOperator) TypeFilter(spoon.reflect.visitor.filter.TypeFilter) A2(spoon.test.visibility.testclasses.A2) Launcher(spoon.Launcher) SpoonAPI(spoon.SpoonAPI) Test(org.junit.Test)

Aggregations

CtBinaryOperator (spoon.reflect.code.CtBinaryOperator)11 Test (org.junit.Test)9 Launcher (spoon.Launcher)6 Factory (spoon.reflect.factory.Factory)6 CtMethod (spoon.reflect.declaration.CtMethod)5 CtIf (spoon.reflect.code.CtIf)4 CtBlock (spoon.reflect.code.CtBlock)3 CtInvocation (spoon.reflect.code.CtInvocation)3 CtStatement (spoon.reflect.code.CtStatement)3 CtClass (spoon.reflect.declaration.CtClass)3 File (java.io.File)2 ArrayList (java.util.ArrayList)2 List (java.util.List)2 Ignore (org.junit.Ignore)2 CtConditional (spoon.reflect.code.CtConditional)2 CtLiteral (spoon.reflect.code.CtLiteral)2 CtNewArray (spoon.reflect.code.CtNewArray)2 CtReturn (spoon.reflect.code.CtReturn)2 CtStatementList (spoon.reflect.code.CtStatementList)2 CtSwitch (spoon.reflect.code.CtSwitch)2