Search in sources :

Example 1 with CtNewArray

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

the class SampleAnnotation method testAnnotate.

@Test
public void testAnnotate() throws Exception {
    CtClass<?> type = build("spoon.test.testclasses", "SampleClass");
    AnnotationFactory af = type.getFactory().Annotation();
    af.annotate(type, SampleAnnotation.class, "names", new String[] { "foo", "bar" });
    final CtAnnotation<SampleAnnotation> annotation = type.getAnnotation(type.getFactory().Annotation().createReference(SampleAnnotation.class));
    assertTrue(annotation.getValue("names") instanceof CtNewArray);
    final CtNewArray names = annotation.getValue("names");
    assertEquals(2, names.getElements().size());
    assertEquals("foo", ((CtLiteral) names.getElements().get(0)).getValue());
    assertEquals("bar", ((CtLiteral) names.getElements().get(1)).getValue());
}
Also used : AnnotationFactory(spoon.reflect.factory.AnnotationFactory) CtNewArray(spoon.reflect.code.CtNewArray) Test(org.junit.Test)

Example 2 with CtNewArray

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

the class CtAnnotationImpl method convertValueToExpression.

private CtExpression convertValueToExpression(Object value) {
    CtExpression res;
    if (value.getClass().isArray()) {
        // Value should be converted to a CtNewArray.
        res = getFactory().Core().createNewArray();
        Object[] values = (Object[]) value;
        res.setType(getFactory().Type().createArrayReference(getFactory().Type().createReference(value.getClass().getComponentType())));
        for (Object o : values) {
            ((CtNewArray) res).addElement(convertValueToExpression(o));
        }
    } else if (value instanceof Collection) {
        // Value should be converted to a CtNewArray.
        res = getFactory().Core().createNewArray();
        Collection values = (Collection) value;
        res.setType(getFactory().Type().createArrayReference(getFactory().Type().createReference(values.toArray()[0].getClass())));
        for (Object o : values) {
            ((CtNewArray) res).addElement(convertValueToExpression(o));
        }
    } else if (value instanceof Class) {
        // Value should be a field access to a .class.
        res = getFactory().Code().createClassAccess(getFactory().Type().createReference((Class) value));
    } else if (value instanceof Field) {
        // Value should be a field access to a field.
        CtFieldReference<Object> variable = getFactory().Field().createReference((Field) value);
        variable.setStatic(true);
        CtTypeAccess target = getFactory().Code().createTypeAccess(getFactory().Type().createReference(((Field) value).getDeclaringClass()));
        CtFieldRead fieldRead = getFactory().Core().createFieldRead();
        fieldRead.setVariable(variable);
        fieldRead.setTarget(target);
        fieldRead.setType(target.getAccessedType());
        res = fieldRead;
    } else if (isPrimitive(value.getClass()) || value instanceof String) {
        // Value should be a literal.
        res = getFactory().Code().createLiteral(value);
    } else if (value.getClass().isEnum()) {
        final CtTypeReference declaringClass = getFactory().Type().createReference(((Enum) value).getDeclaringClass());
        final CtFieldReference variableRef = getFactory().Field().createReference(declaringClass, declaringClass, ((Enum) value).name());
        CtTypeAccess target = getFactory().Code().createTypeAccess(declaringClass);
        CtFieldRead fieldRead = getFactory().Core().createFieldRead();
        fieldRead.setVariable(variableRef);
        fieldRead.setTarget(target);
        fieldRead.setType(declaringClass);
        res = fieldRead;
    } else {
        throw new SpoonException("Please, submit a valid value.");
    }
    return res;
}
Also used : CtFieldRead(spoon.reflect.code.CtFieldRead) CtExpression(spoon.reflect.code.CtExpression) SpoonException(spoon.SpoonException) CtFieldReference(spoon.reflect.reference.CtFieldReference) CtNewArray(spoon.reflect.code.CtNewArray) CtField(spoon.reflect.declaration.CtField) MetamodelPropertyField(spoon.reflect.annotations.MetamodelPropertyField) Field(java.lang.reflect.Field) CtTypeReference(spoon.reflect.reference.CtTypeReference) Collection(java.util.Collection) CtTypeAccess(spoon.reflect.code.CtTypeAccess)

Example 3 with CtNewArray

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

the class AnnotationTest method testReplaceAnnotationValue.

@Test
public void testReplaceAnnotationValue() throws Exception {
    final Launcher launcher = new Launcher();
    launcher.addInputResource("./src/test/java/spoon/test/annotation/testclasses/Main.java");
    launcher.buildModel();
    Factory factory = launcher.getFactory();
    CtType<?> type = factory.Type().get("spoon.test.annotation.testclasses.Main");
    CtMethod<?> m1 = type.getElements(new NamedElementFilter<>(CtMethod.class, "m1")).get(0);
    List<CtAnnotation<? extends Annotation>> annotations = m1.getAnnotations();
    assertEquals(1, annotations.size());
    CtAnnotation<?> a = annotations.get(0);
    AnnotParamTypes annot = (AnnotParamTypes) a.getActualAnnotation();
    // contract: test replace of single value
    CtExpression integerValue = a.getValue("integer");
    assertEquals(42, ((CtLiteral<Integer>) integerValue).getValue().intValue());
    assertEquals(42, annot.integer());
    integerValue.replace(factory.createLiteral(17));
    CtExpression newIntegerValue = a.getValue("integer");
    assertEquals(17, ((CtLiteral<Integer>) newIntegerValue).getValue().intValue());
    assertEquals(17, annot.integer());
    // even if second value is null
    try {
        a.getValue("integer").replace(Arrays.asList(factory.createLiteral(18), null));
        fail();
    } catch (SpoonException e) {
    // OK
    }
    // contract: replacing of single value by no value
    a.getValue("integer").delete();
    assertNull(a.getValue("integer"));
    try {
        annot.integer();
        fail();
    } catch (NullPointerException e) {
    // OK - fails because int cannot be null
    }
    // contract: replace with null value means remove
    a.getValue("string").replace((CtElement) null);
    assertNull(a.getValue("string"));
    // contract: check that null value can be returned
    assertNull(annot.string());
    // contract: replace with null value in collection means remove
    a.getValue("clazz").replace(Collections.singletonList(null));
    assertNull(a.getValue("clazz"));
    // contract: check that null value can be returned
    assertNull(annot.clazz());
    // contract: test replace of item in collection
    assertEquals(1, annot.integers().length);
    assertEquals(42, annot.integers()[0]);
    CtNewArray<?> integersNewArray = (CtNewArray) a.getValue("integers");
    integersNewArray.getElements().get(0).replace(Arrays.asList(null, factory.createLiteral(101), null, factory.createLiteral(102)));
    assertEquals(2, annot.integers().length);
    assertEquals(101, annot.integers()[0]);
    assertEquals(102, annot.integers()[1]);
}
Also used : CtAnnotation(spoon.reflect.declaration.CtAnnotation) AnnotParamTypes(spoon.test.annotation.testclasses.AnnotParamTypes) CtExpression(spoon.reflect.code.CtExpression) SpoonException(spoon.SpoonException) Factory(spoon.reflect.factory.Factory) CtNewArray(spoon.reflect.code.CtNewArray) TypeAnnotation(spoon.test.annotation.testclasses.TypeAnnotation) GlobalAnnotation(spoon.test.annotation.testclasses.GlobalAnnotation) SuperAnnotation(spoon.test.annotation.testclasses.SuperAnnotation) AnnotationDefaultAnnotation(spoon.test.annotation.testclasses.AnnotationDefaultAnnotation) InnerAnnotation(spoon.test.annotation.testclasses.Foo.InnerAnnotation) Annotation(java.lang.annotation.Annotation) MiddleAnnotation(spoon.test.annotation.testclasses.Foo.MiddleAnnotation) OuterAnnotation(spoon.test.annotation.testclasses.Foo.OuterAnnotation) CtAnnotation(spoon.reflect.declaration.CtAnnotation) CtLiteral(spoon.reflect.code.CtLiteral) NamedElementFilter(spoon.reflect.visitor.filter.NamedElementFilter) Launcher(spoon.Launcher) Test(org.junit.Test)

Example 4 with CtNewArray

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

the class AnnotationTest method testInnerAnnotationsWithArray.

@Test
public void testInnerAnnotationsWithArray() throws Exception {
    final Launcher launcher = new Launcher();
    launcher.addInputResource("./src/test/java/spoon/test/annotation/testclasses/Foo.java");
    launcher.buildModel();
    Factory factory = launcher.getFactory();
    final CtClass<?> ctClass = (CtClass<?>) factory.Type().get("spoon.test.annotation.testclasses.Foo");
    final CtMethod<?> testMethod = ctClass.getMethodsByName("test").get(0);
    final List<CtAnnotation<? extends Annotation>> testMethodAnnotations = testMethod.getAnnotations();
    assertEquals(1, testMethodAnnotations.size());
    final CtAnnotation<? extends Annotation> firstAnnotation = testMethodAnnotations.get(0);
    assertEquals(OuterAnnotation.class, getActualClassFromAnnotation(firstAnnotation));
    final CtNewArray<?> arrayAnnotations = (CtNewArray<?>) firstAnnotation.getValues().get("value");
    assertEquals(2, arrayAnnotations.getElements().size());
    final CtAnnotation<?> firstAnnotationInArray = getMiddleAnnotation(arrayAnnotations, 0);
    assertEquals(MiddleAnnotation.class, getActualClassFromAnnotation(firstAnnotationInArray));
    final CtAnnotation<?> secondAnnotationInArray = getMiddleAnnotation(arrayAnnotations, 1);
    assertEquals(MiddleAnnotation.class, getActualClassFromAnnotation(secondAnnotationInArray));
    final CtAnnotation<?> innerAnnotationInFirstMiddleAnnotation = getInnerAnnotation(firstAnnotationInArray);
    assertEquals(InnerAnnotation.class, getActualClassFromAnnotation(innerAnnotationInFirstMiddleAnnotation));
    assertEquals("hello", getLiteralValueInAnnotation(innerAnnotationInFirstMiddleAnnotation).getValue());
    final CtAnnotation<?> innerAnnotationInSecondMiddleAnnotation = getInnerAnnotation(secondAnnotationInArray);
    assertEquals(InnerAnnotation.class, getActualClassFromAnnotation(innerAnnotationInSecondMiddleAnnotation));
    assertEquals("hello again", getLiteralValueInAnnotation(innerAnnotationInSecondMiddleAnnotation).getValue());
}
Also used : CtClass(spoon.reflect.declaration.CtClass) CtAnnotation(spoon.reflect.declaration.CtAnnotation) Launcher(spoon.Launcher) Factory(spoon.reflect.factory.Factory) CtNewArray(spoon.reflect.code.CtNewArray) TypeAnnotation(spoon.test.annotation.testclasses.TypeAnnotation) GlobalAnnotation(spoon.test.annotation.testclasses.GlobalAnnotation) SuperAnnotation(spoon.test.annotation.testclasses.SuperAnnotation) AnnotationDefaultAnnotation(spoon.test.annotation.testclasses.AnnotationDefaultAnnotation) InnerAnnotation(spoon.test.annotation.testclasses.Foo.InnerAnnotation) Annotation(java.lang.annotation.Annotation) MiddleAnnotation(spoon.test.annotation.testclasses.Foo.MiddleAnnotation) OuterAnnotation(spoon.test.annotation.testclasses.Foo.OuterAnnotation) CtAnnotation(spoon.reflect.declaration.CtAnnotation) Test(org.junit.Test)

Example 5 with CtNewArray

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

the class MetamodelTest method testRoleOnField.

@Test
public void testRoleOnField() {
    // contract: all non-final fields must be annotated with {@link spoon.reflect.annotations.MetamodelPropertyField}
    SpoonAPI implementations = new Launcher();
    implementations.addInputResource("src/main/java/spoon/support/reflect");
    implementations.buildModel();
    Factory factory = implementations.getFactory();
    CtTypeReference metamodelPropertyField = factory.Type().get(MetamodelPropertyField.class).getReference();
    final List<String> result = new ArrayList();
    List<CtField> fieldWithoutAnnotation = (List<CtField>) implementations.getModel().getElements(new TypeFilter<CtField>(CtField.class) {

        @Override
        public boolean matches(CtField candidate) {
            if (candidate.hasModifier(ModifierKind.FINAL) || candidate.hasModifier(ModifierKind.STATIC) || candidate.hasModifier(ModifierKind.TRANSIENT)) {
                return false;
            }
            if (// not a role
            "parent".equals(candidate.getSimpleName()) || "metadata".equals(candidate.getSimpleName()) || // cache field
            "valueOfMethod".equals(candidate.getSimpleName())) {
                return false;
            }
            CtClass parent = candidate.getParent(CtClass.class);
            return parent != null && (parent.isSubtypeOf(candidate.getFactory().createCtTypeReference(CtReference.class)) || parent.isSubtypeOf(candidate.getFactory().createCtTypeReference(CtElement.class)));
        }
    }).stream().map(x -> {
        result.add(x.toString());
        return x;
    }).filter(f -> f.getAnnotation(metamodelPropertyField) == null).collect(Collectors.toList());
    assertTrue(result.contains("@spoon.reflect.annotations.MetamodelPropertyField(role = spoon.reflect.path.CtRole.IS_SHADOW)\nboolean isShadow;"));
    assertTrue(result.contains("@spoon.reflect.annotations.MetamodelPropertyField(role = spoon.reflect.path.CtRole.TYPE)\nspoon.reflect.reference.CtTypeReference<T> type;"));
    assertTrue(result.size() > 100);
    Assert.assertEquals(Collections.emptyList(), fieldWithoutAnnotation);
    final CtTypeReference propertySetter = factory.Type().get(PropertySetter.class).getReference();
    final CtTypeReference propertyGetter = factory.Type().get(PropertyGetter.class).getReference();
    List<CtField> fields = factory.getModel().getElements(new AnnotationFilter<CtField>(MetamodelPropertyField.class));
    for (CtField field : fields) {
        CtClass parent = field.getParent(CtClass.class);
        CtExpression roleExpression = field.getAnnotation(metamodelPropertyField).getValue("role");
        List<String> roles = new ArrayList<>();
        if (roleExpression instanceof CtFieldRead) {
            roles.add(((CtFieldRead) roleExpression).getVariable().getSimpleName());
        } else if (roleExpression instanceof CtNewArray) {
            List<CtFieldRead> elements = ((CtNewArray) roleExpression).getElements();
            for (int i = 0; i < elements.size(); i++) {
                CtFieldRead ctFieldRead = elements.get(i);
                roles.add(ctFieldRead.getVariable().getSimpleName());
            }
        }
        CtQuery superQuery = parent.map(new SuperInheritanceHierarchyFunction());
        List<CtMethod> methods = superQuery.map((CtType type) -> type.getMethodsAnnotatedWith(propertyGetter, propertySetter)).list();
        boolean setterFound = false;
        boolean getterFound = false;
        for (CtMethod method : methods) {
            CtAnnotation getterAnnotation = method.getAnnotation(propertyGetter);
            CtAnnotation setterAnnotation = method.getAnnotation(propertySetter);
            if (getterAnnotation != null) {
                getterFound |= roles.contains(((CtFieldRead) getterAnnotation.getValue("role")).getVariable().getSimpleName());
            }
            if (setterAnnotation != null) {
                setterFound |= roles.contains(((CtFieldRead) setterAnnotation.getValue("role")).getVariable().getSimpleName());
            }
        }
        assertTrue(roles + " must have a getter in " + parent.getQualifiedName(), getterFound);
        assertTrue(roles + " must have a setter in " + parent.getQualifiedName(), setterFound);
    }
}
Also used : Arrays(java.util.Arrays) Launcher(spoon.Launcher) IsEqual.equalTo(org.hamcrest.core.IsEqual.equalTo) CtRole(spoon.reflect.path.CtRole) ArrayList(java.util.ArrayList) CtType(spoon.reflect.declaration.CtType) CtElement(spoon.reflect.declaration.CtElement) SpoonAPI(spoon.SpoonAPI) CtExpression(spoon.reflect.code.CtExpression) CtNewArray(spoon.reflect.code.CtNewArray) Metamodel(spoon.Metamodel) MatcherAssert.assertThat(org.hamcrest.MatcherAssert.assertThat) CtQuery(spoon.reflect.visitor.chain.CtQuery) TypeFilter(spoon.reflect.visitor.filter.TypeFilter) CtField(spoon.reflect.declaration.CtField) CtReference(spoon.reflect.reference.CtReference) MetamodelPropertyField(spoon.reflect.annotations.MetamodelPropertyField) SuperInheritanceHierarchyFunction(spoon.reflect.visitor.filter.SuperInheritanceHierarchyFunction) Set(java.util.Set) Assert.assertTrue(org.junit.Assert.assertTrue) Test(org.junit.Test) Factory(spoon.reflect.factory.Factory) PropertySetter(spoon.reflect.annotations.PropertySetter) Collectors(java.util.stream.Collectors) CtTypeReference(spoon.reflect.reference.CtTypeReference) List(java.util.List) CtAnnotation(spoon.reflect.declaration.CtAnnotation) AnnotationFilter(spoon.reflect.visitor.filter.AnnotationFilter) CtClass(spoon.reflect.declaration.CtClass) ModifierKind(spoon.reflect.declaration.ModifierKind) CtFieldRead(spoon.reflect.code.CtFieldRead) Assert(org.junit.Assert) Collections(java.util.Collections) PropertyGetter(spoon.reflect.annotations.PropertyGetter) CtMethod(spoon.reflect.declaration.CtMethod) ArrayList(java.util.ArrayList) Factory(spoon.reflect.factory.Factory) TypeFilter(spoon.reflect.visitor.filter.TypeFilter) CtNewArray(spoon.reflect.code.CtNewArray) CtTypeReference(spoon.reflect.reference.CtTypeReference) CtField(spoon.reflect.declaration.CtField) PropertyGetter(spoon.reflect.annotations.PropertyGetter) ArrayList(java.util.ArrayList) List(java.util.List) SpoonAPI(spoon.SpoonAPI) SuperInheritanceHierarchyFunction(spoon.reflect.visitor.filter.SuperInheritanceHierarchyFunction) CtAnnotation(spoon.reflect.declaration.CtAnnotation) CtFieldRead(spoon.reflect.code.CtFieldRead) CtExpression(spoon.reflect.code.CtExpression) PropertySetter(spoon.reflect.annotations.PropertySetter) CtQuery(spoon.reflect.visitor.chain.CtQuery) MetamodelPropertyField(spoon.reflect.annotations.MetamodelPropertyField) CtClass(spoon.reflect.declaration.CtClass) CtType(spoon.reflect.declaration.CtType) Launcher(spoon.Launcher) CtMethod(spoon.reflect.declaration.CtMethod) Test(org.junit.Test)

Aggregations

CtNewArray (spoon.reflect.code.CtNewArray)11 Test (org.junit.Test)6 CtExpression (spoon.reflect.code.CtExpression)5 Launcher (spoon.Launcher)4 CtClass (spoon.reflect.declaration.CtClass)4 Factory (spoon.reflect.factory.Factory)4 ArrayList (java.util.ArrayList)3 CtElement (spoon.reflect.declaration.CtElement)3 CtField (spoon.reflect.declaration.CtField)3 CtMethod (spoon.reflect.declaration.CtMethod)3 CtTypeReference (spoon.reflect.reference.CtTypeReference)3 Annotation (java.lang.annotation.Annotation)2 SpoonException (spoon.SpoonException)2 CtBinaryOperator (spoon.reflect.code.CtBinaryOperator)2 CtConditional (spoon.reflect.code.CtConditional)2 CtIf (spoon.reflect.code.CtIf)2 CtInvocation (spoon.reflect.code.CtInvocation)2 CtSwitch (spoon.reflect.code.CtSwitch)2 CtAnnotation (spoon.reflect.declaration.CtAnnotation)2 CtAnonymousExecutable (spoon.reflect.declaration.CtAnonymousExecutable)2