[Dev] Add documentation for the ACR authored by Rico Bergmann's avatar Rico Bergmann
......@@ -2,32 +2,103 @@
:sectanchors:
:sectlinks:
:imagesdir: ../assets/generated
:toc:
If you want to find out how to extend the generator and adapt it to fit your own needs, this page
If you want to find out how to extend the Generator and adapt it to fit your own needs, this page
is for you.
== General architecture and workflow
When invoking the generator, it will (roughly) perform the following actions:
When invoking the Generator, it will (roughly) perform the following actions:
.Basic invocation workflow
image::invocation_workflow.png[width=90%, align=center, link={imagesdir}/invocation_workflow.png]
Each of these steps has a corresponding Scala class (called _Services_ hereafter) to take care of
it. So, when extending the generator there are two basic approaches:
it. So, when extending the Generator there are two basic approaches:
[loweralpha]
. modifying one of the _Services_ (either directly or by means of subclassing)
. intercepting the workflow by adding more _Services_
To give you a rough idea of what _Services_ are available and where they will be located, here is an
overview of the generator's architecture:
overview of the Generator's architecture:
.The coarse-scale architecture of the generator
.The coarse-scale architecture of the Generator
image::architecture.png[width=90%, align=center, link={imagesdir}/architecture.png]
== The Scala abstract class representation
== The Scala _Abstract class representation_
The _Abstract class representation_ (ACR) is the hearth of the Generator. It forms the meta-model
for the code to generate and provides facilities to adapt model instances for different purposes.
In short each element of a Scala class has a matching class in the _ACR_. E.g. a method will be
represented by an instance of `SMethod`, attributes become ``SAttribute``s and a class itself will
be mapped to a `SClass`. As the main purpose of the Generator is to provide executable software
models, an abstraction of a model, the `SModel` is provided as well. It is pretty straightforward
and simply provides all the classes in the model.
=== Types and Classes
Models seldom start from scratch. Instead, they will reuse certain data types, such as ``String``s,
``Integer``s, etc. as attributes in the classes that are specified by the model. Usually these data
types are provided by some library and may be mapped to a basic data types of the target programming
language (or a converter is provided along with them).
The Generator follows a similar approach: it provides an abstraction for user-supplied classes (i.e.
the classes specified within the model). This is the `SClass` class already mentioned above.
Additionally a `SType` class is provided to handle predefined data types. When generating source
code these types are expected to exist "as are" and will not be tackled further. I.e. no `.scala`
files will be created for `SType` instances.
As _types_ and _classes_ are concepts only found at a more abstract level and are irrelevant when it
comes to Scala source code, they share a common superclass - `STypedElement` - which will be used
whenever type information (no matter if it is user-supplied or generic) is needed.
=== Working with the _ACR_ on a more abstract level
The _ACR_ forms a trade-off between an abstract meta-model on one side, and a straightforward (hence
simplified) usage on the other side. Therefore low-level abstraction will oftentimes be wrapped by
some higher abstraction. E.g. a `SMethod` consists of abstract ``SMethodStatement``s and may thus
provide abstract functionality for modification. However a `SMethodStatement` simply wraps a
`String` (the actual statement). Dealing with the statements _themselves_ may therefore become
pretty cumbersome at a certain point. To circumvent this issue, the __ACR__'s elements should be
extended by means of subclassing to provide more tailored versions which handle the additional
complexity.
A good example for this approach is the extension of the `SMethod` class to easily generate
__Getter__s and __Setter__s for attributes:
.Example for modifying the _ACR_ on a more abstract level
[source, scala]
----
class SMethod(val name: String,
val result: STypedElement,
val params: Seq[SMethodParameter],
var implementation: Seq[SMethodStatement]) {
// implementation omitted
}
class SGetter(attr: SAttribute) extends SMethod(
name = s"get${attr.name.firstLetterToUpperCase}",
result = attr.attrType,
params = Seq.empty,
implementation = Seq(SMethodStatement(content = attr.name, usedTypes = Set(attr.attrType))) {
// implementation omitted
}
----
__Getter__s may now be generated by only specifying the attribute they are created for - the
cumbersome creation of the actual method statements is hidden within the class implementation.
== Working with models
=== Incremental construction of `SModel` instances
=== Building a model from EMF
== Writing to the File system