Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » OCL » Calling overriding methods
Calling overriding methods [message #60563] Wed, 20 August 2008 02:55 Go to next message
Stefan Schulze is currently offline Stefan SchulzeFriend
Messages: 70
Registered: July 2009
Member
Hi...

in OCL 1.1.2 I have problems with calling overriding methods of classes.

I have a class C1 with method foo():int (returning "1") and class C2
subclassing C1 with method foo():int (returning "2"). If I call foo() on an
object of type C2 it results in "1".
Some debugging shows that it currently depends on the order
EClass#getAllOperations() returns the overridden and overriding methods.
According to the OCL-specification the topmost matching operation (C2#foo())
should be called. To call an overridden method, you have to cast the source
(c.oclAsType(C1).foo()).

I think in UMLReflectionImpl#getOperations(EClassifier) or in
TypeUtil#getOperations(...) (if you want to handle overriding of methods of
OclAny, too) you should filter the overridden methods.

Is this issue already fixed in 1.2.x?

Stefan
Re: Calling overriding methods [message #60937 is a reply to message #60563] Wed, 20 August 2008 12:09 Go to previous messageGo to next message
Eclipse UserFriend
Originally posted by: cdamus.zeligsoft.com

Hi, Stefan,

This is odd. Would the underlying Java method invocation not always
choose the C2 override, anyway? If you can provide a reproducible test
case in a bug, I'd be grateful. This is the first I hear of this
phenomenon; you can be sure that the 1.2 release has the same behaviour.

Cheers,

Christian

Stefan Schulze wrote:
> Hi...
>
> in OCL 1.1.2 I have problems with calling overriding methods of classes.
>
> I have a class C1 with method foo():int (returning "1") and class C2
> subclassing C1 with method foo():int (returning "2"). If I call foo() on an
> object of type C2 it results in "1".
> Some debugging shows that it currently depends on the order
> EClass#getAllOperations() returns the overridden and overriding methods.
> According to the OCL-specification the topmost matching operation (C2#foo())
> should be called. To call an overridden method, you have to cast the source
> (c.oclAsType(C1).foo()).
>
> I think in UMLReflectionImpl#getOperations(EClassifier) or in
> TypeUtil#getOperations(...) (if you want to handle overriding of methods of
> OclAny, too) you should filter the overridden methods.
>
> Is this issue already fixed in 1.2.x?
>
> Stefan
>
>
Re: Calling overriding methods [message #61008 is a reply to message #60937] Wed, 20 August 2008 21:31 Go to previous messageGo to next message
Stefan Schulze is currently offline Stefan SchulzeFriend
Messages: 70
Registered: July 2009
Member
Hi Christian,

I tried to create the test case, but it seems as I where a little bit mixed
up last night.

Now the correct (possible-) bug-descriptions:

1.:
When the parser lookup the called method, it always returns the method which
is the lowest in the inheritance hierarchy (in the example this is
C1::foo()). The correct behaviour would be to return the topmost method
respecting the casted type (see 7.5.8 in OCL 2.0, formal/06-05-01, p. 19).
I attached an eclipse-project which contains an JUnit-TestCase. It tests a
dynamic ecore-structure C3 extends C2 extends C1. If the parser analyzes
C3::oclAsType(C2).foo(), the referredOperation should be C2::foo() but is
C1::foo().
I'm not absolutely sure about the preferred behaviour for calling methods,
because the OCL specification only talks about properties. But this bug
affects the properties, too. (Tests for operations and properties are
attached)


2.:
If a called EOperation is backed by an Java-method, always the topmost
method in the hierarchy is called. This behaviour is conform to Java but
possibly not conform to OCL (see 7.5.8 in OCL 2.0, formal/06-05-01, p. 19).
This Bug can't be profed by a test case, because it is concealed by the bug
described above.


I didn't raise a bug, because I'm not sure whether the behaviour regarding
overridden methods is faulty.

Stefan


"Christian W. Damus" <cdamus@zeligsoft.com> schrieb im Newsbeitrag
news:g8h1ig$iap$1@build.eclipse.org...
> Hi, Stefan,
>
> This is odd. Would the underlying Java method invocation not always
> choose the C2 override, anyway? If you can provide a reproducible test
> case in a bug, I'd be grateful. This is the first I hear of this
> phenomenon; you can be sure that the 1.2 release has the same behaviour.
>
> Cheers,
>
> Christian
>
> Stefan Schulze wrote:
>> Hi...
>>
>> in OCL 1.1.2 I have problems with calling overriding methods of classes.
>>
>> I have a class C1 with method foo():int (returning "1") and class C2
>> subclassing C1 with method foo():int (returning "2"). If I call foo() on
>> an
>> object of type C2 it results in "1".
>> Some debugging shows that it currently depends on the order
>> EClass#getAllOperations() returns the overridden and overriding methods.
>> According to the OCL-specification the topmost matching operation
>> (C2#foo())
>> should be called. To call an overridden method, you have to cast the
>> source
>> (c.oclAsType(C1).foo()).
>>
>> I think in UMLReflectionImpl#getOperations(EClassifier) or in
>> TypeUtil#getOperations(...) (if you want to handle overriding of methods
>> of
>> OclAny, too) you should filter the overridden methods.
>>
>> Is this issue already fixed in 1.2.x?
>>
>> Stefan
>>
>>


Re: Calling overriding methods [message #61146 is a reply to message #61008] Thu, 21 August 2008 13:30 Go to previous messageGo to next message
Eclipse UserFriend
Originally posted by: cdamus.zeligsoft.com

Hi, Stefan,

See some comments in-line, below.

Cheers,

Christian

Stefan Schulze wrote:
> Hi Christian,
>
> I tried to create the test case, but it seems as I where a little bit mixed
> up last night.
>
> Now the correct (possible-) bug-descriptions:
>
> 1.:
> When the parser lookup the called method, it always returns the method which
> is the lowest in the inheritance hierarchy (in the example this is
> C1::foo()). The correct behaviour would be to return the topmost method
> respecting the casted type (see 7.5.8 in OCL 2.0, formal/06-05-01, p. 19).

I think you mean, the most specific definition of the operation in the
static type of the expression, whether it is a cast expression or not.
I don't see how this could fail to be the case, as the parser doesn't
have any run-time type information, so it can only see what the static
type has available in features.


> I attached an eclipse-project which contains an JUnit-TestCase. It tests a
> dynamic ecore-structure C3 extends C2 extends C1. If the parser analyzes
> C3::oclAsType(C2).foo(), the referredOperation should be C2::foo() but is
> C1::foo().

Right, this seems incorrect. It should find the most specific operation
(as I mentioned above) which is C2:: foo() as you indicated. I think
probably that we're just taking the first operation that Ecore provides,
which are probably listed in top-down order instead of bottom-up.

This should be fixed. Please, raise a bug.

> I'm not absolutely sure about the preferred behaviour for calling methods,
> because the OCL specification only talks about properties. But this bug
> affects the properties, too. (Tests for operations and properties are
> attached)

All RedefinableElements behave the same way in UML, so what's good for
the properties is good for the operations.


> 2.:
> If a called EOperation is backed by an Java-method, always the topmost
> method in the hierarchy is called. This behaviour is conform to Java but
> possibly not conform to OCL (see 7.5.8 in OCL 2.0, formal/06-05-01, p. 19).
> This Bug can't be profed by a test case, because it is concealed by the bug
> described above.

Java calls the bottom-most operation definition in the class hierarchy
of the run-time type, not the top-most.

Unfortunately, there is nothing that an OCL mapping to Java can do in
this regard. For security reasons, the Java platform simply doesn't
allow external clients to call overridden operation definitions.

I actually think that this is a flaw in the OCL specification, because
it is trying to violate the semantics of UML redefinition. One of the
reasons why a class would override an operation is to provide a
definition that better aligns with that class's more specific
invariants, possibly even adding constraints to the redefining operation.

I should raise an issue to get the RTF's input.


> I didn't raise a bug, because I'm not sure whether the behaviour regarding
> overridden methods is faulty.

In any case, Java won't permit access to redefined operations, so
there's nothing to do' there. However, the parser does have a bug if it
generations OperationCallExps referencing the wrong operation, such as
in your foo() scenario.

>
> Stefan
>
>
> "Christian W. Damus" <cdamus@zeligsoft.com> schrieb im Newsbeitrag
> news:g8h1ig$iap$1@build.eclipse.org...
>> Hi, Stefan,
>>
>> This is odd. Would the underlying Java method invocation not always
>> choose the C2 override, anyway? If you can provide a reproducible test
>> case in a bug, I'd be grateful. This is the first I hear of this
>> phenomenon; you can be sure that the 1.2 release has the same behaviour.
>>
>> Cheers,
>>
>> Christian
>>
>> Stefan Schulze wrote:
>>> Hi...
>>>
>>> in OCL 1.1.2 I have problems with calling overriding methods of classes.
>>>
>>> I have a class C1 with method foo():int (returning "1") and class C2
>>> subclassing C1 with method foo():int (returning "2"). If I call foo() on
>>> an
>>> object of type C2 it results in "1".
>>> Some debugging shows that it currently depends on the order
>>> EClass#getAllOperations() returns the overridden and overriding methods.
>>> According to the OCL-specification the topmost matching operation
>>> (C2#foo())
>>> should be called. To call an overridden method, you have to cast the
>>> source
>>> (c.oclAsType(C1).foo()).
>>>
>>> I think in UMLReflectionImpl#getOperations(EClassifier) or in
>>> TypeUtil#getOperations(...) (if you want to handle overriding of methods
>>> of
>>> OclAny, too) you should filter the overridden methods.
>>>
>>> Is this issue already fixed in 1.2.x?
>>>
>>> Stefan
>>>
>>>
>
>
Re: Calling overriding methods [message #61169 is a reply to message #61146] Thu, 21 August 2008 22:08 Go to previous message
Stefan Schulze is currently offline Stefan SchulzeFriend
Messages: 70
Registered: July 2009
Member
Christian wrote:
> Stefan wrote:
>> 1.:
>> When the parser lookup the called method, it always returns the method
>> which is the lowest in the inheritance hierarchy (in the example this is
>> C1::foo()). The correct behaviour would be to return the topmost method
>> respecting the casted type (see 7.5.8 in OCL 2.0, formal/06-05-01, p.
>> 19).
>
> I think you mean, the most specific definition of the operation in the
> static type of the expression, whether it is a cast expression or not.

You're right. My inheritance-tree seems to be inverted (most specific at the
top, most general at the bottom) ;)

> I think probably that we're just taking the first operation that Ecore
> provides, which are probably listed in top-down order instead of
> bottom-up.

In my curent implementation (v2.3.2) of EClassImpl#getEAllOperations() this
is true. The most general ones are followed by the most specific ones. But
this order isn't specified somewhere, I think.

> This should be fixed. Please, raise a bug.

Done. I filed https://bugs.eclipse.org/bugs/show_bug.cgi?id=244886.

> Unfortunately, there is nothing that an OCL mapping to Java can do in this
> regard. For security reasons, the Java platform simply doesn't allow
> external clients to call overridden operation definitions.
> I actually think that this is a flaw in the OCL specification, because it
> is trying to violate the semantics of UML redefinition. One of the
> reasons why a class would override an operation is to provide a definition
> that better aligns with that class's more specific invariants, possibly
> even adding constraints to the redefining operation.
>
> I should raise an issue to get the RTF's input.

Java only supports a special case of this with using "super". Decorating a
method by overriding it wouldn't be possible in the OCL without the ability
to access overridden methods.
But you're right. This is a reasonable restriction of Java and we probably
have to live with it.

Stefan
Previous Topic:..*-associations should be Set by default?
Next Topic:Sequence.subSequence with invalid arguments
Goto Forum:
  


Current Time: Tue Nov 25 21:17:47 GMT 2014

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

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