Abstract type declarations are written using TYPEVAR(sym|"T"). Optionally, lower bounds and higher bounds can be specified:
(TYPEVAR("T"): Tree)
(TYPEVAR("T") LOWER(IntClass): Tree)
(TYPEVAR(sym.T) UPPER(ComparableClass TYPE_OF sym.T): Tree)
or in general:
(TYPEVAR(sym|"T") [LOWER(lo|"C")] [UPPER(hi|"D")]).tree
where lo denotes an optional lower bound type and hi upper bound type.
Type alias definitions are written by appending := and right-hand side Type. The alias may accompany type parameters given by withTypeParams(TYPEVAR(...), ...):
TYPEVAR("IntList") := TYPE_LIST(IntClass)
TYPEVAR("Two") withTypeParams(TYPEVAR(sym.A)) := TYPE_TUPLE(sym.A, sym.A)
or in general:
TYPEVAR(sym|"T") [withTypeParams(TYPEVAR(typ1), ...)] := typ2
Variance annotations for the type parameters are set using COVARIANT(...) and CONTRAVARIANT(...):
val A = RootClass.newTypeParameter("A")
(TYPEVAR("M") withTypeParams(TYPEVAR(COVARIANT(A))): Tree)
(TYPEVAR("M") withTypeParams(TYPEVAR(CONTRAVARIANT(A))): Tree)
The above examples print as:
type M[+A]
type M[-A]