Users Guide
Preface¶
A model file is a normal text file with the ending “.gapp”. Model files have to be located in the workspace and can be edited by any text editor. The editor of the Virtual Developer Modeler (VDM) has some advantages, though.
- syntax highlighting
- markers for syntax errors
- code-proposals and code-completion
- outline-view
- tool-tips for model elements (mouse over)
The domain spceific language (DSL) “gapp” allows for the definition of new DSLs. All DSLs share the same file structure. The VDM’s editor recognizes DSL definitions by reading “.gapp” files that are found in the “assets” directory or by scaning installed plug-ins that adhere to certain conventions. More information about the definition of new DSLs can be found in the developers guide.
File Structure¶
A model file basically has the following structure. Please note that the square and round brackets are not part of the syntax and it is not about templates. Square brackets stand for variable ids or names. Round brackets stand for optional parts of the syntax.
namespace [namespace];
import [import0];
import [import1];
...
import [importN];
/*
* Documentation for module
*/
module [module-name] kind = [comma-separated list of module-types];
set [option-name] = [option-value(s)];
link [option-name] = [referenced element(s)];
/*
* Documentation for element
*/
[element-type] [element-name] (extends [element-name]) {
set [option-name] = [option-value(s)];
link [option-name] = [referenced element(s)];
/*
* Documentation for member
*/
[member-type] [member-name] : [element-name] {
set [option-name] = [option-value(s)];
link [option-name] = [referenced element(s)];
}
}
...
more elements
...
Generic Concepts¶
Namespace¶
The namespace is a mandatory model element. It always denotes the start of a model file.
A namespace is used to be able to distinguish two model elements that have the same name but represent different model elements. Typically, a modeled namespace results in a namespace in generated code, e.g. packages in Java or Namespaces in .NET. Here is an example:
namespace com.gs.gapp; // first line in model file
Module¶
Every model file represents a “Module”. The sole purpose of a module is to pool a set of model elements. Every module can be imported into another module that is present in the same Eclipse project. The name of a module has to be identical with the name of the model file.
A module can be modeled independently from any defined DSL. Only by using the keyword “kind”, the types of elements that are allowed to be used in a module are determined. In addition to that, “kind” determines which other module types can be imported in a module. Here is an example:
...
module MyModule kind = Persistence;
...
In the module “MyModule” only element types that are defined in the DSL “Persistence” may be used. The module type “Persistence” also sets the rule that only modules of type “Asset” or “Basic” may be imported.
When the keyword “kind” is not specified, as a consequence all available element types can be used for modeling.
Import¶
With import statements, elements that are defined in other modules are going to be re-used. Imports don’t work transitively. When module A imports module B and B imports module C, then module A does not automatically import module C.
The option to import other modules is limited by the definition of module types. A more detailed guidance can be found in the developers guide. Normally, you only need this information when you plan to develop your own DSLs.
In an import statement, the name of a module is prefixed with the module’s namespace. Here is an example for the module “ContactsPersistence”.
namespace my.name.space;
import com.gs.gapp.sample.contacts.entities.ContactsPersistence;
...
Comment¶
Similar to how it is done in Java, comments are written above of model element definitions. Comments are optional and can be added for mdoules, elements and members. They are not only for the modelers but fully-fledged model elements that can be processed by generators. Here is an example for a module comment:
/*
* This module includes a simple
* model element that serves as
* an example for basic codegeneration
* functionality.
*/
module hello-world;
Please note that comments written with /* and */ always belong to a model element. Such comments cannot float freely in the model. For free floating comments use the C/C++ like comment characters // instead. They can be placed everywhere.
Fundamental Syntax Rules¶
There are a few fundamental syntax rules that simplify the acquisition of DSLs: * Statements for element and member are terminated with a semicolon or alternatively with a block of curly braces. * Namespace-, import- and module-statements are terminated with a semicolon. * Options that are used to define values start with the keyword “set” and are terminated with a semicolon. * Options that are references to other model elements start with the keyword “link” and are terminated with a semicolon. * All model elements have a name.
DSL-specific Concepts¶
Element types, member types and options are specific to a DSL. The “gapp” DSL itself does not define such things. Instead, the “gapp” DSL offers a syntax to define element types, member types and options. That syntax is only of interest for somebody who intends to develop own DSLs. More details related to this can be found in the developers guide.
Module-Type¶
Module types are there to group a set of element types. An element type logically belongs to one or more module types. Module types are applied during modeling when using the keyword “kind”. A DSL designed for the usage in the VDM can contain one or more module types. A module type itself can rule, which other module types can be imported when that module type is applied.
Element¶
Elements are modeled with the help of element types that themselves are defined in DSLs. Modeled elements also serve as types for members and can also be referenced by means of options (keyword “link”). Here is an example from the DSL “Persistence”, where the element type “entity” is used.
entity BaseEntity {
set Storable = false;
field pk : PrimaryKey {
set Id = true;
}
}
Member¶
Members are modeled by using member types that are defined in DSLs. They are modeled within an element’s code block that is delimited with curly brackets. Also members can be referenced by options (keyword “link”). Here is the same example from the DSL “Persistence” that has been used further above. The member type “field” is used here.
entity BaseEntity {
set Storable = false;
field pk : PrimaryKey {
set Id = true;
}
}
Option¶
Options can be modeled for modules, elements and members. An option can have one or more values (number, text, boolean, enumeration). Such options are modeled with the keyword “set”. A special type of option can be used to set references to other modules, elements and members. This special type of option is used with the keyword “link”. Options can have default values. Those default values are not defined by a DSL but by a generator that uses the model files as input.
Again, here is the same example from the DSL “Persistence” that has been used further above. The options “Storable” and “Id” are used here.
Built-In Module-Types and Options¶
The Virtual Developer Modeler comes with a few predefined module types and options. They help to organize the definition of new DSLs and allow for a more flexible type system. Here are the predefined module types:
Module-Types¶
Module-Type | Description |
---|---|
Asset | A module, that has this module type set as “kind” attribute, contains a DSL definition. This module type is only being used when defining a new DSL |
Aliasing | A module, that has this module type set as “kind” attribute, contains the definition of type aliases. A module with this type can be provided by developers of new DSLs. But its also possible that every user of a DSL defines her own type aliases, in order to end up with more expressive models. Generators then resolve the aliases before executing the main part of the code generation. |
Options¶
Module-Type | Option | Option-Type | Description |
---|---|---|---|
Aliasing | Type | Reference, single valued | References a model element, that is of the same type as the model element for which the option is set. This option can be used for modules, elements and members. |
ALL | TypeFilterGroups | Text, multi valued | Is set on the module level. Allows the definition of names that can be used to activate type aliases. The names defined with this option are going to be used with the option “TypeFilters”. |
ALL | TypeFilters | Text, multi valued | Is set on the module level. By specifying one or more of the names that were defined with “TypeFilterGroups”, the related type aliases are activated and used for the parsing of the model as well as the code-completion mechanism. |
ALL | Abstract | Boolean | Can be set for modules, elements or members. For elements this option typically is set to true in order to tell a generator that the element is only used in an inheritance structure and does not play any other role during generation. |
Keyword Reference (Generic Syntax)¶
Here all keywords and syntax rules are listed that can be used for modeling. A description of the supplied built-in DSLs can be found in the DSL sections.
Keyword | Syntax-Rule | Comment |
---|---|---|
namespace | namespace [name]; | The name can include alpha-numeric characters and dots. It must not begin with a number or dot. It is mandatory to model a namespace and there is only one namespace per module/file. |
import | import [module-namespace].[module-name]; | There can be as many import statements as you want. |
module | module [name] (kind = [module-type] (,[module-type])*); | The setting of “kind” is optional. Typically, you do use it, though. This way you have cleaner models where the code-proposal lists are much shorter. |
set | set [option-name] = [value] (, [value])*; | The keyword “set” is used the same way for all DSLs. An option name, option value-type and the number of allowd values is DSL-specific. |
link | link [option-name] = [ref] (, [ref])*; | The keyword “link” is used the same way for all DSLs. The allowed type for the referenced model element is DSL-specific. [ref] denotes the name of the referenced model element. |
extends | extends [element-name] | An optional, single inheritance relation between model elements of the same type. |