[378469] Use eInvoke for all EOperation dispatch
diff --git a/plugins/org.eclipse.ocl.ecore/src/org/eclipse/ocl/ecore/EcoreEvaluationEnvironment.java b/plugins/org.eclipse.ocl.ecore/src/org/eclipse/ocl/ecore/EcoreEvaluationEnvironment.java
index 825efcd..ddb861b 100644
--- a/plugins/org.eclipse.ocl.ecore/src/org/eclipse/ocl/ecore/EcoreEvaluationEnvironment.java
+++ b/plugins/org.eclipse.ocl.ecore/src/org/eclipse/ocl/ecore/EcoreEvaluationEnvironment.java
@@ -38,23 +38,18 @@
import org.eclipse.emf.ecore.EEnumLiteral;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EOperation;
-import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.EParameter;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.ETypedElement;
-import org.eclipse.emf.ecore.InternalEObject;
+import org.eclipse.emf.ecore.EcorePackage;
import org.eclipse.ocl.AbstractEvaluationEnvironment;
import org.eclipse.ocl.EvaluationEnvironment;
import org.eclipse.ocl.LazyExtentMap;
-import org.eclipse.ocl.ecore.delegate.InvocationBehavior;
-import org.eclipse.ocl.ecore.internal.OCLEcorePlugin;
import org.eclipse.ocl.ecore.internal.OCLStandardLibraryImpl;
-import org.eclipse.ocl.ecore.internal.OCLStatusCodes;
import org.eclipse.ocl.ecore.internal.UMLReflectionImpl;
import org.eclipse.ocl.ecore.opposites.OppositeEndFinder;
import org.eclipse.ocl.expressions.CollectionKind;
-import org.eclipse.ocl.internal.l10n.OCLMessages;
import org.eclipse.ocl.types.CollectionType;
import org.eclipse.ocl.types.TupleType;
import org.eclipse.ocl.util.CollectionUtil;
@@ -126,13 +121,13 @@
throws IllegalArgumentException {
// FIXME: Pull up so that UML environment can benefit.
- if (InvocationBehavior.INSTANCE.appliesTo(operation)) {
+ try {
EList<Object> arguments = (args.length == 0)
? ECollections.emptyEList()
: new BasicEList.UnmodifiableEList<Object>(args.length, args);
+ Object result;
+/* if (InvocationBehavior.INSTANCE.appliesTo(operation)) {
- try {
- Object result;
// Fix for Bug 322159
Exception checkFailure;
if (mustCheckOperationReflectionConsistency
@@ -153,18 +148,62 @@
} else {
result = ((EObject) source).eInvoke(operation, arguments);
}
- return coerceValue(operation, result, true);
- } catch (InvocationTargetException e) {
- throw new IllegalArgumentException(e);
- }
+ } else { */
+ System.out.println("Default-callOperation " + operation.getName());
+ result = eInvokeForEObject((EObject) source, operation, arguments);
+// }
+ return coerceValue(operation, result, true);
+ } catch (InvocationTargetException e) {
+ throw new IllegalArgumentException(e);
}
-
// TODO: WBN to pull up createValue to the superclass as a pass-thru
// so that subclasses don't have to override callOperation
- return coerceValue(operation,
- super.callOperation(operation, opcode, source, args), true);
+ // return coerceValue(operation,
+ // super.callOperation(operation, opcode, source, args), true);
}
+ private static Object eInvokeForEObject(EObject eObject, EOperation eOperation, EList<?> arguments) throws InvocationTargetException
+ {
+ if (eOperation.getEContainingClass() == EcorePackage.Literals.EOBJECT) { // Do EObject first since EObject.eInvoke may not be reachable
+ switch (eOperation.getOperationID())
+ {
+ case EcorePackage.EOBJECT___ECLASS :
+ return eObject.eClass();
+ case EcorePackage.EOBJECT___EIS_PROXY :
+ return eObject.eIsProxy();
+ case EcorePackage.EOBJECT___ERESOURCE :
+ return eObject.eResource();
+ case EcorePackage.EOBJECT___ECONTAINER :
+ return eObject.eContainer();
+ case EcorePackage.EOBJECT___ECONTAINING_FEATURE :
+ return eObject.eContainingFeature();
+ case EcorePackage.EOBJECT___ECONTAINMENT_FEATURE :
+ return eObject.eContainmentFeature();
+ case EcorePackage.EOBJECT___ECONTENTS :
+ return eObject.eContents();
+ case EcorePackage.EOBJECT___EALL_CONTENTS :
+ return eObject.eAllContents();
+ case EcorePackage.EOBJECT___ECROSS_REFERENCES :
+ return eObject.eCrossReferences();
+ case EcorePackage.EOBJECT___EGET__ESTRUCTURALFEATURE :
+ return eObject.eGet((EStructuralFeature) arguments.get(0));
+ case EcorePackage.EOBJECT___EGET__ESTRUCTURALFEATURE_BOOLEAN :
+ return eObject.eGet((EStructuralFeature) arguments.get(0), (Boolean) arguments.get(1));
+ case EcorePackage.EOBJECT___ESET__ESTRUCTURALFEATURE_OBJECT :
+ eObject.eSet((EStructuralFeature) arguments.get(0), arguments.get(1));
+ return null;
+ case EcorePackage.EOBJECT___EIS_SET__ESTRUCTURALFEATURE :
+ return eObject.eIsSet((EStructuralFeature) arguments.get(0));
+ case EcorePackage.EOBJECT___EUNSET__ESTRUCTURALFEATURE :
+ eObject.eUnset((EStructuralFeature) arguments.get(0));
+ return null;
+ case EcorePackage.EOBJECT___EINVOKE__EOPERATION_ELIST :
+ return eObject.eInvoke((EOperation) arguments.get(0), (EList<?>) arguments.get(1));
+ }
+ }
+ return eObject.eInvoke(eOperation, arguments);
+ }
+
// implements the inherited specification
@Override
protected Method getJavaMethodFor(EOperation operation, Object receiver) {
diff --git a/tests/org.eclipse.ocl.ecore.tests/src/org/eclipse/ocl/ecore/tests/ComparisonTest.java b/tests/org.eclipse.ocl.ecore.tests/src/org/eclipse/ocl/ecore/tests/ComparisonTest.java
index 7286256..39cfb27 100644
--- a/tests/org.eclipse.ocl.ecore.tests/src/org/eclipse/ocl/ecore/tests/ComparisonTest.java
+++ b/tests/org.eclipse.ocl.ecore.tests/src/org/eclipse/ocl/ecore/tests/ComparisonTest.java
@@ -19,6 +19,7 @@
package org.eclipse.ocl.ecore.tests;
+import java.lang.reflect.InvocationTargetException;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.LinkedHashSet;
@@ -39,6 +40,7 @@
import org.eclipse.emf.ecore.EcoreFactory;
import org.eclipse.emf.ecore.EcorePackage;
import org.eclipse.emf.ecore.impl.EObjectImpl;
+import org.eclipse.emf.ecore.impl.EOperationImpl;
import org.eclipse.ocl.ParserException;
import org.eclipse.ocl.expressions.CollectionKind;
import org.eclipse.ocl.expressions.CollectionLiteralExp;
@@ -57,17 +59,6 @@
public class ComparisonTest
extends AbstractTestSuite {
- EPackage pkg;
- EClass thingType;
- EAttribute values;
- EAttribute bdValue;
- EAttribute biValue;
- EDataType valueType;
- EClass numeroType;
- EReference numeros;
- EClass comparable;
- EDataType myDataType;
- EObject thing;
/**
* Tests the < operator.
@@ -742,154 +733,10 @@
@Override
protected void setUp() {
super.setUp();
+ if (pkg == null) {
+ init();
+ }
- pkg = EcoreFactory.eINSTANCE.createEPackage();
- pkg.setName("pkg");
-
- EFactory factory = EcoreFactory.eINSTANCE.createEFactory();
- pkg.setEFactoryInstance(factory);
-
- valueType = EcoreFactory.eINSTANCE.createEDataType();
- valueType.setName("Value");
- valueType.setInstanceClass(Value.class);
- pkg.getEClassifiers().add(valueType);
-
- thingType = EcoreFactory.eINSTANCE.createEClass();
- thingType.setName("Thing");
- pkg.getEClassifiers().add(thingType);
-
- bdValue = EcoreFactory.eINSTANCE.createEAttribute();
- bdValue.setName("bdValue");
- bdValue.setEType(EcorePackage.Literals.EBIG_DECIMAL);
- bdValue.setUpperBound(1);
- thingType.getEStructuralFeatures().add(bdValue);
-
- biValue = EcoreFactory.eINSTANCE.createEAttribute();
- biValue.setName("biValue");
- biValue.setEType(EcorePackage.Literals.EBIG_INTEGER);
- biValue.setUpperBound(1);
- thingType.getEStructuralFeatures().add(biValue);
-
- values = EcoreFactory.eINSTANCE.createEAttribute();
- values.setName("values");
- values.setEType(valueType);
- values.setUpperBound(ETypedElement.UNBOUNDED_MULTIPLICITY);
- thingType.getEStructuralFeatures().add(values);
-
- numeroType = EcoreFactory.eINSTANCE.createEClass();
- numeroType.setName("Numero");
- numeroType.setInstanceClass(Numero.class);
- pkg.getEClassifiers().add(numeroType);
-
- EOperation oper = EcoreFactory.eINSTANCE.createEOperation();
- oper.setName("+");
- EParameter parm = EcoreFactory.eINSTANCE.createEParameter();
- parm.setName("n");
- parm.setEType(numeroType);
- oper.getEParameters().add(parm);
- oper.setEType(numeroType);
- numeroType.getEOperations().add(oper);
-
- oper = EcoreFactory.eINSTANCE.createEOperation();
- oper.setName("-");
- parm = EcoreFactory.eINSTANCE.createEParameter();
- parm.setName("n");
- parm.setEType(numeroType);
- oper.getEParameters().add(parm);
- oper.setEType(numeroType);
- numeroType.getEOperations().add(oper);
-
- oper = EcoreFactory.eINSTANCE.createEOperation();
- oper.setName("*");
- parm = EcoreFactory.eINSTANCE.createEParameter();
- parm.setName("n");
- parm.setEType(numeroType);
- oper.getEParameters().add(parm);
- oper.setEType(numeroType);
- numeroType.getEOperations().add(oper);
-
- oper = EcoreFactory.eINSTANCE.createEOperation();
- oper.setName("/");
- parm = EcoreFactory.eINSTANCE.createEParameter();
- parm.setName("n");
- parm.setEType(numeroType);
- oper.getEParameters().add(parm);
- oper.setEType(numeroType);
- numeroType.getEOperations().add(oper);
-
- oper = EcoreFactory.eINSTANCE.createEOperation();
- oper.setName("-");
- oper.setEType(numeroType);
- numeroType.getEOperations().add(oper);
-
- oper = EcoreFactory.eINSTANCE.createEOperation();
- oper.setName("<");
- parm = EcoreFactory.eINSTANCE.createEParameter();
- parm.setName("n");
- parm.setEType(numeroType);
- oper.getEParameters().add(parm);
- oper.setEType(EcorePackage.Literals.EBOOLEAN);
- numeroType.getEOperations().add(oper);
-
- oper = EcoreFactory.eINSTANCE.createEOperation();
- oper.setName("<=");
- parm = EcoreFactory.eINSTANCE.createEParameter();
- parm.setName("n");
- parm.setEType(numeroType);
- oper.getEParameters().add(parm);
- oper.setEType(EcorePackage.Literals.EBOOLEAN);
- numeroType.getEOperations().add(oper);
-
- oper = EcoreFactory.eINSTANCE.createEOperation();
- oper.setName(">");
- parm = EcoreFactory.eINSTANCE.createEParameter();
- parm.setName("n");
- parm.setEType(numeroType);
- oper.getEParameters().add(parm);
- oper.setEType(EcorePackage.Literals.EBOOLEAN);
- numeroType.getEOperations().add(oper);
-
- oper = EcoreFactory.eINSTANCE.createEOperation();
- oper.setName(">=");
- parm = EcoreFactory.eINSTANCE.createEParameter();
- parm.setName("n");
- parm.setEType(numeroType);
- oper.getEParameters().add(parm);
- oper.setEType(EcorePackage.Literals.EBOOLEAN);
- numeroType.getEOperations().add(oper);
-
- oper = EcoreFactory.eINSTANCE.createEOperation();
- oper.setName("asLong");
- oper.setEType(EcorePackage.Literals.ELONG);
- numeroType.getEOperations().add(oper);
-
- numeros = EcoreFactory.eINSTANCE.createEReference();
- numeros.setName("numeros");
- numeros.setEType(numeroType);
- numeros.setUpperBound(ETypedElement.UNBOUNDED_MULTIPLICITY);
- numeros.setOrdered(true);
- thingType.getEStructuralFeatures().add(numeros);
-
- thing = factory.create(thingType);
-
- comparable = EcoreFactory.eINSTANCE.createEClass();
- comparable.setName("Comparable");
- comparable.setAbstract(true);
- pkg.getEClassifiers().add(comparable);
-
- oper = EcoreFactory.eINSTANCE.createEOperation();
- oper.setName("compareTo");
- parm = EcoreFactory.eINSTANCE.createEParameter();
- parm.setName("c");
- parm.setEType(comparable);
- oper.getEParameters().add(parm);
- oper.setEType(EcorePackage.Literals.EINT);
- comparable.getEOperations().add(oper);
-
- myDataType = EcoreFactory.eINSTANCE.createEDataType();
- myDataType.setName("MyDataType");
- myDataType.setInstanceClass(Thread.State.class); // enums are comparable
- pkg.getEClassifiers().add(myDataType);
@SuppressWarnings("unchecked")
EList<Numero> list = (EList<Numero>) thing.eGet(numeros);
@@ -939,7 +786,191 @@
}
}
- public static class Numero extends EObjectImpl {
+ public EPackage pkg;
+ public EAttribute values;
+ public EAttribute bdValue;
+ public EAttribute biValue;
+ public EDataType valueType;
+ public EClass numeroType;
+ public EReference numeros;
+ public EClass comparable;
+ public EDataType myDataType;
+ public EClass thingType;
+ public EObject thing;
+
+ public void init() {
+ pkg = EcoreFactory.eINSTANCE.createEPackage();
+ pkg.setName("pkg");
+
+ EFactory factory = EcoreFactory.eINSTANCE.createEFactory();
+ pkg.setEFactoryInstance(factory);
+
+ valueType = EcoreFactory.eINSTANCE.createEDataType();
+ valueType.setName("Value");
+ valueType.setInstanceClass(Value.class);
+ pkg.getEClassifiers().add(valueType);
+
+ thingType = EcoreFactory.eINSTANCE.createEClass();
+ thingType.setName("Thing");
+ pkg.getEClassifiers().add(thingType);
+
+ bdValue = EcoreFactory.eINSTANCE.createEAttribute();
+ bdValue.setName("bdValue");
+ bdValue.setEType(EcorePackage.Literals.EBIG_DECIMAL);
+ bdValue.setUpperBound(1);
+ thingType.getEStructuralFeatures().add(bdValue);
+
+ biValue = EcoreFactory.eINSTANCE.createEAttribute();
+ biValue.setName("biValue");
+ biValue.setEType(EcorePackage.Literals.EBIG_INTEGER);
+ biValue.setUpperBound(1);
+ thingType.getEStructuralFeatures().add(biValue);
+
+ values = EcoreFactory.eINSTANCE.createEAttribute();
+ values.setName("values");
+ values.setEType(valueType);
+ values.setUpperBound(ETypedElement.UNBOUNDED_MULTIPLICITY);
+ thingType.getEStructuralFeatures().add(values);
+
+ numeroType = EcoreFactory.eINSTANCE.createEClass();
+ numeroType.setName("Numero");
+ numeroType.setInstanceClass(Numero.class);
+ pkg.getEClassifiers().add(numeroType);
+ numeroType.getESuperTypes().add(EcorePackage.Literals.EOBJECT);
+
+ EOperation oper = EcoreFactory.eINSTANCE.createEOperation();
+ oper.setName("+");
+ EParameter parm = EcoreFactory.eINSTANCE.createEParameter();
+ parm.setName("n");
+ parm.setEType(numeroType);
+ oper.getEParameters().add(parm);
+ oper.setEType(numeroType);
+ ((EOperationImpl) oper).setOperationID(Numero.NUMERO_PLUS);
+ numeroType.getEOperations().add(oper);
+
+ oper = EcoreFactory.eINSTANCE.createEOperation();
+ oper.setName("-");
+ parm = EcoreFactory.eINSTANCE.createEParameter();
+ parm.setName("n");
+ parm.setEType(numeroType);
+ oper.getEParameters().add(parm);
+ oper.setEType(numeroType);
+ ((EOperationImpl) oper).setOperationID(Numero.NUMERO_MINUS_1);
+ numeroType.getEOperations().add(oper);
+
+ oper = EcoreFactory.eINSTANCE.createEOperation();
+ oper.setName("*");
+ parm = EcoreFactory.eINSTANCE.createEParameter();
+ parm.setName("n");
+ parm.setEType(numeroType);
+ oper.getEParameters().add(parm);
+ oper.setEType(numeroType);
+ ((EOperationImpl) oper).setOperationID(Numero.NUMERO_TIMES);
+ numeroType.getEOperations().add(oper);
+
+ oper = EcoreFactory.eINSTANCE.createEOperation();
+ oper.setName("/");
+ parm = EcoreFactory.eINSTANCE.createEParameter();
+ parm.setName("n");
+ parm.setEType(numeroType);
+ oper.getEParameters().add(parm);
+ oper.setEType(numeroType);
+ ((EOperationImpl) oper).setOperationID(Numero.NUMERO_DIVIDE);
+ numeroType.getEOperations().add(oper);
+
+ oper = EcoreFactory.eINSTANCE.createEOperation();
+ oper.setName("-");
+ oper.setEType(numeroType);
+ ((EOperationImpl) oper).setOperationID(Numero.NUMERO_MINUS_0);
+ numeroType.getEOperations().add(oper);
+
+ oper = EcoreFactory.eINSTANCE.createEOperation();
+ oper.setName("<");
+ parm = EcoreFactory.eINSTANCE.createEParameter();
+ parm.setName("n");
+ parm.setEType(numeroType);
+ oper.getEParameters().add(parm);
+ oper.setEType(EcorePackage.Literals.EBOOLEAN);
+ ((EOperationImpl) oper).setOperationID(Numero.NUMERO_LESS_THAN);
+ numeroType.getEOperations().add(oper);
+
+ oper = EcoreFactory.eINSTANCE.createEOperation();
+ oper.setName("<=");
+ parm = EcoreFactory.eINSTANCE.createEParameter();
+ parm.setName("n");
+ parm.setEType(numeroType);
+ oper.getEParameters().add(parm);
+ oper.setEType(EcorePackage.Literals.EBOOLEAN);
+ ((EOperationImpl) oper).setOperationID(Numero.NUMERO_LESS_THAN_EQUAL);
+ numeroType.getEOperations().add(oper);
+
+ oper = EcoreFactory.eINSTANCE.createEOperation();
+ oper.setName(">");
+ parm = EcoreFactory.eINSTANCE.createEParameter();
+ parm.setName("n");
+ parm.setEType(numeroType);
+ oper.getEParameters().add(parm);
+ oper.setEType(EcorePackage.Literals.EBOOLEAN);
+ ((EOperationImpl) oper).setOperationID(Numero.NUMERO_GREATER_THAN);
+ numeroType.getEOperations().add(oper);
+
+ oper = EcoreFactory.eINSTANCE.createEOperation();
+ oper.setName(">=");
+ parm = EcoreFactory.eINSTANCE.createEParameter();
+ parm.setName("n");
+ parm.setEType(numeroType);
+ oper.getEParameters().add(parm);
+ oper.setEType(EcorePackage.Literals.EBOOLEAN);
+ ((EOperationImpl) oper).setOperationID(Numero.NUMERO_GREATER_THAN_EQUAL);
+ numeroType.getEOperations().add(oper);
+
+ oper = EcoreFactory.eINSTANCE.createEOperation();
+ oper.setName("asLong");
+ oper.setEType(EcorePackage.Literals.ELONG);
+ ((EOperationImpl) oper).setOperationID(Numero.NUMERO_AS_LONG);
+ numeroType.getEOperations().add(oper);
+
+ numeros = EcoreFactory.eINSTANCE.createEReference();
+ numeros.setName("numeros");
+ numeros.setEType(numeroType);
+ numeros.setUpperBound(ETypedElement.UNBOUNDED_MULTIPLICITY);
+ numeros.setOrdered(true);
+ thingType.getEStructuralFeatures().add(numeros);
+
+ thing = factory.create(thingType);
+
+ comparable = EcoreFactory.eINSTANCE.createEClass();
+ comparable.setName("Comparable");
+ comparable.setAbstract(true);
+ pkg.getEClassifiers().add(comparable);
+
+ oper = EcoreFactory.eINSTANCE.createEOperation();
+ oper.setName("compareTo");
+ parm = EcoreFactory.eINSTANCE.createEParameter();
+ parm.setName("c");
+ parm.setEType(comparable);
+ oper.getEParameters().add(parm);
+ oper.setEType(EcorePackage.Literals.EINT);
+ comparable.getEOperations().add(oper);
+
+ myDataType = EcoreFactory.eINSTANCE.createEDataType();
+ myDataType.setName("MyDataType");
+ myDataType.setInstanceClass(Thread.State.class); // enums are comparable
+ pkg.getEClassifiers().add(myDataType);
+ }
+
+ public class Numero extends EObjectImpl {
+ public static final int NUMERO_PLUS = EcorePackage.EOBJECT_OPERATION_COUNT + 0;
+ public static final int NUMERO_MINUS_1 = EcorePackage.EOBJECT_OPERATION_COUNT + 1;
+ public static final int NUMERO_TIMES = EcorePackage.EOBJECT_OPERATION_COUNT + 2;
+ public static final int NUMERO_DIVIDE = EcorePackage.EOBJECT_OPERATION_COUNT + 3;
+ public static final int NUMERO_MINUS_0 = EcorePackage.EOBJECT_OPERATION_COUNT + 4;
+ public static final int NUMERO_LESS_THAN = EcorePackage.EOBJECT_OPERATION_COUNT + 5;
+ public static final int NUMERO_LESS_THAN_EQUAL = EcorePackage.EOBJECT_OPERATION_COUNT + 6;
+ public static final int NUMERO_GREATER_THAN = EcorePackage.EOBJECT_OPERATION_COUNT + 7;
+ public static final int NUMERO_GREATER_THAN_EQUAL = EcorePackage.EOBJECT_OPERATION_COUNT + 8;
+ public static final int NUMERO_AS_LONG = EcorePackage.EOBJECT_OPERATION_COUNT + 9;
+
private long value;
Numero() {
@@ -1020,5 +1051,38 @@
public String toString() {
return "Numero(" + value + ")";
}
+
+ @Override
+ public Object eInvoke(int operationID, EList<?> arguments)
+ throws InvocationTargetException {
+ switch (operationID) {
+ case NUMERO_PLUS :
+ return plus((Numero) arguments.get(0));
+ case NUMERO_MINUS_1 :
+ return minus((Numero) arguments.get(0));
+ case NUMERO_TIMES :
+ return times((Numero) arguments.get(0));
+ case NUMERO_DIVIDE :
+ return divide((Numero) arguments.get(0));
+ case NUMERO_MINUS_0 :
+ return minus();
+ case NUMERO_LESS_THAN :
+ return lessThan((Numero) arguments.get(0));
+ case NUMERO_LESS_THAN_EQUAL :
+ return lessThanEqual((Numero) arguments.get(0));
+ case NUMERO_GREATER_THAN :
+ return greaterThan((Numero) arguments.get(0));
+ case NUMERO_GREATER_THAN_EQUAL :
+ return greaterThanEqual((Numero) arguments.get(0));
+ case NUMERO_AS_LONG :
+ return asLong();
+ }
+ return super.eInvoke(operationID, arguments);
+ }
+
+ @Override
+ protected EClass eStaticClass() {
+ return numeroType;
+ }
}
}