Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordwagelaar2015-02-13 12:21:10 +0000
committerdwagelaar2015-02-13 12:21:10 +0000
commit2dab64d71d280c455351336d31ffe89650271d29 (patch)
tree11e3bb4c6be1230aa486a4a00db06a45ea08d15a /plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse
parent40023d506041524802ee376050b865f0393e67eb (diff)
downloadorg.eclipse.atl-2dab64d71d280c455351336d31ffe89650271d29.tar.gz
org.eclipse.atl-2dab64d71d280c455351336d31ffe89650271d29.tar.xz
org.eclipse.atl-2dab64d71d280c455351336d31ffe89650271d29.zip
415863: Support (multiple) virtual dispatch for lazy rules
Task-Url: https://bugs.eclipse.org/bugs/show_bug.cgi?id=415863
Diffstat (limited to 'plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse')
-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
3 files changed, 120 insertions, 4 deletions
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 0ce6078f..48679aab 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);
}

Back to the top