eclipse-ocl / org.eclipse.ocl

Eclipse Public License 2.0
0 stars 0 forks source link

ClassCastException when using generic type (Pivot) #2029

Closed eclipse-ocl-bot closed 3 hours ago

eclipse-ocl-bot commented 3 hours ago

| --- | --- | | Bugzilla Link | 543173 | | Status | RESOLVED FIXED | | Importance | P3 major | | Reported | Jan 04, 2019 10:14 EDT | | Modified | Jul 01, 2023 02:51 EDT | | See also | 543178, 543187, 582158 | | Reporter | Matthias Schoettle |

Description

In my Ecore model I have a derived property and using the OCLInEcore editor defined it's derivation with OCL (using OCL Examples and Editors). The class the property is defined for has a type parameter and some of the properties of the class have that type parameter as their type.

COREMapping with:\ to: T\ from: T\ /reference: boolean

The OCL to derive the reference property is defined as follows:

core::COREMapping.allInstances()->select(m : core::COREMapping | m->closure(oclContainer())\ ->selectByType(core::COREModelExtension)->notEmpty())\ ->select(m : COREMapping | m.to = self)->notEmpty();

In Eclipse 4.7.3a (OCL Examples and Editors 6.3.0) this worked fine. Opening the same model (which also affects opening the Genmodel) with Eclipse 2018-12 (OCL Examples and Editors 6.6.0) crashes with the following exception:

java.lang.ClassCastException: org.eclipse.ocl.pivot.internal.TemplateParameterImpl cannot be cast to org.eclipse.ocl.pivot.Class\ at org.eclipse.ocl.pivot.internal.manager.TemplateSpecialisation.getSpecialisation(TemplateSpecialisation.java:137)\ at org.eclipse.ocl.pivot.internal.PropertyCallExpImpl.getSpecializedReferredPropertyType(PropertyCallExpImpl.java:489)\ at org.eclipse.ocl.pivot.internal.PropertyCallExpImpl.validateCompatibleResultType(PropertyCallExpImpl.java:751)\ at org.eclipse.ocl.pivot.util.PivotValidator.validatePropertyCallExp_validateCompatibleResultType(PivotValidator.java:3997)\ at org.eclipse.ocl.pivot.util.PivotValidator.validatePropertyCallExp(PivotValidator.java:3950)\ at org.eclipse.ocl.pivot.util.PivotValidator.validate(PivotValidator.java:1187)\ at org.eclipse.emf.ecore.util.EObjectValidator.validate(EObjectValidator.java:324)

A breakpoint in that line revealed that it is the m.to expression where this occurs.

eclipse-ocl-bot commented 3 hours ago

By Ed Willink on Jan 04, 2019 10:38

Please provide the OCLinEcore model so that I can reproduce the template parameterization.

eclipse-ocl-bot commented 3 hours ago

By Matthias Schoettle on Jan 04, 2019 10:42

Created attachment 277067 OCLInEcore model

CORE.ecore

eclipse-ocl-bot commented 3 hours ago

By Matthias Schoettle on Jan 04, 2019 10:43

Digging a bit further reveals:

Based on my (limited) understanding it seems to me that in installEquivalence, when it determines that it is a TemplateParameter, it should use the constraining class(es), but I am unsure what to do with the list of classes.

I also attached the Ecore model.

eclipse-ocl-bot commented 3 hours ago

By Ed Willink on Jan 04, 2019 10:55

Thanks, I can investigate. From the stack trace it appears that a template specialization has not been specialized and so the residual template parameter gives the CCE, for which there should at least be a better error diagnostic.

It looks as if this has always been a problem, but only now shows up with the stronger EMF/OCL validations.

eclipse-ocl-bot commented 3 hours ago

By Ed Willink on Jan 04, 2019 11:11

(In reply to Ed Willink from comment #4)

It looks as if this has always been a problem, but only now shows up with the stronger EMF/OCL validations.

The relevant code is unchanged in the last four years.

a template specialization has not been specialized and so the residual template parameter gives the CCE

The assumption that a property type will be specialized is unsound. The attachment demonstrates that a comparison may be performed on unspecialized types as a consequence of being defined in an abstract parameterized superclass.

Looks as if use of the more abstract Type rayher than Class should avoid the CCE and still work.

for which there should at least be a better error diagnostic.

There is a warning in the Problems View but it doesn't link to the Sample Ecore / OCLinEcore context.

eclipse-ocl-bot commented 3 hours ago

By Ed Willink on Jan 04, 2019 11:38

(In reply to Ed Willink from comment #5)

Looks as if use of the more abstract Type rayher than Class should avoid the CCE and still work.

Yes. There is even a "//FIXME cast" at the CCE and the overridden method had a Type return type anyway. All tests pass.

With this fix the attachment has just one warning; a plausible complaint that

m->closure(oclContainer())

has a body that doesn't conform to the iterator type. Change to

m->closure(e : ocl::OclElement | e.oclContainer())

(We can't really infer the iterator type as the common type of source element and body since we need to know the iterator type to analyze the body.)

eclipse-ocl-bot commented 3 hours ago

By Ed Willink on Jan 04, 2019 12:02

(In reply to Ed Willink from comment #5)

for which there should at least be a better error diagnostic.

There is a warning in the Problems View but it doesn't link to the Sample Ecore / OCLinEcore context.

Bug 543178.

eclipse-ocl-bot commented 3 hours ago

By Ed Willink on Jan 04, 2019 12:09

(In reply to Ed Willink from comment #6)

With this fix the attachment has just one warning

Available now at:

https://hudson.eclipse.org/ocl/job/ocl-branch-tests/141/artifact/releng/org.eclipse.ocl.releng.build-site/target/org.eclipse.ocl-6.7.0.N20190104-1647.zip

6.7.0 will be official in March. I don't think this problem is common enough to merit a 6.6.1.

eclipse-ocl-bot commented 3 hours ago

By Matthias Schoettle on Jan 04, 2019 14:05

Thanks for the fast response and fix!

I can confirm that the issue is fixed now.

Also, thanks for the suggested fix on getting rid of the warning.

eclipse-ocl-bot commented 3 hours ago

By Ed Willink on Jan 05, 2019 04:59

Not FIXED until I push the commit to GIT master.


(In reply to Matthias Schoettle from comment #0)

The OCL to derive the reference property is defined as follows:

core::COREMapping.allInstances()->select(m : core::COREMapping | m->closure(oclContainer()) ->selectByType(core::COREModelExtension)->notEmpty()) ->select(m : COREMapping | m.to = self)->notEmpty();

allInstances() is inefficient in probably all current OCL tools, in some cases very inefficient.

It appears that you are searching for opposites of COREMapping::to that should be possible using self.CORELink, or if necessary self.CORELink[to], allowing

let opposites = self.CORELink->selectByType(COREMapping) in\ let extensionOpposites = opposites->select(m |\ let ancestors = m->closure(e : ocl::OclElement | e.oclContainer()) in\ ancestors->selectByType(core::COREModelExtension)->notEmpty()) in\ extensionOpposites ->notEmpty()

But the self.CORELink unnavigable opposite doesn't seem to work for me. Perhaps template typed properties have no opposite rather than the opposite of the template type's lower bound. Watch this space for a new Bug report.

eclipse-ocl-bot commented 3 hours ago

By Ed Willink on Jan 05, 2019 08:33

(In reply to Ed Willink from comment #10)

Watch this space for a new Bug report.

Bug 543187

eclipse-ocl-bot commented 3 hours ago

By Ed Willink on Jan 05, 2019 16:32

(In reply to Matthias Schoettle from comment #0)

core::COREMapping.allInstances()->select(m : core::COREMapping | m->closure(oclContainer()) ->selectByType(core::COREModelExtension)->notEmpty()) ->select(m : COREMapping | m.to = self)->notEmpty();

(In reply to Ed Willink from comment #10) Bug 543187

The fix allows the unnavigable self.CORELink to be used.

eclipse-ocl-bot commented 3 hours ago

By Matthias Schoettle on Jan 07, 2019 11:07

Thanks, hadn't thought of using the opposite of CORELink.to going from COREModelElement (self).

With "the fix", are you referring to the upcoming fix tracked in the metamodel changes issue?

eclipse-ocl-bot commented 3 hours ago

By Ed Willink on Jan 07, 2019 11:22

The unnavigable opposites fix might be in the latest branch tests, but checking through I was horrified to see that while allInstances() are lazily cached on first use, unnavigable opposites are not, so I'm rectifying that right now.

eclipse-ocl-bot commented 3 hours ago

By Ed Willink on Jan 14, 2019 13:23

(In reply to Ed Willink from comment #14)

so I'm rectifying that right now.

Ensuring that caching worked for unnavigable opposites of template parameters revealed quite a few horrors. All working now.

Pushed to master for M1.

eclipse-ocl-bot commented 3 hours ago

By Ed Willink on Jan 14, 2019 13:30

Fixed too.