Package org.codehaus.groovy.ast.query
Class AstQuery<T extends ASTNode>
java.lang.Object
org.codehaus.groovy.ast.query.AstQuery<T>
- Type Parameters:
T- the node type produced by this query
A small, read-only, fluent query API over a Groovy AST subtree.
An AstQuery selects descendant nodes of a root, optionally filtered by type and by an
arbitrary predicate, and exposes terminal operations that collect or test the matches. It is a
declarative alternative to hand-writing a ClassCodeVisitorSupport subclass for the common
"find / collect / detect" cases.
import org.codehaus.groovy.ast.query.AstQuery
import org.codehaus.groovy.ast.expr.MethodCallExpression
import org.codehaus.groovy.ast.builder.AstBuilder
def code = new AstBuilder().buildFromString('foo(); bar()')[0]
assert AstQuery.from(code).descendants(MethodCallExpression).count() == 2
Traversal and pruning
By default the traversal descends through closures but does not descend into nested classes, mirroringClassCodeVisitorSupport. Use notInto(Class[]) to stop
descending at a boundary type (for example ClosureExpression) and into(Class[])
to opt back in past a default boundary. Nested classes are currently the only default boundary,
so into(ClassNode.class) is the only case in which into(Class[]) has an effect.
Notes
- The query is read-only; it never mutates the AST.
- Matches are produced in document (pre-)order.
- Instances are immutable and re-runnable: each builder method returns a new query and each
terminal performs a fresh traversal, short-circuiting where it can (for example
any()andfindFirst()).
- Since:
- 6.0.0
-
Method Summary
Modifier and TypeMethodDescriptionandSelf()Includes the root node itself as a candidate (it is excluded by default).booleanany()longcount()Selects all descendant nodes regardless of type.descendants(Class<? extends ASTNode>... types) Selects descendant nodes that are instances of any of the given types.descendants(Class<U> type) Selects descendant nodes that are instances of the given type.first()voidforEach(BiConsumer<? super T, AstContext> action) Performs the given action, with enclosing context, for each match in document order.voidPerforms the given action for each match in document order.Starts a query rooted at the given node.Opts the traversal in to descending past a default boundary.list()Collects all matches in document order.booleannone()Stops the traversal from descending into the subtrees rooted at nodes of the given types.stream()where(BiPredicate<? super T, AstContext> p) Restricts the selection to nodes satisfying a predicate that also inspects the enclosingAstContext.Restricts the selection to nodes satisfying the predicate.
-
Method Details
-
from
Starts a query rooted at the given node.- Parameters:
root- the subtree root to query; must not benull- Returns:
- a query selecting (by default) all descendants of
root
-
descendants
Selects all descendant nodes regardless of type.- Returns:
- a query over every descendant
-
descendants
Selects descendant nodes that are instances of the given type.- Type Parameters:
U- the node type- Parameters:
type- the node type to match- Returns:
- a query over descendants of that type
-
descendants
Selects descendant nodes that are instances of any of the given types.- Parameters:
types- the node types to match (logical OR)- Returns:
- a query over descendants matching any type
-
andSelf
Includes the root node itself as a candidate (it is excluded by default).- Returns:
- a query that also considers the root
-
where
Restricts the selection to nodes satisfying the predicate. Multiplewherecalls are combined with logical AND.- Parameters:
p- the predicate (a GroovyClosurecoerces to this functional type)- Returns:
- the refined query
-
where
Restricts the selection to nodes satisfying a predicate that also inspects the enclosingAstContext. Combined with logical AND with any other refinements.- Parameters:
p- the contextual predicate (a two-argument GroovyClosurecoerces to it)- Returns:
- the refined query
-
notInto
Stops the traversal from descending into the subtrees rooted at nodes of the given types. The boundary nodes themselves are still candidates; only their contents are skipped.- Parameters:
boundary- the boundary types (for exampleClosureExpression.class)- Returns:
- the query with the added boundaries
-
into
Opts the traversal in to descending past a default boundary. Currently the only default boundary is nested classes, sointo(ClassNode.class)makes the traversal recurse into inner classes.- Parameters:
types- the boundary types to descend into- Returns:
- the query with the boundaries opened
-
list
Collects all matches in document order.- Returns:
- the matching nodes
-
any
public boolean any()- Returns:
trueif at least one node matches; stops at the first match
-
none
public boolean none()- Returns:
trueif no node matches; stops at the first match
-
count
public long count()- Returns:
- the number of matching nodes
-
findFirst
- Returns:
- the first match in document order, if any; stops at the first match
-
first
- Returns:
- the first match in document order, or
null; stops at the first match
-
forEach
Performs the given action for each match in document order.- Parameters:
action- the action
-
forEach
Performs the given action, with enclosing context, for each match in document order.- Parameters:
action- the action receiving the node and itsAstContext
-
stream
- Returns:
- a sequential
Streamof the matches in document order
-