Notice: this Wiki will be going read only early in 2024 and edits will no longer be possible. Please see: https://gitlab.eclipse.org/eclipsefdn/helpdesk/-/wikis/Wiki-shutdown-plan for the plan.
Papyrus-RT/Developer/Design/0.8/Codegen Architecture Details
Transformation Architecture Detailed Description
- 1 Overview
- 2 Plugins
- 3 The generator core
- 4 The "generator starter" (UMLRTGenerator)
- 5 The "generation director" (CppCodeGenerator)
- 6 The "C++ code pattern" (CppCodePattern)
- 7 The translator from UML2 to xtUMLrt (UML2xtumlrtModelTranslator)
- 8 The "model change tracker" (UML2ChangeTracker)
- 9 The model element generators
The code generator input is a UML2 model (org.eclipse.uml2) with the UML-RT profile applied to it. The output is a CDT project (C++).
More precisely, the input to the generator is a list of UML2 elements that have changed. When invoked from within Papyrus, the tool keeps track of which elements have changed since the last generation.
There are two intermediate meta-models:
- xtUMLrt: a meta-model that simplifies UML-RT and contains a common core shared with xtUML.
- Cpp: a meta-model of a sub-set of C++.
The overall generation process is depicted in the following diagram:
The rationale for the intermediate models is as follows:
- The xtUMLrt meta-model is intended to simplify UML2, in order to simplify the generator itself, while allowing customization, isolating the generator from the toolset, and providing a common language that allows its eventual extension to support xtUML.
- The Cpp meta-model isolates the generator from issues such as formatting, body/header file generation, file regeneration avoidance, CDT project and makefile generation, etc.
The core of the code generator consists of separate sub-generators for different kinds of elements. Namely:
- (Passive) classes
- State machines
- Deployment composition/structure
With the exception of the state machine generator, these translate an xtUMLrt model directly into a C++ model. The state machine generator performs some further intermediate steps on the xtUMLrt model before generating the C++ model. These steps are detailed below.
The following tables provide a description of the features and plugins that form the code generator.
|The top-level feature that groups all plugins
|The code generator feature (separately installable)
|The RTS feature (separately installable)
|The top-level plug-in that provides the Activator
|The core of the generator. Includes Capsule, Class and Protocol generators
|Cpp model representation of the RTS elements
|State machine generator (from flat state machines)
|Deployment structure generator
|Base for language-specific plugins
|The Cpp intermediate meta-model
|State machine flattener
|Extensions to the xtUMLrt meta-model for SM generation
|Standalone generator (does not require Eclipse instance running)
|Papyrus protocol editor
|The RTS (a clone of the umlrt.rts git repository) and UML-RT runtime model library
|Utilities used by several plugins
|New C++ profile
|The common xtUMLrt meta-model (intermediate representation)
|The UML-RT-specific extensions to the common xtUMLrt meta-model
|The xtUML-specific extensions to the common xtUMLrt meta-model
|Base for platform/target specific meta-models
|Extensions for C++ generation
|Unit tests for the Cpp intermediate metamodel
|Unit tests for the base lang plugins
The generator core
The core consists of the following classes. Most are in the org.eclipse.papyrusrt.codegen.cpp plugin.
- The "generator starter" (
- This class is the one that begins the generation process from the UI or the standalone, and invokes the "generation director" (below).
- The "generation director" (
- This class drives the generation process. More on this below.
- The "C++ code pattern" (
- This class provides an interface to the C++ language meta-model, as it is used in this transformation.
- It produces and keeps track of which C++ element has been generated for any given (xtumlrt) model element.
- The translator from UML2 to xtUMLrt (
- This translates UML2 model elements into xtUMLrt model elements and keep track of which source elements gave rise to intermediate xtUMLrt elements.
- The "model change tracker" (
- Responsible of keeping track of model changes in order to enable incremental generation
- The element generator base class (
- This is the base class for individual code generators for specific UML-RT elements.
- This tracks generator instances for different types of elements.
- It is a base class for Eclipse-based and stand-alone generator managers.
- The actual model element generator classes for: [^1]
- Basic (Passive) classes (
- Serializable (Passive) classes (
- Capsules (
- Protocols (
- State Machines (
- Deployment composition/structure (
- Basic (Passive) classes (
- Utility classes
The following diagram shows the class diagram with the general structure of the code generator:
The generation director (
CppCodeGenerator) is instantiated and run from the
UMLRTGenerator in either the org.eclipse.papyrusrt.codegen.papyrus plugin (if executed within the Eclipse GUI) or from the org.eclipse.papyrusrt.codegen.standalone (if executed standalone).
The "generator starter" (
This class has a
generate method that receives a list or target
EObject elements, expected to be instances of
org.eclipse.uml2.uml.Element. Roughly, it does the following:
- Determine the set of related elements that have changed in the editor and add them to a set of changes
- Determine the folder where the code for the elements should be generated (and create a CDT project if needed)
- Translate each UML element to xtUMLrt (the intermediate representation)
- Invoke the
CppCodeGenerator.generatemethod on the target list
- Write (M2T) the resulting Cpp models to their target folders
There are two versions of this class. One in org.eclipse.papyrusrt.papyrus, invoked from within Papyrus, and one in org.eclipse.papyrusrt.standalone, invoked from the stand-alone generator.
This class contains references to:
The "generation director" (
This class has the main method
generate that performs the generation.
The input is a list of target xtUMLrt model elements (typically translated from UML2 by the UI or the standalone generator). This input is passed to the constructor of
The generate process itself performs the following steps:
- Eliminate from the target list, elements which have been explicitly marked as "not to be generated".
- "Collection": creates an instance of each code generator class (
AbstractCppGeneratorsub-classes) according to the type of element. This computes on the fly the transitive closure of affected elements. One generator instance is created for each model element.
Packageelements, it recursively collects the generators for Entities (Classes and Capsules) as well as Protocols in the model/package.
Protocols(non-built-in system protocols), creates a
ProtocolGeneratorand Capsule generators for each capsule in the model which has a port typed by the protocol.
StructTypeelements, creates a
Capsuleelements, creates a
CapsuleGenerator, and a
EmptyStateMachineGenerator(if it has no state machine). Furthermore, if the capsule has been marked as the "top" capsule, it creates a
CompositionGenerator, to create the deployment structure.
- Prune the list of generators to exclude those corresponding to elements that have already been generated and have not changed (according to the change-set)
- Generation: invokes the
generatemethod on each individual generator instance. The result for each element is an element in the C++ model.
- Consume (clean) the set of changed elements
The M2T step is performed by the
UMLRTGenerator class of either the org.eclipse.papyrusrt.papyrus plugin, if it is executed from within Papyrus, or from the org.eclipse.papyrusrt.standalone plugin, if it is invoked from the stand-alone generator.
The "C++ code pattern" (
This class provides an interface to the Cpp meta-model and is used to share C++ model elements generated by different parts of the generator.
It mostly provides methods to create C++ model elements on demand for specific types of xtUMLrt model elements and contexts. These are stored in tables for future reference so that the same C++ model element is returned for the same xtUMLrt model element. This allows the generation of target C++ model elements to occur in any order, which means that code generators can be invoked in any order as they will obtain the C++ model elements when needed.
For example, suppose that there is a
Capsule C1 with a port typed with a
Protocol P1 in the model. If the input list of target elements is
ProtocolGenerator.generate is invoked first on
P1, which will in turn invoke the
CppCodePattern.getCppClass method to obtain the C++ class model element for
CapsuleGenerator.generate is invoked on
C1, which will generate the code for its ports, and when doing so, it will try to obtain the C++ class for
P1 from the
CppCodePattern, and since it was already computed for
P1, it obtains the same C++ model element. If the input list of target elements was
[C1,P1], the C++ class for
P1 will be created when the
CapsuleGenerator is translating
C1 and tries to obtain the corresponding C++ class for the protocol, while the execution of
ProtocolGenerator.generate will obtain that class as it has already been computed.
The translator from UML2 to xtUMLrt (
The "model change tracker" (
The model element generators
: The generators for state machines and the overall model composition are defined in the org.eclipse.papyrusrt.codegen.statemachines and org.eclipse.papyrusrt.codegen.structure plugins respectively.