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());
}
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;
}
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]);
}
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());
}
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);
}
}
Aggregations