Search in sources :

Example 11 with CtQuery

use of spoon.reflect.visitor.chain.CtQuery in project spoon by INRIA.

the class FilterTest method testQueryInQuery.

@Test
public void testQueryInQuery() throws Exception {
    final Launcher launcher = new Launcher();
    launcher.setArgs(new String[] { "--output-type", "nooutput", "--level", "info" });
    launcher.addInputResource("./src/test/java/spoon/test/filters/testclasses");
    launcher.run();
    class Context {

        int count = 0;
    }
    Context context = new Context();
    CtClass<?> cls = launcher.getFactory().Class().get(Tacos.class);
    // first query
    CtQuery allChildPublicClasses = launcher.getFactory().Query().createQuery().filterChildren((CtClass clazz) -> clazz.hasModifier(ModifierKind.PUBLIC));
    // second query,involving the first query
    CtQuery q = launcher.getFactory().Package().getRootPackage().map((CtElement in) -> allChildPublicClasses.setInput(in).list());
    // now the assertions
    q.forEach((CtElement clazz) -> {
        context.count++;
        assertTrue(clazz instanceof CtClass);
        assertTrue(((CtClass<?>) clazz).hasModifier(ModifierKind.PUBLIC));
    });
    assertEquals(6, context.count);
    // reset
    context.count = 0;
    // again second query, but now with CtConsumableFunction
    CtQuery q2 = launcher.getFactory().Package().getRootPackage().map((CtElement in, CtConsumer<Object> out) -> allChildPublicClasses.setInput(in).forEach(out));
    // now the assertions
    q2.forEach((CtElement clazz) -> {
        context.count++;
        assertTrue(clazz instanceof CtClass);
        assertTrue(((CtClass<?>) clazz).hasModifier(ModifierKind.PUBLIC));
    });
    assertEquals(6, context.count);
    // reset
    context.count = 0;
    // again second query, but with low-level circuitry thanks to cast
    CtQuery q3 = launcher.getFactory().Package().getRootPackage().map((in, out) -> ((CtQueryImpl) allChildPublicClasses).evaluate(in, out));
    // now the assertions
    q3.forEach((CtElement clazz) -> {
        context.count++;
        assertTrue(clazz instanceof CtClass);
        assertTrue(((CtClass<?>) clazz).hasModifier(ModifierKind.PUBLIC));
    });
    assertEquals(6, context.count);
}
Also used : CtClass(spoon.reflect.declaration.CtClass) CtElement(spoon.reflect.declaration.CtElement) CtQuery(spoon.reflect.visitor.chain.CtQuery) Launcher(spoon.Launcher) CtConsumer(spoon.reflect.visitor.chain.CtConsumer) Test(org.junit.Test)

Example 12 with CtQuery

use of spoon.reflect.visitor.chain.CtQuery in project spoon by INRIA.

the class FilterTest method testQueryStepScannWithConsumer.

@Test
public void testQueryStepScannWithConsumer() throws Exception {
    final Launcher launcher = new Launcher();
    launcher.setArgs(new String[] { "--output-type", "nooutput" });
    launcher.addInputResource("./src/test/java/spoon/test/filters/testclasses");
    launcher.run();
    class Context {

        int counter = 0;
    }
    Context context = new Context();
    CtQuery l_qv = launcher.getFactory().getModel().filterChildren(new TypeFilter<>(CtClass.class));
    assertEquals(0, context.counter);
    l_qv.forEach(cls -> {
        assertTrue(cls instanceof CtClass);
        context.counter++;
    });
    assertTrue(context.counter > 0);
}
Also used : CtClass(spoon.reflect.declaration.CtClass) CtQuery(spoon.reflect.visitor.chain.CtQuery) Launcher(spoon.Launcher) Test(org.junit.Test)

Example 13 with CtQuery

use of spoon.reflect.visitor.chain.CtQuery in project spoon by INRIA.

the class FilterTest method testElementMapFunctionNull.

@Test
public void testElementMapFunctionNull() throws Exception {
    // contract: when a function returns null, it is discarded at the next step
    final Launcher launcher = new Launcher();
    CtQuery q = launcher.getFactory().Query().createQuery().map((String s) -> null);
    List<String> list = q.setInput("c").list();
    assertEquals(0, list.size());
}
Also used : CtQuery(spoon.reflect.visitor.chain.CtQuery) Launcher(spoon.Launcher) Test(org.junit.Test)

Example 14 with CtQuery

use of spoon.reflect.visitor.chain.CtQuery 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 CtQuery

use of spoon.reflect.visitor.chain.CtQuery in project spoon by INRIA.

the class LocalVariableReferenceFunction method apply.

@Override
public void apply(final CtElement scope, CtConsumer<Object> outputConsumer) {
    CtVariable<?> var = targetVariable;
    if (var == null) {
        if (variableClass.isInstance(scope)) {
            var = (CtVariable<?>) scope;
        } else {
            throw new SpoonException("The input of " + getClass().getSimpleName() + " must be a " + variableClass.getSimpleName() + " but is " + scope.getClass().getSimpleName());
        }
    }
    final CtVariable<?> variable = var;
    final String simpleName = variable.getSimpleName();
    // the context which knows whether we are scanning in scope of local type or not
    final Context context = new Context();
    CtQuery scopeQuery;
    if (scope == variable) {
        // we are starting search from local variable declaration
        scopeQuery = createScopeQuery(variable, scope, context);
    } else {
        // we are starting search later, somewhere deep in scope of variable declaration
        final CtElement variableParent = variable.getParent();
        /*
			 * search in parents of searching scope for the variableParent
			 * 1) to check that scope is a child of variableParent
			 * 2) to detect if there is an local class between variable declaration and scope
			 */
        if (scope.map(new ParentFunction()).select(new Filter<CtElement>() {

            @Override
            public boolean matches(CtElement element) {
                if (element instanceof CtType) {
                    // detected that the search scope is in local class declared in visibility scope of variable
                    context.nrTypes++;
                }
                return variableParent == element;
            }
        }).first() == null) {
            // the scope is not under children of localVariable
            throw new SpoonException("Cannot search for references of variable in wrong scope.");
        }
        // search in all children of the scope element
        scopeQuery = scope.map(new CtScannerFunction().setListener(context));
    }
    scopeQuery.select(new Filter<CtElement>() {

        @Override
        public boolean matches(CtElement element) {
            if (variableReferenceClass.isInstance(element)) {
                CtVariableReference<?> varRef = (CtVariableReference<?>) element;
                if (simpleName.equals(varRef.getSimpleName())) {
                    // we have found a variable reference of required type in visibility scope of targetVariable
                    if (context.hasLocalType()) {
                        // so finally check that found variable reference is really a reference to target variable
                        return variable == varRef.getDeclaration();
                    }
                    // else we can be sure that found reference is reference to variable
                    return true;
                }
            }
            return false;
        }
    }).forEach(outputConsumer);
}
Also used : CtVariableReference(spoon.reflect.reference.CtVariableReference) SpoonException(spoon.SpoonException) CtElement(spoon.reflect.declaration.CtElement) CtQuery(spoon.reflect.visitor.chain.CtQuery) CtType(spoon.reflect.declaration.CtType) Filter(spoon.reflect.visitor.Filter)

Aggregations

CtQuery (spoon.reflect.visitor.chain.CtQuery)16 Test (org.junit.Test)10 Launcher (spoon.Launcher)10 CtType (spoon.reflect.declaration.CtType)7 CtClass (spoon.reflect.declaration.CtClass)6 CtElement (spoon.reflect.declaration.CtElement)5 CtMethod (spoon.reflect.declaration.CtMethod)5 HashSet (java.util.HashSet)3 CtTypeReference (spoon.reflect.reference.CtTypeReference)3 ArrayList (java.util.ArrayList)2 SpoonException (spoon.SpoonException)2 CtField (spoon.reflect.declaration.CtField)2 CtQueryImpl (spoon.reflect.visitor.chain.CtQueryImpl)2 ArrayDeque (java.util.ArrayDeque)1 Arrays (java.util.Arrays)1 Collections (java.util.Collections)1 List (java.util.List)1 Set (java.util.Set)1 Collectors (java.util.stream.Collectors)1 MatcherAssert.assertThat (org.hamcrest.MatcherAssert.assertThat)1