# Type System TypeData type TypeParameterized type

## Type System

The abstraction layer on API basis is called a type system. It provides access to built-in types and different registered metamodel implementations. These registered metamodel implementations offer access to the types they provide. The first part of this documentation describes the type system. The expression sub-language is described afterwards in the second part of this documentation. This differentiation is necessary because the type system and the expression language are two different things. The type system is a kind of reflection layer, that can be extended with metamodel implementations. The expression language defines a concrete syntax for executable expressions, using the type system.

The Java API described here is located in the org.eclipse.xpand.type package and is a part of the subproject core.expressions.

### Types

Every object (e.g. model elements, values, etc.) has a type. A type contains properties and operations. In addition it might inherit from other types (multiple inheritance).

#### Type Names

Types have a simple name (e.g. `String`) and an optional namespace used to distingish between two types with the same name (e.g. `my::metamodel`). The delimiter for name space fragments is a double colon "`::`". A fully qualified name looks like this:

    my::fully::qualified::MetaType

The namespace and name used by a specific type is defined by the corresponding `MetaModel` implementation. The `EmfMetaModel` , for instance, maps `EPackages` to namespace and `EClassifiers` to names. Therefore, the name of the Ecore element `EClassifier` is called:

    ecore::EClassifier

If you do not want to use namespaces (for whatever reason), you can always implement your own metamodel and map the names accordingly.

#### Collection Type Names

The built-in type system also contains the following collection types: `Collection`, `List` and `Set`. Because the expressions language is statically type checked and we do not like casts and `ClassCastExceptions`, we introduced the concept of parameterized types . The type system does not support full featured generics, because we do not need them.

The syntax is:

    Collection[my::Type]
    List[my::Type]
    Set[my::Type]

#### Features

Each type offers features. The type (resp. the metamodel) is responsible for mapping the features. There are three different kinds of features:

- Properties

- Operations

- Static properties

Properties are straight forward: They have a name and a type. They can be invoked on instances of the corresponding type. The same is true for Operations . But in contrast to properties, they can have parameters. Static properties are the equivalent to enums or constants. They must be invoked statically and they do not have parameters.

### Built-In Types

As mentioned before, the expressions framework has several built-in types that define operations and properties. In the following, we will give a rough overview of the types and their features. We will not document all of the operations here, because the built-in types will evolve over time and we want to derive the documentation from the implementation (model-driven, of course). For a complete reference, consult the generated API documentation (http://www.openarchitectureware.org/api/built-ins/).

#### `Object`

`Object` defines a couple of basic operations, like `equals()`. Every type has to extend `Object`.

#### `Void`

The `Void` type can be specified as the return type for operations, although it is not recommended, because whenever possible expressions should be free of side effects whenever possible.

#### Simple types (Data types)

The type system doesn't have a concept data type. Data types are just types. As in OCL, we support the following types: `String`, `Boolean`, `Integer`, `Real`.

- `String` : A rich and convenient `String` library is especially important for code generation. The type system supports the '+' operator for concatenation, the usual `java.lang.String` operations (`length()`, etc.) and some special operations (like `toFirstUpper()`, `toFirstLower()`, regular expressions, etc. often needed in code generation templates).

- `Boolean` : `Boolean` offers the usual operators (Java syntax): &&, ||, !, etc.

- `Integer` and `Real` : `Integer` and `Real` offer the usual compare operators (<,>,<=,>=) and simple arithmetics (+,-,*,/). Note that `Integer` extends `Real`!

#### Collection types

The type system has three different Collection types. `Collection` is the base type, it provides several operations known from `java.util.Collection`. The other two types (`List` , `Set` ) correspond to their java.util equivalents, too.

#### Type system types

The type system describes itself, hence, there are types for the different concepts. These types are needed for reflective programming. To avoid confusion with metatypes with the same name (it is not unusual to have a metatype called `Operation`, for instance) we have prefixed all of the types with the namespace `xpand`. We have:

- `xpand2::Type`

- `xpand2::Feature`

- `xpand2::Property`

- `xpand2::StaticProperty`

- `xpand2::Operation`

### Metamodel Implementations (also known as Meta-Metamodels)

By default, the type system only knows the built-in types. In order to register your own metatypes (e.g. `Entity` or `State`), you need to register a respective metamodel implementation with the type system. Within a metamodel implementation the Xpand type system elements (Type, Property, Operation) are mapped to an arbitrary other type system (Java reflections, Ecore or XML Schema).

#### Example JavaMetaModel

For instance, if you want to have the following JavaBean act as a metatype (i.e. your model contains instances of the type):

    public class Attribute {
       private String name;
       private String type;
       public String getName() {
          return name;
       }
       public void setName(String name) {
          this.name = name;
       }
       public String getType() {
          return type;
       }
       public void setType(String type) {
          this.type = type;
       }
    }

You need to use the `JavaMetaModel` implementation which uses the ordinary Java reflection layer in order to map access to the model.

So, if you have the following expression in e.g. Xpand :

    myattr.name.toFirstUpper()

and `myattr` is the name of a local variable pointing to an instance of `Attribute`. The Xpand type system asks the metamodel implementations, if they 'know' a type for the instance of Attribute. If you have the `JavaMetaModel` registered it will return an `xpand2::Type` which maps to the underlying Java class. When the type is asked if it knows a property '`name`', it will inspect the Java class using the Java reflection API.

The JavaMetaModel implementation shipped with Xpand can be configured with a strategy [GOF95-Pattern] in order to control or change the mapping. For instance, the JavaBeansStrategy maps getter and setter methods to simple properties, so we would use this strategy for the example above.

#### Eclipse IDE MetaModelContributors

You should know that for each `Metamodel` implementation you use at runtime, you need to have a so called `MetamodelContributor` extension for the plugins to work with. If you just use one of the standard metamodel implementations (EMF, UML2 or Java) you don't have to worry about it, since Xpand is shipped with respective MetamodelContributors (see the corresponding docs for details). If you need to implement your own `MetamodelContributor` you should have a look at the Eclipse plug-in reference doc.

#### Configuring Metamodel implementations with the workflow

You need to configure your Xpand language components with the respective metamodel implementations.

A possible configuration of the `Xpand2` generator component looks like this:

    <component class="org.eclipse.xpand2.Generator">
       <metaModel class="org.eclipse.type.emf.EmfMetaModel">
          <metaModelPackage value="my.generated.MetaModel1Package"/>
       </metaModel>
       <metaModel class="org.eclipse.type.emf.EmfMetaModel">
          <metaModelFile value="my/java/package/metamodel2.ecore"/>
       </metaModel>
       ...
    </component>

In this example the `EmfMetaModel` implementation is configured two times. This means that we want to use two metamodels at the same time, both based on EMF. The metaModelPackage property is a property that is specific to the `EmfMetaModel` (located in the `core.emftools` project). It points to the generated `EPackages` interface. The second meta model is configured using the Ecore file. You do no need to have a generated Ecore model for Xpand in order to work. The `EmfMetaModel` works with dynamic EMF models just as it works with generated EMF models.

### Using different Metamodel implementations (also known as Meta-Metamodels)

With Xpad you can work on different kinds of Model representations at the same time in a transparent manner. One can work with EMF models, XML DOM models, and simple JavaBeans in the same Xpand template. You just need to configure the respective MetaModel implementations.

If you want to do so you need to know how the type lookup works. Let us assume that we have an EMF metamodel and a model based on some Java classes. Then the following would be a possible configuration:

    <component class="org.eclipse.xpand2.Generator">
       <metaModel class="org.eclipse.internal.xtend.type.impl.java.JavaMetaModel"/>
       <metaModel class="org.eclipse.xtend.typesystem.emf.EmfMetaModel">
          <metaModelFile value="my/java/package/metamodel.ecore"/>
       </metaModel>

       ...
    </component>

When the runtime needs to access a property of a given object, it asks the metamodels in the configured order. Let us assume that our model element is an instance of the Java type `org.eclipse.emf.ecore.EObject` and it is a dynamic instance of an EMF EClass `MyType`.

We have three Metamodels:

1. Built-Ins (always the first one)

2. JavaMetaModel

3. EMFMetaModel - metamodel.ecore

The first one will return the type `Object` (not `java.lang.Object` but `Object` of Xpand ). At this point the type `Object` best fits the request, so it will act as the desired type.

The second metamodel returns a type called `org::eclipse::emf::ecore::EObject` The type system will check if the returned type is a specialization of the current 'best-fit' type (`Object`). It is, because it extends `Object` (Every metatype has to extend `Object`). At this time the type system assumes `org::eclipse::emf::ecore::EObject` to be the desired type.

The third metamodel will return `metamodel::MyType` which is the desired type. But unfortunately it doesn't extend `org::eclipse::emf::ecore::EObject` as it has nothing to do with those Java types. Instead it extends `emf::EObject` which extends `Object`.

We need to swap the configuration of the two metamodels to get the desired type.

    <component class="org.eclipse.xpand2.Generator">
       <metaModel class="org.eclipse.xtend.typesystem.emf.EmfMetaModel">
          <metaModelFile value="my/java/package/metamodel.ecore"/>
       </metaModel>
       <metaModel class="org.eclipse.internal.xtend.type.impl.java.JavaMetaModel"/>

       ...
    </component>