use of spoon.reflect.visitor.filter.NamedElementFilter in project spoon by INRIA.
the class CtTypeParameterTest method testTypeSame.
@Test
public void testTypeSame() throws Exception {
CtClass<?> ctModel = (CtClass<?>) ModelUtils.buildClass(ErasureModelA.class);
CtTypeParameter tpA = ctModel.getFormalCtTypeParameters().get(0);
CtTypeParameter tpB = ctModel.getFormalCtTypeParameters().get(1);
CtTypeParameter tpC = ctModel.getFormalCtTypeParameters().get(2);
CtTypeParameter tpD = ctModel.getFormalCtTypeParameters().get(3);
CtConstructor<?> ctModelCons = ctModel.getConstructors().iterator().next();
CtMethod<?> ctModelMethod = ctModel.getMethodsByName("method").get(0);
CtMethod<?> ctModelMethod2 = ctModel.getMethodsByName("method2").get(0);
CtClass<?> ctModelB = ctModel.filterChildren(new NamedElementFilter<>(CtClass.class, "ModelB")).first();
CtTypeParameter tpA2 = ctModelB.getFormalCtTypeParameters().get(0);
CtTypeParameter tpB2 = ctModelB.getFormalCtTypeParameters().get(1);
CtTypeParameter tpC2 = ctModelB.getFormalCtTypeParameters().get(2);
CtTypeParameter tpD2 = ctModelB.getFormalCtTypeParameters().get(3);
CtConstructor<?> ctModelBCons = ctModelB.getConstructors().iterator().next();
CtMethod<?> ctModelBMethod = ctModelB.getMethodsByName("method").get(0);
// the type parameters of ErasureModelA and ErasureModelA$ModelB are same if they are on the same position.
checkIsSame(ctModel.getFormalCtTypeParameters(), ctModelB.getFormalCtTypeParameters(), true);
// the type parameters of ErasureModelA#constructor and ErasureModelA$ModelB constructor are same, because constructors has same formal type parameters
// https://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.4.4
checkIsSame(ctModelCons.getFormalCtTypeParameters(), ctModelBCons.getFormalCtTypeParameters(), true);
// the type parameters of ctModel ErasureModelA#method and ErasureModelA$ModelB#method are same if they are on the same position.
checkIsSame(ctModelMethod.getFormalCtTypeParameters(), ctModelBMethod.getFormalCtTypeParameters(), true);
// the type parameters of ctModel ErasureModelA#constructor and ErasureModelA$ModelB#method are never same, because they have different type of scope (Method!=Constructor)
checkIsSame(ctModelCons.getFormalCtTypeParameters(), ctModelBMethod.getFormalCtTypeParameters(), false);
// the type parameters of ctModel ErasureModelA#method and ErasureModelA#method2 are same, because they have same formal type parameters
// https://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.4.4
checkIsSame(ctModelMethod.getFormalCtTypeParameters(), ctModelMethod2.getFormalCtTypeParameters(), true);
CtClass<?> ctModelC = ctModel.filterChildren(new NamedElementFilter<>(CtClass.class, "ModelC")).first();
}
use of spoon.reflect.visitor.filter.NamedElementFilter in project spoon by INRIA.
the class CtTypeTest method testIsSubTypeOfonTypeReferences.
@Test
public void testIsSubTypeOfonTypeReferences() throws Exception {
final Launcher launcher = new Launcher();
launcher.setArgs(new String[] { "-c" });
launcher.addInputResource("./src/test/java/spoon/test/ctType/testclasses/SubtypeModel.java");
launcher.buildModel();
Factory factory = launcher.getFactory();
CtType<?> oCtType = factory.Class().get("spoon.test.ctType.testclasses.SubtypeModel");
CtMethod<?> O_FooMethod = oCtType.filterChildren(new NamedElementFilter<>(CtMethod.class, "foo")).first();
Map<String, CtTypeReference<?>> nameToTypeRef = new HashMap<>();
O_FooMethod.filterChildren(new TypeFilter<>(CtLocalVariable.class)).forEach((CtLocalVariable var) -> {
nameToTypeRef.put(var.getSimpleName(), var.getType());
});
int[] count = new int[1];
O_FooMethod.filterChildren(new TypeFilter<>(CtAssignment.class)).forEach((CtAssignment ass) -> {
for (CtComment comment : ass.getComments()) {
checkIsNotSubtype(comment, nameToTypeRef);
count[0]++;
}
;
count[0]++;
checkIsSubtype(((CtVariableAccess) ass.getAssigned()).getVariable().getType(), ((CtVariableAccess) ass.getAssignment()).getVariable().getType(), nameToTypeRef);
});
assertTrue(count[0] > (9 * 8));
}
use of spoon.reflect.visitor.filter.NamedElementFilter in project spoon by INRIA.
the class ControlTest method testModelBuildingFor.
@Test
public void testModelBuildingFor() throws Exception {
CtType<?> type = build("spoon.test.control.testclasses", "Fors");
assertEquals("Fors", type.getSimpleName());
List<CtFor> fors = type.getElements(new TypeFilter<CtFor>(CtFor.class));
assertEquals(4, fors.size());
CtMethod<?> normalFor = type.getElements(new NamedElementFilter<>(CtMethod.class, "normalFor")).get(0);
CtFor firstFor = (CtFor) normalFor.getBody().getStatements().get(0);
assertEquals("int i = 0", firstFor.getForInit().get(0).toString());
assertEquals("i < 2", firstFor.getExpression().toString());
assertEquals("i++", firstFor.getForUpdate().get(0).toString());
CtMethod<?> empty1 = type.getElements(new NamedElementFilter<>(CtMethod.class, "empty1")).get(0);
CtFor empty1For = (CtFor) empty1.getBody().getStatements().get(1);
assertEquals("i = 0", empty1For.getForInit().get(0).toString());
// TODO: is it good to return null??
// I'm not sure I want to specify this
// I would prefer to add a fake null object that is printed as empty in
// the output
assertNull(empty1For.getExpression());
assertEquals("i++", empty1For.getForUpdate().get(0).toString());
}
use of spoon.reflect.visitor.filter.NamedElementFilter in project spoon by INRIA.
the class GenericsTest method testMethodTypingContextAdaptMethod.
@Test
public void testMethodTypingContextAdaptMethod() 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);
// represents <C> void eatMe(A paramA, B paramB, C paramC){}
CtMethod<?> trLunch_eatMe = ctClassLunch.filterChildren(new NamedElementFilter<>(CtMethod.class, "eatMe")).first();
CtClass<?> ctClassWeddingLunch = factory.Class().get(WeddingLunch.class);
ClassTypingContext ctcWeddingLunch = new ClassTypingContext(ctClassWeddingLunch);
// we all analyze new methods
final MethodTypingContext methodSTH = new MethodTypingContext().setClassTypingContext(ctcWeddingLunch);
// contract: method can be adapted only using MethodTypingContext
methodSTH.setMethod(trLunch_eatMe);
CtMethod<?> adaptedLunchEatMe = (CtMethod<?>) methodSTH.getAdaptationScope();
// contract: adapting of method declared in different scope, returns new method
assertTrue(adaptedLunchEatMe != trLunch_eatMe);
// check that new method is adapted correctly
// is declared in correct class
assertSame(ctClassWeddingLunch, adaptedLunchEatMe.getDeclaringType());
// is not member of the same class (WeddingLunch)
for (CtTypeMember typeMember : ctClassWeddingLunch.getTypeMembers()) {
assertFalse(adaptedLunchEatMe == typeMember);
}
// the name is the same
assertEquals("eatMe", adaptedLunchEatMe.getSimpleName());
// it has the same number of of formal type parameters
assertEquals(1, adaptedLunchEatMe.getFormalCtTypeParameters().size());
assertEquals("C", adaptedLunchEatMe.getFormalCtTypeParameters().get(0).getQualifiedName());
// parameters are correct
assertEquals(3, adaptedLunchEatMe.getParameters().size());
// "A paramA" becomes "X paramA" becomes Lunch%A corresponds to X in WeddingLunch
assertEquals("X", adaptedLunchEatMe.getParameters().get(0).getType().getQualifiedName());
// B paramB becomes Tacos becomes Lunch%B corresponds to Tacos in WeddingLunch (class WeddingLunch<X> extends CelebrationLunch<Tacos, Paella, X>)
assertEquals(Tacos.class.getName(), adaptedLunchEatMe.getParameters().get(1).getType().getQualifiedName());
// "C paramC" stays "C paramC"
assertEquals("C", adaptedLunchEatMe.getParameters().get(2).getType().getQualifiedName());
// contract: adapting of adapted method returns input method
methodSTH.setMethod(adaptedLunchEatMe);
assertSame(adaptedLunchEatMe, methodSTH.getAdaptationScope());
}
use of spoon.reflect.visitor.filter.NamedElementFilter in project spoon by INRIA.
the class GenericsTest method testMethodTypingContext.
@Test
public void testMethodTypingContext() throws Exception {
Factory factory = build(new File("src/test/java/spoon/test/generics/testclasses"));
CtClass<?> ctClassWeddingLunch = factory.Class().get(WeddingLunch.class);
CtMethod<?> trWeddingLunch_eatMe = ctClassWeddingLunch.filterChildren(new NamedElementFilter<>(CtMethod.class, "eatMe")).first();
MethodTypingContext methodSTH = new MethodTypingContext().setMethod(trWeddingLunch_eatMe);
// contract: the method typing context provides its scope
assertSame(trWeddingLunch_eatMe, methodSTH.getAdaptationScope());
CtClass<?> ctClassLunch = factory.Class().get(Lunch.class);
CtMethod<?> trLunch_eatMe = ctClassLunch.filterChildren(new NamedElementFilter<>(CtMethod.class, "eatMe")).first();
CtInvocation<?> invokeReserve = factory.Class().get(CelebrationLunch.class).filterChildren(new TypeFilter<>(CtInvocation.class)).select((CtInvocation i) -> "reserve".equals(i.getExecutable().getSimpleName())).first();
MethodTypingContext methodReserveTC = new MethodTypingContext().setInvocation(invokeReserve);
// contract: the method typing context provides its scope
assertSame(invokeReserve.getExecutable().getDeclaration(), methodReserveTC.getAdaptationScope());
// check that MethodTypingContext made from invocation knows actual type arguments of method and all declaring types
// 1) check method actual type argument
CtMethod<?> methodReserve = (CtMethod<?>) invokeReserve.getExecutable().getDeclaration();
CtTypeParameter methodReserve_S = methodReserve.getFormalCtTypeParameters().get(0);
assertEquals("S", methodReserve_S.getSimpleName());
assertEquals("spoon.test.generics.testclasses.Tacos", methodReserveTC.adaptType(methodReserve_S).getQualifiedName());
// 2) check actual type arguments of declaring type `Section`
CtClass classSection = (CtClass) methodReserve.getDeclaringType();
assertEquals("spoon.test.generics.testclasses.CelebrationLunch$WeddingLunch$Section", classSection.getQualifiedName());
CtTypeParameter classSection_Y = classSection.getFormalCtTypeParameters().get(0);
assertEquals("Y", classSection_Y.getSimpleName());
assertEquals("spoon.test.generics.testclasses.Paella", methodReserveTC.adaptType(classSection_Y).getQualifiedName());
// 3) check actual type arguments of declaring type `WeddingLunch`
CtClass classWeddingLunch = (CtClass) classSection.getDeclaringType();
assertEquals("spoon.test.generics.testclasses.CelebrationLunch$WeddingLunch", classWeddingLunch.getQualifiedName());
CtTypeParameter classWeddingLunch_X = classWeddingLunch.getFormalCtTypeParameters().get(0);
assertEquals("X", classWeddingLunch_X.getSimpleName());
assertEquals("spoon.test.generics.testclasses.Mole", methodReserveTC.adaptType(classWeddingLunch_X).getQualifiedName());
// 4) check actual type arguments of declaring type `CelebrationLunch`
CtClass classCelebrationLunch = (CtClass) classWeddingLunch.getDeclaringType();
assertEquals("spoon.test.generics.testclasses.CelebrationLunch", classCelebrationLunch.getQualifiedName());
CtTypeParameter classCelebrationLunch_K = classCelebrationLunch.getFormalCtTypeParameters().get(0);
CtTypeParameter classCelebrationLunch_L = classCelebrationLunch.getFormalCtTypeParameters().get(1);
CtTypeParameter classCelebrationLunch_M = classCelebrationLunch.getFormalCtTypeParameters().get(2);
assertEquals("K", classCelebrationLunch_K.getSimpleName());
assertEquals("L", classCelebrationLunch_L.getSimpleName());
assertEquals("M", classCelebrationLunch_M.getSimpleName());
assertEquals("spoon.test.generics.testclasses.Tacos", methodReserveTC.adaptType(classCelebrationLunch_K).getQualifiedName());
assertEquals("spoon.test.generics.testclasses.Paella", methodReserveTC.adaptType(classCelebrationLunch_L).getQualifiedName());
assertEquals("spoon.test.generics.testclasses.Mole", methodReserveTC.adaptType(classCelebrationLunch_M).getQualifiedName());
// method->Section->WeddingLunch->CelebrationLunch
GenericTypeAdapter celebrationLunchTC = methodReserveTC.getEnclosingGenericTypeAdapter().getEnclosingGenericTypeAdapter().getEnclosingGenericTypeAdapter();
assertEquals("java.lang.Integer", celebrationLunchTC.adaptType(classCelebrationLunch_K).getQualifiedName());
assertEquals("java.lang.Long", celebrationLunchTC.adaptType(classCelebrationLunch_L).getQualifiedName());
assertEquals("java.lang.Double", celebrationLunchTC.adaptType(classCelebrationLunch_M).getQualifiedName());
}
Aggregations