Author Topic: Some questions related to code generation / C++  (Read 908 times)

32aacp

  • EA Novice
  • *
  • Posts: 4
  • Karma: +0/-0
    • View Profile
Some questions related to code generation / C++
« on: May 17, 2013, 07:33:54 pm »
Hi,

I'm new to EA and I have some questions to code generation which I could not answer by myself with trying out. So I've played around to figure some things out and also have modified templates to get the code style I want. Here are the questions which are left open:

1. We have quite big C++ libraries which use STL-Containers. I tried to bring them into the class definitions so they could be generated as type of attributes. I've tried to set up a vector as collection class and defining a association between the two related classes following these instructions, but had no success. I defined the collection class in the global code generation options for C++ and also for the class(es), further I added a association with defined multiplicity.
It seems to me that the only way for now is just enter the vector with needed class as type into the attribute definition (as it is done by code import). Is there something special I have to consider or aren't the collection classes made for this purpose?

2. Getters and setters can be generated automically. The setters use "newVal" as parametername. If I change afterwards the paramaetername these are generated right for the parameterlist but the method body still uses "newVal". Can this behavior be fixed so that the body uses the right name?

3. For attributes default values can be defined. If I do that in the generated code this isn't considered (no initialisation in constructor). How can I achieve that the attribute initialization with the default values are created by code generation?

4. I've modified some code generation templates and saw the templates for namespaces (I didn't modify them). At the moment using statements are generated like:
using namespace namespace1::namespace2::Class;
As far as I know this would generate a compiler error because Class is no namespace. I didn't found a statement in the templates which would add the classname to the statement. So what could cause this and how can I fix this?

I'm using EA 10, Buil 1007 (Professional).

Thank you.

32aacp

  • EA Novice
  • *
  • Posts: 4
  • Karma: +0/-0
    • View Profile
Re: Some questions related to code generation / C+
« Reply #1 on: May 24, 2013, 08:12:26 pm »
After getting a much better understanding of the code templates, it's abilities and how they work, I could solve most of my questions at least with a work around. But there are still questions open.

to 1.
The collection stuff still isn't working for me. I've also tried to import the header of the STL containers, but this failed too. So I still don't have a idea how I should integrate the STL containers. At the moment I'm solving the problem by entering the type directly into the type fields and including the header manually (what has usually be done once). As I mentioned before at the moment this seems to be the only way for me to get these types for code generation considered. Even if it has disadvantages.

to 2.
I've build a workaround in the code templates for that. I've created a own parameter template which only prints the parametername. I call this template with the list macro when generating the body of a setter. Template "operation body" now looks something like:
Code: [Select]
%elseIf opStereotype == "property set" and opTag:"attribute_name" != ""%
\t%opTag:"attribute_name"% = %list="mytemplate" @separator=" "%;
I know this can cause errors when a operation with more than one parameter has the stereo type "property set". So if there's still a better solution I'd like to know. A better solution I could think of is to access the first parameter, but I didn't found anything how I could implement that in the templates.

to 3.
For that I've created a template too. This template is of type attribute and contains following code
Code: [Select]
%if attInitial != ""%
%attName% = %attInitial%;
%endIf%
This is also called with the list macro in the generation of the default constructor, solving my question completely.

to 4.
I figured out that for C++ code generation the using namespace statement in the implementation file comes from %fileheaders%-variable in the "Import Section Impl"-template. As mentioned this using statement is closed with the class name which would generate a compiler error. I've modified the template to just print the #include statement of the associated headerfile:
Code: [Select]
#include "%fileName%"The namespace templates didn't generate anything about namespaces. Also they're working in some way recursive and I've modified the "Namespace Impl"-template to:
Code: [Select]
%if packageHasGenClasses == "T"%
%packageName%;
%NamespaceBodyImpl%
%else%
%packageName%::%NamespaceBodyImpl%
%endIf%
With "using namespace" before calling this template in the "File Impl"-template the statement is completed.
So now knowing that the namespace generating can be tricky I'd like to know if there is a way to get using statements in the header-files when other headers are imported. EA knows which other headers have to be included when other classes are used as attribute types. When this other classes lay in a different namespace I had to add the using statement manually for them. That's no problem but getting these generated automatically would be very nice. I think there could be a way to extract the namespace Information belonging to the includes/imports as the linking is recognized for the imports.

Stephane B

  • EA User
  • **
  • Posts: 31
  • Karma: +0/-0
    • View Profile
Re: Some questions related to code generation / C+
« Reply #2 on: May 31, 2013, 01:42:28 am »
Hi,

New to EA too, and just gone though this kinda stuff (not for C++, which I don't know though).

About topic2 :
Quote
I know this can cause errors when a operation with more than one parameter has the stereo type "property set". So if there's still a better solution I'd like to know. A better solution I could think of is to access the first parameter, but I didn't found anything how I could implement that in the templates.

If your operation has several parameters, it will not cause an error, it will just concatenate the outputs of your mytemplate applied on each parameter.

But why invoke a list (which is a "foreach") when you have one parameter to your setter :
Code: [Select]
%elseIf opStereotype == "property set" and opTag:"attribute_name" != ""%
\t%opTag:"attribute_name"% = %Parameter__MyTemplate%;

(If your template is typed as Parameter, I guess it should be called Parameter__MyTemplate or something alike).

And what about this opTag:"attribute_name" ? Isn't it the name you want? or maybe with a conversion :

Code: [Select]
%elseIf opStereotype == "property set" and opTag:"attribute_name" != ""%
$paramName = %opTag:"attribute_name"%
$paramName = %CONVERT_NAME($paramName, "pascal case", "camel case")%
\t%opTag:"attribute_name"% = $paramName%;

to.4
Indeed, Namespace templates are not about declaring imports. What they do is process a package. Typically, Namespace calls itself to recursively enter the packages and reach the classes.

Hope this helps,

Stéphane

32aacp

  • EA Novice
  • *
  • Posts: 4
  • Karma: +0/-0
    • View Profile
Re: Some questions related to code generation / C+
« Reply #3 on: June 03, 2013, 03:21:07 pm »
Quote
If your operation has several parameters, it will not cause an error, it will just concatenate the outputs of your mytemplate applied on each parameter.

To make this point more clear, this concatenation will cause a compile error in C++. Because when there are some parameternames concatenated the generated statement makes no sense.

Quote
But why invoke a list (which is a "foreach") when you have one parameter to your setter :
Code: [Select]
%elseIf opStereotype == "property set" and opTag:"attribute_name" != ""%
\t%opTag:"attribute_name"% = %Parameter__MyTemplate%;

(If your template is typed as Parameter, I guess it should be called Parameter__MyTemplate or something alike).

You're right with the Templatename.
I'm invoking a list because your version will not work for me. The template will do nothing resulting in a line like "m_member = ;" with no parametername. I don't know how to access the first or a specific parameter name in the templates. This is why I use the list macro.

Quote
And what about this opTag:"attribute_name" ? Isn't it the name you want? or maybe with a conversion :

Code: [Select]
%elseIf opStereotype == "property set" and opTag:"attribute_name" != ""%
$paramName = %opTag:"attribute_name"%
$paramName = %CONVERT_NAME($paramName, "pascal case", "camel case")%
\t%opTag:"attribute_name"% = $paramName%;

This maybe could be a solution, if a way exist that I can convert the name in the right way. All attributes begin with m_ which is not wished in the parametername and there are some upper/lower case styles I'd like to keep. I'll have a look into that. Thanks.

Quote
Indeed, Namespace templates are not about declaring imports. What they do is process a package. Typically, Namespace calls itself to recursively enter the packages and reach the classes.

This is what I already figured out. What I'm now searching for is a way (and this don't have to be in the namespace templates itself) how I can add Namespace/Import statements at the top for the namespaces of other objects I use, instead of the fully qualified names EA generates usually when these objects are used. Header includes are already generated if they exist and EA knows their location and I'd like to havin something similar for namespaces if this is possible. As mentioned EA usually generates fully qualified names when using these objects, but this collides with our code style and I removed this from the templates. (If I would let generate the fully qualified names this would mean when I import a class and then do a synch or generate code the code file would be changed even when the class wasn't changed in the model)

Stephane B

  • EA User
  • **
  • Posts: 31
  • Karma: +0/-0
    • View Profile
Re: Some questions related to code generation / C+
« Reply #4 on: June 03, 2013, 11:05:24 pm »
Quote
I'm invoking a list because your version will not work for me. The template will do nothing resulting in a line like "m_member = ;" with no parametername.

Have you tried with parentheses at the end of your call?

Quote
All attributes begin with m_ which is not wished

This seems to be an option in Tools >Options > Source code engineering > Attributes/Operations > Default name for associated.

Quote
if a way exist that I can convert the name in the right way

EA provides text handling macros (left, mid, right, trim, convert_name, to_lower, to_upper, find...). My advice is: build your own text handling macro that suits your needs and call it:
Code: [Select]
%MY_TEXT_HANDLING%($paramName)%In the template, you grab the argument like this:
Code: [Select]
$src = $parameter1
For instance, I made myself a LAST_INSTANCE_OF macro.
You have math macros that let you count characters, which are not in any EA user guide  : MATH_ADD, MATH_SUB, MATH_MULT.
Last caution : the RIGHT macro has a bug (%RIGHT("foo", "2")% renders "oo" but  %RIGHT("foo", "3")% yields "". Go figure...)

Do you perform a model transformation before the code generation? I always do a two step generation for Java: MDA transformation from platform independant model to Java specific model, then code generation. My imports are solved two ways : either I create a Dependency connector between my classes, or I add a tagged value to my class:
Code: [Select]
Tag{name="imports" value="import com.whatever.class;"}.
Both at MDA transform time.

Then I tuned the java code generation Class template to print the content of this tagged value by adding the line :
Code: [Select]
%classTag:"imports"%I think that could solve (part of) your namespace problem (though I don't know namespacing in C++).

Stéphane

32aacp

  • EA Novice
  • *
  • Posts: 4
  • Karma: +0/-0
    • View Profile
Re: Some questions related to code generation / C+
« Reply #5 on: June 04, 2013, 04:16:28 pm »
Hi Stephane,

I've tried parantheses and also some usual ways to make a index based access (e.g. %paramName(0)%). Nothing worked.

That attributes start with m_ is not the problem, actually that is right. But when taking the attribute name to build upon this the paramname this prefix would not be right. That's what I tried to express.

After giving this conversion thing some thoughts, I came to the conclusion that this solution would be just as prone to error for the final code as what I already have. This is because I would bring naming logic into the templates, resulting in eventually not working generated code when someone doesn't mind this and defines completely different parameter names. With my list solution at least the defined parametername will be used.

But one thing still is interesting for me: user defined macros can be created? I've searched for such a possibility but did not found it. I also searched something to see which macros are already existing just to know what possibilities are given to me with existing macros. The user guide doesn't tell much about this topic (just short description of existing but not all macros).

Quote
Do you perform a model transformation before the code generation? I always do a two step generation for Java: MDA transformation from platform independant model to Java specific model, then code generation. My imports are solved two ways : either I create a Dependency connector between my classes, or I add a tagged value to my class:

I don't know much about MDA but I've tried it with a transformation to C++ with a single class resulting in no noticeable difference. I think that I'm already doing the UML modeling C++ specific so that there is no need for a transformation.
The solution with the classtags is an acceptable way for defining the needed namespace statements. This works well and I'll have less "after generation"-work ;) Thank you!

Stephane B

  • EA User
  • **
  • Posts: 31
  • Karma: +0/-0
    • View Profile
Re: Some questions related to code generation / C+
« Reply #6 on: June 04, 2013, 06:18:58 pm »
Quote
user defined macros can be created? I've searched for such a possibility but did not found it.

After all, macros are nothing more than templates (or am I missing something?) with Template Type set to "<none>" and their names in upper case (by convention). But the IDE won't provide autocompletion.

Quote
The user guide doesn't tell much about this topic (just short description of existing but not all macros)

I'm afraid that's pretty much all there is. There are few macros in EA, but except the MATH_XXX, they are in the manual.
« Last Edit: June 04, 2013, 06:21:47 pm by StephaneB »