How to create "recursive generic type" reference in AA?

26 views
Skip to first unread message

Typhoon Storm

unread,
Apr 4, 2016, 3:44:40 AM4/4/16
to Xtend Programming Language
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!


Sven Efftinge (sven@efftinge.de)

unread,
Apr 4, 2016, 8:44:25 AM4/4/16
to xtend...@googlegroups.com
You need to create it in two steps. 
First add the type parameter without upperbounds, then add the upperbounds.
I.e.
val tp = derivedType.addTypeParameter(t.simpleName)
tp.upperBounds = myUpperBounds

--
You received this message because you are subscribed to the Google Groups "Xtend Programming Language" group.
To unsubscribe from this group and stop receiving emails from it, send an email to xtend-lang+...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Typhoon Storm

unread,
Apr 4, 2016, 11:26:24 AM4/4/16
to Xtend Programming Language
Yes I tried and it worked! Thanks for your help!
Reply all
Reply to author
Forward
0 new messages