Skip to content

Commit

Permalink
feature CtQuery#select(Filter)
Browse files Browse the repository at this point in the history
  • Loading branch information
pvojtechovsky committed Jan 21, 2017
1 parent 892e129 commit 39b76d2
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 0 deletions.
10 changes: 10 additions & 0 deletions src/main/java/spoon/reflect/visitor/chain/CtQuery.java
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,16 @@ public interface CtQuery extends CtQueryable {
@Override
<R extends CtElement> CtQuery filterChildren(Filter<R> filter);

/**
* The matched element for which (filter.matches(element)==true) is sent to the next query step.
*
* The elements which throw {@link ClassCastException} during {@link Filter#matches(CtElement)}
* are considered as **not matching**, ie. are excluded.
*
* @param filter used to detect if input element can pass to next query step
* @return this to support fluent API
*/
<R extends CtElement> CtQuery select(Filter<R> filter);

/**
* Query elements based on a function, the behavior depends on the return type of the function.
Expand Down
12 changes: 12 additions & 0 deletions src/main/java/spoon/reflect/visitor/chain/CtQueryImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,18 @@ public <R extends CtElement> CtQueryImpl filterChildren(Filter<R> filter) {
return this;
}

@Override
public <R extends CtElement> CtQueryImpl select(final Filter<R> filter) {
map(new CtFunction<R, Boolean>() {
@Override
public Boolean apply(R input) {
return filter.matches(input);
}
});
stepFailurePolicy(QueryFailurePolicy.IGNORE);
return this;
}

/**
* Evaluates this query, ignoring bound input - if any
*
Expand Down
14 changes: 14 additions & 0 deletions src/test/java/spoon/test/filters/FilterTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -534,6 +534,20 @@ class Context {
assertTrue(context.count>0);
}

@Test
public void testFilterQueryStep() 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();

//Contract: the filter(Filter) can be used to detect if input of query step should pass to next query step.
List<CtElement> realList = launcher.getFactory().Package().getRootPackage().filterChildren(e->{return true;}).select(new TypeFilter<>(CtClass.class)).list();
List<CtElement> expectedList = launcher.getFactory().Package().getRootPackage().filterChildren(new TypeFilter<>(CtClass.class)).list();
assertArrayEquals(expectedList.toArray(), realList.toArray());
assertTrue(expectedList.size()>0);
}

@Test
public void testFunctionQueryStep() throws Exception {
final Launcher launcher = new Launcher();
Expand Down

0 comments on commit 39b76d2

Please sign in to comment.