Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

The True and False of Groovy's AST Builder

DZone's Guide to

The True and False of Groovy's AST Builder

· Java Zone
Free Resource

Learn how our document data model can map directly to how you program your app, and native database features like secondary indexes, geospatial and text search give you full access to your data. Brought to you in partnership with MongoDB.

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 

Discover when your data grows or your application performance demands increase, MongoDB Atlas allows you to scale out your deployment with an automated sharding process that ensures zero application downtime. Brought to you in partnership with MongoDB.

Topics:

Opinions expressed by DZone contributors are their own.

THE DZONE NEWSLETTER

Dev Resources & Solutions Straight to Your Inbox

Thanks for subscribing!

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

X

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

{{ parent.tldr }}

{{ parent.urlSource.name }}