Hi,
I want to by AA generate a class which extends an existing one, duplicating its generic type definition, e.g.
==== Xtend source ==================
class Base<T extends Comparable<T>> {}
@Extends(Base)
class Derived {
}
=====Generated code====================
class Derived<T extends Comparable<T>> extends Base<T> {}
What I tried is:
baseType.typeParameters.forEach [ t |
targetType.addWarning('''<«t.simpleName» extends «t.upperBounds.map[toString].join(", ")»>''') // <---- Prints "<T extends Comparable<T>>"
val tp = derivedType.addTypeParameter(t.simpleName, t.upperBounds) // <-- Point A
]
which only generates:
class Derived<T extends Comparable<?>> extends Base<T> {}
It seems at Point A the t.upperBounds contains correct information, it's just contains a type parameter that is out of scope ( in Base<T> ) so cannot be resolved at Derived class.
And I do not know how to specify type parameter of Comparable in class Derived, because at Point A what I need to do is make the type parameter being added(val tp = ...) to be type parameter of upperBounds of itself! It's like
val tp = derivedType.addTypeParameter(t.simpleName, SOMEHOW(t.upperBounds, tp))
Just in concept, I know it's impossible.
I wonder if there is any way to do this? If I missed one please point out. Otherwise I think that would require the following abilities:
1. in source type reference, detect self reference, e.g. for type refence t = T extends Comparable<T>, being able to tell type parameter of Comparable<> is t itself;
I tried to use this code to judge, seems working, not sure if it is appropriate way to do it:
targetType.addError(''«t.upperBounds.head.actualTypeArguments.head == t.simpleName»''') which outputs true.
2. when creating dest type parameter, being able to get a type reference to the type parameter being created itself, and use it to parameterize the upperBounds. That is like:
derivedType.addTypeParameter(t.simpleName) [ selfTypeParameter |
selfTypeParameter.upperBounds = SOMEHOW( t.upperBounds, selfTypeParameter)
]
It is hopefully extracted as a service, a common utility operating on AA type system. Sometimes I really think we need this. Thanks for your time!