Home » Modeling » TMF (Xtext) » [Xtext] Problem modifying enumeration in post processing (Xtend)
[Xtext] Problem modifying enumeration in post processing (Xtend) [message #54144] |
Tue, 30 June 2009 05:14  |
Eclipse User |
|
|
|
Hi all,
I'm trying to migrate from oAW Xtext to TMF Xtext. Since the handling
of enumarations has been changed, I want to post process the ecore
model in order to restore the original behaviour.
In my grammar, an enumeration is defined (actually this is only one
example, I have severals. In the following case I might add a "package"
as default NULL value, but I have cases in which this doesn't work):
------------------------
enum VisibilityModifier:
public | private;
------------------------
Now I want to add the NULL literal. Only adding a new literal doesn't
help, as public becomes the default value (and its value is 0). That
is, I have to increment the value for all defined literals and then add
my NULL literal.
However, I don't get Xtend to do that. Adding a literal is working like that:
--------------------------------------------------------
Void addNullValue(ecore::EPackage p, String toEnum):
let e=(ecore::EEnum) p.getEClassifier(toEnum):
e.addLiteral("NULL", "NULL", 0);
--------------------------------------------------------
OK, but as explained, this does only solve half of the problem, I still
have to increment the values for the existing literals. I tried several
variations, the most simple one:
--------------------------------------------------------
Void addNullValue(ecore::EPackage p, String toEnum):
let e=(ecore::EEnum) p.getEClassifier(toEnum):
e.eLiterals.collect(lit|lit.setValue(lit.value+1)) ->
e.addLiteral("NULL", "NULL", 0);
--------------------------------------------------------
It does not work, the following error occurs:
--------------------------------------------------------
EvaluationException : Couldn't find property 'value' for type
mitra::VisibilityModifier
de::feu::MitraPostProcessor.ext[4181,9] on line 100 'lit.value'
de::feu::MitraPostProcessor.ext[190,37] on line 11
'addNullValue(p,"VisibilityModifier")'
--------------------------------------------------------
I do not understand how this happens. "lit" is expected to be an
intance of ecore::EEnumLiteral, that is a literal of
VisibilityModifier, and not the enum itself. (Also, there are no errors
"compiling" the Xtend source). OK, I tried it to manually iterate over
the collection (I removed the let-expression as it caused lots of weird
syntax errors I don't fully understand... I assume there is something
wrong with let, e.g., code assist does not work within a let
expression):
--------------------------------------------------------
Void addNullValue(ecore::EPackage p, String toEnum):
((ecore::EEnum)p.getEClassifier(toEnum)).eLiterals.incAllVal ues() ->
((ecore::EEnum)p.getEClassifier(toEnum)).addLiteral("NULL", "NULL", 0);
ecore::EEnumLiteral incValue(ecore::EEnumLiteral literal):
literal.setValue(literal.value+1) -> literal;
Void incAllValues(List[ecore::EEnumLiteral] list):
if list.size>0 then
list.first().incValue() ->
list.withoutFirst().incAllValues();
--------------------------------------------------------
But, again, the same error as above:
--------------------------------------------------------
EvaluationException : Couldn't find operation 'incValue()' for
mitra::VisibilityModifier.
de::feu::MitraPostProcessor.ext[4540,23] on line 111 'list.first().incValue()'
de::feu::MitraPostProcessor.ext[4016,65] on line 98
'(ecore::EEnum)p.getEClassifier(toEnum).eLiterals.incAllValu es()'
de::feu::MitraPostProcessor.ext[190,37] on line 11
'addNullValue(p,"VisibilityModifier")'
--------------------------------------------------------
At this point I assume it's a bug, as incAllValues is called without an
error, which means the list must contain EEnumLiterals -- but then how
does the enumeration sneaks into this collection again?
Do you have any solutions for my problem? (In the worst case, I'll try
to write a Java extension, but I assume this problem should be solvable
within Xtend).
Cheers
Jens
|
|
|
Re: [Xtext] Problem modifying enumeration in post processing (Xtend) [message #54175 is a reply to message #54144] |
Tue, 30 June 2009 05:58   |
Eclipse User |
|
|
|
Hi all,
I'm answering my self, or at least add some details. I have now
implemented the extension in Java:
------------------------------------------------------------ ---
Void addNullValue(ecore::EPackage p, String toEnum):
doAddNullValue( (ecore::EEnum) p.getEClassifier(toEnum) );
Void doAddNullValue(ecore::EEnum e):
JAVA
de.feu.MitraPostProcessorHelper.addNullValue(org.eclipse.emf .ecore.EEnum);
------------------------------------------------------------ ---
with
------------------------------------------------------------ ---
public
class MitraPostProcessorHelper {
public static void addNullValue(org.eclipse.emf.ecore.EEnum e) {
for (EEnumLiteral literal : e.getELiterals()) {
literal.setValue(literal.getValue() + 1);
}
EEnumLiteral nullLiteral = EcoreFactory.eINSTANCE.createEEnumLiteral();
nullLiteral.setName("NULL");
nullLiteral.setLiteral("NULL");
nullLiteral.setValue(0);
e.getELiterals().add(0, nullLiteral);
}
}
------------------------------------------------------------ ---
Previously I assumed that it's the value of a literal which makes it
the default value (if set to 0). But that's wrong, instead it is the
first literal in the list which becomes the default one. That is,
-------------------------------------
e.getELiterals().add(0, nullLiteral);
-------------------------------------
does not make the nullLiteral the default one, but
-------------------------------------
e.getELiterals().add(0, nullLiteral);
-------------------------------------
does. As I don't know how to easily implement the last line in Xtend
(add(int, Object) is not available), I have to use Java anyway.
Cheers
Jens
|
|
| | | |
Re: [Xtext] Problem modifying enumeration in post processing (Xtend) [message #54386 is a reply to message #54305] |
Wed, 01 July 2009 03:49   |
Eclipse User |
|
|
|
Hi Krzysztof,
yes, that is definitely an option and should work fine.
Regards,
Sebastian
Am 01.07.2009 0:36 Uhr, schrieb Krzysztof Kowalczyk:
> Sebastian Zarnekow pisze:
>> Hi Jens,
>>
>> please be aware of the fact that JAVA extensions should not be used
>> from within the post processor step. The post processor is used from
>> inside your IDE which has no idea about any java classes that reside
>> in your project. They are only available at runtime.
>
> But it still is possible to put Java extensions to a plugin and install
> the plugin to the eclipse instance, isn't it?
> So if some extension reside in a plugin that is installed it should be
> possible to reach them.
> That, in some way, should solve the problem of QVT / ATL integration too.
>
> Regards,
> Krzysztof Kowalczyk
|
|
|
Re: [Xtext] Problem modifying enumeration in post processing (Xtend) [message #54409 is a reply to message #54226] |
Wed, 01 July 2009 04:41   |
Eclipse User |
|
|
|
Hi Sebastian,
On 2009-06-30 15:53:23 +0200, Sebastian Zarnekow
<Sebastian.Zarnekow@itemis.de> said:
> please be aware of the fact that JAVA extensions should not be used
> from within the post processor step. The post processor is used from
> inside your IDE which has no idea about any java classes that reside in
> your project. They are only available at runtime.
I'm not sure if I understand what you mean. At least, the JAVA
extension _is_ working within the post processor step. That is, I have
an Xtext project with the Xtext grammar and the MWE workflow. I have
created a Java class within the same folder as the Xtend postprocessor
extension, and I can simply call this Java class as a JAVA extension as
decribed in my second posting. Actually, my second posting doesn't
describe a problem, it describes a running solution.
But I agree insofar as I prefer solving the problem within Xtend -- but
the problem is that Xtend obviously has a problem with the
ecore::EEnumLiteral as described in my initial posting. This is why I
created the JAVA extension in the first place.
> Can you please describe the oAW behavior, that you want to mimic?
Quite simple: I want to mimic the oAW Xtext enum behaviour with default
NULL literals.
Cheers,
Jens
|
|
| | | |
Re: [Xtext] Problem modifying enumeration in post processing (Xtend) [message #54647 is a reply to message #54488] |
Thu, 02 July 2009 03:31  |
Eclipse User |
|
|
|
Hi Jens,
Jens v.P. wrote:
> On 2009-07-01 12:45:30 +0200, knut.wannheden@paranor.ch (Knut Wannheden)
> said:
>> You should also be able to add your enumeration literal to the end of
>> the list and then set the default on the EAttributes of that type
>> (using EAttribute#setDefaultValueLiteral(String)). That is then a pure
>> Xtend solution.
>
> OK.... but how? Do you have any hints?
>
Sorry if I wasn't quite clear enough. You've already worked out how to
add the enumeration literal to the end of the list. Now all you have to
do is set the default you want on the EAttributes of that type. IMHO
this is a good practice anyways.
In your case the post processing might look like this:
import xtext;
import ecore;
process(GeneratedMetamodel this) :
ePackage.process()
;
process(EPackage this) :
eClassifiers.process()
;
process(EClassifier this) :
null
;
process(EClass this) :
eStructuralFeatures.process()
;
process(EEnum this) :
if name == 'VisibilityModifier' then
eLiterals.add(newLiteral('null', 'NULL', eLiterals.size))
;
create EEnumLiteral newLiteral(String literal, String name, int value) :
setLiteral(literal) -> setName(name) -> setValue(value)
;
process(EStructuralFeature this) :
null
;
process(EAttribute this) :
if eAttributeType.name == 'VisibilityModifier' then
setDefaultValueLiteral('NULL')
;
Hope that helps,
--knut
|
|
|
Goto Forum:
Current Time: Sat Apr 26 01:06:50 EDT 2025
Powered by FUDForum. Page generated in 0.03122 seconds
|