Chapter 8
[ 215 ]
| |_ConstantExpression getState
| |_ArgumentListExpression
|_ArgumentListExpression
Note how the toString() and getState() calls in the method body are nested.
The toString() method is called on the result of the getState() call. You can
imagine artificially adding scoping brackets around the code to reflect precedence of
method calling. Each of the following expressions is equivalent. The last expression
however best reflects how the individual expressions are structured in the AST. The
outer expressions will be at the top of the AST, whereas the inner expressions will be
nested in the following code:
context.state.toString()
(context).getState().toString()
((context).(getState)()).(toString)()
The last thing we need to do to the client class is add methods for each of the event
handlers. These event handler methods simply delegate calls to the equivalent event
handler in the current state so the body of a toggle() event handler method will just
be context.state.toggle():
def buildClientEventMethods() {
for (event in model.events) {
def methodStatement = new ExpressionStatement(
new MethodCallExpression(
new MethodCallExpression(
new VariableExpression('context'),
new ConstantExpression('getState'),
ArgumentListExpression.EMPTY_ARGUMENTS
),
new ConstantExpression("${event}"),
ArgumentListExpression.EMPTY_ARGUMENTS
)
)
def eventMethodNode = new MethodNode(
"${event}",
Modifier.PUBLIC,
null,
new Parameter[0],
null,
methodStatement
)
classNode.addMethod(eventMethodNode)
}
}