Over a million developers have joined DZone.

The True and False of Groovy's AST Builder

· Java Zone

Learn more about how the Java language, tools and frameworks have been the foundation of countless enterprise systems, brought to you in partnership with Salesforce.

Last week saw three(!) conference sessions on Groovy AST Transformations. At SpringOne2gx I started with an AST Transform deep dive, Venkat followed up with a more gentle, and better performed, overview of Transforms, and I finished out with a video taped AST talk at StrangeLoop (watch infoQ for the video).

At the sessions there was some confusion about the API of the new AstBuilder in Groovy 1.7 (currently in RC1). Hopefully this post can clear that up.

The AstBuilder helps you create abstract syntax trees, and the User Guide is the best place to start learning about it. It lets you create the AST for code by simply passing the code into a method:

List<ASTNode> x = new AstBuilder().buildFromCode { " a constant " }

The big question everyone has is, "What's in the List of ASTNodes?"

The question is mostly easily answered by looking at GroovyConsole's AST Browser. Just type in "a constant" into GroovyConsole and press Ctrl+T/Cmd+T to view the AST:

Do you see that there are two root nodes? A BlockStatement and a ClassNode? The reason for this is that all Groovy scripts are compiled into classes of type Script by the compiler. Remember, to the JVM there are no scripts, only classes. If you expand out the AST, you can see that the script (in this case, the ConstantExpression) is in two places in the AST: within the BlockStatement and within the Script#run method:

So this is why the AstBuilder returns a List of ASTNodes. You'll be returned both the script BlockStatement and the Script ClassNode. For the most part, you're probably only interested in the script and not the ClassNode. The boolean parameter on the buildFromCode and buildFromString methods exist so that you don't have to see that ClassNode. The default value of this 'statementsOnly' parameter is true, so be default you'll only be given the script BlockStatements.
List<ASTNode> x = new AstBuilder().buildFromCode { " a constant " }

assert x[0].class == BlockStatement
assert x[1] == null

But when you need it, you can specify 'false', meaning you want the ClassNode as well as the BlockNode:
List<ASTNode> x = new AstBuilder().buildFromCode(
false, // get the ClassNode
{ " a constant " })

assert x[0].class == BlockStatement
assert x[1].class == ClassNode

For a fun, educational exercise, create multiple classes in GroovyConsole and see what the AST looks like. Hopefully you won't be surprised. But please don't enter an anonymous class because then you'll break the AST Browser! (It's a defect in 1.7 RC1 that I promise to fix soon).


From http://hamletdarcy.blogspot.com 

Discover how the Force.com Web Services Connector (WSC) is a code-generation tool and runtime library for use with Force.com Web services, brought to you in partnership with Salesforce.


The best of DZone straight to your inbox.

Please provide a valid email address.

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}