use of spoon.reflect.declaration.CtAnnotation in project spoon by INRIA.
the class MetaModelTest method elementAnnotationRoleTest.
@Test
public void elementAnnotationRoleTest() {
Launcher launcher = new Launcher();
Factory factory = launcher.getFactory();
CtClass<?> type = (CtClass) factory.Core().create(CtClass.class);
CtAnnotation<?> annotation = factory.Annotation().annotate(type, Parameter.class, "value", "abc");
// check direct getValueByRole
List<CtAnnotation<?>> value = type.getValueByRole(CtRole.ANNOTATION);
assertEquals(1, value.size());
assertSame(annotation, value.get(0));
try {
value.remove(annotation);
fail();
} catch (Exception e) {
this.getClass();
}
// check setValueByRole
type.setValueByRole(CtRole.ANNOTATION, Collections.emptyList());
value = type.getValueByRole(CtRole.ANNOTATION);
assertEquals(0, value.size());
type.setValueByRole(CtRole.ANNOTATION, Collections.singletonList(annotation));
value = type.getValueByRole(CtRole.ANNOTATION);
assertEquals(1, value.size());
assertSame(annotation, value.get(0));
try {
// contract value must be a list of annotation. One annotation is not actually OK. This contract might be changed in future
type.setValueByRole(CtRole.ANNOTATION, annotation);
fail();
} catch (ClassCastException e) {
// OK
}
}
use of spoon.reflect.declaration.CtAnnotation 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);
}
}
use of spoon.reflect.declaration.CtAnnotation in project spoon by INRIA.
the class AnnotationTest method testRepeatSameAnnotationOnPackage.
@Test
public void testRepeatSameAnnotationOnPackage() throws Exception {
final Launcher launcher = new Launcher();
launcher.addInputResource("./src/test/java/spoon/test/annotation/testclasses/AnnotationsRepeated.java");
launcher.addInputResource("./src/test/java/spoon/test/annotation/testclasses/package-info.java");
launcher.buildModel();
Factory factory = launcher.getFactory();
final CtPackage pkg = factory.Package().get("spoon.test.annotation.testclasses");
final List<CtAnnotation<? extends Annotation>> annotations = pkg.getAnnotations();
assertEquals("Local variable must to have multi annotation of the same type", 2, annotations.size());
assertEquals("Type of the first annotation is AnnotationRepeated", AnnotationRepeated.class, annotations.get(0).getAnnotationType().getActualClass());
assertEquals("Type of the second annotation is AnnotationRepeated", AnnotationRepeated.class, annotations.get(1).getAnnotationType().getActualClass());
assertEquals("Argument of the first annotation is \"Package 1\"", "Package 1", ((CtLiteral) annotations.get(0).getValue("value")).getValue());
assertEquals("Argument of the second annotation is \"Package 2\"", "Package 2", ((CtLiteral) annotations.get(1).getValue("value")).getValue());
}
use of spoon.reflect.declaration.CtAnnotation in project spoon by INRIA.
the class AnnotationTest method testRepeatableAnnotationAreManaged.
@Test
public void testRepeatableAnnotationAreManaged() {
// contract: when two identical repeatable annotation are used, they should be displayed in two different annotations and not factorized
Launcher spoon = new Launcher();
spoon.addInputResource("./src/test/java/spoon/test/annotation/testclasses/repeatable");
spoon.buildModel();
CtType type = spoon.getFactory().Type().get(Repeated.class);
CtMethod firstMethod = (CtMethod) type.getMethodsByName("method").get(0);
List<CtAnnotation<?>> annotations = firstMethod.getAnnotations();
assertEquals(2, annotations.size());
for (CtAnnotation a : annotations) {
assertEquals("Tag", a.getAnnotationType().getSimpleName());
}
String classContent = type.toString();
assertTrue("Content of the file: " + classContent, classContent.contains("@spoon.test.annotation.testclasses.repeatable.Tag(\"machin\")"));
assertTrue("Content of the file: " + classContent, classContent.contains("@spoon.test.annotation.testclasses.repeatable.Tag(\"truc\")"));
}
use of spoon.reflect.declaration.CtAnnotation in project spoon by INRIA.
the class AnnotationTest method testUsageOfTypeAnnotationInCast.
@Test
public void testUsageOfTypeAnnotationInCast() throws Exception {
final Launcher launcher = new Launcher();
launcher.addInputResource("./src/test/java/spoon/test/annotation/testclasses/AnnotationsAppliedOnAnyTypeInAClass.java");
launcher.buildModel();
Factory factory = launcher.getFactory();
final CtClass<?> ctClass = (CtClass<?>) factory.Type().get("spoon.test.annotation.testclasses.AnnotationsAppliedOnAnyTypeInAClass");
final CtReturn<?> returns = ctClass.getElements(new AbstractFilter<CtReturn<?>>(CtReturn.class) {
@Override
public boolean matches(CtReturn<?> element) {
return !element.getReturnedExpression().getTypeCasts().isEmpty();
}
}).get(0);
final CtExpression<?> returnedExpression = returns.getReturnedExpression();
final List<CtAnnotation<? extends Annotation>> typeAnnotations = returnedExpression.getTypeCasts().get(0).getAnnotations();
assertEquals("Cast with a type annotation must have it in its model", 1, typeAnnotations.size());
assertEquals("Type annotation in the cast must be typed by TypeAnnotation", TypeAnnotation.class, typeAnnotations.get(0).getAnnotationType().getActualClass());
assertEquals(CtAnnotatedElementType.TYPE_USE, typeAnnotations.get(0).getAnnotatedElementType());
assertEquals("Cast with an type annotation must be well printed", "((java.lang.@spoon.test.annotation.testclasses.TypeAnnotation" + System.lineSeparator() + "String) (s))", returnedExpression.toString());
}
Aggregations