Skip to content

JS Metamodel quirks

Stéphane Épardaud edited this page Oct 16, 2015 · 9 revisions

Since most of the metamodel stuff is native in both backends, and the JS one is particularly messy, here's some insight for anyone who dares touch that crap.

Type Information

Type information for type arguments and such, is stored as simple JSON objects, referring to the type function (every type is a function in JS, i.e. Iterable, Object, List, etc). This allows for type arguments to be included. The names for the type parameters include the type owner, so that type arguments for different types can coexist within the same type.

{t:List, a:{List$Element:{t:Integer}}}

Type arguments for function are very similar; they are passed as the last argument to the function:

{Type$type:{t:List,a:{List$Element:{t:Integer}}}}

Representation of type information at runtime

For a given type Foo:

Key Description
Foo.$$ constructor function
Foo.$$.T$name type name, such as com.pkg::Foo
Foo.$$.T$all a map for supertype by name
Foo.$$.T$all[typeName] Foo (this type)
Foo.$crtmm$ The runtime metamodel function (see below)

The constructor proto is enhanced with two functions (that can then be called on every instance):

Key Description
Foo.$$.prototype.getT$name the type name
Foo.$$.prototype.getT$all the supertypes

Metamodel

Watch out, there are two sorts of metamodel in JS: the compile-time metamodel which likes in name-version-model.js files, and the runtime metamodel which is included in the main name-version.js file.

Runtime metamodel

Every function has a property called $crtmm$ which contains its runtime metamodel information. It's a function which returns an object with all the data for the function or type; the function need only be called once. There's a helper function called getrtmm$$ which replaces the function with its returned object and stored it under the same property:

var mm=getrtmm$$($_String);

(certain type names such as Object and String have a $_ prepended to them because they're reserved in JS).

The metamodel object keys can vary depending on what they're describing, but all have these keys in common:

Key Description
mod A reference to the compile-time model.
d The path to the model inside the compile-time model, as a list of keys.
tp (optional) for generic stuff, this key contains the type parameter information.
an The annotations that have arguments or cannot be packed into a bitmap for whatever reason.
pa The packed annotations.
$cont (optional) A reference to the containing type or function.

Packed annotations

Mask Description
1 shared
2 actual
4 formal
8 default
16 sealed
32 final
64 native
128 late
256 abstract
512 annotation
1024 variable
2048 serializable

Type metamodels

Type metamodel objects have these keys in addition to the common ones:

Key Description
sts The list of satisfied types.
of The list of algebraic types (references to their definitions), or the name of the self-type.
super The type's supertype.
ps For constructors or classes with initializers, the parameter list.

Function metamodels

Function metamodel objects have these keys:

Key Description
$t The outermost return type. For functions with MPL this is the "full type": a Callable which is the return type of the outermost function.
$rt The innermost return type. For functions with MPL this is the return type of the innermost function.
ps The parameter list. For functions with MPL this is the parameter list of the outermost function.

Value metamodels

Value metamodel objects have these keys:

Key Description
$t The value type.
name The value name.

Packed annotations

The pa key contains a numeric value indicating the presence of certain annotations. Starting from least significant, the packed annotations are: shared, actual, formal, default, sealed, final, native, late, abstract, annotation, variable and serializable. So if the value of pa is 5, it means shared and formal.

Attributes

Toplevel attributes are implemented as functions, so they contain a metamodel just like any other model object. However, member attributes are implemented using JS properties, so there is a separate property in the attribute's container, prefixed $prop$get. For example for the string property of a type, the metamodel is under $prop$getString.

Compile metamodel

Stuffed in .meta fields.

Packages

Public members are found by name as properties. Unshared members are found in the '$pkgunsh$'+this.name.$_replace('.','$') object member by name as properties.