use of spoon.reflect.declaration.CtElement in project spoon by INRIA.
the class ElementTest method testGetFactory.
@Test
public void testGetFactory() {
// contract: getFactory should always return an object
// even if an element is created via its constructor
// and not through the factory
Launcher spoon = new Launcher();
CtElement element = spoon.getFactory().createAnnotation();
assertNotNull(element.getFactory());
CtElement otherElement = new CtAnnotationImpl<>();
assertNotNull(otherElement.getFactory());
CtElement yetAnotherOne = new CtMethodImpl<>();
assertNotNull(yetAnotherOne.getFactory());
// contract: a singleton is used for the default factory
assertSame(otherElement.getFactory(), yetAnotherOne.getFactory());
}
use of spoon.reflect.declaration.CtElement in project spoon by INRIA.
the class FieldFactoryTest method testCreate.
@Test
public void testCreate() throws Exception {
CtClass<?> type = build("spoon.test.testclasses", "SampleClass");
FieldFactory ff = type.getFactory().Field();
TypeFactory tf = type.getFactory().Type();
Set<ModifierKind> mods = new HashSet<ModifierKind>();
mods.add(ModifierKind.PRIVATE);
CtTypeReference<?> tref = tf.createReference(String.class);
ff.create(type, mods, tref, "name");
CtField<?> field = type.getField("name");
Assert.assertEquals("name", field.getSimpleName());
Assert.assertEquals(tref, field.getType());
CtElement parent = field.getParent();
Assert.assertTrue(parent instanceof CtClass<?>);
Assert.assertEquals("SampleClass", ((CtClass<?>) parent).getSimpleName());
}
use of spoon.reflect.declaration.CtElement in project spoon by INRIA.
the class ReplaceParametrizedTest method testContract.
@Test
public void testContract() throws Throwable {
List<String> problems = new ArrayList<>();
// contract: all elements are replaceable wherever they are in the model
// this test puts them at all possible locations
CtType<?> toTest = typeToTest.getModelInterface();
CtElement o = factory.Core().create((Class<? extends CtElement>) toTest.getActualClass());
for (MetamodelProperty mmField : typeToTest.getRoleToProperty().values()) {
Class<?> argType = mmField.getItemValueType().getActualClass();
if (!CtElement.class.isAssignableFrom(argType)) {
continue;
}
CtTypeReference<?> itemType = mmField.getItemValueType();
// special cases...
if (itemType.getQualifiedName().equals(CtStatement.class.getName())) {
// the children of CtLoop wraps CtStatement into an implicit CtBlock. So make a block directly to test plain get/set and not wrapping.
itemType = factory.createCtTypeReference(CtBlock.class);
}
if (o.getClass().getSimpleName().equals("CtAnnotationFieldAccessImpl") && mmField.getRole() == CtRole.VARIABLE) {
itemType = factory.createCtTypeReference(CtFieldReference.class);
} else if (CtFieldAccess.class.isAssignableFrom(o.getClass()) && mmField.getRole() == CtRole.VARIABLE) {
itemType = factory.createCtTypeReference(CtFieldReference.class);
}
CtElement argument = (CtElement) createCompatibleObject(itemType);
assertNotNull(argument);
// we create a fresh object
CtElement receiver = ((CtElement) o).clone();
RoleHandler rh = RoleHandlerHelper.getRoleHandler(o.getClass(), mmField.getRole());
if (mmField.isUnsettable()) {
try {
// we invoke the setter
invokeSetter(rh, receiver, argument);
} catch (SpoonException e) {
// ok this unsettable property has no setter at all
return;
}
// this unsettable property has setter, but it should do nothing
CtRole argumentsRoleInParent = argument.getRoleInParent();
if (argumentsRoleInParent == null) {
// OK - unsettable property set no value
continue;
}
if (argumentsRoleInParent == mmField.getRole()) {
problems.add("UnsettableProperty " + mmField + " sets the value");
} else {
if (mmField.isDerived()) {
// it is OK, that setting of value into derived unsettable field influences other field
// Example 1: CtCatchVariable.setType(x) influences result of getMultitype()
// Example 2: CtEnumValue.setAssignment(x) influences result of getDefaultExpression()
} else {
problems.add("UnsettableProperty " + mmField + " sets the value into different role " + argumentsRoleInParent);
}
}
continue;
}
// we invoke the setter
invokeSetter(rh, receiver, argument);
// contract: a property setter sets properties that are visitable by a scanner
CtElement finalArgument = argument;
class Scanner extends CtScanner {
boolean found = false;
@Override
public void scan(CtRole role, CtElement e) {
super.scan(role, e);
if (e == finalArgument) {
if (rh.getRole() == role || rh.getRole().getSuperRole() == role) {
found = true;
return;
}
// if (rh.getRole()==CtRole.TYPE && role==CtRole.MULTI_TYPE) {
// //CtCatchVaraible#type sets CtCatchVaraible#multiType - OK
// found = true;
// return;
// }
problems.add("Argument was set into " + rh.getRole() + " but was found in " + role);
}
}
}
;
Scanner s = new Scanner();
receiver.accept(s);
assertTrue("Settable field " + mmField.toString() + " should set value.\n" + getReport(problems), s.found);
// contract: a property getter on the same role can be used to get the value back
assertSame(argument, invokeGetter(rh, receiver));
final CtElement argument2 = argument.clone();
assertNotSame(argument, argument2);
// we do the replace
argument.replace(argument2);
// the new element is indeed now in this AST
assertTrue(receiver.getClass().getSimpleName() + " failed for " + mmField, receiver.getElements(new Filter<CtElement>() {
@Override
public boolean matches(CtElement element) {
return element == argument2;
}
}).size() == 1);
}
if (problems.size() > 0) {
fail(getReport(problems));
}
}
use of spoon.reflect.declaration.CtElement in project spoon by INRIA.
the class ReplaceTest method testReplaceReplace.
@Test
public void testReplaceReplace() throws Exception {
// bug found by Benoit
CtClass<?> foo = factory.Package().get("spoon.test.replace.testclasses").getType("Foo");
CtMethod<?> fooMethod = foo.getElements(new NamedElementFilter<>(CtMethod.class, "foo")).get(0);
assertEquals("foo", fooMethod.getSimpleName());
CtMethod<?> barMethod = foo.getElements(new NamedElementFilter<>(CtMethod.class, "bar")).get(0);
assertEquals("bar", barMethod.getSimpleName());
CtLocalVariable<?> assignment = (CtLocalVariable<?>) fooMethod.getBody().getStatements().get(0);
CtLocalVariable<?> newAssignment = barMethod.getBody().getStatement(0);
assignment.replace(newAssignment);
assertEquals(fooMethod.getBody(), newAssignment.getParent());
CtLiteral<Integer> lit = (CtLiteral<Integer>) foo.getElements(new TypeFilter<CtLiteral<?>>(CtLiteral.class)).get(0);
final CtElement parent = lit.getParent();
CtLiteral<Integer> newLit = factory.Code().createLiteral(0);
lit.replace(newLit);
assertEquals("int y = 0", fooMethod.getBody().getStatement(0).toString());
assertEquals(parent, newLit.getParent());
}
use of spoon.reflect.declaration.CtElement in project spoon by INRIA.
the class VariableReferencesTest method testCheckModelConsistency.
@Test
public void testCheckModelConsistency() throws Exception {
// 2) check that each of them is using different identification value
class Context {
Map<Integer, CtElement> unique = new HashMap<>();
int maxKey = 0;
void checkKey(int key, CtElement ele) {
CtElement ambiquous = unique.put(key, ele);
if (ambiquous != null) {
fail("Two variables [" + ambiquous.toString() + " in " + getParentMethodName(ambiquous) + "," + ele.toString() + " in " + getParentMethodName(ele) + "] has same value");
}
maxKey = Math.max(maxKey, key);
}
}
Context context = new Context();
modelClass.filterChildren((CtElement e) -> {
if (e instanceof CtVariable) {
CtVariable<?> var = (CtVariable<?>) e;
if (isTestFieldName(var.getSimpleName()) == false) {
return false;
}
// check only these variables whose name is isTestFieldName(name)==true
Integer val = getLiteralValue(var);
// System.out.println("key = "+val+" - "+var.toString());
context.checkKey(val, var);
}
return false;
}).list();
// System.out.println("Next available key is: "+(context.maxKey+1));
assertTrue(context.unique.size() > 0);
assertEquals("Only these keys were found: " + context.unique.keySet(), context.maxKey, context.unique.size());
assertEquals("AllLocalVars#maxValue must be equal to maximum value number ", (int) getLiteralValue((CtVariable) modelClass.filterChildren(new NamedElementFilter<>(CtVariable.class, "maxValue")).first()), context.maxKey);
}
Aggregations