Skip to content

Commit

Permalink
add query factory and use it
Browse files Browse the repository at this point in the history
  • Loading branch information
pvojtechovsky committed Jan 8, 2017
1 parent c6d8cb8 commit 2c375e2
Show file tree
Hide file tree
Showing 5 changed files with 82 additions and 9 deletions.
3 changes: 3 additions & 0 deletions src/main/java/spoon/reflect/factory/Factory.java
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,9 @@ public interface Factory {

ConstructorFactory Constructor(); // used 3 times

QueryFactory Query();


/**
* @see CodeFactory#createAnnotation(CtTypeReference)
*/
Expand Down
13 changes: 13 additions & 0 deletions src/main/java/spoon/reflect/factory/FactoryImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,19 @@ public TypeFactory Type() {
return type;
}

private transient QueryFactory query;

/**
* The query sub-factory.
*/
@Override
public QueryFactory Query() {
if (query == null) {
query = new QueryFactory(this);
}
return query;
}

/**
* A constructor that takes the parent factory
*/
Expand Down
51 changes: 51 additions & 0 deletions src/main/java/spoon/reflect/factory/QueryFactory.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/**
* Copyright (C) 2006-2016 INRIA and contributors
* Spoon - http://spoon.gforge.inria.fr/
*
* This software is governed by the CeCILL-C License under French law and
* abiding by the rules of distribution of free software. You can use, modify
* and/or redistribute the software under the terms of the CeCILL-C license as
* circulated by CEA, CNRS and INRIA at http://www.cecill.info.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the CeCILL-C License for more details.
*
* The fact that you are presently reading this means that you have had
* knowledge of the CeCILL-C license and that you accept its terms.
*/
package spoon.reflect.factory;

import spoon.reflect.visitor.chain.CtQuery;
import spoon.reflect.visitor.chain.CtQueryImpl;

/**
* A factory to create some queries on the Spoon metamodel.
*/
public class QueryFactory extends SubFactory {

/**
* Creates the evaluation factory.
*/
public QueryFactory(Factory factory) {
super(factory);
}

/**
* Creates a unbound query. Use {@link CtQuery#setInput(Object...)}
* before {@link CtQuery#forEach(spoon.reflect.visitor.chain.CtConsumer)}
* or {@link CtQuery#list()} is called
*/
public CtQuery createQuery() {
return new CtQueryImpl();
}

/**
* Creates a bound query. Use directly
* {@link CtQuery#forEach(spoon.reflect.visitor.chain.CtConsumer)}
* or {@link CtQuery#list()} to evaluate the query
*/
public CtQuery createQuery(Object input) {
return new CtQueryImpl(input);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@
import spoon.reflect.visitor.Filter;
import spoon.reflect.visitor.ModelConsistencyChecker;
import spoon.reflect.visitor.Query;
import spoon.reflect.visitor.chain.CtQueryImpl;
import spoon.reflect.visitor.chain.CtFunction;
import spoon.reflect.visitor.chain.CtConsumableFunction;
import spoon.reflect.visitor.chain.CtQuery;
Expand Down Expand Up @@ -261,17 +260,17 @@ public <E extends CtElement> List<E> getElements(Filter<E> filter) {

@Override
public <I> CtQuery map(CtConsumableFunction<I> queryStep) {
return new CtQueryImpl(this).map(queryStep);
return factory.Query().createQuery(this).map(queryStep);
}

@Override
public <I, R> CtQuery map(CtFunction<I, R> function) {
return new CtQueryImpl(this).map(function);
return factory.Query().createQuery(this).map(function);
}

@Override
public <P extends CtElement> CtQuery filterChildren(Filter<P> predicate) {
return new CtQueryImpl(this).filterChildren(predicate);
return factory.Query().createQuery(this).filterChildren(predicate);
}

public <T extends CtReference> List<T> getReferences(Filter<T> filter) {
Expand Down
17 changes: 12 additions & 5 deletions src/test/java/spoon/test/filters/FilterTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -629,7 +629,7 @@ public void testElementMapConsumableFunction() throws Exception {
@Test
public void testElementMapFunctionArray() throws Exception {
final Launcher launcher = new Launcher();
CtQueryImpl q = new CtQueryImpl().map((String s)->new String[]{"a", null, s});
CtQuery q = launcher.getFactory().Query().createQuery().map((String s)->new String[]{"a", null, s});
List<String> list = q.setInput(null).list();
assertEquals(0, list.size());

Expand All @@ -641,7 +641,7 @@ public void testElementMapFunctionArray() throws Exception {
@Test
public void testElementMapFunctionNull() throws Exception {
final Launcher launcher = new Launcher();
CtQueryImpl q = new CtQueryImpl().map((String s)->null);
CtQuery q = launcher.getFactory().Query().createQuery().map((String s)->null);
List<String> list = q.setInput(null).list();
assertEquals(0, list.size());

Expand Down Expand Up @@ -701,7 +701,7 @@ class Context {

CtClass<?> cls = launcher.getFactory().Class().get(Tacos.class);
CtClass<?> cls2 = launcher.getFactory().Class().get(Tostada.class);
CtQueryImpl q = new CtQueryImpl().map((CtClass<?> c, CtConsumer<Object> out)->out.accept(c.getSimpleName()));
CtQueryImpl q = (CtQueryImpl)launcher.getFactory().Query().createQuery().map((CtClass<?> c, CtConsumer<Object> out)->out.accept(c.getSimpleName()));
q.evaluate(cls, (String name)->{
context.count++;
assertEquals(cls.getSimpleName(), name);
Expand Down Expand Up @@ -730,8 +730,15 @@ class Context {
Context context = new Context();

CtClass<?> cls = launcher.getFactory().Class().get(Tacos.class);
CtQueryImpl allChildPublicClasses = new CtQueryImpl().filterChildren((CtClass clazz)->clazz.hasModifier(ModifierKind.PUBLIC));
launcher.getFactory().Package().getRootPackage().map((in,out)->allChildPublicClasses.evaluate(in,out)).forEach((CtElement clazz)->{
CtQuery allChildPublicClasses = (CtQueryImpl)launcher.getFactory().Query().createQuery().filterChildren((CtClass clazz)->clazz.hasModifier(ModifierKind.PUBLIC));
launcher.getFactory().Package().getRootPackage().map((in,out)->allChildPublicClasses.setInput(in).forEach(out)).forEach((CtElement clazz)->{
context.count++;
assertTrue(clazz instanceof CtClass);
assertTrue(((CtClass<?>)clazz).hasModifier(ModifierKind.PUBLIC));
});
assertTrue(context.count>0);
context.count=0;
launcher.getFactory().Package().getRootPackage().map((in,out)->((CtQueryImpl)allChildPublicClasses).evaluate(in,out)).forEach((CtElement clazz)->{
context.count++;
assertTrue(clazz instanceof CtClass);
assertTrue(((CtClass<?>)clazz).hasModifier(ModifierKind.PUBLIC));
Expand Down

0 comments on commit 2c375e2

Please sign in to comment.