Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--plugins/org.eclipse.m2m.atl.emftvm/model/emftvm.ecore13
-rw-r--r--plugins/org.eclipse.m2m.atl.emftvm/model/emftvm.genmodel11
-rw-r--r--plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse/m2m/atl/emftvm/Rule.java25
-rw-r--r--plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse/m2m/atl/emftvm/impl/EmftvmPackageImpl.java13
-rw-r--r--plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse/m2m/atl/emftvm/impl/RuleImpl.java86
-rw-r--r--tests/org.eclipse.m2m.atl.emftvm.tests/src/org/eclipse/m2m/atl/emftvm/tests/RuleTest.java28
6 files changed, 172 insertions, 4 deletions
diff --git a/plugins/org.eclipse.m2m.atl.emftvm/model/emftvm.ecore b/plugins/org.eclipse.m2m.atl.emftvm/model/emftvm.ecore
index 674726d0..070b038e 100644
--- a/plugins/org.eclipse.m2m.atl.emftvm/model/emftvm.ecore
+++ b/plugins/org.eclipse.m2m.atl.emftvm/model/emftvm.ecore
@@ -566,6 +566,15 @@
</eGenericType>
</eParameters>
</eOperations>
+ <eOperations name="matchOneOnly" eType="ecore:EDataType platform:/plugin/org.eclipse.emf.ecore/model/Ecore.ecore#//EBoolean">
+ <eParameters name="frame" eType="#//StackFrame"/>
+ <eParameters name="valuesMap">
+ <eGenericType eClassifier="ecore:EDataType platform:/plugin/org.eclipse.emf.ecore/model/Ecore.ecore#//EMap">
+ <eTypeArguments eClassifier="ecore:EDataType platform:/plugin/org.eclipse.emf.ecore/model/Ecore.ecore#//EString"/>
+ <eTypeArguments eClassifier="ecore:EDataType platform:/plugin/org.eclipse.emf.ecore/model/Ecore.ecore#//EJavaObject"/>
+ </eGenericType>
+ </eParameters>
+ </eOperations>
<eOperations name="createTraces">
<eParameters name="frame" eType="#//StackFrame"/>
</eOperations>
@@ -582,6 +591,10 @@
<eOperations name="applyFirst" eType="ecore:EDataType platform:/plugin/org.eclipse.emf.ecore/model/Ecore.ecore#//EBoolean">
<eParameters name="frame" eType="#//StackFrame"/>
</eOperations>
+ <eOperations name="applyOne" eType="ecore:EDataType platform:/plugin/org.eclipse.emf.ecore/model/Ecore.ecore#//EJavaObject">
+ <eParameters name="frame" eType="#//StackFrame"/>
+ <eParameters name="trace" eType="ecore:EClass platform:/plugin/org.eclipse.m2m.atl.emftvm.trace/model/trace.ecore#//TraceLink"/>
+ </eOperations>
<eOperations name="applyFor" eType="ecore:EDataType platform:/plugin/org.eclipse.emf.ecore/model/Ecore.ecore#//EJavaObject">
<eParameters name="frame" eType="#//StackFrame"/>
<eParameters name="trace" eType="ecore:EClass platform:/plugin/org.eclipse.m2m.atl.emftvm.trace/model/trace.ecore#//TraceLink"/>
diff --git a/plugins/org.eclipse.m2m.atl.emftvm/model/emftvm.genmodel b/plugins/org.eclipse.m2m.atl.emftvm/model/emftvm.genmodel
index 370adeb6..f5daac57 100644
--- a/plugins/org.eclipse.m2m.atl.emftvm/model/emftvm.genmodel
+++ b/plugins/org.eclipse.m2m.atl.emftvm/model/emftvm.genmodel
@@ -480,6 +480,10 @@
<genParameters ecoreParameter="emftvm.ecore#//Rule/matchOne/frame"/>
<genParameters ecoreParameter="emftvm.ecore#//Rule/matchOne/valuesMap"/>
</genOperations>
+ <genOperations ecoreOperation="emftvm.ecore#//Rule/matchOneOnly">
+ <genParameters ecoreParameter="emftvm.ecore#//Rule/matchOneOnly/frame"/>
+ <genParameters ecoreParameter="emftvm.ecore#//Rule/matchOneOnly/valuesMap"/>
+ </genOperations>
<genOperations ecoreOperation="emftvm.ecore#//Rule/createTraces">
<genParameters ecoreParameter="emftvm.ecore#//Rule/createTraces/frame"/>
</genOperations>
@@ -496,6 +500,10 @@
<genOperations ecoreOperation="emftvm.ecore#//Rule/applyFirst">
<genParameters ecoreParameter="emftvm.ecore#//Rule/applyFirst/frame"/>
</genOperations>
+ <genOperations ecoreOperation="emftvm.ecore#//Rule/applyOne">
+ <genParameters ecoreParameter="emftvm.ecore#//Rule/applyOne/frame"/>
+ <genParameters ecoreParameter="emftvm.ecore#//Rule/applyOne/trace"/>
+ </genOperations>
<genOperations ecoreOperation="emftvm.ecore#//Rule/applyFor">
<genParameters ecoreParameter="emftvm.ecore#//Rule/applyFor/frame"/>
<genParameters ecoreParameter="emftvm.ecore#//Rule/applyFor/trace"/>
@@ -516,6 +524,9 @@
<genParameters ecoreParameter="emftvm.ecore#//Rule/compileIterables/env"/>
</genOperations>
<genOperations ecoreOperation="emftvm.ecore#//Rule/clearFields"/>
+ <genOperations ecoreOperation="emftvm.ecore#//Rule/findInputElement">
+ <genParameters ecoreParameter="emftvm.ecore#//Rule/findInputElement/name"/>
+ </genOperations>
</genClasses>
<genClasses ecoreClass="emftvm.ecore#//RuleElement">
<genFeatures createChild="false" ecoreFeature="ecore:EAttribute emftvm.ecore#//RuleElement/models"/>
diff --git a/plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse/m2m/atl/emftvm/Rule.java b/plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse/m2m/atl/emftvm/Rule.java
index 239d362f..4942b3ab 100644
--- a/plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse/m2m/atl/emftvm/Rule.java
+++ b/plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse/m2m/atl/emftvm/Rule.java
@@ -549,6 +549,19 @@ public interface Rule extends NamedElement {
/**
* <!-- begin-user-doc -->
+ * Matches this rule only (without suoer-rules) for <code>valuesMap</code>.
+ * Call {@link #compileState()} before calling this method.
+ * @param frame the stack frame in which to execute the matcher
+ * @param valuesMap the values to match against
+ * @return <code>true</code> iff the rule matches
+ * <!-- end-user-doc -->
+ * @model frameDataType="org.eclipse.m2m.atl.emftvm.StackFrame"
+ * @generated
+ */
+ boolean matchOneOnly(StackFrame frame, Map<String, Object> valuesMap);
+
+ /**
+ * <!-- begin-user-doc -->
* Creates trace elements for the recorded matches for this rule.
* Call {@link #compileState()} before calling this method.
* @param frame the stack frame context
@@ -612,6 +625,18 @@ public interface Rule extends NamedElement {
boolean applyFirst(StackFrame frame);
/**
+ * <!-- begin-user-doc -->
+ * Applies {@link #getRule()} to <code>trace</code>
+ * @param frame the stack frame in which to execute the applier and post-apply
+ * @param trace the source and target values to which to apply the rule
+ * @return the rule application result
+ * <!-- end-user-doc -->
+ * @model frameDataType="org.eclipse.m2m.atl.emftvm.StackFrame"
+ * @generated
+ */
+ Object applyOne(StackFrame frame, TraceLink trace);
+
+ /**
* <!-- begin-user-doc -->
* Applies this rule for the given <code>trace</code>. Call {@link #compileState()} before calling this method.
*
diff --git a/plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse/m2m/atl/emftvm/impl/EmftvmPackageImpl.java b/plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse/m2m/atl/emftvm/impl/EmftvmPackageImpl.java
index bcff1330..fb63727a 100644
--- a/plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse/m2m/atl/emftvm/impl/EmftvmPackageImpl.java
+++ b/plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse/m2m/atl/emftvm/impl/EmftvmPackageImpl.java
@@ -3745,6 +3745,15 @@ public class EmftvmPackageImpl extends EPackageImpl implements EmftvmPackage {
g1.getETypeArguments().add(g2);
addEParameter(op, g1, "valuesMap", 0, 1, IS_UNIQUE, IS_ORDERED);
+ op = addEOperation(ruleEClass, theEcorePackage.getEBoolean(), "matchOneOnly", 0, 1, IS_UNIQUE, IS_ORDERED);
+ addEParameter(op, this.getStackFrame(), "frame", 0, 1, IS_UNIQUE, IS_ORDERED);
+ g1 = createEGenericType(theEcorePackage.getEMap());
+ g2 = createEGenericType(theEcorePackage.getEString());
+ g1.getETypeArguments().add(g2);
+ g2 = createEGenericType(theEcorePackage.getEJavaObject());
+ g1.getETypeArguments().add(g2);
+ addEParameter(op, g1, "valuesMap", 0, 1, IS_UNIQUE, IS_ORDERED);
+
op = addEOperation(ruleEClass, null, "createTraces", 0, 1, IS_UNIQUE, IS_ORDERED);
addEParameter(op, this.getStackFrame(), "frame", 0, 1, IS_UNIQUE, IS_ORDERED);
@@ -3761,6 +3770,10 @@ public class EmftvmPackageImpl extends EPackageImpl implements EmftvmPackage {
op = addEOperation(ruleEClass, theEcorePackage.getEBoolean(), "applyFirst", 0, 1, IS_UNIQUE, IS_ORDERED);
addEParameter(op, this.getStackFrame(), "frame", 0, 1, IS_UNIQUE, IS_ORDERED);
+ op = addEOperation(ruleEClass, theEcorePackage.getEJavaObject(), "applyOne", 0, 1, IS_UNIQUE, IS_ORDERED);
+ addEParameter(op, this.getStackFrame(), "frame", 0, 1, IS_UNIQUE, IS_ORDERED);
+ addEParameter(op, theTracePackage.getTraceLink(), "trace", 0, 1, IS_UNIQUE, IS_ORDERED);
+
op = addEOperation(ruleEClass, theEcorePackage.getEJavaObject(), "applyFor", 0, 1, IS_UNIQUE, IS_ORDERED);
addEParameter(op, this.getStackFrame(), "frame", 0, 1, IS_UNIQUE, IS_ORDERED);
addEParameter(op, theTracePackage.getTraceLink(), "trace", 0, 1, IS_UNIQUE, IS_ORDERED);
diff --git a/plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse/m2m/atl/emftvm/impl/RuleImpl.java b/plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse/m2m/atl/emftvm/impl/RuleImpl.java
index 2777d140..6f921d74 100644
--- a/plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse/m2m/atl/emftvm/impl/RuleImpl.java
+++ b/plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse/m2m/atl/emftvm/impl/RuleImpl.java
@@ -21,6 +21,7 @@ import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
+import java.util.Set;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.NotificationChain;
@@ -138,7 +139,7 @@ public class RuleImpl extends NamedElementImpl implements Rule {
final Object[] values);
/**
- *
+ * Matches
* @param frame
* @param values
* @return
@@ -179,13 +180,47 @@ public class RuleImpl extends NamedElementImpl implements Rule {
assert !isUnique();
final Map<String, Object> valuesMap = createValuesMap(values);
if (matchOne(frame, valuesMap)) {
- return applyTo(frame, createTrace(frame, valuesMap));
+ final Set<Rule> matchedRules = matchManualSubRules(RuleImpl.this, frame, valuesMap);
+ final int size = matchedRules.size();
+ switch (size) {
+ case 0:
+ //TODO should not work for abstract rules
+ return applyOne(frame, createTrace(frame, valuesMap));
+ case 1:
+ return matchedRules.iterator().next().applyOne(frame, createTrace(frame, valuesMap));
+ default:
+ throw new VMException(frame, String.format("More than one matching sub-rule found for %s: %s",
+ RuleImpl.this, matchedRules));
+ }
} else {
return null;
}
}
/**
+ * TODO
+ * @param rule
+ * @param frame
+ * @param valuesMap
+ * @return
+ */
+ private Set<Rule> matchManualSubRules(final Rule rule, final StackFrame frame, final Map<String, Object> valuesMap) {
+ final Set<Rule> matchedRules = new HashSet<Rule>();
+ for (Rule subRule : rule.getESubRules()) {
+ if (subRule.matchOneOnly(frame, valuesMap)) {
+ Set<Rule> matchedSubRules = matchManualSubRules(subRule, frame, valuesMap);
+ if (!matchedSubRules.isEmpty()) {
+ matchedRules.addAll(matchedSubRules);
+ } else {
+ //TODO not for abstract rules
+ matchedRules.add(subRule);
+ }
+ }
+ }
+ return matchedRules;
+ }
+
+ /**
* {@inheritDoc}
*/
@Override
@@ -2086,13 +2121,23 @@ public class RuleImpl extends NamedElementImpl implements Rule {
* <!-- end-user-doc -->
* @generated NOT
*/
- public boolean matchOne(StackFrame frame, Map<String, Object> valuesMap) {
+ public boolean matchOne(final StackFrame frame, final Map<String, Object> valuesMap) {
for (Rule superRule : getESuperRules()) {
if (!superRule.matchOne(frame, valuesMap)) {
return false;
}
}
+ return matchOneOnly(frame, valuesMap);
+ }
+
+ /**
+ * <!-- begin-user-doc. -->
+ * {@inheritDoc}
+ * <!-- end-user-doc -->
+ * @generated NOT
+ */
+ public boolean matchOneOnly(StackFrame frame, Map<String, Object> valuesMap) {
// Check value types
final ExecEnv env = frame.getEnv();
final Object[] values = createValuesArray(valuesMap);
@@ -2124,7 +2169,7 @@ public class RuleImpl extends NamedElementImpl implements Rule {
}
// Check bound values
- final CodeBlock binding = re.getBinding();
+ CodeBlock binding = re.getBinding();
if (binding != null) {
final Object bvalue = binding.execute(frame.getSubFrame(binding, values));
if (bvalue == null) {
@@ -2239,6 +2284,39 @@ public class RuleImpl extends NamedElementImpl implements Rule {
* <!-- end-user-doc -->
* @generated NOT
*/
+ public Object applyOne(final StackFrame frame, final TraceLink trace) {
+ Object result = null;
+ for (Rule rule : getAllESuperRules()) {
+ if (rule.getApplier() != null) {
+ result = rule.applyFor(frame, trace);
+ } else {
+ rule.applyFor(frame, trace);
+ }
+ if (rule.getPostApply() != null) {
+ result = rule.postApplyFor(frame, trace);
+ } else {
+ rule.postApplyFor(frame, trace);
+ }
+ }
+ if (getApplier() != null) {
+ result = applierCbState.applyFor(frame, trace);
+ } else {
+ applierCbState.applyFor(frame, trace);
+ }
+ if (getPostApply() != null) {
+ result = applierCbState.postApplyFor(frame, trace);
+ } else {
+ applierCbState.postApplyFor(frame, trace);
+ }
+ return result;
+ }
+
+ /**
+ * <!-- begin-user-doc. -->
+ * {@inheritDoc}
+ * <!-- end-user-doc -->
+ * @generated NOT
+ */
public Object applyFor(final StackFrame frame, final TraceLink trace) {
return applierCbState.applyFor(frame, trace);
}
diff --git a/tests/org.eclipse.m2m.atl.emftvm.tests/src/org/eclipse/m2m/atl/emftvm/tests/RuleTest.java b/tests/org.eclipse.m2m.atl.emftvm.tests/src/org/eclipse/m2m/atl/emftvm/tests/RuleTest.java
index 9dc0fefc..4fe9431a 100644
--- a/tests/org.eclipse.m2m.atl.emftvm.tests/src/org/eclipse/m2m/atl/emftvm/tests/RuleTest.java
+++ b/tests/org.eclipse.m2m.atl.emftvm.tests/src/org/eclipse/m2m/atl/emftvm/tests/RuleTest.java
@@ -42,11 +42,13 @@ import org.eclipse.m2m.atl.emftvm.Rule;
* <li>{@link org.eclipse.m2m.atl.emftvm.Rule#matchRecursive(org.eclipse.m2m.atl.emftvm.util.StackFrame) <em>Match Recursive</em>}</li>
* <li>{@link org.eclipse.m2m.atl.emftvm.Rule#matchManual(org.eclipse.m2m.atl.emftvm.util.StackFrame, java.lang.Object[]) <em>Match Manual</em>}</li>
* <li>{@link org.eclipse.m2m.atl.emftvm.Rule#matchOne(org.eclipse.m2m.atl.emftvm.util.StackFrame, java.util.Map) <em>Match One</em>}</li>
+ * <li>{@link org.eclipse.m2m.atl.emftvm.Rule#matchOneOnly(org.eclipse.m2m.atl.emftvm.util.StackFrame, java.util.Map) <em>Match One Only</em>}</li>
* <li>{@link org.eclipse.m2m.atl.emftvm.Rule#createTraces(org.eclipse.m2m.atl.emftvm.util.StackFrame) <em>Create Traces</em>}</li>
* <li>{@link org.eclipse.m2m.atl.emftvm.Rule#completeTraceFor(org.eclipse.m2m.atl.emftvm.util.StackFrame, org.eclipse.m2m.atl.emftvm.trace.TraceLink) <em>Complete Trace For</em>}</li>
* <li>{@link org.eclipse.m2m.atl.emftvm.Rule#apply(org.eclipse.m2m.atl.emftvm.util.StackFrame) <em>Apply</em>}</li>
* <li>{@link org.eclipse.m2m.atl.emftvm.Rule#postApply(org.eclipse.m2m.atl.emftvm.util.StackFrame) <em>Post Apply</em>}</li>
* <li>{@link org.eclipse.m2m.atl.emftvm.Rule#applyFirst(org.eclipse.m2m.atl.emftvm.util.StackFrame) <em>Apply First</em>}</li>
+ * <li>{@link org.eclipse.m2m.atl.emftvm.Rule#applyOne(org.eclipse.m2m.atl.emftvm.util.StackFrame, org.eclipse.m2m.atl.emftvm.trace.TraceLink) <em>Apply One</em>}</li>
* <li>{@link org.eclipse.m2m.atl.emftvm.Rule#applyFor(org.eclipse.m2m.atl.emftvm.util.StackFrame, org.eclipse.m2m.atl.emftvm.trace.TraceLink) <em>Apply For</em>}</li>
* <li>{@link org.eclipse.m2m.atl.emftvm.Rule#postApplyFor(org.eclipse.m2m.atl.emftvm.util.StackFrame, org.eclipse.m2m.atl.emftvm.trace.TraceLink) <em>Post Apply For</em>}</li>
* <li>{@link org.eclipse.m2m.atl.emftvm.Rule#getAllESuperRules() <em>Get All ESuper Rules</em>}</li>
@@ -284,6 +286,19 @@ public class RuleTest extends NamedElementTest {
}
/**
+ * Tests the '{@link org.eclipse.m2m.atl.emftvm.Rule#matchOneOnly(org.eclipse.m2m.atl.emftvm.util.StackFrame, java.util.Map) <em>Match One Only</em>}' operation.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @see org.eclipse.m2m.atl.emftvm.Rule#matchOneOnly(org.eclipse.m2m.atl.emftvm.util.StackFrame, java.util.Map)
+ * @generated
+ */
+ public void testMatchOneOnly__StackFrame_Map() {
+ // TODO: implement this operation test method
+ // Ensure that you remove @generated or mark it @generated NOT
+ fail();
+ }
+
+ /**
* Tests the '{@link org.eclipse.m2m.atl.emftvm.Rule#createTraces(org.eclipse.m2m.atl.emftvm.util.StackFrame) <em>Create Traces</em>}'
* operation. <!-- begin-user-doc --> <!-- end-user-doc -->
*
@@ -351,6 +366,19 @@ public class RuleTest extends NamedElementTest {
}
/**
+ * Tests the '{@link org.eclipse.m2m.atl.emftvm.Rule#applyOne(org.eclipse.m2m.atl.emftvm.util.StackFrame, org.eclipse.m2m.atl.emftvm.trace.TraceLink) <em>Apply One</em>}' operation.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @see org.eclipse.m2m.atl.emftvm.Rule#applyOne(org.eclipse.m2m.atl.emftvm.util.StackFrame, org.eclipse.m2m.atl.emftvm.trace.TraceLink)
+ * @generated
+ */
+ public void testApplyOne__StackFrame_TraceLink() {
+ // TODO: implement this operation test method
+ // Ensure that you remove @generated or mark it @generated NOT
+ fail();
+ }
+
+ /**
* Tests the '
* {@link org.eclipse.m2m.atl.emftvm.Rule#applyFor(org.eclipse.m2m.atl.emftvm.util.StackFrame, org.eclipse.m2m.atl.emftvm.trace.TraceLink)
* <em>Apply For</em>}' operation. <!-- begin-user-doc --> <!-- end-user-doc -->

Back to the top