Annotation Interface TypeSystem
instanceof
operator, and a default cast is done using a
standard Java cast conversion. However, for some types, this behavior needs to be customized or
extended. Therefore, operations can decide to use type systems. If used, type systems are applied
to operation classes using the TypeSystemReference
annotation. Only one type system can
be active for a single operation. Type systems are inherited from operation superclasses so that
the most concrete type system reference is used. If no type system reference is found in the type
hierarchy, all type checks and casts are kept default.
Example usage:
@TypeSystem public static class ExampleTypeSystem { @TypeCast(Undefined.class) public static Undefined asUndefined(Object value) { return Undefined.INSTANCE; } @TypeCheck(Undefined.class) public static boolean isUndefined(Object value) { return value == Undefined.INSTANCE; } @ImplicitCast public static double castInt(int value) { return value; } } @TypeSystemReference(ExampleTypeSystem.class) public abstract class BaseNode extends Node { abstract Object execute(); } public static final class Undefined { public static final Undefined INSTANCE = new Undefined(); }The example type system declared in here defines a special type check and cast for the type Undefined using methods annotated with
TypeCheck
and TypeCast
. Undefined is a
singleton type and therefore, only a single instance of it exists at a time. For singleton types
the type check can be implemented using an identity comparison and instead of casting a value to
Undefined we can implement it by returning a constant value. Both the singleton check and cast
are considered more efficient than the default check and cast behavior.
Multiple distinct Java types can be used to represent values of the same semantic guest language
type. For example our JavaScript implementation uses the Java types int
and
double
to represent the JavaScript numeric type. Whenever a type needs to be checked
for the type numeric we need to check the value for each representation type. Defining a
specialization with two numeric parameters would normally require us to specify four
specializations, for each combination of the representation type. However, in Java, an
int
type has the interesting property of always being representable with a double
value without losing precision. Type systems allows the user to specify such relationships using
implicit casts such as the castInt
method declared in the example After declaring an
implicit cast from int
to double
we can specify a single specialization
with double type guards to implicitly represent all the cases of the JavaScript numeric type.
Whenever the DSL implementation needs to cast a value from int
to
double
then the implicit cast method is called. Specializations with
int
type guards can be declared before specializations with double
type
guards. If an int specialization is declared after the double
specialization then
the int
specialization is unreachable due to the implicit cast. The requirements for
implicit casts can vary between guest languages. Therefore, no implicit cast is enabled by
default or if no type system is referenced.
If multiple implicit casts are declared for a single target type then their types are checked in declaration order. Languages implementations are encouraged to optimize their implicit cast declaration order by sorting them starting with the most frequently used type.
- Since:
- 0.8 or earlier
- See Also:
-
Optional Element Summary
Modifier and TypeOptional ElementDescriptionClass<?>[]
The list of types as child elements of theTypeSystem
.
-
Element Details
-
value
Class<?>[] valueThe list of types as child elements of theTypeSystem
. Each precedes its super type.- Since:
- 0.8 or earlier
- Default:
{}
-