Search in sources :

Example 16 with CtQuery

use of spoon.reflect.visitor.chain.CtQuery 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

CtQuery (spoon.reflect.visitor.chain.CtQuery)16 Test (org.junit.Test)10 Launcher (spoon.Launcher)10 CtType (spoon.reflect.declaration.CtType)7 CtClass (spoon.reflect.declaration.CtClass)6 CtElement (spoon.reflect.declaration.CtElement)5 CtMethod (spoon.reflect.declaration.CtMethod)5 HashSet (java.util.HashSet)3 CtTypeReference (spoon.reflect.reference.CtTypeReference)3 ArrayList (java.util.ArrayList)2 SpoonException (spoon.SpoonException)2 CtField (spoon.reflect.declaration.CtField)2 CtQueryImpl (spoon.reflect.visitor.chain.CtQueryImpl)2 ArrayDeque (java.util.ArrayDeque)1 Arrays (java.util.Arrays)1 Collections (java.util.Collections)1 List (java.util.List)1 Set (java.util.Set)1 Collectors (java.util.stream.Collectors)1 MatcherAssert.assertThat (org.hamcrest.MatcherAssert.assertThat)1