Java Mailing List Archive

Home » eclipse-plugin-dev.groovy »

[groovy-eclipse-plugin-dev] Type Safe Method Name Reflection AST

Jason Cheatham


Replies: Find Java Web Hosting

Author LoginPost Reply

Hello all,

I want to be able to have a type safe way to get the name of a method as a String.

Given this class:

@AddMethodNamesAsStringFields(annotatedWith = "test.annotations.PropertyMethod")
class TestingAST {
def methodToRun() {

I've written an AST that will add a static final String field that matches the method name like this:
class TestingAST {
public static final String methodToRun = "methodToRun"

The goal is to then use the IDE's code assist to get the String:

The AST Transformation code is at the bottom.  Originally I had written the code in Groovy and it didn't work in the project, but when I wrote it in Java then it works fine within Eclipse.  However the IDE code assist completion doesn't work.  Is it possible to get the IDE to recognize the TestingAST.methodToRun field?

I'm using the Groovy Eclipse plugin and groovy-eclipse-compiler for maven.  There seems to be a new capability of the eclipse plugin to selectively allow some ast transforms to run during reconciling that may work.  I'm not sure exactly where to set this, though.  Should I set it in the pom.xml here?  
New compiler option that can be set like other java compiler options.
In CompilerOptions:
String OPTIONG_GroovyTransformsToRunOnReconcile = "org.eclipse.jdt.core.compiler.groovy.groovyTransformsToRunOnReconcile";
which can be initialized from a system property if not being set by another means:

I appreciate any help, thanks,

@AddMethodNamesAsStringFields(annotatedWith = "test.annotations.PropertyMethod")
class TestingAST {

static main(args) {
TestingAST t = new TestingAST();
        assert TestingAST.methodToRun == "methodToRun"
        assert TestingAST.otherMethod == "otherMethod"
        println TestingAST.methodToRun
        println TestingAST.otherMethod
def methodToRun() {

println "ran method methodToRun()"
    def otherMethod() {
        println "ran method otherMethod()"

package test.annotations
@Target(value = [ElementType.METHOD, ElementType.TYPE])
public @interface PropertyMethod {

package test.ast;

public @interface AddMethodNamesAsStringFields {
    String[] annotatedWith() default {};


@GroovyASTTransformation(phase = CompilePhase.CANONICALIZATION)
public class AddMethodNamesAsStringFieldsASTTransformation  extends AbstractASTTransformation {
    public void visit(ASTNode[] astNodes, SourceUnit sourceUnit) {
        if (astNodes==null || astNodes.length < 2) return;
        if (astNodes[0] == null || astNodes[1] == null) return;
        if (!(astNodes[0] instanceof AnnotationNode)) return;
        AnnotationNode annotationNode = (AnnotationNode)astNodes[0];
        if (annotationNode.getClassNode() == null || (!annotationNode.getClassNode().getName().equals(AddMethodNamesAsStringFields.class.getName()))) return;

        ClassNode classThatIsAnnotated = (ClassNode)astNodes[1];
        List<String> annotatedWith = getMemberList(annotationNode, "annotatedWith");
        List<String> methodNames = new ArrayList<String>();
        for(MethodNode methodNode: classThatIsAnnotated.getAllDeclaredMethods()) {

            for(AnnotationNode inspectAnnotation:methodNode.getAnnotations()) {
                if (inspectAnnotation != null) {
                    for(String annotationName : annotatedWith) {
                        ClassNode classNode = inspectAnnotation.getClassNode();
                        if (classNode != null && classNode.getName().equals(annotationName)) {
        for(String methodName:methodNames) {

            classThatIsAnnotated.addField(new FieldNode(methodName, ACC_PUBLIC | ACC_FINAL | ACC_STATIC, ClassHelper.STRING_TYPE, classThatIsAnnotated, new ConstantExpression(methodName)));


©2008 - Jax Systems, LLC, U.S.A.