Annotations
The typescript template set reads EAnnotation details from the .ecore file. In the file, an annotation looks like this:
<eOperations name="describe" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"> <eAnnotations source="https://typemf.dev/generator"> <details key="body" value="return this.getTitle() + ' by ' + this.getAuthor()?.getName();"/> </eAnnotations></eOperations>| Source | Key | On | Meaning |
|---|---|---|---|
https://typemf.dev/generator |
documentation |
any element | TSDoc comment |
https://typemf.dev/generator |
body |
operation | TypeScript method body |
https://typemf.dev/generator |
dispatch |
overloaded operation | condition that selects this overload |
https://typemf.dev/generator |
type |
data type | TypeScript type the data type maps to |
https://typemf.dev/generator/feature |
get, set |
structural feature | custom getter and setter body |
https://typemf.dev/generator/import |
type, from, internal-from |
data type, operation, feature | symbol to import and where from |
Values are used as written, without checks. An empty value counts as missing.
Documentation
Section titled “Documentation”documentation becomes the TSDoc comment of the generated element. If the https://typemf.dev/generator annotation has none, it is read from the source http://www.eclipse.org/emf/2002/Ecore. Documentation under the GenModel source http://www.eclipse.org/emf/2002/GenModel is not read.
Operation bodies
Section titled “Operation bodies”body is the body of the generated method. If the https://typemf.dev/generator annotation has none, it is read from http://www.eclipse.org/emf/2002/GenModel. That is where EMF keeps Java bodies, so a .ecore file from EMF needs a TypeScript body under https://typemf.dev/generator for every such operation. An operation without a body throws when called.
Overloaded operations
Section titled “Overloaded operations”Operations of the same name in a class become one TypeScript method with an overload signature each. The implementation runs the body of the overload whose condition matches the arguments. The generator derives the conditions from the parameters: a missing parameter must be undefined, and where the overloads differ in a parameter’s type, that type must be a primitive with a runtime test such as typeof x === 'string'. If it can’t derive a condition, set dispatch on the overload: a TypeScript condition over the parameter names. If no overload has a body, two overloads get the same condition, or a condition can’t be derived, the method throws when called.
Custom getters and setters
Section titled “Custom getters and setters”get and set replace the generated getter and setter of a feature. The setter’s parameter is value.
- A feature with only
gethas no stored value. The getter’s result is cached until the model changes. For a many-valued feature, the getter returns a read-only list. - A feature with
getandsetis not cached. If one of the bodies usesthis._<feature name>, the class gets that field to store the value. - A many-valued feature has no setter, so
seton it is ignored. - A custom setter replaces the generated notification logic too; sending notifications is up to the body.
Data types
Section titled “Data types”A data type’s TypeScript type is, in this order: the type detail of https://typemf.dev/generator, the data type’s instanceClassName, or its name.
If that type has to be imported, add an annotation with source https://typemf.dev/generator/import:
| Key | Meaning |
|---|---|
type |
The symbol to import. Without it, the annotation is ignored. |
from |
The module other packages import it from. |
internal-from |
Where the generated package itself imports it from, relative to its root when it starts with ./ or ../. Defaults to from. |
<eClassifiers xsi:type="ecore:EDataType" name="Color"> <eAnnotations source="https://typemf.dev/generator"> <details key="type" value="Color"/> </eAnnotations> <eAnnotations source="https://typemf.dev/generator/import"> <details key="type" value="Color"/> <details key="from" value="@example/colors"/> </eAnnotations></eClassifiers>The type-imports option of a config file overrides this annotation, for example for data types of a model you can’t change. The annotations of a data type are kept in the generated package, so generating another package that uses the data type reads them from there.
Imports for bodies
Section titled “Imports for bodies”An operation or feature whose body uses other symbols gets one https://typemf.dev/generator/import annotation per symbol. Here internal-from applies, falling back to from.
<eOperations name="sortedBooks" upperBound="-1" eType="#//Book"> <eAnnotations source="https://typemf.dev/generator"> <details key="body" value="return sortByTitle(this.getBooks().toArray());"/> </eAnnotations> <eAnnotations source="https://typemf.dev/generator/import"> <details key="type" value="sortByTitle"/> <details key="internal-from" value="../sorting.js"/> </eAnnotations></eOperations>