use of spoon.reflect.visitor.filter.NamedElementFilter in project spoon by INRIA.
the class GenericsTest method testModelBuildingTree.
@Test
public void testModelBuildingTree() throws Exception {
CtClass<?> type = build("spoon.test.generics", "Tree");
assertEquals("Tree", type.getSimpleName());
// New type parameter declaration.
CtTypeParameter typeParameter = type.getFormalCtTypeParameters().get(0);
assertEquals("V", typeParameter.getSimpleName());
assertEquals("[java.io.Serializable, java.lang.Comparable<V>]", typeParameter.getSuperclass().asCtIntersectionTypeReference().getBounds().toString());
CtMethod<?> node5 = type.getElements(new NamedElementFilter<>(CtMethod.class, "node5")).get(0);
assertEquals("this.<java.lang.Class<? extends java.lang.Throwable>>foo()", node5.getBody().getStatement(0).toString());
}
use of spoon.reflect.visitor.filter.NamedElementFilter in project spoon by INRIA.
the class GenericsTest method testClassTypingContextMethodSignature.
@Test
public void testClassTypingContextMethodSignature() throws Exception {
// core contracts of MethodTypingContext#adaptMethod
Factory factory = build(new File("src/test/java/spoon/test/generics/testclasses"));
CtClass<?> ctClassLunch = factory.Class().get(Lunch.class);
CtClass<?> ctClassWeddingLunch = factory.Class().get(WeddingLunch.class);
// represents <C> void eatMe(A paramA, B paramB, C paramC){}
CtMethod<?> trLunch_eatMe = ctClassLunch.filterChildren(new NamedElementFilter<>(CtMethod.class, "eatMe")).first();
// represents <C> void eatMe(M paramA, K paramB, C paramC)
CtMethod<?> trWeddingLunch_eatMe = ctClassWeddingLunch.filterChildren(new NamedElementFilter<>(CtMethod.class, "eatMe")).first();
ClassTypingContext ctcWeddingLunch = new ClassTypingContext(ctClassWeddingLunch);
assertTrue(ctcWeddingLunch.isOverriding(trLunch_eatMe, trLunch_eatMe));
assertTrue(ctcWeddingLunch.isOverriding(trLunch_eatMe, trWeddingLunch_eatMe));
assertTrue(ctcWeddingLunch.isSubSignature(trLunch_eatMe, trWeddingLunch_eatMe));
// contract: check that adapting of methods still produces same results, even when scopeMethod is already assigned
assertTrue(ctcWeddingLunch.isOverriding(trWeddingLunch_eatMe, trLunch_eatMe));
assertTrue(ctcWeddingLunch.isOverriding(trWeddingLunch_eatMe, trWeddingLunch_eatMe));
assertTrue(ctcWeddingLunch.isSubSignature(trWeddingLunch_eatMe, trWeddingLunch_eatMe));
}
use of spoon.reflect.visitor.filter.NamedElementFilter in project spoon by INRIA.
the class TemplateTest method testTemplateC1.
@Test
public void testTemplateC1() throws Exception {
Launcher spoon = new Launcher();
Factory factory = spoon.createFactory();
spoon.createCompiler(factory, SpoonResourceHelper.resources("./src/test/java/spoon/test/template/testclasses/constructors/C1.java"), SpoonResourceHelper.resources("./src/test/java/spoon/test/template/testclasses/constructors/TemplateWithConstructor.java", "./src/test/java/spoon/test/template/testclasses/constructors/TemplateWithFieldsAndMethods.java")).build();
CtClass<?> c1 = factory.Class().get(C1.class);
// before template: 1 constructor
assertEquals(// this is the default implicit constructor
1, c1.getConstructors().size());
// the actual substitution
new TemplateWithConstructor(factory.Type().createReference(Date.class)).apply(c1);
// after template: 3 constructors
// System.out.println("==>"+c1.getConstructors());
assertEquals(3, c1.getConstructors().size());
CtField<?> toBeInserted = c1.getElements(new NamedElementFilter<>(CtField.class, "toBeInserted")).get(0);
assertEquals(Date.class, toBeInserted.getType().getActualTypeArguments().get(0).getActualClass());
assertEquals("java.util.List<java.util.Date> toBeInserted = new java.util.ArrayList<java.util.Date>();", toBeInserted.toString());
new TemplateWithFieldsAndMethods("testparam", factory.Code().createLiteral("testparam2")).apply(c1);
assertEquals(3, c1.getConstructors().size());
assertNotNull(c1.getField("fieldToBeInserted"));
CtMethod<?> m = c1.getMethod("methodToBeInserted");
assertNotNull(m);
assertEquals("return \"testparam\"", m.getBody().getStatement(0).toString());
CtMethod<?> m2 = c1.getMethod("methodToBeInserted2");
assertNotNull(m2);
assertEquals("return \"testparam2\"", m2.getBody().getStatement(0).toString());
new ModelConsistencyChecker(factory.getEnvironment(), false, true).scan(c1);
assertEquals(0, factory.getEnvironment().getErrorCount());
assertEquals(0, factory.getEnvironment().getWarningCount());
}
use of spoon.reflect.visitor.filter.NamedElementFilter in project spoon by INRIA.
the class TemplateTest method testTemplateInheritance.
@Test
public void testTemplateInheritance() throws Exception {
Launcher spoon = new Launcher();
Factory factory = spoon.getFactory();
spoon.getEnvironment().setCommentEnabled(true);
spoon.createCompiler(factory, SpoonResourceHelper.resources("./src/test/java/spoon/test/template/testclasses/inheritance/SubClass.java", "./src/test/java/spoon/test/template/testclasses/inheritance/SuperClass.java"), SpoonResourceHelper.resources("./src/test/java/spoon/test/template/testclasses/inheritance/SubTemplate.java", "./src/test/java/spoon/test/template/testclasses/inheritance/SuperTemplate.java")).build();
// Collects type members which should contain generated by comment
final Map<CtElement, String> elementToGeneratedByMember = new IdentityHashMap<>();
CtClass<?> superc = factory.Class().get(SuperClass.class);
new SuperTemplate().addGeneratedBy(true).apply(superc);
CtMethod<?> addedMethod = superc.getElements(new NamedElementFilter<>(CtMethod.class, "toBeOverriden")).get(0);
assertEquals("toBeOverriden", addedMethod.getSimpleName());
elementToGeneratedByMember.put(addedMethod, "#toBeOverriden");
CtClass<?> subc = factory.Class().get(SubClass.class);
SubTemplate template = new SubTemplate();
template.addGeneratedBy(true);
template.params = new ArrayList<>();
CtParameter<Integer> parameter = factory.Core().createParameter();
parameter.setSimpleName("x");
parameter.setType(factory.Type().createReference(int.class));
template.params.add(parameter);
// templating the invocation
template.invocation = factory.Code().createInvocation(null, addedMethod.getReference());
// templating the foreach
template.intValues = new CtExpression[2];
template.intValues[0] = factory.Code().createLiteral(0);
template.intValues[1] = factory.Code().createLiteral(1);
// we apply the extension template to subc
template.apply(subc);
CtMethod<?> addedMethod2 = subc.getElements(new NamedElementFilter<>(CtMethod.class, "toBeOverriden")).get(0);
assertEquals("toBeOverriden", addedMethod2.getSimpleName());
assertEquals("super.toBeOverriden()", addedMethod2.getBody().getStatements().get(0).toString());
elementToGeneratedByMember.put(addedMethod2, "#toBeOverriden");
// contract; method parameter templates are handled
CtMethod<?> methodWithTemplatedParameters = subc.getElements(new NamedElementFilter<>(CtMethod.class, "methodWithTemplatedParameters")).get(0);
assertEquals("methodWithTemplatedParameters", methodWithTemplatedParameters.getSimpleName());
assertEquals("x", methodWithTemplatedParameters.getParameters().get(0).getSimpleName());
assertEquals("int x", methodWithTemplatedParameters.getParameters().get(0).toString());
elementToGeneratedByMember.put(methodWithTemplatedParameters, "#methodWithTemplatedParameters");
// contract: nested types of the templates are copied
assertEquals(1, subc.getNestedTypes().size());
elementToGeneratedByMember.put(subc.getNestedTypes().iterator().next(), "$InnerClass");
// contract: methods are renamed
assertEquals(1, subc.getMethodsByName("newVarName").size());
CtMethod<?> varMethod = subc.getMethodsByName("newVarName").get(0);
elementToGeneratedByMember.put(varMethod, "#var");
// contract: parameters are replaced in comments too. The Class parameter value is converted to String
assertEquals("newVarName", varMethod.getComments().get(0).getContent().split("[\\n\\r]+")[0]);
assertEquals("{@link LinkedList}", varMethod.getComments().get(1).getContent());
assertEquals("{@link SuperClass#toBeOverriden()}", varMethod.getComments().get(2).getContent());
// contract: variable are renamed
assertEquals("java.util.List newVarName = null", methodWithTemplatedParameters.getBody().getStatement(0).toString());
// contract: types are replaced by other types
assertEquals("java.util.LinkedList l = null", methodWithTemplatedParameters.getBody().getStatement(1).toString());
// contract: casts are replaced by substitution types
assertEquals("java.util.List o = ((java.util.LinkedList) (new java.util.LinkedList()))", methodWithTemplatedParameters.getBody().getStatement(2).toString());
// contract: invocations are replaced by actual invocations
assertEquals("toBeOverriden()", methodWithTemplatedParameters.getBody().getStatement(3).toString());
// contract: foreach in block is inlined into that wrapping block
CtBlock templatedForEach = methodWithTemplatedParameters.getBody().getStatement(4);
assertEquals("java.lang.System.out.println(0)", templatedForEach.getStatement(0).toString());
assertEquals("java.lang.System.out.println(1)", templatedForEach.getStatement(1).toString());
// contract: foreach with single body block are inlined without extra block
assertEquals("java.lang.System.out.println(0)", methodWithTemplatedParameters.getBody().getStatement(5).toString());
assertEquals("java.lang.System.out.println(1)", methodWithTemplatedParameters.getBody().getStatement(6).toString());
// contract: foreach with double body block are inlined with one extra block for each inlined statement
assertEquals("java.lang.System.out.println(0)", ((CtBlock) methodWithTemplatedParameters.getBody().getStatement(7)).getStatement(0).toString());
assertEquals("java.lang.System.out.println(1)", ((CtBlock) methodWithTemplatedParameters.getBody().getStatement(8)).getStatement(0).toString());
// contract: foreach with statement are inlined without extra (implicit) block
assertFalse(methodWithTemplatedParameters.getBody().getStatement(9) instanceof CtBlock);
assertEquals("java.lang.System.out.println(0)", methodWithTemplatedParameters.getBody().getStatement(9).toString());
assertFalse(methodWithTemplatedParameters.getBody().getStatement(10) instanceof CtBlock);
assertEquals("java.lang.System.out.println(1)", methodWithTemplatedParameters.getBody().getStatement(10).toString());
// contract: for each whose expression is not a template parameter is not inlined
assertTrue(methodWithTemplatedParameters.getBody().getStatement(11) instanceof CtForEach);
// contract: local variable write are replaced by local variable write with modified local variable name
assertEquals("newVarName = o", methodWithTemplatedParameters.getBody().getStatement(12).toString());
// contract: local variable read are replaced by local variable read with modified local variable name
assertEquals("l = ((java.util.LinkedList) (newVarName))", methodWithTemplatedParameters.getBody().getStatement(13).toString());
// contract; field access is handled same like local variable access
CtMethod<?> methodWithFieldAccess = subc.getElements(new NamedElementFilter<>(CtMethod.class, "methodWithFieldAccess")).get(0);
elementToGeneratedByMember.put(methodWithFieldAccess, "#methodWithFieldAccess");
elementToGeneratedByMember.put(subc.getField("newVarName"), "#var");
// contract: field write are replaced by field write with modified field name
assertEquals("newVarName = o", methodWithFieldAccess.getBody().getStatement(2).toString());
// contract: field read are replaced by field read with modified field name
assertEquals("l = ((java.util.LinkedList) (newVarName))", methodWithFieldAccess.getBody().getStatement(3).toString());
class Context {
int nrTypeMembers = 0;
int nrOthers = 0;
}
final Context ctx = new Context();
// contract: each CtTypeMember has `Generated by ` with appropriate template class name, member name and line number
superc.filterChildren(null).forEach((CtElement e) -> {
if (e instanceof CtTypeMember) {
ctx.nrTypeMembers++;
assertCommentHasGeneratedBy(e, SuperTemplate.class.getName(), elementToGeneratedByMember);
} else {
ctx.nrOthers++;
assertTrue(e.getDocComment() == null || e.getDocComment().indexOf("Generated by") == -1);
}
});
assertTrue(ctx.nrTypeMembers > 0);
assertTrue(ctx.nrOthers > 0);
ctx.nrTypeMembers = 0;
ctx.nrOthers = 0;
subc.filterChildren(null).forEach((CtElement e) -> {
if (e instanceof CtTypeMember) {
ctx.nrTypeMembers++;
assertCommentHasGeneratedBy(e, SubTemplate.class.getName(), elementToGeneratedByMember);
} else {
ctx.nrOthers++;
assertTrue(e.getDocComment() == null || e.getDocComment().indexOf("Generated by") == -1);
}
});
assertTrue(ctx.nrTypeMembers > 0);
assertTrue(ctx.nrOthers > 0);
}
use of spoon.reflect.visitor.filter.NamedElementFilter 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]);
}
Aggregations