Search in sources :

Example 11 with ClassTypingContext

use of spoon.support.visitor.ClassTypingContext in project spoon by INRIA.

the class GenericsTest method testIsSameSignatureWithReferencedGenerics.

@Test
public void testIsSameSignatureWithReferencedGenerics() {
    Launcher launcher = new Launcher();
    launcher.addInputResource("./src/test/java/spoon/test/generics/testclasses2/SameSignature3.java");
    launcher.buildModel();
    CtClass ctClass = launcher.getFactory().Class().get(SameSignature3.class);
    CtMethod classMethod = (CtMethod) ctClass.getMethodsByName("visitCtConditional").get(0);
    CtType<?> iface = launcher.getFactory().Type().get("spoon.test.generics.testclasses2.ISameSignature3");
    CtMethod ifaceMethod = (CtMethod) iface.getMethodsByName("visitCtConditional").get(0);
    ClassTypingContext ctcSub = new ClassTypingContext(ctClass.getReference());
    assertTrue(ctcSub.isOverriding(classMethod, ifaceMethod));
    assertTrue(ctcSub.isOverriding(ifaceMethod, classMethod));
    assertTrue(ctcSub.isSubSignature(classMethod, ifaceMethod));
    assertTrue(ctcSub.isSubSignature(ifaceMethod, classMethod));
    assertTrue(ctcSub.isSameSignature(classMethod, ifaceMethod));
    assertTrue(ctcSub.isSameSignature(ifaceMethod, classMethod));
}
Also used : LikeCtClass(spoon.test.generics.testclasses2.LikeCtClass) CtClass(spoon.reflect.declaration.CtClass) ClassTypingContext(spoon.support.visitor.ClassTypingContext) Launcher(spoon.Launcher) CtMethod(spoon.reflect.declaration.CtMethod) MainTest(spoon.test.main.MainTest) Test(org.junit.Test)

Example 12 with ClassTypingContext

use of spoon.support.visitor.ClassTypingContext in project spoon by INRIA.

the class GenericsTest method testTypeAdapted.

@Test
public void testTypeAdapted() throws Exception {
    // contract: one can get the actual value of a generic type in a given context
    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);
    CtClass<?> ctModelB = ctModel.filterChildren(new NamedElementFilter<>(CtClass.class, "ModelB")).first();
    ClassTypingContext sth = new ClassTypingContext(ctModelB);
    // in ModelB, "A" is "A2"
    assertEquals("A2", sth.adaptType(tpA).getQualifiedName());
    // in ModelB, "B" is "B2"
    assertEquals("B2", sth.adaptType(tpB).getQualifiedName());
    // and so on and so forth
    assertEquals("C2", sth.adaptType(tpC).getQualifiedName());
    assertEquals("D2", sth.adaptType(tpD).getQualifiedName());
    CtClass<?> ctModelC = ctModel.filterChildren(new NamedElementFilter<>(CtClass.class, "ModelC")).first();
    ClassTypingContext sthC = new ClassTypingContext(ctModelC);
    assertEquals("java.lang.Integer", sthC.adaptType(tpA).getQualifiedName());
    assertEquals("java.lang.RuntimeException", sthC.adaptType(tpB).getQualifiedName());
    assertEquals("java.lang.IllegalArgumentException", sthC.adaptType(tpC).getQualifiedName());
    assertEquals("java.util.List", sthC.adaptType(tpD).getQualifiedName());
}
Also used : LikeCtClass(spoon.test.generics.testclasses2.LikeCtClass) CtClass(spoon.reflect.declaration.CtClass) ClassTypingContext(spoon.support.visitor.ClassTypingContext) CtTypeParameter(spoon.reflect.declaration.CtTypeParameter) ErasureModelA(spoon.test.ctType.testclasses.ErasureModelA) NamedElementFilter(spoon.reflect.visitor.filter.NamedElementFilter) MainTest(spoon.test.main.MainTest) Test(org.junit.Test)

Example 13 with ClassTypingContext

use of spoon.support.visitor.ClassTypingContext in project spoon by INRIA.

the class GenericsTest method testIsGenericTypeEqual.

@Test
public void testIsGenericTypeEqual() {
    Launcher launcher = new Launcher();
    launcher.addInputResource("./src/test/java/spoon/test/generics/testclasses2/LikeCtClass.java");
    launcher.addInputResource("./src/test/java/spoon/test/generics/testclasses2/LikeCtClassImpl.java");
    launcher.buildModel();
    CtType<?> ctIFace = launcher.getFactory().Interface().get(LikeCtClass.class);
    CtMethod<?> ifaceGetter = (CtMethod) ctIFace.getMethodsByName("getConstructors").get(0);
    CtMethod<?> ifaceSetter = (CtMethod) ctIFace.getMethodsByName("setConstructors").get(0);
    assertEquals(ifaceGetter.getType().toString(), ifaceSetter.getParameters().get(0).getType().toString());
    assertEquals(ifaceGetter.getType(), ifaceSetter.getParameters().get(0).getType());
    CtType<?> ctClass = launcher.getFactory().Class().get(LikeCtClassImpl.class);
    CtMethod<?> classGetter = (CtMethod) ctClass.getMethodsByName("getConstructors").get(0);
    CtMethod<?> classSetter = (CtMethod) ctClass.getMethodsByName("setConstructors").get(0);
    assertEquals(classGetter.getType().toString(), classSetter.getParameters().get(0).getType().toString());
    assertEquals(classGetter.getType(), classSetter.getParameters().get(0).getType());
    assertEquals(ifaceGetter.getType().toString(), classGetter.getType().toString());
    assertEquals(ifaceGetter.getType(), classGetter.getType());
    assertEquals(ifaceSetter.getParameters().get(0).getType().toString(), classSetter.getParameters().get(0).getType().toString());
    assertEquals(ifaceSetter.getParameters().get(0).getType(), classSetter.getParameters().get(0).getType());
    assertEquals(ifaceSetter.getParameters().get(0).getType(), classGetter.getType());
    MethodTypingContext mtc = new MethodTypingContext().setClassTypingContext(new ClassTypingContext(ctClass)).setMethod(ifaceSetter);
    CtMethod<?> adaptedMethod = (CtMethod<?>) mtc.getAdaptationScope();
    /*
		 * after adaptation of `Set<AnType<T>>` from scope of interface to scope of class there is Set<AnType<T extends Object>>
		 * Which is semantically equivalent, but Equals check does not know that
		 */
    assertEquals(adaptedMethod.getParameters().get(0).getType(), classGetter.getType());
    assertEquals(adaptedMethod.getParameters().get(0).getType(), classSetter.getParameters().get(0).getType());
    MainTest.checkParentConsistency(launcher.getFactory().getModel().getRootPackage());
    MainTest.checkParentConsistency(adaptedMethod);
}
Also used : ClassTypingContext(spoon.support.visitor.ClassTypingContext) MethodTypingContext(spoon.support.visitor.MethodTypingContext) Launcher(spoon.Launcher) CtMethod(spoon.reflect.declaration.CtMethod) MainTest(spoon.test.main.MainTest) Test(org.junit.Test)

Example 14 with ClassTypingContext

use of spoon.support.visitor.ClassTypingContext in project spoon by INRIA.

the class AllMethodsSameSignatureFunction method apply.

@Override
public void apply(final CtExecutable<?> targetExecutable, final CtConsumer<Object> outputConsumer) {
    // prepare filter for lambda expression. It will be configured by the algorithm below
    final LambdaFilter lambdaFilter = new LambdaFilter();
    final CtQuery lambdaQuery = targetExecutable.getFactory().getModel().filterChildren(lambdaFilter);
    // the to be searched method
    CtMethod<?> targetMethod;
    if (targetExecutable instanceof CtLambda) {
        // the input is lambda
        if (includingSelf && includingLambdas) {
            outputConsumer.accept(targetExecutable);
            if (query.isTerminated()) {
                return;
            }
        }
        // in case of lambda, the target method is the method implemented by lambda
        targetMethod = ((CtLambda<?>) targetExecutable).getOverriddenMethod();
        outputConsumer.accept(targetMethod);
        if (query.isTerminated()) {
            return;
        }
        // the input is the lambda expression, which was already returned or doesn't have to be returned at all because includingSelf == false
        // add extra filter into lambdaQuery which skips that input lambda expression
        lambdaQuery.select(new Filter<CtLambda<?>>() {

            @Override
            public boolean matches(CtLambda<?> lambda) {
                return targetExecutable != lambda;
            }
        });
    } else if (targetExecutable instanceof CtMethod) {
        if (includingSelf) {
            outputConsumer.accept(targetExecutable);
            if (query.isTerminated()) {
                return;
            }
        }
        targetMethod = (CtMethod<?>) targetExecutable;
    } else {
        // CtConstructor or CtAnonymousExecutable never overrides other executable. We are done
        if (includingSelf) {
            outputConsumer.accept(targetExecutable);
        }
        return;
    }
    final List<CtMethod<?>> targetMethods = new ArrayList<>();
    targetMethods.add(targetMethod);
    CtType<?> declaringType = targetMethod.getDeclaringType();
    lambdaFilter.addImplementingInterface(declaringType);
    // search for all declarations and implementations of this method in sub and super classes and interfaces of all related hierarchies.
    class Context {

        boolean haveToSearchForSubtypes;
    }
    final Context context = new Context();
    // at the beginning we know that we have to always search for sub types too.
    context.haveToSearchForSubtypes = true;
    // Sub inheritance hierarchy function, which remembers visited sub types and does not returns/visits them again
    final SubInheritanceHierarchyResolver subHierarchyFnc = new SubInheritanceHierarchyResolver(declaringType.getFactory().getModel().getRootPackage());
    // add hierarchy of `targetMethod` as to be checked for sub types of declaring type
    subHierarchyFnc.addSuperType(declaringType);
    // unique names of all types whose super inheritance hierarchy was searched for rootType
    Set<String> typesCheckedForRootType = new HashSet<>();
    // list of sub types whose inheritance hierarchy has to be checked
    final List<CtType<?>> toBeCheckedSubTypes = new ArrayList<>();
    // add hierarchy of `targetMethod` as to be checked for super types of declaring type
    toBeCheckedSubTypes.add(declaringType);
    while (toBeCheckedSubTypes.size() > 0) {
        for (CtType<?> subType : toBeCheckedSubTypes) {
            ClassTypingContext ctc = new ClassTypingContext(subType);
            // search for first target method from the same type inheritance hierarchy
            targetMethod = getTargetMethodOfHierarchy(targetMethods, ctc);
            // search for all methods with same signature in inheritance hierarchy of `subType`
            forEachOverridenMethod(ctc, targetMethod, typesCheckedForRootType, new CtConsumer<CtMethod<?>>() {

                @Override
                public void accept(CtMethod<?> overriddenMethod) {
                    targetMethods.add(overriddenMethod);
                    outputConsumer.accept(overriddenMethod);
                    CtType<?> type = overriddenMethod.getDeclaringType();
                    lambdaFilter.addImplementingInterface(type);
                    subHierarchyFnc.addSuperType(type);
                    // mark that new super type was added, so we have to search for sub types again
                    context.haveToSearchForSubtypes = true;
                }
            });
            if (query.isTerminated()) {
                return;
            }
        }
        toBeCheckedSubTypes.clear();
        if (context.haveToSearchForSubtypes) {
            context.haveToSearchForSubtypes = false;
            // there are some new super types, whose sub inheritance hierarchy has to be checked
            // search their inheritance hierarchy for sub types
            subHierarchyFnc.forEachSubTypeInPackage(new CtConsumer<CtType<?>>() {

                @Override
                public void accept(CtType<?> type) {
                    toBeCheckedSubTypes.add(type);
                }
            });
        }
    }
    if (includingLambdas) {
        // search for all lambdas implementing any of the found interfaces
        lambdaQuery.forEach(outputConsumer);
    }
}
Also used : ClassTypingContext(spoon.support.visitor.ClassTypingContext) ClassTypingContext(spoon.support.visitor.ClassTypingContext) CtLambda(spoon.reflect.code.CtLambda) CtQuery(spoon.reflect.visitor.chain.CtQuery) ArrayList(java.util.ArrayList) CtType(spoon.reflect.declaration.CtType) SubInheritanceHierarchyResolver(spoon.support.visitor.SubInheritanceHierarchyResolver) CtMethod(spoon.reflect.declaration.CtMethod) HashSet(java.util.HashSet)

Example 15 with ClassTypingContext

use of spoon.support.visitor.ClassTypingContext in project spoon by INRIA.

the class CtMethodImpl method getTopDefinitions.

@Override
public Collection<CtMethod<?>> getTopDefinitions() {
    List<CtMethod<?>> s = new ArrayList<>();
    // first collect potential declarations of this method in the type hierarchy
    ClassTypingContext context = new ClassTypingContext(this.getDeclaringType());
    getDeclaringType().map(new AllTypeMembersFunction(CtMethod.class)).forEach((CtMethod<?> m) -> {
        if (m != this && context.isOverriding(this, m)) {
            s.add(m);
        }
    });
    // now removing the intermediate methods for which there exists a definition upper in the hierarchy
    List<CtMethod<?>> finalMeths = new ArrayList<>(s);
    for (CtMethod m1 : s) {
        boolean m1IsIntermediate = false;
        for (CtMethod m2 : s) {
            if (context.isOverriding(m1, m2)) {
                m1IsIntermediate = true;
            }
        }
        if (!m1IsIntermediate) {
            finalMeths.add(m1);
        }
    }
    return finalMeths;
}
Also used : ClassTypingContext(spoon.support.visitor.ClassTypingContext) ArrayList(java.util.ArrayList) AllTypeMembersFunction(spoon.reflect.visitor.filter.AllTypeMembersFunction) CtMethod(spoon.reflect.declaration.CtMethod)

Aggregations

ClassTypingContext (spoon.support.visitor.ClassTypingContext)17 Test (org.junit.Test)11 MainTest (spoon.test.main.MainTest)11 CtMethod (spoon.reflect.declaration.CtMethod)10 CtClass (spoon.reflect.declaration.CtClass)6 LikeCtClass (spoon.test.generics.testclasses2.LikeCtClass)5 Launcher (spoon.Launcher)4 File (java.io.File)3 Factory (spoon.reflect.factory.Factory)3 AllTypeMembersFunction (spoon.reflect.visitor.filter.AllTypeMembersFunction)3 NamedElementFilter (spoon.reflect.visitor.filter.NamedElementFilter)3 MethodTypingContext (spoon.support.visitor.MethodTypingContext)3 ModelUtils.createFactory (spoon.testing.utils.ModelUtils.createFactory)3 ArrayList (java.util.ArrayList)2 HashSet (java.util.HashSet)2 CtTypeMember (spoon.reflect.declaration.CtTypeMember)2 CtTypeParameter (spoon.reflect.declaration.CtTypeParameter)2 CtLambda (spoon.reflect.code.CtLambda)1 CtNewClass (spoon.reflect.code.CtNewClass)1 CtReturn (spoon.reflect.code.CtReturn)1