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/blogCheck 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