Groovy for Domain-specific Languages - Second Edition

(nextflipdebug2) #1

Integrating It All


[ 328 ]

Our starting point with this AST transformation will be a single Groovy script class
containing the DSL code. We know from earlier chapters that this means we will
have an existing class with the same name as the script file. So if we start out with
a file named Engine.groovy, we will find that the DSL script has a class in it
called engine.


That class will already have several methods and constructors in it. By the end of the
transformation process, the only part of the original class that we will make use of is
its default constructor. By the end of the transformation process, we will have added
a constructor and event methods to the original script class. We will have changed
the class so it implements a trait and we will have added several other classes to
the module.


The first step is to add the session class since this is referenced extensively in the rest
of the generated code. At this point in the book, the mechanism for constructing code
with the AST APIs should be familiar to you so I won't describe every aspect in detail
unless it is a feature we have not encountered already.


In Chapter 8, AST Transformations, the simple state pattern we implemented did
not have any methods with more than a single line of code. We were therefore
able to represent each method body with a single ExpressionStatement object.
The constructor method in the generated session class has two lines, so we
use a BlockStatement object to represent the code part of the constructor. A
BlockStatement object is simply constructed from an array of statements and a
scope object:


void buildSessionClass() {
def sessionClassNode = new AstBuilder().buildFromString
CompilePhase.SEMANTIC_ANALYSIS, true, """
class ${className}Session extends PersistableSession{
}
"""

contextClass = sessionClassNode[1]
moduleNode.addClass(sessionClassNode[1])
sessionClassName = "${className}Session"

def blockStatement = new BlockStatement([
new ExpressionStatement(
new ConstructorCallExpression(
ClassHelper.make(
PersistableSession.class
),
ArgumentListExpression.EMPTY_ARGUMENTS
)

http://www.ebook3000.com
Free download pdf