« Return to Thread: Groovy AST not taking?

Re: Groovy AST not taking?

by Robert Fischer :: Rate this Message:

Reply to Author | View in Thread

Comments interspersed.

Peter Niederwieser wrote:

> Hi Robert,
> To investigate your transform, I used the following class:
>
> class WithLogTest {
>     static void main(args) {
>         def clazz = new GroovyClassLoader().parseClass("""  
> class WLT {
>     static run() {
>         println HasLog.log
>     }
> }
>
> @foo.WithLog
> class HasLog {}
>         """)
>
>         clazz.run()
>     }
> }
>
Wait a sec -- what's the deal with "@foo.WithLog"?

> Your transform can be simplified to:
>
> @GroovyASTTransformation(phase=CompilePhase.SEMANTIC_ANALYSIS)
> public class WithLogImpl implements ASTTransformation {
>   public void visit(ASTNode[] nodes, SourceUnit sourceUnit) {
>       def classNode = nodes[1] // nodes[0] is the annotation that triggered
> the transform
>       classNode.addField("log",
>           ClassNode.ACC_PUBLIC | ClassNode.ACC_STATIC | ClassNode.ACC_FINAL,
> new ClassNode(Logger),
>           new StaticMethodCallExpression(new ClassNode(Logger), "getLogger",
> new ClassExpression(classNode))
>       )
>   }
> }
>
I was running under the documentation at http://groovy.codehaus.org/Local+AST+Transformations (which
looks copy-pasted from Hamlet's Behind the Times blog post), which says this:
==
   The public visit(ASTNode[], SourceUnit) method is invoked for each source unit that contains your
   target annotation. The AST you receive is not for the @WithLogging annotated method, it is for the
   entire file that contains @WithLogging.
==
Is that a lie?  Or is there something different going on?

> One downside of using a local transform for this task is that you won't be
> able to refer to 'log' via its class name from within the class because the
> Groovy compiler will complain about a missing property 'log' before your
> transform kicks in. To solve this problem you'll probably need to use a
> global transform in phase CONVERSION. Such a transform will look pretty much
> like your version of the local transform, only that it will take a bit more
> work to identify @WithLog annotations because types haven't been resolved
> yet.
>
I thought that AST Transforms mangled the class during compilation.  I want my log property to not
only be visible via Groovy, but to Java classes, too.  Do I really need to do a global transform for
this? I really don't like the sound of that, because it creates hassle in compiling.

Is there a better Compile Phase I could be using?  The documentation on compile phases is
practically non-existent, so I'm just aping what I'm seeing in the example.
http://groovy.codehaus.org/api/org/codehaus/groovy/control/CompilePhase.html

> PS: Please provide output and/or stacktrace when asking such a question.
>
Sorry -- the complaint was a missing property exception for "log" when I called "assertNotNull Foo.log".

~~ Robert Fischer, Smokejumper IT Consulting.
Enfranchised Mind Blog http://EnfranchisedMind.com/blog

Check out my book, "Grails Persistence with GORM and GSQL"!
http://www.smokejumperit.com/redirect.html

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email


 « Return to Thread: Groovy AST not taking?