Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » M2T (model-to-text transformation) » [Acceleo3] Generating code for nested elements(Calling template for top level node only and using recursion)
[Acceleo3] Generating code for nested elements [message #558102] Fri, 10 September 2010 08:14 Go to next message
Cedric Moonen is currently offline Cedric MoonenFriend
Messages: 274
Registered: August 2009
Senior Member
Hello,

I am developping a graphical editor with GMF in which the user is able to create blocks (with input and output ports) and link the ports together with connectors. A special type of block is a container block which can contain other blocks (and which opens in a separate diagram to reduce complexity). The main diagram is in fact just a container block.
The final purpose will be to generate C code that evaluates all the blocks and assign the different input and output ports (which are just variables).

For now, what I am trying to achieve is to generate one file containing the declaration of all blocks which are not container blocks. For this, my first restriction is that I want to call my main template only for the top level container block, and not for all container blocks which are further down in the chain. I solved this by having a pre condition on the template.

My module code looks like this:
[comment encoding = UTF-8 /]

[module generate(....)/]

[template public generate(container : ContainerBlock)? (container.eContainer() = null)]
	
[comment @main /]
[file (container.name, false, 'UTF-8')] 

[container.createVariables()/]

[/file]	
[/template]

[template public createVariables(container : ContainerBlock)]
[for (block: PLCOpenBlock | container.blocks) ? (not block.oclIsTypeOf(ContainerBlock))]
[block.type/] [block.name/];
[/for]
[for (block: PLCOpenBlock | container.blocks) ? (block.oclIsTypeOf(ContainerBlock))]
[container.createVariables()/]
[/for]

[/template]


This works fine only when I have one container block at the root and no other container blocks contained in this root container.
As soon as I have another container block inside the root container, my output file is empty. It seems the "createVariables" template is not event called, because I added some testing output text which is not printed in the output file.

What could be the reason of such a behavior ?
Re: [Acceleo3] Generating code for nested elements [message #558115 is a reply to message #558102] Fri, 10 September 2010 08:54 Go to previous message
Cedric Moonen is currently offline Cedric MoonenFriend
Messages: 274
Registered: August 2009
Senior Member
Well, this is typical: I found the problem a few moments after having posted the question...

I made a mistake in the recursion call: I call "createVariables" each time for the same block, which means that there is probably a stack overflow thrown which causes the data not to be written to the file.

I should modify the createVariables template to something like this:
[template public createVariables(container : ContainerBlock) )]
[for (block: PLCOpenBlock | container.blocks) ? (not block.oclIsTypeOf(ContainerBlock))]
[block.type/] [block.name/];
[/for]
[for (block: ContainerBlock | container.blocks)]
[block.createVariables()/]
[/for]
[/template]
Re: [Acceleo3] Generating code for nested elements [message #558124 is a reply to message #558102] Fri, 10 September 2010 08:51 Go to previous message
Laurent Goubet is currently offline Laurent GoubetFriend
Messages: 1877
Registered: July 2009
Senior Member
This is a multi-part message in MIME format.
--------------030204050106040606010202
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 7bit

Hi Cedric,

I had some trouble spotting "wrong" things in your templates, yet I do
have some things to mention :

The default Java generator considers there is a single "root" element in
your resource. This seem to be the case for you (one "root" container
that contains a number of others), but if it isn't, you'll have to alter
the "generate" method of the generated launcher in order to take into
account the other roots.

That set aside, you have an infinite loop in your "createVariables"
template. When you launch the generation that gives you an empty file,
are you sure there is nothing logged in the error log view (Window ->
show view -> Error log)? I believe you should get a
StackOverflowException. The reason is :

[...]

[template public createVariables(container : ContainerBlock)]
[...]
[for (block: PLCOpenBlock | container.blocks) ?
(block.oclIsTypeOf(ContainerBlock))]
[container.createVariables()/] <= should be "block.createVariables()"
[/for]
[/template]

I don't think there are other mistakes in your templates, they seem fine
to me. Please let me know if fixing this loop doesn't help (and if you
do have something in your error log which is not a StackOverflow, please
copy the stack trace :)).

Regards,

Laurent Goubet
Obeo

Cedric wrote:
> Hello,
>
> I am developping a graphical editor with GMF in which the user is able
> to create blocks (with input and output ports) and link the ports
> together with connectors. A special type of block is a container block
> which can contain other blocks (and which opens in a separate diagram to
> reduce complexity). The main diagram is in fact just a container block.
> The final purpose will be to generate C code that evaluates all the
> blocks and assign the different input and output ports (which are just
> variables).
>
> For now, what I am trying to achieve is to generate one file containing
> the declaration of all blocks which are not container blocks. For this,
> my first restriction is that I want to call my main template only for
> the top level container block, and not for all container blocks which
> are further down in the chain. I solved this by having a pre condition
> on the template.
>
> My module code looks like this:
> [comment encoding = UTF-8 /]
>
> [module generate(....)/]
>
> [template public generate(container : ContainerBlock)?
> (container.eContainer() = null)]
>
> [comment @main /]
> [file (container.name, false, 'UTF-8')]
> [container.createVariables()/]
>
> [/file]
> [/template]
>
> [template public createVariables(container : ContainerBlock)]
> [for (block: PLCOpenBlock | container.blocks) ? (not
> block.oclIsTypeOf(ContainerBlock))]
> [block.type/] [block.name/];
> [/for]
> [for (block: PLCOpenBlock | container.blocks) ?
> (block.oclIsTypeOf(ContainerBlock))]
> [container.createVariables()/]
> [/for]
>
> [/template]
>
> This works fine only when I have one container block at the root and no
> other container blocks contained in this root container.
> As soon as I have another container block inside the root container, my
> output file is empty. It seems the "createVariables" template is not
> event called, because I added some testing output text which is not
> printed in the output file.
>
> What could be the reason of such a behavior ?


--------------030204050106040606010202
Content-Type: text/x-vcard; charset=utf-8;
name="laurent_goubet.vcf"
Content-Transfer-Encoding: base64
Content-Disposition: attachment;
filename="laurent_goubet.vcf"

YmVnaW46dmNhcmQNCmZuOkxhdXJlbnQgR291YmV0DQpuOkdvdWJldDtMYXVy ZW50DQpvcmc6
PGEgaHJlZj0iaHR0cDovL3d3dy5vYmVvLmZyIj5PYmVvPC9hPg0KZW1haWw7 aW50ZXJuZXQ6
bGF1cmVudC5nb3ViZXRAb2Jlby5mcg0KdXJsOmh0dHA6Ly93d3cub2Jlby5m cg0KdmVyc2lv
bjoyLjENCmVuZDp2Y2FyZA0KDQo=
--------------030204050106040606010202--
Previous Topic:[Acceleo3] Generation for user defined metamodels
Next Topic:[xpand] name of UMLPrimitiveType not generated (=null)
Goto Forum:
  


Current Time: Wed Jan 29 10:35:47 GMT 2020

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

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

Back to the top