public class VariableScopeVisitor
extends ClassCodeVisitorSupport
Initializes the variable scopes for an AST.
For JEP 394 instanceof pattern variables (GROOVY-12242), this
class is the single authoritative source of scope decisions.
InstanceofFlowBindings answers which pattern variables are definitely
bound on each control-flow path; this visitor:
@TypeChecked enforces at compile
time); and| Modifiers | Name | Description |
|---|---|---|
static class |
VariableScopeVisitor.InstanceofFlowBindings |
Flow-sensitive result for JEP 394 instanceof pattern
bindings (GROOVY-12242) — the Groovy equivalent of the JLS §6.3.1
“introduced by” sets. |
| Constructor and description |
|---|
VariableScopeVisitor(SourceUnit source, boolean recurseInnerClasses)Creates a new variable scope visitor with optional recursion into inner classes. |
VariableScopeVisitor(SourceUnit source)Creates a new variable scope visitor that does not recurse into inner classes. |
| Type Params | Return Type | Name and description |
|---|---|---|
|
protected SourceUnit |
getSourceUnit()* Provides access to the SourceUnit for error reporting during visitation. * Implementations must override this method. * *
|
|
public void |
prepareVisit(ClassNode node)Sets the current class node context. |
|
protected void |
visitAnnotation(AnnotationNode node)* Visits an individual AnnotationNode, traversing all member expression values. * Subclasses may override to perform custom annotation processing. * *
|
|
public void |
visitArrayExpression(ArrayExpression expression)* Visits an ArrayExpression, traversing element expressions and size expressions. * *
|
|
public void |
visitAssertStatement(AssertStatement statement)* Visits an AssertStatement, invoking the statement hook before parent traversal. * *
|
|
public void |
visitBinaryExpression(BinaryExpression expression)Visits binary expressions with flow-aware scoping for && / ||
so pattern variables follow Java short-circuit rules (GROOVY-12242 / JEP 394):
|
|
public void |
visitBlockStatement(BlockStatement statement)* Visits a BlockStatement, invoking the statement hook before parent traversal. * *
|
|
public void |
visitCastExpression(CastExpression expression)* Visits a CastExpression, traversing the operand expression. * *
|
|
public void |
visitCatchStatement(CatchStatement statement)* Visits a CatchStatement, processing variable annotations and invoking the statement hook. * *
|
|
public void |
visitClass(ClassNode node)* Visits a ClassNode, processing its annotations, package, imports, contents, and object initializers. * *
|
|
public void |
visitClassExpression(ClassExpression expression)* Visits a ClassExpression. No traversal is performed as class expressions contain no child expressions. * *
|
|
public void |
visitClosureExpression(ClosureExpression expression)* Visits a ClosureExpression with annotation processing, traversing parameter annotations * before delegating to parent traversal. * *
|
|
public void |
visitConstantExpression(ConstantExpression expression)* Visits a ConstantExpression. No traversal is performed as constants contain no child expressions. * *
|
|
public void |
visitConstructorCallExpression(ConstructorCallExpression expression)* Visits a ConstructorCallExpression, traversing its argument list. * *
|
|
protected void |
visitConstructorOrMethod(MethodNode node, boolean isConstructor)* Visits a constructor or method node (implementation detail for both visit methods). * Processes the node's annotations, all parameter annotations, and code block. * *
|
|
public void |
visitDeclarationExpression(DeclarationExpression expression)* Visits a DeclarationExpression with annotation processing, traversing expression annotations * before delegating to parent traversal. * *
|
|
public void |
visitDoWhileLoop(DoWhileStatement statement)Visits a do/while loop (GROOVY-12242). |
|
public void |
visitExpressionStatement(ExpressionStatement statement)* Visits an ExpressionStatement, invoking the statement hook before parent traversal. * *
|
|
public void |
visitField(FieldNode node)* Visits a FieldNode, processing its annotations and initial value expression if present. * *
|
|
public void |
visitFieldExpression(FieldExpression expression)* Visits a FieldExpression. No traversal is performed as field expressions contain no child expressions. * *
|
|
public void |
visitForLoop(ForStatement statement)* Visits a ForStatement, invoking statement hooks and processing loop variable annotations. * *
|
|
public void |
visitIfElse(IfStatement statement)Visits an if/else statement, establishing correct
lexical scopes for JEP 394 instanceof pattern variables
(GROOVY-12242) and attaching InstanceofFlowBindings metadata so
later phases need not re-derive the flow analysis. |
|
public void |
visitMethodCallExpression(MethodCallExpression expression)* Visits a MethodCallExpression, traversing the object expression, * method expression, and argument list. * *
|
|
public void |
visitProperty(PropertyNode node)* Visits a PropertyNode, processing its annotations, initial value expression, * and getter/setter blocks if present. * *
|
|
public void |
visitPropertyExpression(PropertyExpression expression)* Visits a PropertyExpression, traversing the object and property name expressions. * *
|
|
public void |
visitReturnStatement(ReturnStatement statement)* Visits a ReturnStatement, invoking the statement hook before parent traversal. * *
|
|
public void |
visitSwitch(SwitchStatement statement)* Visits a SwitchStatement, invoking the statement hook before parent traversal. * *
|
|
public void |
visitTernaryExpression(TernaryExpression expression)Visits a ternary / Elvis expression with flow scoping for pattern variables: true-path bindings are in scope in the then-branch; false-path bindings in the else-branch (GROOVY-12242 / JEP 394). |
|
public void |
visitVariableExpression(VariableExpression expression)* Visits a VariableExpression. No traversal is performed as variable expressions contain no child expressions. * *
|
|
public void |
visitWhileLoop(WhileStatement statement)Visits a while loop with partial JEP 394 flow scoping
for instanceof pattern variables (GROOVY-12242). |
Creates a new variable scope visitor with optional recursion into inner classes.
source - the source unit being processedrecurseInnerClasses - whether to recurse into inner classesCreates a new variable scope visitor that does not recurse into inner classes.
source - the source unit being processed* Provides access to the SourceUnit for error reporting during visitation. * Implementations must override this method. * *
Sets the current class node context.
* Visits an individual AnnotationNode, traversing all member expression values. * Subclasses may override to perform custom annotation processing. * *
node - the annotation node to visit* Visits an ArrayExpression, traversing element expressions and size expressions. * *
expression - the array expression* Visits an AssertStatement, invoking the statement hook before parent traversal. * *
statement - the assert statement to visit Visits binary expressions with flow-aware scoping for && / ||
so pattern variables follow Java short-circuit rules (GROOVY-12242 / JEP 394):
a && b — true-path bindings of a are in scope in ba || b — true-path bindings of a are not in scope in b;
false-path bindings of a aree !instanceof T t / !(e instanceof T t) — pattern declare is
isolated on the left of short-circuit ops; only flow-live sets are re-introduced* Visits a BlockStatement, invoking the statement hook before parent traversal. * *
statement - the block statement to visit* Visits a CastExpression, traversing the operand expression. * *
expression - the cast expression* Visits a CatchStatement, processing variable annotations and invoking the statement hook. * *
statement - the catch statement to visit* Visits a ClassNode, processing its annotations, package, imports, contents, and object initializers. * *
node - the class node to visit* Visits a ClassExpression. No traversal is performed as class expressions contain no child expressions. * *
expression - the class expression* Visits a ClosureExpression with annotation processing, traversing parameter annotations * before delegating to parent traversal. * *
expression - the closure expression to visit* Visits a ConstantExpression. No traversal is performed as constants contain no child expressions. * *
expression - the constant expression* Visits a ConstructorCallExpression, traversing its argument list. * *
call - the constructor call expression* Visits a constructor or method node (implementation detail for both visit methods). * Processes the node's annotations, all parameter annotations, and code block. * *
node - the method or constructor node
*isConstructor - true if node is a constructor, false if it is a method* Visits a DeclarationExpression with annotation processing, traversing expression annotations * before delegating to parent traversal. * *
expression - the declaration expression to visit Visits a do/while loop (GROOVY-12242).
The body runs before the condition, so pattern variables from the
condition are not in scope in the body (same as Java). The
condition is visited in a nested scope so short-circuit RHS works and
pattern names do not leak after the loop. Like visitWhileLoop,
there is no after-loop introduction of whenFalse bindings.
* Visits an ExpressionStatement, invoking the statement hook before parent traversal. * *
statement - the expression statement to visit* Visits a FieldNode, processing its annotations and initial value expression if present. * *
node - the field node to visit* Visits a FieldExpression. No traversal is performed as field expressions contain no child expressions. * *
expression - the field expression* Visits a ForStatement, invoking statement hooks and processing loop variable annotations. * *
statement - the for statement to visit Visits an if/else statement, establishing correct
lexical scopes for JEP 394 instanceof pattern variables
(GROOVY-12242) and attaching InstanceofFlowBindings metadata so
later phases need not re-derive the flow analysis.
Rules applied (JLS §6.3.2.2 / JEP 394):
e.whenTrue() are in scope in the then-block (S).e.whenFalse() are in scope in the else-block (T).e.whenTrue(), the var is introduced after the if-else.e.whenFalse(), the var is introduced
after the if-else.@TypeChecked
enforces the same rules at compile time; both modes share this visitor.
* Visits a MethodCallExpression, traversing the object expression, * method expression, and argument list. * *
call - the method call expression* Visits a PropertyNode, processing its annotations, initial value expression, * and getter/setter blocks if present. * *
node - the property node to visit* Visits a PropertyExpression, traversing the object and property name expressions. * *
expression - the property expression* Visits a ReturnStatement, invoking the statement hook before parent traversal. * *
statement - the return statement to visit* Visits a SwitchStatement, invoking the statement hook before parent traversal. * *
statement - the switch statement to visitVisits a ternary / Elvis expression with flow scoping for pattern variables: true-path bindings are in scope in the then-branch; false-path bindings in the else-branch (GROOVY-12242 / JEP 394). Also attaches InstanceofFlowBindings metadata for later phases.
* Visits a VariableExpression. No traversal is performed as variable expressions contain no child expressions. * *
expression - the variable expression Visits a while loop with partial JEP 394 flow scoping
for instanceof pattern variables (GROOVY-12242).
What is supported (aligned with the if-then rule for the body):
&& / ||).e.whenTrue() pattern variables are in scope in the loop body.
Intentional divergence from JLS §6.3.2.3 (while):
Groovy does not introduce e.whenFalse() after the loop when
the body cannot complete normally. Full after-loop introduction would need
definite abrupt-completion analysis of every exit path (including
break/continue of nested loops) and is left out for 6.0 —
pattern variables never leak past the loop. Documented as a deliberate
partial implementation, not an oversight.
Copyright © 2003-2026 The Apache Software Foundation. All rights reserved.