Hamlet D'Arcy has been writing software for over a decade, and has spent considerable time coding in C++, Java, and Groovy. He's passionate about learning new languages and different ways to think about problems, and recently he's been discovering the joys of both F# and Scheme. He's an active member of the Groovy Users of Minnesota and the Object Technology User Group, is a committer on the Groovy project, and is a contributor on a few open source projects (including JConch and the IDEA Groovy Plugin). He blogs regularly at http://hamletdarcy.blogspot.com and can be found on Twitter as HamletDRC (http://twitter.com/hamletdrc). Hamlet is a DZone MVB and is not an employee of DZone and has posted 28 posts at DZone. You can read more from them at their website. View Full User Profile

The True and False of Groovy's AST Builder

10.26.2009
| 7595 views |
  • submit to reddit

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(
CompilePhase.CONVERSION,
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).

Enjoy!

From http://hamletdarcy.blogspot.com 

Published at DZone with permission of Hamlet D'Arcy, author and DZone MVB.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Tags: