Added support for named parameters in model element constructors
diff --git a/plugins/org.eclipse.epsilon.eol.engine/src/org/eclipse/epsilon/eol/dom/TypeInitialiser.java b/plugins/org.eclipse.epsilon.eol.engine/src/org/eclipse/epsilon/eol/dom/TypeInitialiser.java
index b4420f5..ac8f2ac 100644
--- a/plugins/org.eclipse.epsilon.eol.engine/src/org/eclipse/epsilon/eol/dom/TypeInitialiser.java
+++ b/plugins/org.eclipse.epsilon.eol.engine/src/org/eclipse/epsilon/eol/dom/TypeInitialiser.java
@@ -3,9 +3,12 @@
import java.util.ArrayList;
import java.util.List;
+import org.eclipse.epsilon.eol.exceptions.EolIllegalPropertyException;
import org.eclipse.epsilon.eol.exceptions.EolRuntimeException;
import org.eclipse.epsilon.eol.exceptions.models.EolNotInstantiableModelElementTypeException;
import org.eclipse.epsilon.eol.execute.context.IEolContext;
+import org.eclipse.epsilon.eol.execute.introspection.IPropertySetter;
+import org.eclipse.epsilon.eol.models.IModel;
import org.eclipse.epsilon.eol.types.EolCollectionType;
import org.eclipse.epsilon.eol.types.EolMapType;
import org.eclipse.epsilon.eol.types.EolModelElementType;
@@ -26,17 +29,57 @@
throw new EolNotInstantiableModelElementTypeException(modelElementType);
}
- if (!parameters.isEmpty()) {
- ArrayList<Object> parameterValues = new ArrayList<Object>();
+ if (type instanceof EolModelElementType) {
+
+ Object instance = type.createInstance();
+
for (Expression parameter : parameters) {
- parameterValues.add(context.getExecutorFactory().execute(parameter, context));
+ if (parameter instanceof EqualsOperatorExpression) {
+ EqualsOperatorExpression equalsOperatorExpression = (EqualsOperatorExpression) parameter;
+ if (equalsOperatorExpression.getFirstOperand() instanceof NameExpression) {
+ String property = ((NameExpression) equalsOperatorExpression.getFirstOperand()).getName();
+ IPropertySetter setter = context.getIntrospectionManager().getPropertySetterFor(instance, property, context);
+ if (setter != null) {
+ setter.setAst(parameter);
+ setter.invoke(context.getExecutorFactory().execute(equalsOperatorExpression.getSecondOperand(), context));
+ }
+ else throw new EolIllegalPropertyException(instance, property, equalsOperatorExpression.getFirstOperand(), context);
+ }
+ else {
+ throw new EolRuntimeException("Property name expected", equalsOperatorExpression.getFirstOperand());
+ }
+ }
+ else {
+ throw new EolRuntimeException("Property initialisation expression expected", parameter);
+ }
}
- return type.createInstance(parameterValues);
+
+ return instance;
+
}
else {
- return type.createInstance();
+ if (!parameters.isEmpty()) {
+ ArrayList<Object> parameterValues = new ArrayList<Object>();
+ for (Expression parameter : parameters) {
+ parameterValues.add(context.getExecutorFactory().execute(parameter, context));
+ }
+ return type.createInstance(parameterValues);
+ }
+ else {
+ return type.createInstance();
+ }
}
}
return null;
}
+
+ protected IModel getModelThatKnowsAboutProperty(Object instance, String property, IEolContext context) {
+ for (IModel model : context.getModelRepository().getModels()) {
+ if (model.knowsAboutProperty(instance, property)) {
+ return model;
+ }
+ }
+ return null;
+ }
+
}
diff --git a/tests/org.eclipse.epsilon.eol.engine.test.acceptance/src/org/eclipse/epsilon/eol/engine/test/acceptance/ModelElementConstructorTests.eol b/tests/org.eclipse.epsilon.eol.engine.test.acceptance/src/org/eclipse/epsilon/eol/engine/test/acceptance/ModelElementConstructorTests.eol
new file mode 100644
index 0000000..96aa9f7
--- /dev/null
+++ b/tests/org.eclipse.epsilon.eol.engine.test.acceptance/src/org/eclipse/epsilon/eol/engine/test/acceptance/ModelElementConstructorTests.eol
@@ -0,0 +1,30 @@
+@setup
+operation setup() {
+ modelManager.unloadAllModels();
+}
+
+@test
+operation testNamedParametersInModelElementConstructor() {
+ modelManager.createInMemoryEmfModel("M", "http://www.eclipse.org/emf/2002/Ecore");
+
+ // EClass is a valid type for both First and Second, so issue a warning
+ var x = new EClass(
+ name = "c1",
+ eSuperTypes = Sequence {
+ new EClass (name = "c2")
+ }
+ );
+
+ assertEquals("c1", x.name);
+ assertEquals(1, x.eSuperTypes.size());
+ assertEquals("c2", x.eSuperTypes.first().name);
+
+}
+
+@test
+operation testNoParametersModelElementConstructor() {
+ modelManager.createInMemoryEmfModel("M", "http://www.eclipse.org/emf/2002/Ecore");
+
+ var x = new EClass();
+ assertEquals(M, x.owningModel);
+}
\ No newline at end of file
diff --git a/tests/org.eclipse.epsilon.eol.engine.test.acceptance/src/org/eclipse/epsilon/eol/engine/test/acceptance/ModelElementConstructorTests.java b/tests/org.eclipse.epsilon.eol.engine.test.acceptance/src/org/eclipse/epsilon/eol/engine/test/acceptance/ModelElementConstructorTests.java
new file mode 100644
index 0000000..819ecb3
--- /dev/null
+++ b/tests/org.eclipse.epsilon.eol.engine.test.acceptance/src/org/eclipse/epsilon/eol/engine/test/acceptance/ModelElementConstructorTests.java
@@ -0,0 +1,9 @@
+package org.eclipse.epsilon.eol.engine.test.acceptance;
+
+import org.eclipse.epsilon.eol.engine.test.acceptance.eunit.EUnitRunner;
+import org.junit.runner.RunWith;
+
+@RunWith(EUnitRunner.class)
+public class ModelElementConstructorTests {
+
+}