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);
}
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);
}
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());
}
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);
}
}
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);
}
Aggregations