Скажем, у меня есть интерфейс Java:
public interface IMyInterface {
void hello(String who);
}
Я хочу создать активную аннотацию с Xtend, которая автоматически (и в целом) реализует этот интерфейс для класса Xtend. Так что, когда я пишу
@InterfaceImplementor
class MyInterfaceImplementation implements IMyInterface {
}
Я хочу, чтобы Xtend генерировал
@InterfaceImplementor
@SuppressWarnings("all")
public class MyInterfaceImplementation implements IMyInterface {
public void hello(final String who) {
delegate.hello(who);
}
}
Я дошел до этого:
@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(', ')
}
}
Это работает до тех пор, пока я переопределяю каждый метод в целевом классе:
@InterfaceImplementor
class MyInterfaceImplementation implements IMyInterface {
override hello(String who) {}
}
Тем не менее, я действительно хочу, чтобы Xtend генерировал все тело класса, без необходимости вручную объявлять каждый метод. Для этого я попытался использовать element.implementedInterfaces
в активной аннотации, но это всего лишь TypeReference
s, и я не знаю, как получить объявленные методы из ссылки на тип. Так вот где я застрял.
Возможно ли даже разрешить TypeReference
во время активной аннотации? Есть ли другой способ достичь моей цели?
"element.declaredMethods" возвращает локально объявленные методы (т.е. пуст в вашем случае). Вам нужно пройти методы внедренного интерфейса, а затем создать новые методы в текущей цели аннотации.
Вы также можете взглянуть на новую встроенную аннотацию @Delegate Xtend.
Этот пример взят из примечаний к выпуску (https://eclipse.org/xtend/releasenotes.html):
interface I {
def void m1()
def void m2()
def void m3()
}
class A implements I {
override m1() {}
override m2() {}
override m3() {}
}
class B implements I {
//all methods automatically implemented
@Delegate A delegate = new A
}
Вот ссылка на соответствующий раздел в онлайн-документации Xtend: https://eclipse.org/xtend/documentation/204_activeannotations.html
TypeReference
element.implementedInterfaces
. Но как я могу получить методы, объявленные ссылочным интерфейсом?TypeReference
имеет методgetType()
который возвращаетType
который может быть приведен кInterfaceDeclaration
. Это был недостающий кусок. Спасибо, Свен!