Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » M2T (model-to-text transformation) » [Acceleo] Generate a complex inheritance list
[Acceleo] Generate a complex inheritance list [message #665684] Fri, 15 April 2011 13:51 Go to next message
Cedric Moonen is currently offline Cedric MoonenFriend
Messages: 274
Registered: August 2009
Senior Member
Hello,

I am currently using Acceleo to generate C++ code. I have a case in which I need to generate a C++ which inherits from some other classes. The classes it is inheriting from are not all contained in one sequence of my object but rather should be composed depending of different conditions.

It becomes quite difficult to manage the code in that case. Let's take a simple example: suppose that for a certain model, all the conditions end up that my class doesn't inherit from any interface. In that specific case, I can't generate a ':' character before the list of inherited classes (this will end up in a compilation error). Already for this simple example, this becomes difficult because for that simple character, I have to make a lot of checks to see if I have to print it.

Then another problem is the fact that I have to generate a ',' between each classes. Here also, it becomes very complex to write the checks.

A solution would be to be able to build a list of strings beforehand (each string corresponds to a class name) depending on the different checks, and then generate the code based on that list. It then becomes much easier to write: I simply have to check if my list is empty or not (for the ':' character) and then write a simple for loop with a ',' separator.

Unfortunately, building such a list seems impossible since variables in Acceleo are final.

Is there another way to achieve something like this without having to use a java service ?
Re: [Acceleo] Generate a complex inheritance list [message #665927 is a reply to message #665684] Mon, 18 April 2011 08:17 Go to previous messageGo to next message
Stephane Begaudeau is currently offline Stephane BegaudeauFriend
Messages: 458
Registered: April 2010
Location: Nantes (France)
Senior Member

Hi Cedric,

I understand perfectly the kind of problem that you are facing, here are some solutions for you:

>>> Then another problem is the fact that I have to generate a ',' between each classes. Here also, it becomes very complex to write the checks.
- You want to write a collection of element separated by "," except for the last one like "A, B, C, D, E". You have two solutions :

[Sequence{'A', 'B', 'C', 'D', 'E'}->sep(', ')/]
[for (str : String | Sequence{'A', 'B', 'C', 'D', 'E'}) seperator(', ')][str/][/for]


In a Java generator, in order to write something like this:

public final MyClass implements MyInterface1, MyInterface2, MyInterface3 {

}


Which is a similar problem, we are doing something like this:

[template protected genBody(aClass : Class)]
[genVisibility()/][genAbstract()/][genFinal()/]class [genName()/][genInheritance()/][genInterfaceRealization()/] {
[genClassMembers()/]
}
[/template]

[template public genInterfaceRealization(aClass : Class)]
[if (not aClass.getAllInterfaces()->isEmpty())] implements [for (namedElement : NamedElement | aClass.getAllInterfaces()) separator(', ')][namedElement.genName()/][/for][/if]
[/template]



You should try something similar with ":" instead of "implements" and with the same use of the "separator" keyword. In our case, the "getAllInterface()" is a query in order to simplify the "genInterfaceRealization" template. The result of a query being stored in a cache it also improve performances since we are calling it several times.


Stephane Begaudeau, Obeo
--
Twitter: @sbegaudeau
Acceleo wiki: http://wiki.eclipse.org/Acceleo
Blogs: http://stephanebegaudeau.tumblr.com & http://sbegaudeau.tumblr.com

[Updated on: Mon, 18 April 2011 08:22]

Report message to a moderator

Re: [Acceleo] Generate a complex inheritance list [message #665936 is a reply to message #665927] Mon, 18 April 2011 08:58 Go to previous messageGo to next message
Cedric Moonen is currently offline Cedric MoonenFriend
Messages: 274
Registered: August 2009
Senior Member
Hello Stéphane,

Thank you for your answer. Yes I'm aware of the separator feature of the for block and it is indeed appropriate in this case. However, my problem resides earlier: building such a sequence of classes to inherit from.

My model doesn't have an attribute listing all base classes to inherit from. This list should in fact be built from several attributes of my model. To make it simple, suppose that my model has several boolean attributes which when there are true specifies that the component inherit from a specific class. My case is a bit more complex than this but this summarize my problem: I have to build the list of base classes based on different attributes in my model.

Since all variables in Acceleo are final, I don't really see how I can create such a list...

Thank you,
Cédric
Re: [Acceleo] Generate a complex inheritance list [message #665937 is a reply to message #665684] Mon, 18 April 2011 09:04 Go to previous messageGo to next message
Stephane Begaudeau is currently offline Stephane BegaudeauFriend
Messages: 458
Registered: April 2010
Location: Nantes (France)
Senior Member

Hi,

It is a bit difficult to answer this question without the metamodel but you could try something like:

myRootElement.eAllContent->filter(Type1)->collect(t1 : Type1 | t1.shouldExtend)- >union(myRootElement.eAllContent->filter(Type2)->collect(t2 : Type2 | t2.shouldExtend))

Variables are indeed final but with operators like ->union() you can still create composed lists.

Stephane Begaudeau, Obeo
--
Twitter: @sbegaudeau
Acceleo wiki: http://wiki.eclipse.org/Acceleo
Blogs: http://stephanebegaudeau.tumblr.com & http://sbegaudeau.tumblr.com

[Updated on: Mon, 18 April 2011 09:05]

Report message to a moderator

Re: [Acceleo] Generate a complex inheritance list [message #666106 is a reply to message #665684] Tue, 19 April 2011 07:24 Go to previous messageGo to next message
Cedric Moonen is currently offline Cedric MoonenFriend
Messages: 274
Registered: August 2009
Senior Member
Hello,

The problen is that I don't have a sequence original, but I need to build it from scratch. I could eventually use a lot of LET blocks which are always the result of the previous LET block with one (or more) appended element. But this soon becomes quite complex.
I also need to have some IF test to check whether an element has to be appended to the list.

In java, this would be something like this:
List<String> myInterfaces = new LinkedList<String>();
if (myElement.val1) {
   myInterfaces.add("Interfaces1");
}
if (myElement.val2) {
   myInterfaces.add("Interfaces2");
}
for (Behavior behavior : myElement.behaviors) {
   myInterfaces.add(behavior.getName() );
}


This is some code that shows more or less what I'm trying to achieve (myElement is my model element that I'm generating code for).
I know that I could use a Java service and simply write a similar piece of code but I would like to know if there is a way to do that in pure Acceleo.
If you had to "translate" that piece of code in Acceleo, would you be able to do so ?

Thank you,
Cédric
Re: [Acceleo] Generate a complex inheritance list [message #666133 is a reply to message #665684] Tue, 19 April 2011 09:09 Go to previous messageGo to next message
Stephane Begaudeau is currently offline Stephane BegaudeauFriend
Messages: 458
Registered: April 2010
Location: Nantes (France)
Senior Member

Hello

I'll have to admit this organization is not very easy to manipulate. It should work with something like this:

[let seq : Sequence(String) = Sequence{}]
[seq->union(if(true) then Sequence{'a'} else Sequence{} endif)->union(if(true) then Sequence{'b'} else Sequence{} endif)/]
[/let]


or

[let seq : Sequence(String) = (if true then if false then Sequence{'a'} else Sequence{'b'} endif else Sequence{} endif)]
[seq->sep(', ')/]
[/let]


>>> If you had to "translate" that piece of code in Acceleo, would you be able to do so ?
I can translate it but if I really had to do it, I would see if I can change the metamodel (not always possible since it may be used by other software and in that case any changes could be expensive) and if I really had to manipulate this, I think I would choose a Java service because it would be easier to maintain than a complex expression. So if you just need this for a small problem, go for it, if you need several lines of "if then else endif' to solve your problem, use a Java service.

Stephane Begaudeau, Obeo
--
Twitter: @sbegaudeau
Acceleo wiki: http://wiki.eclipse.org/Acceleo
Blogs: http://stephanebegaudeau.tumblr.com & http://sbegaudeau.tumblr.com

[Updated on: Tue, 19 April 2011 09:14]

Report message to a moderator

Re: [Acceleo] Generate a complex inheritance list [message #666679 is a reply to message #665684] Thu, 21 April 2011 14:51 Go to previous message
Niels Brouwers is currently offline Niels BrouwersFriend
Messages: 80
Registered: July 2009
Member
Hi Cedric,

It seems to me that the meta-model is too far away from the target meta-model. When writing code generators, always make sure the gap to cross is relatively small. The abstraction level of the meta-model language should be almost the same as the target programming language. Proceed the M2T transformation with a M2M transformation, which actually performs the translation from the problem domain to the software domain.

In my opinion there are three things you can try to make the code templates easier:
1) Refactor the meta-model by adding the missing relationships. Create the instance model by hand, or preceed the M2T transformation with a M2M transformation, or
2) Create derived attributes in your meta-model that create the sequence of abstract classes, or
3) Create queries which populate the sequence (I assume this is possible in Acceleo)

Regards,
Niels.



Kind regards,
Niels Brouwers.
Previous Topic:[Acceleo3] using ecore in query
Next Topic:[Acceleo] Howto process the output before it is saved to a file
Goto Forum:
  


Current Time: Fri Mar 29 10:01:47 GMT 2024

Powered by FUDForum. Page generated in 0.03080 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top