Eclipse Community Forums - RDF feed
https://www.eclipse.org/forums/
Eclipse Community ForumsCollections and typecasting...
https://www.eclipse.org/forums/index.php/mv/msg/440627/987427/#msg_987427
I'm still having fun with QVT/OCL and UML profiles. I have a profile that
defines a Stereotype MyStereo that has a to-n reference to NamedElement:
MyStereo
{
usages : NamedElement[*];
}
Now, in an inplace QVTO transformation I'm working with elements that have
MyStereo applied and I want to 1) access and 2) add to the MyStereo::usages
collection.
I've tried several ways, but always hit a dead end at some typecast or
other. I can get the value typed as OclAny with
var stereo := self.getAppliedStereotype("MyProfile::MyStereo");
var value := self.getValue(stereo, "usages");
but then I don't know how to proceed to work with it as a Collection. I can
get a collection of the correct type doing something like
var usages := value.oclAsSet()->flatten()->selectByKind(NamedElement);
But the resulting Set is no longer the original collection. So when adding
an element to it with e.g.
usages+=self;
I guess I have to set the resulting collection back on the Stereotype.
Unfortunately, this doesn't work:
self.setValue(stereo, "usages", usages);
"Cannot find operation (setValue(Stereotype, String,
Collection(NamedElement))) for the type Element"
I can't figure out how to cast usages so the setValue() operation is applicable.
Going the other way round by directly casting value to the correct type
doesn't work either. From what I could gather by stepping through the
parser, it's due to the known issues with type expressions. This:
var usages := value.oclAsType(Collection(NamedElement));
gives me "Unrecognized Variable: (Collection)" because it's resolved as a
variable expression instead of a collection type literal.
Do you have any suggestions for another, working way to add something into a
stereotype instance?]]>Carsten Reckord2012-11-26T15:03:29-00:00Re: Collections and typecasting...
https://www.eclipse.org/forums/index.php/mv/msg/440627/987441/#msg_987441
tl;dr; - What it seems to come down to is this:
How can I cast a variable of type Collection(NamedElement) to OclAny?
var stereo := self.getAppliedStereotype("MyProfile::MyStereo");
var value := self.getValue(stereo, "usages");
var usages := value.oclAsSet()->flatten()->selectByKind(NamedElement);
usages+=self;
var x : OclAny := usages.oclAsType(OclAny);
self.setValue(stereo, "usages", x);
Here, the cast 'usages.oclAsType(OclAny)' only seems to change the member
type of the collection, resulting in this error:
Type mismatch: can not convert from 'MyTrafo::Collection(NamedElement)'
to 'oclstdlib::OclAny' type]]>Carsten Reckord2012-11-26T15:54:13-00:00Re: Collections and typecasting...
https://www.eclipse.org/forums/index.php/mv/msg/440627/987457/#msg_987457
I'm afraid you're hitting one of the limitations of the Ecore-based OCL,
which endeavours to deduce types from values and compensates the
commonest errors with a strange heuristic. The problem is that eGet()
returns Object for Collections requiring the heuristic compensation.
(The new Pivot-based approach retains static type information for eGet
and stereotypes so that the correct behaviour is achievable without
heuristics.)
This doesn't help you today.
I recommend using a Java function with a clear name so that you can take
control. If you try tricking the compiler/evaluator you will just move
from one strange combination to another.
Regards
Ed Willink
On 26/11/2012 15:54, Carsten Reckord wrote:
> Addendum:
>
> tl;dr; - What it seems to come down to is this:
>
> How can I cast a variable of type Collection(NamedElement) to OclAny?
>
> var stereo := self.getAppliedStereotype("MyProfile::MyStereo");
> var value := self.getValue(stereo, "usages");
> var usages := value.oclAsSet()->flatten()->selectByKind(NamedElement);
> usages+=self;
> var x : OclAny := usages.oclAsType(OclAny);
> self.setValue(stereo, "usages", x);
>
> Here, the cast 'usages.oclAsType(OclAny)' only seems to change the member
> type of the collection, resulting in this error:
>
> Type mismatch: can not convert from 'MyTrafo::Collection(NamedElement)'
> to 'oclstdlib::OclAny' type
>]]>Ed Willink2012-11-26T16:54:51-00:00