Bug 580300 - thisModule.refSetValue() not supported in EMFTVM
Change-Id: I5a97b321922d4a9a85b19fc30e62a916124603df
Signed-off-by: Dennis Wagelaar <dwagelaar@gmail.com>
diff --git a/plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse/m2m/atl/emftvm/util/OCLOperations.java b/plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse/m2m/atl/emftvm/util/OCLOperations.java
index 2fdb480..27f6a56 100644
--- a/plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse/m2m/atl/emftvm/util/OCLOperations.java
+++ b/plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse/m2m/atl/emftvm/util/OCLOperations.java
@@ -37,6 +37,7 @@
import org.eclipse.m2m.atl.emftvm.CodeBlock;
import org.eclipse.m2m.atl.emftvm.EmftvmFactory;
import org.eclipse.m2m.atl.emftvm.ExecEnv;
+import org.eclipse.m2m.atl.emftvm.Field;
import org.eclipse.m2m.atl.emftvm.Model;
import org.eclipse.m2m.atl.emftvm.Module;
import org.eclipse.m2m.atl.emftvm.Operation;
@@ -864,6 +865,115 @@
rule, name, EMFTVMUtil.toPrettyString(object, frame.getEnv())));
}
});
+ createOperation(true, "refGetValue", Types.EXEC_ENV_TYPE, Types.OCL_ANY_TYPE,
+ new String[][][]{{{"propname"}, Types.STRING_TYPE}},
+ new NativeCodeBlock() {
+ @Override
+ public Object execute(final StackFrame frame) {
+ final ExecEnv env = frame.getEnv();
+ final String propname = (String) frame.getLocal(0, 0);
+ final Field field = env.findStaticField(EXEC_ENV, propname);
+ if (field != null) {
+ return field.getStaticValue(frame);
+ }
+ throw new VMException(frame,
+ String.format("Cannot find property %s::%s",
+ EMFTVMUtil.toPrettyString(EXEC_ENV, env), propname));
+ }
+ });
+ createOperation(false, "refGetValue", Types.EXEC_ENV_TYPE, Types.OCL_ANY_TYPE,
+ new String[][][]{{{"propname"}, Types.STRING_TYPE}},
+ new NativeCodeBlock() {
+ @Override
+ public Object execute(final StackFrame frame) {
+ final ExecEnv env = (ExecEnv) frame.getLocal(0, 0);
+ final String propname = (String) frame.getLocal(0, 1);
+ final Field field = env.findStaticField(EXEC_ENV, propname);
+ if (field != null) {
+ return field.getStaticValue(frame);
+ }
+ throw new VMException(frame,
+ String.format("Cannot find property %s::%s",
+ EMFTVMUtil.toPrettyString(EXEC_ENV, env), propname));
+ }
+ });
+ createOperation(true, "refSetValue", Types.EXEC_ENV_TYPE, Types.EXEC_ENV_TYPE,
+ new String[][][]{{{"propname"}, Types.STRING_TYPE}, {{"value"}, Types.OCL_ANY_TYPE}},
+ new NativeCodeBlock() {
+ @Override
+ public Object execute(final StackFrame frame) {
+ final ExecEnv env = frame.getEnv();
+ final String propname = (String) frame.getLocal(0, 0);
+ final Object value = frame.getLocal(0, 1);
+ final Field field = env.findStaticField(EXEC_ENV, propname);
+ if (field != null) {
+ field.setStaticValue(value);
+ return env;
+ }
+ throw new VMException(frame,
+ String.format("Cannot find property %s::%s",
+ EMFTVMUtil.toPrettyString(EXEC_ENV, env), propname));
+ }
+ });
+ createOperation(false, "refSetValue", Types.EXEC_ENV_TYPE, Types.EXEC_ENV_TYPE,
+ new String[][][] { { { "propname" }, Types.STRING_TYPE }, { { "value" }, Types.OCL_ANY_TYPE } },
+ new NativeCodeBlock() {
+ @Override
+ public Object execute(final StackFrame frame) {
+ final ExecEnv env = (ExecEnv) frame.getLocal(0, 0);
+ final String propname = (String) frame.getLocal(0, 1);
+ final Object value = frame.getLocal(0, 2);
+ final Field field = env.findStaticField(EXEC_ENV, propname);
+ if (field != null) {
+ field.setStaticValue(value);
+ return env;
+ }
+ throw new VMException(frame, String.format("Cannot find property %s::%s",
+ EMFTVMUtil.toPrettyString(EXEC_ENV, env), propname));
+ }
+ });
+ createOperation(true, "refUnsetValue", Types.EXEC_ENV_TYPE, Types.EXEC_ENV_TYPE,
+ new String[][][]{{{"propname"}, Types.STRING_TYPE}},
+ new NativeCodeBlock() {
+ @Override
+ public Object execute(final StackFrame frame) {
+ final ExecEnv env = frame.getEnv();
+ final String propname = (String) frame.getLocal(0, 0);
+ final Field field = env.findStaticField(EXEC_ENV, propname);
+ if (field != null) {
+ field.clear();
+ return env;
+ }
+ throw new VMException(frame,
+ String.format("Cannot find property %s::%s",
+ EMFTVMUtil.toPrettyString(EXEC_ENV, env), propname));
+ }
+ });
+ createOperation(false, "refUnsetValue", Types.EXEC_ENV_TYPE, Types.EXEC_ENV_TYPE,
+ new String[][][]{{{"propname"}, Types.STRING_TYPE}},
+ new NativeCodeBlock() {
+ @Override
+ public Object execute(final StackFrame frame) {
+ final ExecEnv env = (ExecEnv) frame.getLocal(0, 0);
+ final String propname = (String) frame.getLocal(0, 1);
+ final Field field = env.findStaticField(EXEC_ENV, propname);
+ if (field != null) {
+ field.clear();
+ return env;
+ }
+ throw new VMException(frame,
+ String.format("Cannot find property %s::%s",
+ EMFTVMUtil.toPrettyString(EXEC_ENV, env), propname));
+ }
+ });
+ createOperation(true, "getEnv", Types.EXEC_ENV_TYPE, Types.EXEC_ENV_TYPE,
+ new String[][][] {},
+ new NativeCodeBlock() {
+ @Override
+ public Object execute(final StackFrame frame) {
+ return frame.getEnv();
+ }
+ });
/////////////////////////////////////////////////////////////////////
// Class
/////////////////////////////////////////////////////////////////////
diff --git a/tests/org.eclipse.m2m.atl.emftvm.tests/launch/Bug580300.launch b/tests/org.eclipse.m2m.atl.emftvm.tests/launch/Bug580300.launch
new file mode 100644
index 0000000..df8c008
--- /dev/null
+++ b/tests/org.eclipse.m2m.atl.emftvm.tests/launch/Bug580300.launch
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<launchConfiguration type="org.eclipse.m2m.atl.emftvm.launcher.EMFTVMTransformation">
+ <stringAttribute key="ATL File Name" value="//org.eclipse.m2m.atl.emftvm.tests/test-data/Regression/Bug580300.atl"/>
+ <booleanAttribute key="Disable JIT compiler" value="false"/>
+ <booleanAttribute key="Display Profiling Data" value="false"/>
+ <booleanAttribute key="Display Timing Data" value="true"/>
+ <mapAttribute key="Inout Model Options"/>
+ <mapAttribute key="Inout Models"/>
+ <mapAttribute key="Inout Models Output Locations"/>
+ <mapAttribute key="Input Model Options"/>
+ <mapAttribute key="Input Models">
+ <mapEntry key="IN" value="http://www.eclipse.org/emf/2002/Ecore"/>
+ </mapAttribute>
+ <mapAttribute key="Metamodel Options">
+ <mapEntry key="ECORE" value="isMetametamodel"/>
+ </mapAttribute>
+ <mapAttribute key="Metamodels">
+ <mapEntry key="ECORE" value=""/>
+ </mapAttribute>
+ <stringAttribute key="Module Name" value="Regression::Bug580300"/>
+ <stringAttribute key="Module Path" value="/org.eclipse.m2m.atl.emftvm.tests/test-data/"/>
+ <mapAttribute key="Output Model Options">
+ <mapEntry key="OUT" value="derivedFile"/>
+ </mapAttribute>
+ <mapAttribute key="Output Models">
+ <mapEntry key="OUT" value="platform:/resource/org.eclipse.m2m.atl.emftvm.tests/test-data/Regression/Bug580300-out.ecore"/>
+ </mapAttribute>
+ <listAttribute key="Superimpose"/>
+</launchConfiguration>
diff --git a/tests/org.eclipse.m2m.atl.emftvm.tests/src/org/eclipse/m2m/atl/emftvm/tests/integration/IntegrationTest.java b/tests/org.eclipse.m2m.atl.emftvm.tests/src/org/eclipse/m2m/atl/emftvm/tests/integration/IntegrationTest.java
index 056bb0c..bd63365 100644
--- a/tests/org.eclipse.m2m.atl.emftvm.tests/src/org/eclipse/m2m/atl/emftvm/tests/integration/IntegrationTest.java
+++ b/tests/org.eclipse.m2m.atl.emftvm.tests/src/org/eclipse/m2m/atl/emftvm/tests/integration/IntegrationTest.java
@@ -425,6 +425,28 @@
}
/**
+ * Tests regression of <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=580300">Bug # 580300</a>.
+ */
+ public void testBug580300() {
+ final ResourceSet rs = new ResourceSetImpl();
+ final ExecEnv env = EmftvmFactory.eINSTANCE.createExecEnv();
+ final TimingData td = new TimingData();
+ final Metamodel metamodel = EmftvmFactory.eINSTANCE.createMetamodel(EcorePackage.eINSTANCE.eResource());
+ final Model out = createTestModel(rs, "/test-data/Regression/Bug441027-out.xmi");
+ env.registerMetaModel("ECORE", metamodel);
+ env.registerInputModel("IN", metamodel);
+ env.registerOutputModel("OUT", out);
+ env.loadModule(createTestModuleResolver(), "Regression::Bug580300");
+ td.finishLoading();
+ env.run(td);
+ td.finish();
+
+ final ResourceSet refRs = new ResourceSetImpl();
+ final Model refOut = loadTestModel(refRs, "/test-data/Regression/Bug580300-out.ecore");
+ assertEquals(refOut.getResource(), out.getResource());
+ }
+
+ /**
* Tests the ATL metamodel API.
*/
public void testATLAPI() throws Exception {
diff --git a/tests/org.eclipse.m2m.atl.emftvm.tests/test-data/Regression/Bug580300-out.ecore b/tests/org.eclipse.m2m.atl.emftvm.tests/test-data/Regression/Bug580300-out.ecore
new file mode 100644
index 0000000..8f279f6
--- /dev/null
+++ b/tests/org.eclipse.m2m.atl.emftvm.tests/test-data/Regression/Bug580300-out.ecore
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ecore:EPackage xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" name="ecoreCounter">
+ <eClassifiers xsi:type="ecore:EClass" name="1"/>
+ <eClassifiers xsi:type="ecore:EClass" name="2"/>
+ <eClassifiers xsi:type="ecore:EClass" name="3"/>
+ <eClassifiers xsi:type="ecore:EClass" name="4"/>
+ <eClassifiers xsi:type="ecore:EClass" name="5"/>
+ <eClassifiers xsi:type="ecore:EClass" name="6"/>
+ <eClassifiers xsi:type="ecore:EClass" name="7"/>
+ <eClassifiers xsi:type="ecore:EClass" name="8"/>
+ <eClassifiers xsi:type="ecore:EClass" name="9"/>
+ <eClassifiers xsi:type="ecore:EClass" name="10"/>
+ <eClassifiers xsi:type="ecore:EClass" name="11"/>
+ <eClassifiers xsi:type="ecore:EClass" name="12"/>
+ <eClassifiers xsi:type="ecore:EClass" name="13"/>
+ <eClassifiers xsi:type="ecore:EClass" name="14"/>
+ <eClassifiers xsi:type="ecore:EClass" name="15"/>
+ <eClassifiers xsi:type="ecore:EClass" name="16"/>
+ <eClassifiers xsi:type="ecore:EClass" name="17"/>
+ <eClassifiers xsi:type="ecore:EClass" name="18"/>
+ <eClassifiers xsi:type="ecore:EClass" name="19"/>
+ <eClassifiers xsi:type="ecore:EClass" name="20"/>
+</ecore:EPackage>
diff --git a/tests/org.eclipse.m2m.atl.emftvm.tests/test-data/Regression/Bug580300.atl b/tests/org.eclipse.m2m.atl.emftvm.tests/test-data/Regression/Bug580300.atl
new file mode 100644
index 0000000..d27568a
--- /dev/null
+++ b/tests/org.eclipse.m2m.atl.emftvm.tests/test-data/Regression/Bug580300.atl
@@ -0,0 +1,42 @@
+-- @atlcompiler emftvm
+-- @nsURI ECORE=http://www.eclipse.org/emf/2002/Ecore
+module "Regression::Bug580300";
+
+create OUT : ECORE from IN : ECORE;
+
+helper def: diff2 : Integer = 0;
+
+-- This helper increments diff2 value
+-- CONTEXT: thisModule
+-- RETURN: Integer
+helper def: incDiff2() : Integer =
+ thisModule.refSetValue('diff2', thisModule.diff2+1).refGetValue('diff2');
+
+rule EPackage {
+ from
+ s : ECORE!EPackage
+ to
+ t : ECORE!EPackage (
+ name <- s.name + 'Counter',
+ eClassifiers <- s.eClassifiers->select(c | c.oclIsKindOf(ECORE!EClass)),
+ eSubpackages <- s.eSubpackages
+ )
+}
+
+rule EClass {
+ from
+ s : ECORE!EClass
+ to
+ t : ECORE!EClass (
+ name <- thisModule.incDiff2().toString()
+ )
+}
+
+endpoint rule After() {
+ do {
+ thisModule.refUnsetValue('diff2');
+ thisModule.getEnv().debug('getEnv')
+ .findStaticField(EMFTVM!ExecEnv, 'diff2').debug('findField')
+ .getStaticValue().debug('getStaticValue');
+ }
+}
diff --git a/tests/org.eclipse.m2m.atl.emftvm.tests/test-data/Regression/Bug580300.emftvm b/tests/org.eclipse.m2m.atl.emftvm.tests/test-data/Regression/Bug580300.emftvm
new file mode 100644
index 0000000..c85ed92
--- /dev/null
+++ b/tests/org.eclipse.m2m.atl.emftvm.tests/test-data/Regression/Bug580300.emftvm
Binary files differ