The output of the Code Generation is the completed program. Depending on the contents of the design, we could also generate Unit test cases.
To do the work we need the design model, containing both static and dynamic descriptions of the program.
It is rather straightforward to do this generation, at least as long as we do it for an object-oriented language. This is some of the basic rules:
A class will become a class.
In some target languages (like java, c++) they also become files and compilation units.
A generalization will become an inheritance.
If the target language does not support inheritance and we didn't address this during the design, some special conversions are required to solve this.
An attribute will become a member variable.
A navigable association will become a member variable.
Depending on the target language, target platform, and the association multiplicities this will be a pointer, a reference, a collection class, an entry in some table or map.
A non-abstract operation in a class will become a method.
An abstract operation in a class will become an abstract method.
An in parameter in an operation will become a parameter in the method.
For simple types (int, boolean), this is the normal case. For C++, these will probably const classes. For Java, this cannot be enforced for classes.
An out or in/out parameter in an operation will become a referenced parameter in the method.
For C++, these will be referenced non-const parameters. For Java classes, this is the default. Simple types (int, boolean) must, in java, be converted to an object of a corresponding class (Integer, Boolean).
The visibilities of the attributes, associations, and operations will become visibilities on the member variables or methods.
Packages will become directories, namespaces, or both.
This conversion is not as straight-forward as the conversion of the static structure. It is much more depending on the target language and target platform.
In general it is only possible to say the following for interactions:
A message is converted into a function call.
The class of the recipient will have to have a function with the correct name and signature.
The sender function in the class of the sender will have a call to the function in the recipient.
An asynchronous message is converted to either posting a message to be handled by some other thread or a function call to a function that starts a new thread.
The following describes one possible way to generate state machines:
A State Machine is generated to a set of member variables that each method in this class refer to when deciding behavior.
A State is generated to a closed set of combination of values on these member variables.
An Event is generated as a call to a member method that can change the state.
These methods would then typically have one big switch statement splitting on the current state.
A Guard is generated to an if statement in the event member method in the branch for the correct state.
A Transition is generated as an assignment of some state variable.
An Action is generated as a function call.