Search in sources :

Example 6 with Filter

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

CtElement (spoon.reflect.declaration.CtElement)6 CtType (spoon.reflect.declaration.CtType)4 Filter (spoon.reflect.visitor.Filter)4 ArrayList (java.util.ArrayList)3 Test (org.junit.Test)3 SpoonException (spoon.SpoonException)3 CtLocalVariable (spoon.reflect.code.CtLocalVariable)3 CtStatement (spoon.reflect.code.CtStatement)3 CtField (spoon.reflect.declaration.CtField)3 Arrays (java.util.Arrays)2 Collection (java.util.Collection)2 Comparator (java.util.Comparator)2 Iterator (java.util.Iterator)2 List (java.util.List)2 TreeSet (java.util.TreeSet)2 Predicate (java.util.function.Predicate)2 Collectors (java.util.stream.Collectors)2 Assert.assertArrayEquals (org.junit.Assert.assertArrayEquals)2 Assert.assertEquals (org.junit.Assert.assertEquals)2 Assert.assertFalse (org.junit.Assert.assertFalse)2