Hi Cédric!
Thank you for your hint.
My example was oversimplified, sorry: I put the annotation on an import statement and on the package declaration (in two different tests), but both

s.getClass().getAnnotations()

and

s.getClass().getPackage().getAnnotations()

were empty.
So I tried implementing an ASTTransform that puts my annotation on ClassNode: contrary to my belief, it was simple and now I can find the annotation on the class.
These are the correct examples and the ASTTransformation:

--- CustomAnnotation.java ---

package xxxx;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import org.codehaus.groovy.transform.GroovyASTTransformationClass;

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({   ElementType.METHOD,
            ElementType.TYPE,
            ElementType.CONSTRUCTOR,
            ElementType.FIELD,
            ElementType.LOCAL_VARIABLE,
            ElementType.PACKAGE
})
@GroovyASTTransformationClass("xxxx.CustomAnnotationASTTransformation")
public @interface CustomAnnotation {

    String value() default "";
    String description() default "";

}

--- END ---

--- CustomAnnotationASTTransformation.java ---

package xxxx;

import java.util.List;

import org.codehaus.groovy.ast.ASTNode;
import org.codehaus.groovy.ast.AnnotationNode;
import org.codehaus.groovy.ast.ClassHelper;
import org.codehaus.groovy.ast.ClassNode;
import org.codehaus.groovy.control.CompilePhase;
import org.codehaus.groovy.control.SourceUnit;
import org.codehaus.groovy.transform.AbstractASTTransformation;
import org.codehaus.groovy.transform.GroovyASTTransformation;

@GroovyASTTransformation(phase = CompilePhase.CANONICALIZATION)
public class CustomAnnotationASTTransformation extends AbstractASTTransformation {

    static final Class<?> MY_CLASS = CustomAnnotation.class;
    static final ClassNode MY_TYPE = ClassHelper.make(MY_CLASS);

    public void visit(ASTNode[] nodes, SourceUnit source) {
        init(nodes, source);
        AnnotationNode anno = (AnnotationNode) nodes[0];
        if (!MY_TYPE.equals(anno.getClassNode()))
            return;
        ClassNode scriptClass = source.getAST().getClasses().get(0);
List<AnnotationNode> annos = scriptClass.getAnnotations(anno.getClassNode());
        if (annos.isEmpty()) {
            scriptClass.addAnnotation(anno);
        }
    }
}

--- END ---

--- script1.groovy ---

package xxxx
@CustomAnnotation("xyz")
import xxxx.CustomAnnotation;

println "Hello world!"

--- END ---

--- script2.groovy ---

@CustomAnnotation("xyz")
package xxxx
import xxxx.CustomAnnotation;

class XYZ {}

println "Hello world!"

--- END ---

Now both script1 and script2 have one annotation at class level.

Stefano

--
-----------------------------------------
Ing. Stefano Rocca
e-mail: s.ro...@oandsi.it

O.&.S.I. Srl
Outsourcing & Sistemi Informativi
via Goldoni, 27
20023 Cerro Maggiore (MI) - Italy
Tel. +39 0331 421787 Fax. +39 0331 511238

Reply via email to