Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » M2T (model-to-text transformation) » Jet : define recursive fonction.
Jet : define recursive fonction. [message #15903] Fri, 11 May 2007 09:39 Go to next message
Eclipse User
Originally posted by: fifre.news.free.fr

Hello,

I'm trying to use Jet to transform an instance of an ecore-based model in
a dot file (in order to represent my instances in a more friendly way).
My models use the "composite" pattern, so i must define a recursive
function to browse all my composite elements.

I didn't find in the documentation how to define a function in a Jet file,
so i don't know how can i process elements recursively.

thanks for reading,
regards,
Bastien Amar
Re: define recursive fonction. [message #16881 is a reply to message #15903] Thu, 17 May 2007 10:02 Go to previous message
Paul Elder is currently offline Paul Elder
Messages: 849
Registered: July 2009
Senior Member
Bastien:

Recursion is a bit of pain in JET. There are two possibilities: flattening
and recursive templates. Let's assume you have an input model that describes
Java classes:

<project name="foo">
<package name="a.b.c">
<class name="Foo">
<class name="NestedInFoo"/>
</class>
<class name="Bar"/>
</package>
</project>

1) flattening. The XPath implementation lets you write expressions like:
$package//class, which, assuming $package references a package element, will
return all the class elements directly or indirectly contained under
$package. You could then write a simple <c:iterate> to process each element.
There are, however, times when this probably won't do.

2) recursive templates. A template my invoke another template via
<c:include>. Although the tag is called 'include', the template is in fact
invoked, like a method; as such, you can do recursion. The biggest pain is
passing values to the invoked template. JET only has global variables (I'd
like to fix that one day...), but c:include has a passVariables attribute
which lets you pretend that variables are scoped to the template invocation.
An example:

Assume you have a template that generates a class from a 'class' element,
and that $class is the current class instance. main.jet might look like:

<c:iterate select="/project/package/class" var="class">
<ws:file template="templates/class/genClass.jet" path="..."/>
</c:iterate>

The genClass.jet template needs to include itself recursively...

class <c:get select="$class/@name"/> {
<c:iterate select="$class/class" var="class">
<c:include template="genClass.jet" />
</c:iterate>
}

This works, because <c:iterate> carefully saves the current value of $class
before setting it during the loop. But, you could also write:

class <c:get select="$class/@name"/> {
<c:iterate select="$class/class" var="class">
<c:include template="genClass.jet" passVariables="class" />
</c:iterate>
}

The differences between the two is that with passVariables, the template
only receives that variables, and any variables set during the template's
execution are removed when it exits.

Finally, as with any recursion, infinite loops, manifesting themselves by
long pauses and then stack overflows are possible.

Hope this helps.

Paul
Previous Topic:Antlr and jet2 integration
Next Topic:Using AND in a test
Goto Forum:
  


Current Time: Fri Apr 18 14:32:00 EDT 2014

Powered by FUDForum. Page generated in 0.02032 seconds