Home » Modeling » TMF (Xtext) » How to add customized method to the xtext generated dsl interface(How to use customized processor to add method declaration in the infered ecore model )
How to add customized method to the xtext generated dsl interface [message #645974] |
Tue, 21 December 2010 12:32 |
Pierre-Alain BOURDIL Messages: 25 Registered: September 2010 |
Junior Member |
|
|
Greetings,
The problem :
i defined a dsl, which manage interface, such as :
Interface:
"interface" name=ID {
members += InterfaceMembers
}
InterfaceMembers:
Operation|Attribute
Attribute :
"attribute" name=ID
Operation
"operation" name=ID
The Interface generated by xtext has operation to get InterfaceMembers :
EList<InterfaceMember> getMembers();
I'd like to add two operations to this Interface (along with their implementation in the InterfaceImpl class), getOperations and getAttributes, with the above signature :
EList<Operation> getOperations();
EList<Attribute> getAttribute();
One tentative of solution :
I've tried to customize the xtext code generation, namely ecore inference, to add the operation "getOperations", but i failed. I've created a Xtend file, which look likes that :
import ecore;
import webIDL;
process(xtext::GeneratedMetamodel this) :
ePackage.process()
;
process(EPackage this) :
eClassifiers.process()
;
process(EClassifier this) :
null
;
process(EClass this) :
if this.name == 'Interface' then
this.addOperation(
"getOperations",
List[Operation], // This is my dsl operation type, imported from "import WebIDL", encapsulated in a Xpand2::type list
'return new org.eclipse.emf.common.util.BasicEList<Operation>();')
;
create ecore::EOperation addOperation(ecore::EClassifier c,
String strName,
xpand2::Type type,
String strBody):
type->
setName(strName) ->
setEType(type) -> // type error
((ecore::EClass)c).eOperations.add(this);
The code above does not work, because setEType expect an ecore::EClassifier as a parameter, changing the type of the addOperation type argument to ecore::EClassifier does not solve the problem. Moreover, i can't figure out how force the ecore inference to generate an EList of operation for the getOperation method.
My questions are :
1) How can i force the ecore inference to generate an EList of Operation as return type of my getOperation ?
2) Did i misused the postprocessor functionnality ? My idea here was to add those methods directly in my dsl ecore metamodel and let the xtext ecore inference output the source code. In case y idea's wrong, how can i generate those methods ?
|
|
|
Re: How to add customized method to the xtext generated dsl interface [message #646004 is a reply to message #645974] |
Tue, 21 December 2010 14:26 |
Jan Koehnlein Messages: 760 Registered: July 2009 Location: Hamburg |
Senior Member |
|
|
It looks like you're confusing type systems (xpand, ecore, Java) in your
transformation - at least the argument 'type' should rather be an
ecore::Classifier, and its multiplicity should be provided by setting
'upperBound' to -1 on the EOperation instead of passing a list.
Nevertheless, I am not sure if that's the only problem.
You might have noticed that it's kind of tricky writing this
transformation, so I'd suggest to modify the Ecore model by hand (start
with the generated one) to get it clear on the EMF side and use the
modified Ecore as an imported metamodel.
Am 21.12.10 13:32, schrieb Pierre-Alain BOURDIL:
> Greetings,
> The problem :
> i defined a dsl, which manage interface, such as :
> Interface:
> "interface" name=ID {
> members += InterfaceMembers
> }
>
> InterfaceMembers: Operation|Attribute
>
> Attribute : "attribute" name=ID
>
> Operation
> "operation" name=ID
>
>
> The Interface generated by xtext has operation to get InterfaceMembers :
>
> EList<InterfaceMember> getMembers();
>
>
> I'd like to add two operations to this Interface (along with their
> implementation in the InterfaceImpl class), getOperations and
> getAttributes, with the above signature :
>
> EList<Operation> getOperations();
> EList<Attribute> getAttribute();
>
>
> One tentative of solution :
>
> I've tried to customize the xtext code generation, namely ecore
> inference, to add the operation "getOperations", but i failed. I've
> created a Xtend file, which look likes that :
>
> import ecore;
> import webIDL;
>
>
> process(xtext::GeneratedMetamodel this) :
> ePackage.process()
> ;
>
> process(EPackage this) :
> eClassifiers.process()
> ;
>
> process(EClassifier this) :
> null
> ;
>
> process(EClass this) :
> if this.name == 'Interface' then
> this.addOperation(
> "getOperations",
> List[Operation], // This is my dsl operation type, imported from "import
> WebIDL", encapsulated in a Xpand2::type list
> 'return new org.eclipse.emf.common.util.BasicEList<Operation>();')
> ;
>
>
> create ecore::EOperation addOperation(ecore::EClassifier c, String strName,
> xpand2::Type type, String strBody):
> type-> setName(strName) ->
> setEType(type) -> // type error ((ecore::EClass)c).eOperations.add(this);
>
>
> The code above does not work, because setEType expect an
> ecore::EClassifier as a parameter, changing the type of the addOperation
> type argument to ecore::EClassifier does not solve the problem.
> Moreover, i can't figure out how force the ecore inference to generate
> an EList of operation for the getOperation method.
>
> My questions are :
> 1) How can i force the ecore inference to generate an EList of Operation
> as return type of my getOperation ? 2) Did i misused the postprocessor
> functionnality ? My idea here was to add those methods directly in my
> dsl ecore metamodel and let the xtext ecore inference output the source
> code. In case y idea's wrong, how can i generate those methods ?
--
Need professional support for Eclipse Modeling?
Go visit: http://xtext.itemis.com
---
Get professional support from the Xtext committers at www.typefox.io
|
|
|
Re: How to add customized method to the xtext generated dsl interface [message #646029 is a reply to message #646004] |
Tue, 21 December 2010 16:26 |
Pierre-Alain BOURDIL Messages: 25 Registered: September 2010 |
Junior Member |
|
|
Thanks for your answer,
what i understood is that there's no easy way to add method using ecore inference postprocessing. Manually update the ecore mm, then using it as an imported mm prohibits evolution on this mm, thereby on my grammar, which is not possible for me at this time.
Regarding type confusion, you're right, i was wondering if exists an easy way to reference dsl specific type within xpand context , because of my little knowledge of those tools.
Now, if there' s no way to easily custom the generated interface using xtend, is there a way to generate a posteriori the source code for the method directly in the Interface and InterfaceImpl code, using xpand template or maybe atl transformation plugged using the MWE workflow ?
Regards.
|
|
| |
Re: How to add customized method to the xtext generated dsl interface [message #646122 is a reply to message #646029] |
Wed, 22 December 2010 08:41 |
Jan Koehnlein Messages: 760 Registered: July 2009 Location: Hamburg |
Senior Member |
|
|
First of all: What do you need this separation for? If you need that in
an Xpand code generator only, the easiest and most common way is to
write an Xtend function filtering the feature. As you can put the first
parameter of a function call in front of the method name with a dot the
call will look like a method call on the object itself, e.g.
getAttributes(Interface this) : getOperations().typeSelect(Attribute);
// call as myInterface.getAttributes()
If you really need these operations on the Java classes you have to
modify the Ecore model. Manually evolving the ecore model in parallel to
the grammar is not that complicated, as the grammar editor will give you
early feedback on mismatches. We have discovered that the Ecore
derivation can help a lot in the early stages of a project, but it makes
sense to switch to the imported metamodel when the complexity increases.
If you want to do the transformation anyway, here are a couple of hints
1) Use the JavaMetamodel (import Java namespaces rather than Ecore
ones). This will give you a lot more control over the Ecore artifacts -
not only the structural features but also the Java-Bean-Properties
2) If you cannot access the EClass Objects from Xtend directly, write an
Xtend-Function that delegates to Java.
3) AFAIK, there are a couple of ways to get the implementation body into
an EOperation, e.g. by an EAnnotation, using delegates or by just
manually adding them in the Java class and marking the method as not
@generated. The latter will not work with Xtext, as the Java classes are
completely wiped on each generation run. I'd recommend having a loog at
the
/org.eclipse.emf.mwe2.lib/src/org/eclipse/emf/mwe2/ecore/Eco reGenerator.java
from MWE, which is an alternative EcoreGeneratorFragment allowing to put
customizations (Java classes that extend the generated ones) at specific
locations and automatically dealing with adapting the factory.
Am 21.12.10 17:26, schrieb Pierre-Alain BOURDIL:
> Thanks for your answer,
> what i understood is that there's no easy way to add method using ecore
> inference postprocessing. Manually update the ecore mm, then using it as
> an imported mm prohibits evolution on this mm, thereby on my grammar,
> which is not possible for me at this time.
> Regarding type confusion, you're right, i was wondering if exists an
> easy way to reference dsl specific type within xpand context , because
> of my little knowledge of those tools.
> Now, if there' s no way to easily custom the generated interface using
> xtend, is there a way to generate a posteriori the source code for the
> method directly in the Interface and InterfaceImpl code, using xpand
> template or maybe atl transformation plugged using the MWE workflow ?
> Regards.
--
Need professional support for Eclipse Modeling?
Go visit: http://xtext.itemis.com
---
Get professional support from the Xtext committers at www.typefox.io
|
|
|
Re: How to add customized method to the xtext generated dsl interface [message #646902 is a reply to message #646122] |
Sun, 02 January 2011 21:06 |
Pierre-Alain BOURDIL Messages: 25 Registered: September 2010 |
Junior Member |
|
|
Greetings,
Thanks everyone for your answers, it helped so much. I finally found how to solve my problem, using xtend and postprocessing :
process(EClass this) :
if this.name == 'Interface' then
addOperation(
"getOperations",
ePackage.getEClassifier("Operation"),
-1,
' //JAVA CODE HERE' )->
if this.name == 'Interface' then
addOperation(
"getAttributes",
ePackage.getEClassifier("Attribute"),
-1,
'//JAVA CODE HERE'');
create ecore::EOperation addOperation(
ecore::EClassifier c, String strName,
ecore::EClassifier type,
Integer upperBound,
String strBody):
setName(strName) ->
setEType(type) ->
setUpperBound(upperBound)->
addBodyAnnotation(strBody)->
((ecore::EClass)c).eOperations.add(this);
create ecore::EAnnotation addBodyAnnotation(ecore::EOperation op, String strBody):
setSource("http://www.eclipse.org/emf/2002/GenModel") ->
this.createBody(strBody) ->
op.eAnnotations.add(this);
create ecore::EStringToStringMapEntry createBody(ecore::EAnnotation anno, String strBody):
setKey("body") ->
setValue(strBody) ->
anno.details.add(this);
The code above uses m2m Xtend capabilities, namely "create" operation. The createBody operation create the body of the operation using EAnnotation (key = body).
Two operations, getAttributes and getOperations, are added, using the chain expression. Their types are multi-valued, because of the -1 upper bound.
One problem was to reference dsl specific type within xpand context, and there is a very easy way to do that, provided by the ecore EMFMetaModel from Xtend :
ePackage.getEClassifier("Attribute"),
This expression returns the EClass "Attribute" generated by xtext.
Regards ,
|
|
|
Goto Forum:
Current Time: Fri Apr 26 02:55:47 GMT 2024
Powered by FUDForum. Page generated in 0.03883 seconds
|