| Summary: | Operation Template Parameters not erased for generated eInvoke | ||
|---|---|---|---|
| Product: | [Modeling] EMF | Reporter: | Ed Willink <ed> |
| Component: | Core | Assignee: | Ed Merks <Ed.Merks> |
| Status: | CLOSED FIXED | QA Contact: | |
| Severity: | normal | ||
| Priority: | P3 | ||
| Version: | 2.6.0 | ||
| Target Milestone: | --- | ||
| Hardware: | PC | ||
| OS: | Windows Vista | ||
| Whiteboard: | |||
I'm trying to fix this since it's holding me up. The problem is potentially curable by having GenBaseImpl.getTypeArguments use '?' when a type argument is an operation type parameter not visible in the current scope. This seems to require an additional operation scope to be passed to identify a known operation context. This scope enables a test of whether a type parameter is visible. Such a change looks messy: affects many getType() signatures. Any suggestions? Yes, I was looking at this as well. Indeed it seems new and specific to operation and parameter types and requires determining omitting out-of-scope template parameters. That does seem to require new signatures (for GenOperation and GenParameter), though perhaps just one with a boolean to indicate whether or not operation type parameters are in scope... A hack for the time being would be to use the raw type in the template... How to do even a raw-type hack is not clear to me; the variety and complexity of the type methods baffles me. I was trying to put a 'in-eInvoke' flag in to the genClass.eAdapters so that the boolean state could be passed through the existing signatures. Struggling with imports at present. But if you're going to fix this soon, I'll abandon my super-hack and be patient. I hope to find time in the coming week. I'm imagining this as new methods on GenOperation and GenParamater... This is a bit of a nightmare...
Imagine a signature like this.
<T extends List<Object> & Comparable<Object>> void foo(EList<T> x);
Just casting the argument to
foo((EList<?>)arguments.get(0));
doesn't work because ? doesn't conform to T's bounds.
I can't think of any way to make the compiler happy except to use a raw type.
foo((EList)arguments.get(0));
If there is a single bound we could use it like this
foo((EList<List<Object>>)arguments.get(0));
In the end, it all makes me wonder if we shouldn't just always cast to the raw type given that nothing else is checked anyway.
(In reply to comment #5) > In the end, it all makes me wonder if we shouldn't just always cast to the raw > type given that nothing else is checked anyway. Makes sense to me. There would probably be other challenges for ridiculously nested templates too. The changes are committed to CVS for 2.8. Fixed. The changes are available in builds. |
When using a templated operation I get a syntax error on the return accept((Visitor<T>)arguments.get(0)); in: /** * <!-- begin-user-doc --> * <!-- end-user-doc --> * @generated */ public <T> T accept(Visitor<T> visitor) { return VisitableOperations.accept(this, visitor); } /** * <!-- begin-user-doc --> * <!-- end-user-doc --> * @generated */ @Override @SuppressWarnings("unchecked") public Object eInvoke(int operationID, EList<?> arguments) throws InvocationTargetException { switch (operationID) { case PivotPackage.VISITABLE___ACCEPT__VISITOR: return accept((Visitor<T>)arguments.get(0)); } return eDynamicInvoke(operationID, arguments); } since T is not defined. The template parameter should have been erased to: return accept((Visitor<?>)arguments.get(0)); (and the @SuppressWarnings("unchecked") eliminated).