Facets
Overview
Facets are a mechanism to annotate types and slots with metadata. Facets are similar to Java annotations or C# attributes. A facet is a serialized instance of const class declared on a type or slot which implements the Facet
mixin.
Facet Classes
Facets are defined as normal classes using the facet
positional keyword:
// simple marker facet with no fields facet class Indexed {} // struct facet with one or more const fields facet class Table { const Str name := "" const Bool autoCreate }
All facets classes automatically inherit the Facet
mixin. Facets are implied to be const classes which means all their fields must be const.
Facet classes are not allowed to define their own constructor. Instead the compiler will generate one for you. If your facet has fields, then it is implied to be Serializable and all its fields must be serializable types.
The classes above will have the following synthetic definitions:
// marker facet with no instance fields is singleton const class Indexed : Facet { static const Indexed defVal := Indexed() private new make() {} } // struct facet with instance fields gets it-block constructor @Serializable const class class Table : Facet { new make(|This|? f) { f?.call(this) } }
Annotations
Any type or slot can be annotated with facets using the @
symbol:
@Indexed @Table { name = "Employees"; autoCreate = true } class Employee {}
Struct facets assign their field values inside curly braces similiar to an it-block. Only simple literal expressions may be used in facet annotations which the compiler can determine how to serialize.
Reflection
Facets are available at runtime via the following methods:
Always prefer the facet
and hasFacet
methods over facets
since it is much more efficient. Some examples:
// check if a type is serializable, returns null if not Serializable? ser := obj.typeof.facet(Serializable#, false) // check if a field is transient field.hasFacet(Transient#)
Inheritance
You can annotate a facet class with the FacetMeta
facet to declare that a type-level facet should be inherited:
@FacetMeta { inherited = true } facet class F {} @F class A {} class B : A {}
In the example above the class B
will inherit the facet F
. Facet inheritance works on any type (class or mixin) in the inheritance hierarchy
.