Search code examples
javacode-generationxtend

Automatic Interface Implementation via Xtend ActiveAnnotations


Let's say, I have a Java interface:

public interface IMyInterface {
    void hello(String who);
}

I want to create an active annotation with Xtend that automatically (and generically) implements that interface for an Xtend class. So that, when I write

@InterfaceImplementor
class MyInterfaceImplementation implements IMyInterface {       
} 

I want Xtend to generate

@InterfaceImplementor
@SuppressWarnings("all")
public class MyInterfaceImplementation implements IMyInterface {
  public void hello(final String who) {
    delegate.hello(who);
  }
}

I came as far as this:

@Active(typeof(ImplementationGenerator))
annotation InterfaceImplementor{}

class ImplementationGenerator implements TransformationParticipant<MutableClassDeclaration> {

    override doTransform(List<? extends MutableClassDeclaration> annotatedTargetElements, extension TransformationContext context) 
    {
        for(element : annotatedTargetElements)
        {
            for(method : element.declaredMethods) 
            {
                implementMethod(element, method, context)               
            }
        }
    }

    def implementMethod(MutableClassDeclaration clazz, MutableMethodDeclaration method, extension TransformationContext context) 
    {
        method.body = ['''delegate.«method.simpleName»(«method.callParameters»);''']
    }

    def callParameters(MutableMethodDeclaration method) 
    {
        method.parameters.map[ simpleName ].join(', ')
    }
}

This works as long as I override each method in the target class:

@InterfaceImplementor
class MyInterfaceImplementation implements IMyInterface {       

    override hello(String who) {}

} 

However, I actually want Xtend to generate the whole class body, without me having to declare each method manually. For this, I tried to use element.implementedInterfaces in the active annotation, but these are merely TypeReferences, and I don't know how to get the declared methods from a type reference. So this is where I am stuck.

Is it even possible to resolve a TypeReference during an active annotation evaluation? Is there any other way of reaching my goal?


Solution

  • "element.declaredMethods" returns locally declared methods (i.e. is empty in your case). You need to traverse the methods of the implemented interface instead and then create new methods in the current annotation target.