@Retention(value=CLASS) @Target(value=TYPE) public @interface TypeSystem
Each Node
has one TypeSystem
at its root to define the types that can be used
throughout the system. Multiple TypeSystem
s are allowed, but they cannot be mixed inside
a single Node
hierarchy. A TypeSystem
optionally defines a list of types as its
child elements, in which every type precedes its super types. The latter condition ensures that
the most concrete type is found first when searching the list sequentially for the type of a
given generic value.
Each TypeSystem.value()
is represented as a Java type. A type can specify two annotations:
TypeCheck
and TypeCast
. The TypeCheck
checks whether a given generic
value matches to the current type. The TypeCast
casts a generic type value to the current
type. If the TypeCheck
and TypeCast
annotations are not declared in the
TypeSystem
the a default implementation is provided. The default implementation of
TypeCheck
returns true
only on an exact type match and TypeCast
is
only a cast to this type. Specified methods with TypeCheck
and TypeCast
may be
used to extend the definition of a type in the language. In our example, the
isInteger
and asInteger
methods are defined in a way so that they
accept also Integer
values, implicitly converting them to Double
. This example
points out how we express implicit type conversions.
Example: The TypeSystem
contains the types Boolean
, Integer
, and
Double
. The type Object
is always used implicitly as the generic type represent
all values.
@TypeSystem(types = {boolean.class, int.class, double.class}) public abstract class ExampleTypeSystem { @TypeCheck public boolean isInteger(Object value) { return value instanceof Integer || value instanceof Double; } @TypeCast public double asInteger(Object value) { return ((Number)value).doubleValue(); } }
Modifier and Type | Optional Element and Description |
---|---|
Class<?>[] |
value
The list of types as child elements of the
TypeSystem . |
public abstract Class<?>[] value
TypeSystem
. Each precedes its super type.