Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEd Willink2016-10-09 13:35:56 +0000
committerEd Willink2016-10-30 11:37:23 +0000
commitba56020b91d0cc0f4391cc2b80b89bfe5eb47654 (patch)
treeac63bafd9af29f6cebade01bbe9047d21d2ac90e
parent42d12406c8517a62affc454fea29d6106b604d89 (diff)
downloadorg.eclipse.qvtd-ba56020b91d0cc0f4391cc2b80b89bfe5eb47654.tar.gz
org.eclipse.qvtd-ba56020b91d0cc0f4391cc2b80b89bfe5eb47654.tar.xz
org.eclipse.qvtd-ba56020b91d0cc0f4391cc2b80b89bfe5eb47654.zip
[500962] Refactor out InvocationConstructor
-rw-r--r--plugins/org.eclipse.qvtd.codegen/src/org/eclipse/qvtd/codegen/qvti/java/QVTiCG2JavaVisitor.java15
-rw-r--r--plugins/org.eclipse.qvtd.pivot.qvtbase/annotations/java/util/Arrays.eea7
-rw-r--r--plugins/org.eclipse.qvtd.pivot.qvtimperative/src/org/eclipse/qvtd/pivot/qvtimperative/evaluation/Execution2GraphVisitor.java264
-rw-r--r--plugins/org.eclipse.qvtd.pivot.qvtimperative/src/org/eclipse/qvtd/pivot/qvtimperative/evaluation/QVTiIncrementalExecutor.java16
-rw-r--r--plugins/org.eclipse.qvtd.runtime/.options3
-rw-r--r--plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/evaluation/AbstractExecutionVisitor.java4
-rw-r--r--plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/evaluation/AbstractInvocation.java9
-rw-r--r--plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/evaluation/AbstractTransformer.java1
-rw-r--r--plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/evaluation/Connection.java10
-rw-r--r--plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/evaluation/DefaultInterval.java (renamed from plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/evaluation/Invoker.java)18
-rw-r--r--plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/evaluation/ExecutionVisitor.java2
-rw-r--r--plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/evaluation/Interval.java9
-rw-r--r--plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/evaluation/Invocation.java28
-rw-r--r--plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/evaluation/InvocationConstructor.java52
-rw-r--r--plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/evaluation/InvocationManager.java10
-rw-r--r--plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/internal/evaluation/AbstractConnectionInternal.java110
-rw-r--r--plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/internal/evaluation/AbstractEnforcedConnectionInternal.java3
-rw-r--r--plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/internal/evaluation/AbstractIntervalInternal.java183
-rw-r--r--plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/internal/evaluation/AbstractInvocationConstructor.java166
-rw-r--r--plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/internal/evaluation/AbstractInvocationInternal.java5
-rw-r--r--plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/internal/evaluation/AbstractInvocationManagerInternal.java87
-rw-r--r--plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/internal/evaluation/AbstractTransformerInternal.java23
-rw-r--r--plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/internal/evaluation/AbstractUnenforcedConnectionInternal.java3
-rw-r--r--plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/internal/evaluation/ConnectionLinkage.java18
-rw-r--r--plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/internal/evaluation/IncrementalInvocationManager.java6
-rw-r--r--plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/internal/evaluation/IncrementalObjectManager.java5
-rw-r--r--plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/internal/evaluation/LazyInvocationManager.java6
-rw-r--r--plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/internal/evaluation/LazyObjectManager.java5
-rw-r--r--tests/org.eclipse.qvtd.xtext.qvtimperative.tests/src/org/eclipse/qvtd/xtext/qvtimperative/tests/QVTiCompilerTests.java41
-rw-r--r--tests/org.eclipse.qvtd.xtext.qvtimperative.tests/src/org/eclipse/qvtd/xtext/qvtimperative/tests/Tree2TallTree/Tree2TallTreeInstall.qvti55
-rw-r--r--tests/org.eclipse.qvtd.xtext.qvtimperative.tests/src/org/eclipse/qvtd/xtext/qvtimperative/tests/Tree2TallTree/Tree2TallTreeInstallManual.java511
31 files changed, 1441 insertions, 234 deletions
diff --git a/plugins/org.eclipse.qvtd.codegen/src/org/eclipse/qvtd/codegen/qvti/java/QVTiCG2JavaVisitor.java b/plugins/org.eclipse.qvtd.codegen/src/org/eclipse/qvtd/codegen/qvti/java/QVTiCG2JavaVisitor.java
index 01fcc778d..ed0de1690 100644
--- a/plugins/org.eclipse.qvtd.codegen/src/org/eclipse/qvtd/codegen/qvti/java/QVTiCG2JavaVisitor.java
+++ b/plugins/org.eclipse.qvtd.codegen/src/org/eclipse/qvtd/codegen/qvti/java/QVTiCG2JavaVisitor.java
@@ -111,6 +111,7 @@ import org.eclipse.qvtd.runtime.evaluation.AbstractInvocation;
import org.eclipse.qvtd.runtime.evaluation.AbstractTransformer;
import org.eclipse.qvtd.runtime.evaluation.AbstractValueOccurrence;
import org.eclipse.qvtd.runtime.evaluation.Invocation;
+import org.eclipse.qvtd.runtime.evaluation.InvocationConstructor;
import org.eclipse.qvtd.runtime.evaluation.InvocationManager;
import org.eclipse.qvtd.runtime.evaluation.ObjectManager;
import org.eclipse.qvtd.runtime.evaluation.TransformationExecutor;
@@ -420,7 +421,9 @@ public class QVTiCG2JavaVisitor extends CG2JavaVisitor<@NonNull QVTiCodeGenerato
js.pushIndentation(null);
js.append("return new ");
js.appendClassReference(IncrementalInvocationManager.class);
- js.append("();\n");
+ js.append("(");
+ js.append(JavaConstants.EXECUTOR_NAME);
+ js.append(");\n");
js.popIndentation();
js.append("}\n");
js.append("\n");
@@ -960,7 +963,7 @@ public class QVTiCG2JavaVisitor extends CG2JavaVisitor<@NonNull QVTiCodeGenerato
js.append(getMappingName(cgMapping));
js.append("(");
if (isIncremental) {
- js.appendClassReference(true, isIncremental ? Invocation.Constructor.Incremental.class : Invocation.Constructor.class);
+ js.appendClassReference(true, isIncremental ? InvocationConstructor.Incremental.class : InvocationConstructor.class);
js.append(" constructor, ");
}
js.appendIsRequired(true);
@@ -969,10 +972,10 @@ public class QVTiCG2JavaVisitor extends CG2JavaVisitor<@NonNull QVTiCodeGenerato
js.append(" [] boundValues) {\n");
js.pushIndentation(null);
if (isIncremental) {
- js.append("super(invocationManager.getDefaultInterval(), constructor);\n");
+ js.append("super(invocationManager.getRootInterval(), constructor);\n");
}
else {
- js.append("super(invocationManager.getDefaultInterval());\n");
+ js.append("super(invocationManager.getRootInterval());\n");
}
int i = 0;
for (@NonNull CGGuardVariable cgFreeVariable : cgFreeVariables) {
@@ -1003,7 +1006,7 @@ public class QVTiCG2JavaVisitor extends CG2JavaVisitor<@NonNull QVTiCodeGenerato
js.appendClassReference(true, constructorClass);
js.append(" " + getMappingCtorName(cgMapping) + " = new ");
js.appendClassReference(constructorClass);
- js.append("(idResolver, ");
+ js.append("(invocationManager.getRootInterval(), ");
js.appendString(QVTiCGUtil.getName(cgMapping));
js.append(")\n");
js.append("{\n");
@@ -1132,7 +1135,7 @@ public class QVTiCG2JavaVisitor extends CG2JavaVisitor<@NonNull QVTiCodeGenerato
js.pushIndentation(null);
if (isIncremental) {
js.appendClassReference(Invocation.class);
- js.append(" rootInvocation = " + getMappingCtorName(cgRootMapping) + ".newInstance(new @NonNull Object[0]);\n");
+ js.append(" rootInvocation = " + getMappingCtorName(cgRootMapping) + ".getInstance(new @NonNull Object[0]);\n");
js.append("return rootInvocation.execute() && invocationManager.flush();\n");
}
else {
diff --git a/plugins/org.eclipse.qvtd.pivot.qvtbase/annotations/java/util/Arrays.eea b/plugins/org.eclipse.qvtd.pivot.qvtbase/annotations/java/util/Arrays.eea
new file mode 100644
index 000000000..afeb20325
--- /dev/null
+++ b/plugins/org.eclipse.qvtd.pivot.qvtbase/annotations/java/util/Arrays.eea
@@ -0,0 +1,7 @@
+class java/util/Arrays
+copyOf
+ <T:Ljava/lang/Object;>([TT;I)[TT;
+ <T:Ljava/lang/Object;>([1TT;I)[1TT;
+copyOfRange
+ <T:Ljava/lang/Object;>([TT;II)[TT;
+ <T:Ljava/lang/Object;>([1TT;II)[1TT;
diff --git a/plugins/org.eclipse.qvtd.pivot.qvtimperative/src/org/eclipse/qvtd/pivot/qvtimperative/evaluation/Execution2GraphVisitor.java b/plugins/org.eclipse.qvtd.pivot.qvtimperative/src/org/eclipse/qvtd/pivot/qvtimperative/evaluation/Execution2GraphVisitor.java
index 7cec34d73..19fd86596 100644
--- a/plugins/org.eclipse.qvtd.pivot.qvtimperative/src/org/eclipse/qvtd/pivot/qvtimperative/evaluation/Execution2GraphVisitor.java
+++ b/plugins/org.eclipse.qvtd.pivot.qvtimperative/src/org/eclipse/qvtd/pivot/qvtimperative/evaluation/Execution2GraphVisitor.java
@@ -10,6 +10,8 @@
******************************************************************************/
package org.eclipse.qvtd.pivot.qvtimperative.evaluation;
+import java.io.IOException;
+import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
@@ -17,12 +19,15 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
+import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EAttribute;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.ecore.resource.URIConverter;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
+import org.eclipse.qvtd.pivot.qvtbase.graphs.GraphMLStringBuilder;
import org.eclipse.qvtd.pivot.qvtbase.graphs.GraphStringBuilder;
import org.eclipse.qvtd.pivot.qvtbase.graphs.GraphStringBuilder.GraphEdge;
import org.eclipse.qvtd.pivot.qvtbase.graphs.GraphStringBuilder.GraphNode;
@@ -31,7 +36,10 @@ import org.eclipse.qvtd.pivot.qvtimperative.evaluationstatus.AttributeStatus;
import org.eclipse.qvtd.pivot.qvtimperative.evaluationstatus.ClassStatus;
import org.eclipse.qvtd.pivot.qvtimperative.evaluationstatus.PropertyStatus;
import org.eclipse.qvtd.runtime.evaluation.AbstractExecutionVisitor;
+import org.eclipse.qvtd.runtime.evaluation.Connection;
+import org.eclipse.qvtd.runtime.evaluation.Interval;
import org.eclipse.qvtd.runtime.evaluation.Invocation;
+import org.eclipse.qvtd.runtime.evaluation.InvocationConstructor;
import org.eclipse.qvtd.runtime.evaluation.InvocationManager;
import org.eclipse.qvtd.runtime.evaluation.ObjectManager;
import org.eclipse.qvtd.runtime.evaluation.SlotState;
@@ -46,16 +54,21 @@ public class Execution2GraphVisitor extends AbstractExecutionVisitor<@Nullable O
private final @NonNull GraphNode sourceNode;
private final @NonNull GraphNode targetNode;
private final @NonNull String color;
+ private final @Nullable String style;
- protected ExecutionEdge(@NonNull GraphNode sourceNode, @NonNull GraphNode targetNode, @NonNull String color) {
+ protected ExecutionEdge(@NonNull GraphNode sourceNode, @NonNull GraphNode targetNode, @NonNull String color, @Nullable String style) {
this.sourceNode = sourceNode;
this.targetNode = targetNode;
this.color = color;
+ this.style = style;
}
@Override
public void appendEdgeAttributes(@NonNull GraphStringBuilder s, @NonNull GraphNode source, @NonNull GraphNode target) {
s.setColor(color);
+ if (style != null) {
+ s.setStyle(style);
+ }
s.appendAttributedEdge(source, this, target);
}
@@ -72,11 +85,28 @@ public class Execution2GraphVisitor extends AbstractExecutionVisitor<@Nullable O
protected static @NonNull String NULL_PLACEHOLDER = "\"<null>\""; //$NON-NLS-1$
+ public static void writeGraphMLfile(Transformer tx, @NonNull URI graphmlURI) {
+ try {
+ OutputStream outputStream = URIConverter.INSTANCE.createOutputStream(graphmlURI);
+ GraphMLStringBuilder s = new GraphMLStringBuilder();
+ Execution2GraphVisitor execution2GraphVisitor = new Execution2GraphVisitor(s);
+ tx.accept(execution2GraphVisitor);
+ outputStream.write(s.toString().getBytes());
+ outputStream.close();
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+
protected final @NonNull GraphStringBuilder context;
private Map<@NonNull AssociationStatus, @NonNull String> associationId = new HashMap<>();
private Map<@NonNull ClassStatus, @NonNull String> classId = new HashMap<>();
+ private Map<@NonNull Connection, @NonNull GraphNode> connection2node = new HashMap<>();
+ private Map<@NonNull Interval, @NonNull GraphNode> interval2node = new HashMap<>();
private Map<@NonNull Invocation, @NonNull GraphNode> invocation2node = new HashMap<>();
+ private Map<@NonNull InvocationConstructor, @NonNull GraphNode> invocationConstructor2node = new HashMap<>();
private Map<@NonNull Object, @NonNull GraphNode> object2node = new HashMap<>();
private Map<@NonNull SlotState, @NonNull GraphNode> slot2node = new HashMap<>();
// private Map<@NonNull String, @NonNull String> propertyId2associationId = new HashMap<>();
@@ -86,8 +116,8 @@ public class Execution2GraphVisitor extends AbstractExecutionVisitor<@Nullable O
this.context = s;
}
- protected void appendEdge(@NonNull GraphNode sourceNode, @NonNull GraphNode targetNode, @NonNull String color) {
- context.appendEdge(sourceNode, new ExecutionEdge(sourceNode, targetNode, color), targetNode);
+ protected void appendEdge(@NonNull GraphNode sourceNode, @NonNull GraphNode targetNode, @NonNull String color, @Nullable String style) {
+ context.appendEdge(sourceNode, new ExecutionEdge(sourceNode, targetNode, color, style), targetNode);
}
protected @NonNull String getAssociationColor(@NonNull AssociationStatus associationStatus) {
@@ -147,18 +177,79 @@ public class Execution2GraphVisitor extends AbstractExecutionVisitor<@Nullable O
return id;
}
+ protected @NonNull GraphNode getConnectionNode(@NonNull Connection object) {
+ GraphNode node = connection2node.get(object);
+ if (node == null) {
+ final String label = object.getName();
+ node = new GraphNode()
+ {
+ @Override
+ public void appendNode(@NonNull GraphStringBuilder s, @NonNull String nodeName) {
+ s.setLabel(label);
+ s.setShape("ellipse");
+ s.setColor("brown");
+ s.appendAttributedNode(nodeName);
+ }
+ };
+ connection2node.put(object, node);
+ context.appendNode(node);
+ }
+ return node;
+ }
+
+ protected @NonNull GraphNode getIntervalNode(@NonNull Interval object) {
+ GraphNode node = interval2node.get(object);
+ if (node == null) {
+ final String label = " " + object.getName() + " ";
+ node = new GraphNode()
+ {
+ @Override
+ public void appendNode(@NonNull GraphStringBuilder s, @NonNull String nodeName) {
+ s.setLabel(label);
+ s.setShape("octagon");
+ s.setColor("black");
+ s.appendAttributedNode(nodeName);
+ }
+ };
+ interval2node.put(object, node);
+ context.appendNode(node);
+ }
+ return node;
+ }
+
+ protected @NonNull GraphNode getInvocationConstructorNode(@NonNull InvocationConstructor object) {
+ GraphNode node = invocationConstructor2node.get(object);
+ if (node == null) {
+ final String label = object.getName();
+ node = new GraphNode()
+ {
+ @Override
+ public void appendNode(@NonNull GraphStringBuilder s, @NonNull String nodeName) {
+ s.setLabel(label);
+ s.setShape("hexagon");
+ s.setColor("brown");
+ s.appendAttributedNode(nodeName);
+ }
+ };
+ invocationConstructor2node.put(object, node);
+ context.appendNode(node);
+ }
+ return node;
+ }
+
protected @NonNull GraphNode getInvocationNode(@NonNull Invocation object) {
GraphNode node = invocation2node.get(object);
if (node == null) {
// id = object.getReferredMappingCall().getReferredMapping().getName() + "-" + (mappingId.size() + 1);
- final String label;
- if (object instanceof EObject) {
- label = ((EObject)object).eClass().getName() + "-" + (invocation2node.size() + 1);
- }
- else {
- label = object.toString().replace("@", "\n@");
- // label = object.getClass().getSimpleName() + "-" + (invocation2node.size() + 1);
- }
+ final String label = object.getName();
+ // final String label;
+ // if (object instanceof EObject) {
+ // label = ((EObject)object).eClass().getName() + "-" + (invocation2node.size() + 1);
+ // }
+ // else {
+ // label = object.toString().replace("@", "\n@");
+ // label = object.getClass().getSimpleName() + "-" + (invocation2node.size() + 1);
+ // }
node = new GraphNode()
{
@Override
@@ -176,7 +267,7 @@ public class Execution2GraphVisitor extends AbstractExecutionVisitor<@Nullable O
return node;
}
- protected @NonNull GraphNode getObjectNode(@NonNull Object object, @NonNull String color) {
+ protected @NonNull GraphNode getObjectNode(@NonNull Object object) {
GraphNode node = object2node.get(object);
if (node == null) {
// id = object.getReferredMappingCall().getReferredMapping().getName() + "-" + (mappingId.size() + 1);
@@ -194,7 +285,7 @@ public class Execution2GraphVisitor extends AbstractExecutionVisitor<@Nullable O
public void appendNode(@NonNull GraphStringBuilder s, @NonNull String nodeName) {
s.setLabel(label);
s.setShape("rectangle");
- s.setColor(color);
+ s.setColor("blue");
s.appendAttributedNode(nodeName);
}
};
@@ -216,7 +307,7 @@ public class Execution2GraphVisitor extends AbstractExecutionVisitor<@Nullable O
}
}
- protected @NonNull GraphNode getSlotNode(SlotState.@NonNull Incremental object, @NonNull String color) {
+ protected @NonNull GraphNode getSlotNode(SlotState.@NonNull Incremental object) {
if (object.getValue() != null) {
object = object.getPrimarySlotState();
}
@@ -230,6 +321,14 @@ public class Execution2GraphVisitor extends AbstractExecutionVisitor<@Nullable O
label += " / " + eOpposite.getName();
}
}
+ else if (eFeature instanceof EAttribute) {
+ Object value = object.getValue(); // FIXME may be null for inputs, and some slots seem crooked
+ String stringValue = value != null ? value.toString() : "???";
+ if (stringValue.length() > 20) {
+ stringValue = stringValue.substring(0, 17) + "...";
+ }
+ label += " \n " + stringValue;
+ }
final String finalLabel = label;
node = new GraphNode()
{
@@ -240,7 +339,7 @@ public class Execution2GraphVisitor extends AbstractExecutionVisitor<@Nullable O
if (eFeature instanceof EAttribute) {
s.setStyle("rounded");
}
- s.setColor(color);
+ s.setColor("blue");
s.appendAttributedNode(nodeName);
}
};
@@ -250,6 +349,31 @@ public class Execution2GraphVisitor extends AbstractExecutionVisitor<@Nullable O
return node;
}
+ @Override
+ public @Nullable Object visitConnection(@NonNull Connection object) {
+ GraphNode connectionNode = getConnectionNode(object);
+ for (@NonNull InvocationConstructor producer : object.getAppenders()) {
+ GraphNode producerNode = getInvocationConstructorNode(producer);
+ appendEdge(producerNode, connectionNode, "brown", null);
+ }
+ for (@NonNull InvocationConstructor consumer : object.getConsumers()) {
+ GraphNode consumerNode = getInvocationConstructorNode(consumer);
+ appendEdge(connectionNode, consumerNode, "brown", null);
+ }
+ int iMax = object.getValues();
+ for (int i = 0; i < iMax; i++) {
+ Object value = object.getValue(i);
+ if (value != null) {
+ GraphNode objectNode = getObjectNode(value);
+ appendEdge(connectionNode, objectNode, "brown", "dotted");
+ // for (@NonNull Invocation invocation : object.getConsumers(i)) {
+ // GraphNode consumerNode = getInvocationNode(invocation);
+ // }
+ }
+ }
+ return null;
+ }
+
/* @Override
public String visiting(@NonNull EvaluationElement visitable) {
// append(visitable.getClass().getName());
@@ -312,50 +436,74 @@ public class Execution2GraphVisitor extends AbstractExecutionVisitor<@Nullable O
} */
@Override
+ public @Nullable Object visitInterval(@NonNull Interval object) {
+ GraphNode intervalNode = getIntervalNode(object);
+ for (@NonNull Connection connection : object.getConnections()) {
+ connection.accept(this);
+ GraphNode connectionNode = getConnectionNode(connection);
+ appendEdge(connectionNode, intervalNode, "black", "dashed");
+ }
+ return null;
+ }
+
+ @Override
public @Nullable String visitInvocation(@NonNull Invocation object) {
@SuppressWarnings("unused")
GraphNode invocationNode = getInvocationNode(object);
/* context.appendNode(mappingId, "hexagon", "#ffcc00", 30, 150, mappingId.replace("-", "\n"));
- for (ElementStatus inputStatus : object.getInputs()) {
- if (inputStatus instanceof ClassStatus) {
- ClassStatus classStatus = (ClassStatus)inputStatus;
- String classId = getClassId(classStatus);
- context.appendEdge(classId, mappingId, "#000000", "line","none", "standard");
- }
- else if (inputStatus instanceof PropertyStatus) {
- PropertyStatus propertyStatus = (PropertyStatus)inputStatus;
- String propertyId = getPropertyId(propertyStatus);
- context.appendEdge(propertyId, mappingId, "#000000", "dashed","none", "standard");
+ for (ElementStatus inputStatus : object.getInputs()) {
+ if (inputStatus instanceof ClassStatus) {
+ ClassStatus classStatus = (ClassStatus)inputStatus;
+ String classId = getClassId(classStatus);
+ context.appendEdge(classId, mappingId, "#000000", "line","none", "standard");
+ }
+ else if (inputStatus instanceof PropertyStatus) {
+ PropertyStatus propertyStatus = (PropertyStatus)inputStatus;
+ String propertyId = getPropertyId(propertyStatus);
+ context.appendEdge(propertyId, mappingId, "#000000", "dashed","none", "standard");
+ }
}
+ for (ElementStatus outputStatus : object.getOutputs()) {
+ if (outputStatus instanceof ClassStatus) {
+ ClassStatus classStatus = (ClassStatus)outputStatus;
+ String classId = getClassId(classStatus);
+ context.appendEdge(mappingId, classId, "#000000", "line","none", "standard");
+ }
+ else if (outputStatus instanceof PropertyStatus) {
+ PropertyStatus propertyStatus = (PropertyStatus)outputStatus;
+ String propertyId = getPropertyId(propertyStatus);
+ context.appendEdge(mappingId, propertyId, "#000000", "dashed","none", "standard");
+ }
+ } */
+ return null;
+ }
+
+ @Override
+ public @Nullable Object visitInvocationConstructor(@NonNull InvocationConstructor object) {
+ GraphNode invokerNode = getInvocationConstructorNode(object);
+ GraphNode intervalNode = getIntervalNode(object.getInterval());
+ appendEdge(invokerNode, intervalNode, "black", "dashed");
+ for (@NonNull Invocation invocation : object.getInvocations()) {
+ GraphNode invocationNode = getInvocationNode(invocation);
+ appendEdge(invokerNode, invocationNode, "orange", "dotted");
}
- for (ElementStatus outputStatus : object.getOutputs()) {
- if (outputStatus instanceof ClassStatus) {
- ClassStatus classStatus = (ClassStatus)outputStatus;
- String classId = getClassId(classStatus);
- context.appendEdge(mappingId, classId, "#000000", "line","none", "standard");
- }
- else if (outputStatus instanceof PropertyStatus) {
- PropertyStatus propertyStatus = (PropertyStatus)outputStatus;
- String propertyId = getPropertyId(propertyStatus);
- context.appendEdge(mappingId, propertyId, "#000000", "dashed","none", "standard");
- }
- } */
return null;
}
@Override
public @Nullable String visitInvocationManager(@NonNull InvocationManager object) {
- // context.open();
- // for (ClassStatus classStatus : object.getOwnedClassStatuses()) {
- // classStatus.accept(this);
- // }
- // for (MappingStatus mappingStatus : object.getOwnedMappingStatuses()) {
- // mappingStatus.accept(this);
- // }
- // for (AssociationStatus associationStatus : object.getOwnedAssociationStatuses()) {
- // associationStatus.accept(this);
- // }
- // context.close();
+ GraphNode previousNode = null;
+ for (@NonNull InvocationConstructor invoker : object.getInvokers()) {
+ invoker.accept(this);
+ }
+ for (@NonNull Interval interval : object.getIntervals()) {
+ interval.accept(this);
+ GraphNode nextNode = getIntervalNode(interval);
+ if (previousNode != null) {
+ appendEdge(previousNode, nextNode, "black", null);
+ }
+ previousNode = nextNode;
+ }
return null;
}
@@ -383,29 +531,29 @@ public class Execution2GraphVisitor extends AbstractExecutionVisitor<@Nullable O
invocation.accept(this);
GraphNode invocationNode = getInvocationNode(invocation);
for (@NonNull Object createdObject : invocation.getCreatedObjects()) {
- GraphNode objectNode = getObjectNode(createdObject, "green");
- appendEdge(invocationNode, objectNode, "green");
+ GraphNode objectNode = getObjectNode(createdObject);
+ appendEdge(invocationNode, objectNode, "green", null);
}
}
for (SlotState.@NonNull Incremental slotState : allSlots) {
- GraphNode slotNode = getSlotNode(slotState, "green");
+ GraphNode slotNode = getSlotNode(slotState);
slotState.accept(this);
for (@NonNull Invocation invocation : slotState.getSources()) {
- appendEdge(getInvocationNode(invocation), slotNode, "green");
+ appendEdge(getInvocationNode(invocation), slotNode, "green", null);
}
for (@NonNull Invocation invocation : slotState.getTargets()) {
- appendEdge(slotNode, getInvocationNode(invocation), "cyan");
+ appendEdge(slotNode, getInvocationNode(invocation), "cyan", null);
}
Iterables.addAll(allInvocations, slotState.getTargets());
}
for (@NonNull Object object : objectManager.getObjects()) {
- GraphNode objectNode = getObjectNode(object, "blue");
+ GraphNode objectNode = getObjectNode(object);
List<SlotState.@NonNull Incremental> slots = object2slots.get(object);
if (slots != null) {
for (SlotState.@NonNull Incremental slotState : slots) {
- GraphNode slotNode = getSlotNode(slotState, "blue");
+ GraphNode slotNode = getSlotNode(slotState);
slotState.accept(this);
- appendEdge(objectNode, slotNode, "blue");
+ appendEdge(objectNode, slotNode, "blue", null);
}
}
}
@@ -419,7 +567,9 @@ public class Execution2GraphVisitor extends AbstractExecutionVisitor<@Nullable O
}
@Override
- public @Nullable String visitTransformer(@NonNull Transformer object) {
+ public @Nullable String visitTransformer(@NonNull Transformer transformer) {
+ transformer.getInvocationManager().accept(this);
+ transformer.getObjectManager().accept(this);
return null;
}
diff --git a/plugins/org.eclipse.qvtd.pivot.qvtimperative/src/org/eclipse/qvtd/pivot/qvtimperative/evaluation/QVTiIncrementalExecutor.java b/plugins/org.eclipse.qvtd.pivot.qvtimperative/src/org/eclipse/qvtd/pivot/qvtimperative/evaluation/QVTiIncrementalExecutor.java
index afb96a50c..8b115b01b 100644
--- a/plugins/org.eclipse.qvtd.pivot.qvtimperative/src/org/eclipse/qvtd/pivot/qvtimperative/evaluation/QVTiIncrementalExecutor.java
+++ b/plugins/org.eclipse.qvtd.pivot.qvtimperative/src/org/eclipse/qvtd/pivot/qvtimperative/evaluation/QVTiIncrementalExecutor.java
@@ -27,6 +27,7 @@ import org.eclipse.ocl.pivot.Property;
import org.eclipse.ocl.pivot.evaluation.EvaluationVisitor;
import org.eclipse.ocl.pivot.ids.IdResolver;
import org.eclipse.ocl.pivot.utilities.ClassUtil;
+import org.eclipse.ocl.pivot.utilities.LabelUtil;
import org.eclipse.ocl.pivot.utilities.PivotUtil;
import org.eclipse.ocl.pivot.utilities.ValueUtil;
import org.eclipse.ocl.pivot.values.InvalidValueException;
@@ -44,6 +45,7 @@ import org.eclipse.qvtd.runtime.evaluation.AbstractInvocation;
import org.eclipse.qvtd.runtime.evaluation.AbstractTransformer;
import org.eclipse.qvtd.runtime.evaluation.Computation;
import org.eclipse.qvtd.runtime.evaluation.Invocation;
+import org.eclipse.qvtd.runtime.evaluation.InvocationConstructor;
import org.eclipse.qvtd.runtime.evaluation.InvocationFailedException;
import org.eclipse.qvtd.runtime.evaluation.InvocationManager;
import org.eclipse.qvtd.runtime.evaluation.ObjectManager;
@@ -78,7 +80,7 @@ public class QVTiIncrementalExecutor extends BasicQVTiExecutor
protected final @NonNull InvocationManager invocationManager;
protected final @NonNull ObjectManager objectManager;
private Invocation.@Nullable Incremental currentInvocation = null;
- private @Nullable Map<@NonNull Mapping, Invocation.@NonNull Constructor> mapping2invocationConstructor = null;
+ private @Nullable Map<@NonNull Mapping, @NonNull InvocationConstructor> mapping2invocationConstructor = null;
private @Nullable Map<@NonNull Operation, Computation.@NonNull Constructor> operation2computationConstructor = null;
public QVTiIncrementalExecutor(@NonNull QVTiEnvironmentFactory environmentFactory, @NonNull ImperativeTransformation transformation, @NonNull Mode mode) {
@@ -86,7 +88,7 @@ public class QVTiIncrementalExecutor extends BasicQVTiExecutor
this.mode = mode;
this.transformationAnalysis = getModelManager().getTransformationAnalysis();
boolean isLazy = mode == Mode.LAZY;
- this.invocationManager = isLazy ? new LazyInvocationManager() : new IncrementalInvocationManager();
+ this.invocationManager = isLazy ? new LazyInvocationManager(this) : new IncrementalInvocationManager(this);
this.objectManager = isLazy ? new LazyObjectManager((LazyInvocationManager)invocationManager) : new IncrementalObjectManager((IncrementalInvocationManager)invocationManager);
}
@@ -157,17 +159,17 @@ public class QVTiIncrementalExecutor extends BasicQVTiExecutor
return super.internalExecuteMappingCall(mappingCall, boundValues, undecoratedVisitor);
}
}
- Map<@NonNull Mapping, Invocation.@NonNull Constructor> mapping2invocationConstructor2 = mapping2invocationConstructor;
+ Map<@NonNull Mapping, @NonNull InvocationConstructor> mapping2invocationConstructor2 = mapping2invocationConstructor;
if (mapping2invocationConstructor2 == null) {
mapping2invocationConstructor = mapping2invocationConstructor2 = new HashMap<>();
}
- Invocation.Constructor invocationConstructor = mapping2invocationConstructor2.get(asMapping);
+ InvocationConstructor invocationConstructor = mapping2invocationConstructor2.get(asMapping);
if (invocationConstructor == null) {
- invocationConstructor = new AbstractInvocationConstructor.Incremental(idResolver, QVTimperativeUtil.getName(asMapping))
+ invocationConstructor = new AbstractInvocationConstructor.Incremental(invocationManager.getRootInterval(), QVTimperativeUtil.getName(asMapping))
{
@Override
public @NonNull Invocation newInstance(@NonNull Object @NonNull [] theseValues) {
- Invocation.Incremental invocation = new AbstractInvocation.Incremental(invocationManager.getDefaultInterval(), this)
+ Invocation.Incremental invocation = new AbstractInvocation.Incremental(invocationManager.getRootInterval(), this)
{
protected Object returnStatus;
@@ -253,7 +255,7 @@ public class QVTiIncrementalExecutor extends BasicQVTiExecutor
objectManager.getting(sourceValue, eFeature, isOpposite);
ecoreValue = super.internalExecuteNavigationCallExp(navigationCallExp, referredProperty, sourceValue);
if (debugInvocations) {
- AbstractTransformer.INVOCATIONS.println("got " + eFeature.getEContainingClass().getName() + "::" + eFeature.getName() + " for " + sourceValue + " = " + ecoreValue);
+ AbstractTransformer.INVOCATIONS.println("got " + eFeature.getEContainingClass().getName() + "::" + eFeature.getName() + " for " + LabelUtil.getLabel(sourceValue) + " = " + LabelUtil.getLabel(ecoreValue));
}
}
else {
diff --git a/plugins/org.eclipse.qvtd.runtime/.options b/plugins/org.eclipse.qvtd.runtime/.options
index e0294cf01..5ef141ff5 100644
--- a/plugins/org.eclipse.qvtd.runtime/.options
+++ b/plugins/org.eclipse.qvtd.runtime/.options
@@ -3,6 +3,9 @@
# Trace transformation connection appends
org.eclipse.qvtd.runtime/tx/appends=false
+# Trace transformation connection consumes
+org.eclipse.qvtd.runtime/tx/consumes=false
+
# Trace transformation exceptions
org.eclipse.qvtd.runtime/tx/exceptions=false
diff --git a/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/evaluation/AbstractExecutionVisitor.java b/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/evaluation/AbstractExecutionVisitor.java
index faab92923..138922dbb 100644
--- a/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/evaluation/AbstractExecutionVisitor.java
+++ b/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/evaluation/AbstractExecutionVisitor.java
@@ -48,12 +48,12 @@ public /*abstract*/ class AbstractExecutionVisitor<R> implements ExecutionVisito
}
@Override
- public R visitInvocationManager(@NonNull InvocationManager object) {
+ public R visitInvocationConstructor(@NonNull InvocationConstructor object) {
return visiting(object);
}
@Override
- public R visitInvoker(@NonNull Invoker object) {
+ public R visitInvocationManager(@NonNull InvocationManager object) {
return visiting(object);
}
diff --git a/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/evaluation/AbstractInvocation.java b/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/evaluation/AbstractInvocation.java
index d833b2fa3..b1b7d64b2 100644
--- a/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/evaluation/AbstractInvocation.java
+++ b/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/evaluation/AbstractInvocation.java
@@ -28,14 +28,14 @@ public abstract class AbstractInvocation extends AbstractInvocationInternal
public static final @NonNull List<@NonNull Object> EMPTY_OBJECT_LIST = Collections.emptyList();
public static final @NonNull List<SlotState.@NonNull Incremental> EMPTY_SLOT_LIST = Collections.emptyList();
- protected final Invocation.@NonNull Constructor constructor;
+ protected final @NonNull InvocationConstructor constructor;
protected final int sequence;
private Set<@NonNull Object> createdObjects = null;
private Set<SlotState.@NonNull Incremental> readSlots = null;
private Set<SlotState.@NonNull Incremental> writeSlots = null;
- protected Incremental(@NonNull Interval interval, Invocation.Constructor.@NonNull Incremental constructor) {
+ protected Incremental(@NonNull Interval interval, InvocationConstructor.@NonNull Incremental constructor) {
super(interval);
this.constructor = constructor;
this.sequence = constructor.nextSequence();
@@ -101,4 +101,9 @@ public abstract class AbstractInvocation extends AbstractInvocationInternal
public <R> R accept(@NonNull ExecutionVisitor<R> visitor) {
return visitor.visitInvocation(this);
}
+
+ @Override
+ public @NonNull String getName() {
+ return toString().replace("@", "\n@");
+ }
} \ No newline at end of file
diff --git a/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/evaluation/AbstractTransformer.java b/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/evaluation/AbstractTransformer.java
index 7fffbaa34..c8298563b 100644
--- a/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/evaluation/AbstractTransformer.java
+++ b/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/evaluation/AbstractTransformer.java
@@ -26,6 +26,7 @@ public abstract class AbstractTransformer extends AbstractTransformerInternal
{
public static final @NonNull String PLUGIN_ID = "org.eclipse.qvtd.runtime";
public static final @NonNull TracingOption APPENDS = new TracingOption(PLUGIN_ID, "tx/appends");
+ public static final @NonNull TracingOption CONSUMES = new TracingOption(PLUGIN_ID, "tx/consumes");
public static final @NonNull TracingOption EXCEPTIONS = new TracingOption(PLUGIN_ID, "tx/exceptions");
public static final @NonNull TracingOption INVOCATIONS = new TracingOption(PLUGIN_ID, "tx/invocations");
diff --git a/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/evaluation/Connection.java b/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/evaluation/Connection.java
index 455e6249d..201ea85c6 100644
--- a/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/evaluation/Connection.java
+++ b/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/evaluation/Connection.java
@@ -27,9 +27,9 @@ import org.eclipse.ocl.pivot.utilities.Nameable;
*/
public interface Connection extends ExecutionVisitable, Nameable
{
- void addConsumer(@NonNull Invoker consumingInvoker);
+ void addAppender(@NonNull InvocationConstructor appendingInvoker);
- void addProducer(@NonNull Invoker producingInvoker);
+ void addConsumer(@NonNull InvocationConstructor consumingInvoker);
/**
* Append aValue to the contents, enforcing uniqueness if necessary, and waking up the overall
@@ -46,14 +46,14 @@ public interface Connection extends ExecutionVisitable, Nameable
void consume(int elementIndex, @NonNull Invocation mapping);
+ @NonNull Iterable<@NonNull InvocationConstructor> getAppenders();
+
int getCapacity();
- @NonNull Iterable<@NonNull Invoker> getConsumers();
+ @NonNull Iterable<@NonNull InvocationConstructor> getConsumers();
// @NonNull Iterable<@NonNull Invocation> getConsumers(int i);
- @NonNull Iterable<@NonNull Invoker> getProducers();
-
@Nullable Object getValue(int i);
int getValues();
diff --git a/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/evaluation/Invoker.java b/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/evaluation/DefaultInterval.java
index 3ddc218a3..f01089baa 100644
--- a/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/evaluation/Invoker.java
+++ b/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/evaluation/DefaultInterval.java
@@ -11,18 +11,14 @@
package org.eclipse.qvtd.runtime.evaluation;
import org.eclipse.jdt.annotation.NonNull;
-import org.eclipse.ocl.pivot.utilities.Nameable;
+import org.eclipse.qvtd.runtime.internal.evaluation.AbstractIntervalInternal;
/**
- * An Invoker marshalls the arguments to invoke a mapping Invocation.
- *
- * @noimplement clients should derive from AbstractInvoker
+ * DefaultInterval provides the standard implementation of the scheduling interval manager.
*/
-public interface Invoker extends ExecutionVisitable, Nameable
+public class DefaultInterval extends AbstractIntervalInternal
{
- @NonNull Interval getInterval();
-
- @NonNull Iterable<@NonNull Invocation> getInvocations();
-
- void propagate();
-} \ No newline at end of file
+ public DefaultInterval(@NonNull InvocationManager invocationManager, int intervalIndex) {
+ super(invocationManager, intervalIndex);
+ }
+}
diff --git a/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/evaluation/ExecutionVisitor.java b/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/evaluation/ExecutionVisitor.java
index c1db83d2b..7b6127ba1 100644
--- a/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/evaluation/ExecutionVisitor.java
+++ b/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/evaluation/ExecutionVisitor.java
@@ -29,8 +29,8 @@ public interface ExecutionVisitor<R>
R visitConnection(@NonNull Connection object);
R visitInterval(@NonNull Interval object);
R visitInvocation(@NonNull Invocation object);
+ R visitInvocationConstructor(@NonNull InvocationConstructor object);
R visitInvocationManager(@NonNull InvocationManager object);
- R visitInvoker(@NonNull Invoker object);
R visitObjectManager(@NonNull ObjectManager object);
R visitSlotState(@NonNull SlotState object);
R visitTransformer(@NonNull Transformer object);
diff --git a/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/evaluation/Interval.java b/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/evaluation/Interval.java
index aa81794a5..b1e7feb16 100644
--- a/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/evaluation/Interval.java
+++ b/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/evaluation/Interval.java
@@ -11,6 +11,7 @@
package org.eclipse.qvtd.runtime.evaluation;
import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.ocl.pivot.ids.CollectionTypeId;
import org.eclipse.ocl.pivot.utilities.Nameable;
/**
@@ -21,8 +22,12 @@ import org.eclipse.ocl.pivot.utilities.Nameable;
*/
public interface Interval extends ExecutionVisitable, Nameable
{
+ @NonNull Connection createConnection(@NonNull String name, @NonNull CollectionTypeId typeId, boolean isEnforced);
+
boolean flush();
+ @NonNull Iterable<@NonNull Connection> getConnections();
+
int getIndex();
@NonNull InvocationManager getInvocationManager();
@@ -32,6 +37,10 @@ public interface Interval extends ExecutionVisitable, Nameable
void invoke(@NonNull Invocation invocation, boolean doFlush);
+ boolean isFlushed();
+
+ void queue(@NonNull Connection connection);
+
void queue(@NonNull Invocation consumer);
void unblock(@NonNull Invocation invocation);
diff --git a/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/evaluation/Invocation.java b/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/evaluation/Invocation.java
index f6b72e80d..a0768dcd8 100644
--- a/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/evaluation/Invocation.java
+++ b/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/evaluation/Invocation.java
@@ -11,7 +11,6 @@
package org.eclipse.qvtd.runtime.evaluation;
import org.eclipse.jdt.annotation.NonNull;
-import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.ocl.pivot.ids.IdResolver;
import org.eclipse.ocl.pivot.utilities.Nameable;
@@ -20,7 +19,7 @@ import org.eclipse.ocl.pivot.utilities.Nameable;
*
* @noimplement clients should derive from AbstractInvocation
*/
-public interface Invocation extends ExecutionVisitable
+public interface Invocation extends ExecutionVisitable, Nameable
{
/**
* Execute the mapping invocation, returning true if successfully executed, or false if some predicate failed.
@@ -40,6 +39,7 @@ public interface Invocation extends ExecutionVisitable
*/
boolean isEqual(@NonNull IdResolver idResolver, @NonNull Object @NonNull [] thoseValues);
+ void queue();
/**
* Remove this Invocation from the blocked or waiting invocations linked list.
@@ -48,29 +48,7 @@ public interface Invocation extends ExecutionVisitable
void unblock();
- public interface Constructor extends Nameable
- {
- public interface Incremental extends Constructor
- {
- int nextSequence();
- }
-
- /**
- * Return the first invocation of this constructor with argValues, using newInstance(argValues) to
- * create a new invocation instance if necessary. Returns null if an instance already created.
- */
- @Nullable Invocation getFirstInvocation(@NonNull Object @NonNull [] argValues);
-
- @Override
- @NonNull String getName();
-
- /**
- * Create the invocation identified by this constructor and values.
- */
- @NonNull Invocation newInstance(@NonNull Object @NonNull [] values);
- }
-
- public interface Incremental extends Invocation, Nameable
+ public interface Incremental extends Invocation
{
void addCreatedObject(@NonNull Object createdObject);
void addReadSlot(SlotState.@NonNull Incremental readSlot);
diff --git a/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/evaluation/InvocationConstructor.java b/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/evaluation/InvocationConstructor.java
new file mode 100644
index 000000000..1643fea97
--- /dev/null
+++ b/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/evaluation/InvocationConstructor.java
@@ -0,0 +1,52 @@
+/*******************************************************************************
+ * Copyright (c) 2013, 2016 Willink Transformations and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * E.D.Willink - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.qvtd.runtime.evaluation;
+
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.jdt.annotation.Nullable;
+import org.eclipse.ocl.pivot.utilities.Nameable;
+
+/**
+ * An Invocation identifies a unique invocation of a Mapping and the objects/values bound to its guard variables.
+ *
+ * @noimplement clients should derive from AbstractInvocation
+ */
+public interface InvocationConstructor extends ExecutionVisitable, Nameable
+{
+ public interface Incremental extends InvocationConstructor
+ {
+ int nextSequence();
+ }
+
+ void addAppendedConnection(@NonNull Connection connection);
+
+ void addConsumedConection(@NonNull Connection connection);
+
+ /**
+ * Return the first invocation of this constructor with argValues, using newInstance(argValues) to
+ * create a new invocation instance if necessary. Returns null if an instance already created.
+ */
+ @Nullable Invocation getFirstInvocation(@NonNull Object @NonNull [] argValues);
+
+ /**
+ * Create the invocation identified by this constructor and values.
+ */
+ @NonNull Invocation getInstance(@NonNull Object @NonNull [] values);
+
+ @NonNull Interval getInterval();
+
+ @NonNull Iterable<@NonNull Invocation> getInvocations();
+
+ @Override
+ @NonNull String getName();
+
+ void propagate();
+} \ No newline at end of file
diff --git a/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/evaluation/InvocationManager.java b/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/evaluation/InvocationManager.java
index 91995113b..7fc08384a 100644
--- a/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/evaluation/InvocationManager.java
+++ b/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/evaluation/InvocationManager.java
@@ -11,6 +11,7 @@
package org.eclipse.qvtd.runtime.evaluation;
import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.ocl.pivot.evaluation.Executor;
/**
* An InvocationManager supervises the invocations of mappings, inhibiting re-executions and
@@ -21,7 +22,14 @@ import org.eclipse.jdt.annotation.NonNull;
*/
public interface InvocationManager extends ExecutionVisitable
{
+ void addInvoker(@NonNull InvocationConstructor constructor);
@NonNull Interval createInterval();
+ // @NonNull InvocationConstructor createInvoker(@NonNull InvocationConstructor constructor, int consumedConnections, @NonNull Interval interval, @NonNull Connection @NonNull ... connections);
boolean flush();
- @NonNull Interval getDefaultInterval();
+ @NonNull Executor getExecutor();
+ @NonNull Iterable<@NonNull Interval> getIntervals();
+ @NonNull Iterable<@NonNull InvocationConstructor> getInvokers();
+ @NonNull Interval getRootInterval();
+ // @Nullable Transformer getTransformer();
+ void setWorkToDoAt(int intervalIndex);
}
diff --git a/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/internal/evaluation/AbstractConnectionInternal.java b/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/internal/evaluation/AbstractConnectionInternal.java
index d5927662e..9af54fd6b 100644
--- a/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/internal/evaluation/AbstractConnectionInternal.java
+++ b/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/internal/evaluation/AbstractConnectionInternal.java
@@ -16,12 +16,13 @@ import java.util.List;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.ocl.pivot.ids.CollectionTypeId;
+import org.eclipse.ocl.pivot.utilities.LabelUtil;
import org.eclipse.qvtd.runtime.evaluation.AbstractTransformer;
import org.eclipse.qvtd.runtime.evaluation.Connection;
import org.eclipse.qvtd.runtime.evaluation.ExecutionVisitor;
import org.eclipse.qvtd.runtime.evaluation.Interval;
import org.eclipse.qvtd.runtime.evaluation.Invocation;
-import org.eclipse.qvtd.runtime.evaluation.Invoker;
+import org.eclipse.qvtd.runtime.evaluation.InvocationConstructor;
/**
* An AbstractConnection maintains the values between one or more sources, typically Mappings, that
@@ -32,26 +33,37 @@ import org.eclipse.qvtd.runtime.evaluation.Invoker;
*
* Incremental update is supported by a revoke() or an append(), or a replace() of an appended value.
*/
-public abstract class AbstractConnectionInternal extends ConnectionLinkage implements Connection
+public abstract class AbstractConnectionInternal implements Connection
{
protected static final int VALUE_INDEX = 0;
protected static final int INDEX_INDEX = 1;
protected static final int COUNT_INDEX = 2;
protected final boolean debugAppends = AbstractTransformer.APPENDS.isActive();
+ protected final boolean debugConsumes = AbstractTransformer.CONSUMES.isActive();
protected final @NonNull Interval interval;
protected final @NonNull String name;
protected final @NonNull CollectionTypeId typeId;
/**
+ * Singly linked list element of connections awaiting propagation from their interval, null when last/unlinked.
+ */
+ private @Nullable AbstractConnectionInternal nextConnection = null;
+
+ /**
+ * True when this connection is part of the interval's list of connections awaiting propagation.
+ */
+ private boolean isQueued = false;
+
+ /**
* The consumers of each appended value.
*/
- protected final @NonNull List<@NonNull Invoker> consumers = new ArrayList<>();
+ protected final @NonNull List<@NonNull InvocationConstructor> consumers = new ArrayList<>();
/**
- * The producers of values.
+ * The appenders of values.
*/
- protected final @NonNull List<@NonNull Invoker> producers = new ArrayList<>();
+ protected final @NonNull List<@NonNull InvocationConstructor> appenders = new ArrayList<>();
/**
* The earlist interval at which a consumer can execute.
@@ -81,7 +93,14 @@ public abstract class AbstractConnectionInternal extends ConnectionLinkage imple
}
@Override
- public void addConsumer(@NonNull Invoker consumer) {
+ public void addAppender(@NonNull InvocationConstructor appender) {
+ if (!appenders.contains(appender)) {
+ appenders.add(appender);
+ }
+ }
+
+ @Override
+ public void addConsumer(@NonNull InvocationConstructor consumer) {
// assert listOfValueAndConsumingInvocations.isEmpty() || listOfValueAndConsumingInvocations.get(0).;
if (!consumers.contains(consumer)) {
consumers.add(consumer);
@@ -91,13 +110,6 @@ public abstract class AbstractConnectionInternal extends ConnectionLinkage imple
}
}
- @Override
- public void addProducer(@NonNull Invoker producer) {
- if (!producers.contains(producer)) {
- producers.add(producer);
- }
- }
-
/**
* Remove the revoked entries and update the internal indexes accordingly.
*/
@@ -124,6 +136,14 @@ public abstract class AbstractConnectionInternal extends ConnectionLinkage imple
valueAndConsumingInvocations.add(invocation);
// FIXME empty status if all consumers at final index
// invocationManager.dequeue(this);
+ if (debugConsumes) {
+ AbstractTransformer.CONSUMES.println(this + " => " + LabelUtil.getLabel(valueAndConsumingInvocations.get(VALUE_INDEX)));
+ }
+ }
+
+ @Override
+ public @NonNull Iterable<@NonNull InvocationConstructor> getAppenders() {
+ return appenders;
}
@Override
@@ -132,7 +152,7 @@ public abstract class AbstractConnectionInternal extends ConnectionLinkage imple
}
@Override
- public @NonNull Iterable<@NonNull Invoker> getConsumers() {
+ public @NonNull Iterable<@NonNull InvocationConstructor> getConsumers() {
return consumers;
}
@@ -141,9 +161,8 @@ public abstract class AbstractConnectionInternal extends ConnectionLinkage imple
return name;
}
- @Override
- public @NonNull Iterable<@NonNull Invoker> getProducers() {
- return producers;
+ final @Nullable AbstractConnectionInternal getNextConnection() {
+ return nextConnection;
}
@Override
@@ -152,24 +171,6 @@ public abstract class AbstractConnectionInternal extends ConnectionLinkage imple
return valueAndConsumingInvocations != null ? valueAndConsumingInvocations.get(VALUE_INDEX) : null;
}
- /* @Override
- public void insertAfter(@NonNull Interval predecessor) {
- @NonNull AbstractIntervalInternal castPredecessor = (AbstractIntervalInternal)predecessor;
- @NonNull AbstractIntervalInternal successor = castPredecessor.next;
- successor.prev = this;
- next = successor;
- castPredecessor.next = this;
- prev = castPredecessor;
- } */
-
- /* @Override
- public void remove() {
- prev.next = next;
- next.prev = prev;
- prev = this;
- next = this;
- } */
-
@Override
public int getValues() {
return listOfValueAndConsumingInvocations.size();
@@ -177,32 +178,41 @@ public abstract class AbstractConnectionInternal extends ConnectionLinkage imple
@Override
public void propagate() {
- for (@NonNull Invoker consumer : consumers) {
+ for (@NonNull InvocationConstructor consumer : consumers) {
consumer.propagate();
}
}
- protected void queue() {
- throw new UnsupportedOperationException();
- // if (nextConnection == this) {
- // interval.queue(this);
- // }
+ protected final void queue() {
+ if (!isQueued) {
+ isQueued = true;
+ interval.queue(this);
+ }
+ }
+
+ void resetQueued() {
+ isQueued = false;
+ this.nextConnection = null;
+ }
+
+ void setNextConnection(@NonNull AbstractConnectionInternal nextConnection) {
+ assert nextConnection != this;
+ assert isQueued;
+ this.nextConnection = nextConnection;
}
@Override
public String toString() {
StringBuilder s = new StringBuilder();
+ s.append("<");
s.append(interval.getIndex());
- s.append(": ");
+ s.append(">");
s.append(name);
- s.append(" : ");
- s.append(typeId);
- s.append(": ");
- int i = 0;
- for (@NonNull ConnectionLinkage nextConnectionLinkage = nextConnection; nextConnectionLinkage != this; nextConnectionLinkage = nextConnectionLinkage.nextConnection) {
- i++;
- }
- s.append(i);
+ // s.append(" : ");
+ // s.append(typeId);
+ s.append("[");
+ s.append(listOfValueAndConsumingInvocations.size());
+ s.append("]");
return s.toString();
}
} \ No newline at end of file
diff --git a/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/internal/evaluation/AbstractEnforcedConnectionInternal.java b/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/internal/evaluation/AbstractEnforcedConnectionInternal.java
index efbd493e9..9327e1820 100644
--- a/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/internal/evaluation/AbstractEnforcedConnectionInternal.java
+++ b/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/internal/evaluation/AbstractEnforcedConnectionInternal.java
@@ -17,6 +17,7 @@ import java.util.Map;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.ocl.pivot.ids.CollectionTypeId;
+import org.eclipse.ocl.pivot.utilities.LabelUtil;
import org.eclipse.qvtd.runtime.evaluation.AbstractInvocation;
import org.eclipse.qvtd.runtime.evaluation.AbstractTransformer;
import org.eclipse.qvtd.runtime.evaluation.Interval;
@@ -47,7 +48,7 @@ public abstract class AbstractEnforcedConnectionInternal extends AbstractConnect
@Override
public synchronized @NonNull Object append(@NonNull Object aValue) {
if (debugAppends) {
- AbstractTransformer.APPENDS.println(this + " - " + aValue);
+ AbstractTransformer.APPENDS.println(this + " <= " + LabelUtil.getLabel(aValue));
}
List<@NonNull Object> valueAndConsumingInvocations = uniqueValues2valueAndConsumingInvocations.get(aValue);
if (valueAndConsumingInvocations == null) {
diff --git a/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/internal/evaluation/AbstractIntervalInternal.java b/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/internal/evaluation/AbstractIntervalInternal.java
index 48a84f48e..ab3ca7713 100644
--- a/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/internal/evaluation/AbstractIntervalInternal.java
+++ b/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/internal/evaluation/AbstractIntervalInternal.java
@@ -10,26 +10,50 @@
*******************************************************************************/
package org.eclipse.qvtd.runtime.internal.evaluation;
+import java.util.ArrayList;
+import java.util.List;
+
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
+import org.eclipse.ocl.pivot.ids.CollectionTypeId;
import org.eclipse.qvtd.runtime.evaluation.AbstractTransformer;
+import org.eclipse.qvtd.runtime.evaluation.Connection;
+import org.eclipse.qvtd.runtime.evaluation.EnforcedConnection;
import org.eclipse.qvtd.runtime.evaluation.ExecutionVisitor;
import org.eclipse.qvtd.runtime.evaluation.Interval;
import org.eclipse.qvtd.runtime.evaluation.Invocation;
import org.eclipse.qvtd.runtime.evaluation.InvocationFailedException;
import org.eclipse.qvtd.runtime.evaluation.InvocationManager;
import org.eclipse.qvtd.runtime.evaluation.SlotState;
+import org.eclipse.qvtd.runtime.evaluation.UnenforcedConnection;
/**
* AbstractIntervalInternal provides the shared implementation of the intrusive blocked/waiting linked list functionality.
*/
-public abstract class AbstractIntervalInternal extends ConnectionLinkage implements Interval
+public abstract class AbstractIntervalInternal implements Interval
{
protected final boolean debugInvocations = AbstractTransformer.INVOCATIONS.isActive();
protected final @NonNull InvocationManager invocationManager;
protected final int intervalIndex;
+ // public @Nullable SlotState debug_blockedBy = null;
+
+ /**
+ * Head of a singly linked list element of connections awaiting propagation, null when empty.
+ */
+ private @Nullable AbstractConnectionInternal headConnection = null;
+
+ /**
+ * Tail of a singly linked list element of connections awaiting propagation, null when empty.
+ */
+ private @Nullable AbstractConnectionInternal tailConnection = null;
+
+ /**
+ * Head of doubly linked list of blocked invocations.
+ */
+ private @NonNull List<@NonNull Connection> connections = new ArrayList<>();
+
/**
* Head of doubly linked list of blocked invocations.
*/
@@ -69,23 +93,36 @@ public abstract class AbstractIntervalInternal extends ConnectionLinkage impleme
}
@Override
- public boolean flush() {
- flushInternal();
- AbstractInvocationInternal blockedInvocation = blockedInvocations;
- if (blockedInvocation == null) {
- return true;
+ public @NonNull Connection createConnection(@NonNull String name, @NonNull CollectionTypeId typeId, boolean isEnforced) {
+ Connection connection;
+ if (isEnforced) {
+ connection = new EnforcedConnection(this, name, typeId);
}
- do {
- if (debugInvocations) {
- AbstractTransformer.INVOCATIONS.println("still blocked " + blockedInvocation + " by " + blockedInvocation.debug_blockedBy);
- }
- blockedInvocation = blockedInvocation.next;
+ else {
+ connection = new UnenforcedConnection(this, name, typeId);
}
- while (blockedInvocation != blockedInvocations);
- return false;
+ connections.add(connection);
+ return connection;
}
- private void flushInternal() {
+ @Override
+ public boolean flush() {
+ while (headConnection != null) {
+ AbstractConnectionInternal nextConnection2;
+ synchronized(this) {
+ nextConnection2 = headConnection;
+ if (nextConnection2 != null) {
+ headConnection = nextConnection2.getNextConnection();
+ if (headConnection == null) {
+ tailConnection = null;
+ }
+ nextConnection2.resetQueued();
+ }
+ }
+ if (nextConnection2 != null) {
+ nextConnection2.propagate();
+ }
+ }
while (waitingInvocations != null) {
AbstractInvocationInternal invocation = null;
synchronized (this) {
@@ -106,6 +143,23 @@ public abstract class AbstractIntervalInternal extends ConnectionLinkage impleme
invoke(invocation, false);
}
}
+ AbstractInvocationInternal blockedInvocation = blockedInvocations;
+ if (blockedInvocation == null) {
+ return true;
+ }
+ do {
+ if (debugInvocations) {
+ AbstractTransformer.INVOCATIONS.println("still blocked " + blockedInvocation + " by " + blockedInvocation.debug_blockedBy);
+ }
+ blockedInvocation = blockedInvocation.next;
+ }
+ while (blockedInvocation != blockedInvocations);
+ return false;
+ }
+
+ @Override
+ public @NonNull Iterable<@NonNull Connection> getConnections() {
+ return connections;
}
@Override
@@ -131,7 +185,26 @@ public abstract class AbstractIntervalInternal extends ConnectionLinkage impleme
AbstractTransformer.INVOCATIONS.println("done " + invocation);
}
if (doFlush) {
- flushInternal();
+ while (waitingInvocations != null) {
+ AbstractInvocationInternal invocation2 = null;
+ synchronized (this) {
+ AbstractInvocationInternal waitingInvocations2 = waitingInvocations;
+ if (waitingInvocations2 != null) {
+ invocation2 = waitingInvocations2;
+ waitingInvocations = waitingInvocations2.next;
+ if (waitingInvocations == invocation2) {
+ waitingInvocations = null;
+ }
+ invocation2.remove();
+ }
+ }
+ if (invocation2 != null) {
+ if (debugInvocations) {
+ AbstractTransformer.INVOCATIONS.println("re-invoke " + invocation2);
+ }
+ invoke(invocation2, false);
+ }
+ }
}
}
catch (InvocationFailedException e) {
@@ -140,6 +213,42 @@ public abstract class AbstractIntervalInternal extends ConnectionLinkage impleme
}
@Override
+ public boolean isFlushed() {
+ if (tailConnection != null) {
+ return false;
+ }
+ // assert each connection fully propagatred
+ if (blockedInvocations != null) {
+ return false;
+ }
+ if (waitingInvocations != null) {
+ return false;
+ }
+ return true;
+ }
+
+ public void queue() {
+ invocationManager.setWorkToDoAt(intervalIndex);
+ }
+
+ @Override
+ public synchronized void queue(@NonNull Connection connection) {
+ AbstractConnectionInternal connection2 = (AbstractConnectionInternal)connection;
+ AbstractConnectionInternal tailConnection2 = tailConnection;
+ if (tailConnection2 == null) { // Empty list
+ assert headConnection == null;
+ assert connection2.getNextConnection() == null;
+ headConnection = connection2;
+ }
+ else { // New element
+ assert headConnection != null;
+ tailConnection2.setNextConnection(connection2);
+ }
+ tailConnection = connection2;
+ queue();
+ }
+
+ @Override
public synchronized void queue(@NonNull Invocation invocation) {
if (debugInvocations) {
AbstractTransformer.INVOCATIONS.println("queue " + invocation);
@@ -160,13 +269,45 @@ public abstract class AbstractIntervalInternal extends ConnectionLinkage impleme
@Override
public String toString() {
StringBuilder s = new StringBuilder();
+ s.append("<");
s.append(intervalIndex);
- // s.append(": ");
- // int i = 0;
- // for (@NonNull ConnectionLinkage nextConnectionLinkage = nextConnection; nextConnectionLinkage != this; nextConnectionLinkage = nextConnectionLinkage.nextConnection) {
- // i++;
- // }
- // s.append(i);
+ s.append("> ");
+ int i = 0;
+ for (AbstractConnectionInternal aConnection = headConnection; aConnection != null; aConnection = aConnection.getNextConnection()) {
+ i++;
+ if (i > 100) {
+ i = 999999;
+ break;
+ }
+ }
+ s.append(i);
+ s.append(" connections, ");
+ int j = 0;
+ for (AbstractInvocationInternal anInvocation = blockedInvocations; anInvocation != null; anInvocation = anInvocation.next) {
+ j++;
+ if (j > 100) {
+ j = 999999;
+ break;
+ }
+ if (anInvocation == blockedInvocations) {
+ break;
+ }
+ }
+ s.append(j);
+ s.append(" blocked, ");
+ int k = 0;
+ for (AbstractInvocationInternal anInvocation = waitingInvocations; anInvocation != null; anInvocation = anInvocation.next) {
+ k++;
+ if (k > 100) {
+ k = 999999;
+ break;
+ }
+ if (anInvocation == waitingInvocations) {
+ break;
+ }
+ }
+ s.append(k);
+ s.append(" waiting");
return s.toString();
}
diff --git a/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/internal/evaluation/AbstractInvocationConstructor.java b/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/internal/evaluation/AbstractInvocationConstructor.java
index b28271192..84a8f4112 100644
--- a/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/internal/evaluation/AbstractInvocationConstructor.java
+++ b/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/internal/evaluation/AbstractInvocationConstructor.java
@@ -17,17 +17,38 @@ import java.util.Map;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
+import org.eclipse.ocl.pivot.evaluation.Executor;
import org.eclipse.ocl.pivot.ids.IdResolver;
+import org.eclipse.qvtd.runtime.evaluation.Connection;
+import org.eclipse.qvtd.runtime.evaluation.ExecutionVisitor;
+import org.eclipse.qvtd.runtime.evaluation.Interval;
import org.eclipse.qvtd.runtime.evaluation.Invocation;
+import org.eclipse.qvtd.runtime.evaluation.InvocationConstructor;
+import org.eclipse.qvtd.runtime.evaluation.InvocationManager;
-public abstract class AbstractInvocationConstructor implements Invocation.Constructor
+public abstract class AbstractInvocationConstructor implements InvocationConstructor
{
- public static abstract class Incremental extends AbstractInvocationConstructor implements Invocation.Constructor.Incremental
+ public static abstract class Incremental extends AbstractInvocationConstructor implements InvocationConstructor.Incremental
{
protected int sequence = 0;
- public Incremental(@NonNull IdResolver idResolver, @NonNull String name) {
- super(idResolver, name);
+ public Incremental(@NonNull Interval interval, @NonNull String name) {
+ super(interval, name);
+ }
+
+ public void connect(@NonNull Connection @Nullable [] consumedConnections, @NonNull Connection @Nullable [] appendedConnections) {
+ if (consumedConnections != null) {
+ for (@NonNull Connection consumedConnection : consumedConnections) {
+ consumedConnection.addConsumer(this);
+ addConsumedConection(consumedConnection);
+ }
+ }
+ if (appendedConnections != null) {
+ for (@NonNull Connection appendedConnection : appendedConnections) {
+ appendedConnection.addAppender(this);
+ addAppendedConnection(appendedConnection);
+ }
+ }
}
@Override
@@ -36,6 +57,7 @@ public abstract class AbstractInvocationConstructor implements Invocation.Constr
}
}
+ protected final @NonNull Interval interval;
protected final IdResolver.@NonNull IdResolverExtension idResolver;
protected final @NonNull String name;
@@ -45,11 +67,50 @@ public abstract class AbstractInvocationConstructor implements Invocation.Constr
* <br>
* This map is used to inhibit repeated invocations.
*/
- private final @NonNull Map<@NonNull Integer, @NonNull Object> hashCode2invocations = new HashMap<@NonNull Integer, @NonNull Object>();
+ private final @NonNull Map<@NonNull Integer, @NonNull Object> hashCode2invocations = new HashMap<>();
+
+ private final @NonNull List<@NonNull Invocation> debugInvocations = new ArrayList<>();
- protected AbstractInvocationConstructor(@NonNull IdResolver idResolver, @NonNull String name) {
- this.idResolver = (IdResolver.IdResolverExtension)idResolver;
+ private final @NonNull List<@NonNull Connection> consumedConnections = new ArrayList<>();
+ private final @NonNull List<@NonNull Connection> appendedConnections = new ArrayList<>();
+ private int /*@LazyNonNull*/ [] oldConsumedIndexes = null;
+
+ protected AbstractInvocationConstructor(@NonNull Interval interval, @NonNull String name) {
+ this.interval = interval;
+ InvocationManager invocationManager = interval.getInvocationManager();
+ // TransformationExecutor executor = ClassUtil.nonNullState(invocationManager.getTransformer()).getExecutor();
+ Executor executor = invocationManager.getExecutor();
+ this.idResolver = (IdResolver.IdResolverExtension)executor.getIdResolver(); // FIXME null Transformer
this.name = name;
+ invocationManager.addInvoker(this);
+ }
+ /* protected AbstractInvokerN(@NonNull Interval interval, @NonNull InvocationConstructor constructor, @NonNull Connection @NonNull [] consumedConnections, @NonNull Connection @NonNull [] appendedConnections) {
+ super(interval, constructor, appendedConnections);
+ this.consumedConnections = consumedConnections;
+ int consumedConnectionsSize = consumedConnections.length;
+ oldConsumedIndexes = new int[consumedConnectionsSize];
+ for (int i = 0; i < consumedConnectionsSize; i++) {
+ oldConsumedIndexes[i] = 0;
+ }
+ } */
+
+
+ @Override
+ public <R> R accept(@NonNull ExecutionVisitor<R> visitor) {
+ return visitor.visitInvocationConstructor(this);
+ }
+
+ @Override
+ public void addAppendedConnection(@NonNull Connection connection) {
+ assert oldConsumedIndexes == null;
+ assert !appendedConnections.contains(connection);
+ appendedConnections.add(connection);
+ }
+
+ @Override
+ public void addConsumedConection(@NonNull Connection connection) {
+ assert !consumedConnections.contains(connection);
+ consumedConnections.add(connection);
}
@Override
@@ -78,6 +139,7 @@ public abstract class AbstractInvocationConstructor implements Invocation.Constr
}
}
Invocation theInvocation = newInstance(argValues);
+ debugInvocations.add(theInvocation);
if (zeroOrMoreInvocations == null) {
hashCode2invocations.put(hashCode, theInvocation);
}
@@ -96,7 +158,97 @@ public abstract class AbstractInvocationConstructor implements Invocation.Constr
}
@Override
+ public @NonNull Invocation getInstance(@NonNull Object @NonNull [] values) {
+ // FIXME Move invokeOnce to constructor
+ Invocation theInvocation = newInstance(values);
+ // theInvocation.queue();
+ debugInvocations.add(theInvocation);
+ return theInvocation;
+ }
+
+ @Override
+ public @NonNull Interval getInterval() {
+ return interval;
+ }
+
+
+ @Override
+ public @NonNull Iterable<@NonNull Invocation> getInvocations() {
+ /* List<@NonNull Invocation> allInvocations = new ArrayList<>(); // FIXME provide a lazy iterable
+ for (Object zeroOrMoreInvocations : hashCode2invocations.values()) {
+ if (zeroOrMoreInvocations instanceof Invocation) {
+ allInvocations.add((Invocation)zeroOrMoreInvocations);
+ }
+ else if (zeroOrMoreInvocations instanceof List<?>) {
+ @SuppressWarnings("unchecked")@NonNull List<@NonNull Invocation> zeroOrMoreInvocations2 = (List<@NonNull Invocation>)zeroOrMoreInvocations;
+ allInvocations.addAll(zeroOrMoreInvocations2);
+ }
+ } */
+ return debugInvocations;
+ }
+
+ @Override
public @NonNull String getName() {
return name;
}
+
+ protected abstract @NonNull Invocation newInstance(@NonNull Object @NonNull [] values);
+
+ @Override
+ public void propagate() {
+ int consumedConnectionsSize = consumedConnections.size();
+ if (oldConsumedIndexes == null) {
+ oldConsumedIndexes = new int[consumedConnectionsSize];
+ for (int i = 0; i < consumedConnectionsSize; i++) {
+ oldConsumedIndexes[i] = 0;
+ }
+ }
+ int @NonNull [] newConsumedIndexes = new int[consumedConnectionsSize];
+ boolean hasWork = false;
+ for (int i = 0; i < consumedConnectionsSize; i++) {
+ Connection consumedConnection = consumedConnections.get(i);
+ newConsumedIndexes[i] = consumedConnection.getCapacity();
+ if (newConsumedIndexes[i] > oldConsumedIndexes[i]) {
+ hasWork = true;
+ }
+ }
+ if (hasWork) {
+ int appendedConnectionsSize = appendedConnections.size();
+ @NonNull Object @NonNull [] boundValues = new @NonNull Object[consumedConnectionsSize + appendedConnectionsSize];
+ for (int i = 0; i < appendedConnectionsSize; i++) {
+ boundValues[consumedConnectionsSize+i] = appendedConnections.get(i);
+ }
+ int @NonNull [] consumeIndexes = new int[consumedConnectionsSize];
+ propagate(0, newConsumedIndexes, consumeIndexes, boundValues);
+ for (int i = 0; i < consumedConnectionsSize; i++) {
+ oldConsumedIndexes[i] = newConsumedIndexes[i];
+ }
+ }
+ }
+ private void propagate(int depth, int @NonNull [] newConsumedIndexes, int @NonNull [] consumeIndexes, @NonNull Object @NonNull [] boundValues) {
+ int consumedConnectionsSize = consumedConnections.size();
+ if (depth < consumedConnectionsSize) {
+ Connection consumedConnection = consumedConnections.get(depth);
+ for (int i = oldConsumedIndexes[depth]; i < newConsumedIndexes[depth]; i++) {
+ consumeIndexes[depth] = i;
+ Object value = consumedConnection.getValue(i);
+ if (value != null) { // Revoked value may be null.
+ boundValues[depth] = value;
+ propagate(depth+1, newConsumedIndexes, consumeIndexes, boundValues);
+ }
+ }
+ }
+ else {
+ Invocation mappingInstance = getInstance(boundValues);
+ for (int i = 0; i < consumedConnectionsSize; i++) {
+ Connection consumedConnection = consumedConnections.get(i);
+ consumedConnection.consume(consumeIndexes[i], mappingInstance);
+ }
+ }
+ }
+
+ @Override
+ public @NonNull String toString() {
+ return getName();
+ }
} \ No newline at end of file
diff --git a/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/internal/evaluation/AbstractInvocationInternal.java b/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/internal/evaluation/AbstractInvocationInternal.java
index 03e10f5f3..342198ada 100644
--- a/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/internal/evaluation/AbstractInvocationInternal.java
+++ b/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/internal/evaluation/AbstractInvocationInternal.java
@@ -47,6 +47,11 @@ public abstract class AbstractInvocationInternal implements Invocation
}
@Override
+ public void queue() {
+ interval.queue(this);
+ }
+
+ @Override
public void remove() {
prev.next = next;
next.prev = prev;
diff --git a/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/internal/evaluation/AbstractInvocationManagerInternal.java b/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/internal/evaluation/AbstractInvocationManagerInternal.java
index 7b071490b..127591bba 100644
--- a/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/internal/evaluation/AbstractInvocationManagerInternal.java
+++ b/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/internal/evaluation/AbstractInvocationManagerInternal.java
@@ -14,13 +14,16 @@ import java.util.ArrayList;
import java.util.List;
import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.ocl.pivot.evaluation.Executor;
import org.eclipse.qvtd.runtime.evaluation.AbstractInvocationManager;
+import org.eclipse.qvtd.runtime.evaluation.DefaultInterval;
import org.eclipse.qvtd.runtime.evaluation.Interval;
+import org.eclipse.qvtd.runtime.evaluation.InvocationConstructor;
/**
* InvocationManager supervises and provides thread safety for the lists of blocked and waiting invocations.
*/
-public class AbstractInvocationManagerInternal extends AbstractInvocationManager
+public abstract class AbstractInvocationManagerInternal extends AbstractInvocationManager
{
/**
* The distinct intervals of the schedule. Wherever possible work for earlier intervals is completed before that
@@ -28,28 +31,92 @@ public class AbstractInvocationManagerInternal extends AbstractInvocationManager
*/
private final @NonNull List<@NonNull Interval> intervals = new ArrayList<>();
+ /**
+ * The invokers that create invocations.
+ */
+ private final @NonNull List<@NonNull InvocationConstructor> invokers = new ArrayList<>();
+
+ private volatile int nextIndex = Integer.MAX_VALUE;
+
+ protected final @NonNull Executor executor;
- private /*@LazyNonNull*/ Interval defaultInterval = null;
+ protected AbstractInvocationManagerInternal(@NonNull Executor executor) {
+ this.executor = executor;
+ }
+
+ @Override
+ public void addInvoker(@NonNull InvocationConstructor constructor) {
+ assert !invokers.contains(constructor);
+ invokers.add(constructor);
+ }
@Override
public @NonNull Interval createInterval() {
- assert defaultInterval == null;
- Interval interval = new AbstractIntervalInternal(this, intervals.size()) {};
+ Interval interval = new DefaultInterval(this, intervals.size());
intervals.add(interval);
return interval;
}
+ /* @Override
+ public @NonNull InvocationConstructor createInvoker(@NonNull InvocationConstructor constructor, int consumedConnections, @NonNull Interval interval, @NonNull Connection @NonNull ... connections) {
+ InvocationConstructor invoker;
+ if (consumedConnections == 1) {
+ invoker = new AbstractInvoker1(interval, constructor, connections[0], Arrays.copyOfRange(connections, 1, connections.length));
+ }
+ else {
+ invoker = new AbstractInvokerN(interval, constructor, Arrays.copyOf(connections, consumedConnections), Arrays.copyOfRange(connections, consumedConnections, connections.length));
+ }
+ invokers.add(invoker);
+ return invoker;
+ } */
+
@Override
public boolean flush() {
- return getDefaultInterval().flush();
+ for (int index = nextIndex; index < intervals.size(); index = nextIndex) {
+ nextIndex = index+1;
+ Interval nextInterval = intervals.get(index);
+ nextInterval.flush(); // May set nextIndex back to 'same' or even earlier
+ }
+ for (@NonNull Interval interval : intervals) {
+ if (!interval.isFlushed()) {
+ return false;
+ }
+ }
+ return true;
}
@Override
- public @NonNull Interval getDefaultInterval() {
- Interval defaultInterval2 = defaultInterval;
- if (defaultInterval2 == null) {
- defaultInterval2 = defaultInterval = createInterval();
+ public @NonNull Executor getExecutor() {
+ return executor;
+ }
+
+ @Override
+ public @NonNull Iterable<@NonNull Interval> getIntervals() {
+ return intervals;
+ }
+
+ @Override
+ public @NonNull Iterable<@NonNull InvocationConstructor> getInvokers() {
+ return invokers;
+ }
+
+ @Override
+ public @NonNull Interval getRootInterval() {
+ if (intervals.size() <= 0) {
+ createInterval();
+ }
+ return intervals.get(0);
+ }
+
+ // @Override
+ // public @Nullable Transformer getTransformer() {
+ // return transformer;
+ // }
+
+ @Override
+ public void setWorkToDoAt(int intervalIndex) {
+ if (intervalIndex < nextIndex) {
+ nextIndex = intervalIndex;
}
- return defaultInterval2;
}
} \ No newline at end of file
diff --git a/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/internal/evaluation/AbstractTransformerInternal.java b/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/internal/evaluation/AbstractTransformerInternal.java
index f4b6aecb7..e644dfb98 100644
--- a/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/internal/evaluation/AbstractTransformerInternal.java
+++ b/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/internal/evaluation/AbstractTransformerInternal.java
@@ -48,6 +48,7 @@ import org.eclipse.qvtd.runtime.evaluation.AbstractTransformer;
import org.eclipse.qvtd.runtime.evaluation.AbstractTypedModelInstance;
import org.eclipse.qvtd.runtime.evaluation.ExecutionVisitable;
import org.eclipse.qvtd.runtime.evaluation.Invocation;
+import org.eclipse.qvtd.runtime.evaluation.InvocationConstructor;
import org.eclipse.qvtd.runtime.evaluation.InvocationFailedException;
import org.eclipse.qvtd.runtime.evaluation.InvocationManager;
import org.eclipse.qvtd.runtime.evaluation.ObjectManager;
@@ -539,7 +540,7 @@ public abstract class AbstractTransformerInternal extends AbstractModelManager i
* Create the InvocationManager. Creates a LazyInvocationManager by default.
*/
protected @NonNull InvocationManager createInvocationManager() {
- return new LazyInvocationManager();
+ return new LazyInvocationManager(executor);
}
protected SetValue.@NonNull Accumulator createUnenforcedSetAccumulatorValue(@NonNull CollectionTypeId typeId) {
@@ -723,12 +724,26 @@ public abstract class AbstractTransformerInternal extends AbstractModelManager i
return false;
}
+ /* protected void install(@NonNull InvocationConstructor constructor, int consumedConnections, @NonNull Connection @NonNull ... connections) {
+ // InvocationConstructor invoker = invocationManager.createInvoker(constructor, consumedConnections, interval, connections);
+ for (int i = 0; i < consumedConnections; i++) {
+ Connection consumedConnection = connections[i];
+ consumedConnection.addConsumer(constructor);
+ constructor.addConsumedConection(consumedConnection);
+ }
+ for (int i = consumedConnections; i < connections.length; i++) {
+ Connection appendedConnection = connections[i];
+ appendedConnection.addProducer(constructor);
+ constructor.addAppendedConnection(appendedConnection);
+ }
+ } */
+
/**
* Invoke a mapping with the given constructor with a given set of boundValues once. This shortform of invokeOnce
* should only be used when it is known that recursive invocation is impossible.
*/
- public <@Nullable T extends Invocation> void invoke(Invocation.@NonNull Constructor constructor, @NonNull Object @NonNull ... boundValues) {
- @NonNull Invocation invocation = constructor.newInstance(boundValues);
+ public <@Nullable T extends Invocation> void invoke(@NonNull InvocationConstructor constructor, @NonNull Object @NonNull ... boundValues) {
+ @NonNull Invocation invocation = constructor.getInstance(boundValues);
if (debugInvocations) {
AbstractTransformer.INVOCATIONS.println("invoke " + invocation);
}
@@ -738,7 +753,7 @@ public abstract class AbstractTransformerInternal extends AbstractModelManager i
/**
* Invoke a mapping with the given constructor with a given set of boundValues once. Repeated invocation attempts are ignored.
*/
- public void invokeOnce(Invocation.@NonNull Constructor constructor, @NonNull Object @NonNull ... boundValues) {
+ public void invokeOnce(@NonNull InvocationConstructor constructor, @NonNull Object @NonNull ... boundValues) {
@Nullable Invocation invocation = constructor.getFirstInvocation(boundValues);
if (invocation != null) {
if (debugInvocations) {
diff --git a/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/internal/evaluation/AbstractUnenforcedConnectionInternal.java b/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/internal/evaluation/AbstractUnenforcedConnectionInternal.java
index 018dc3097..b1d1011f8 100644
--- a/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/internal/evaluation/AbstractUnenforcedConnectionInternal.java
+++ b/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/internal/evaluation/AbstractUnenforcedConnectionInternal.java
@@ -15,6 +15,7 @@ import java.util.List;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.ocl.pivot.ids.CollectionTypeId;
+import org.eclipse.ocl.pivot.utilities.LabelUtil;
import org.eclipse.qvtd.runtime.evaluation.AbstractInvocation;
import org.eclipse.qvtd.runtime.evaluation.AbstractTransformer;
import org.eclipse.qvtd.runtime.evaluation.Interval;
@@ -42,7 +43,7 @@ public abstract class AbstractUnenforcedConnectionInternal extends AbstractConne
@Override
public synchronized @NonNull Object append(@NonNull Object aValue) {
if (debugAppends) {
- AbstractTransformer.APPENDS.println(this + " - " + aValue);
+ AbstractTransformer.APPENDS.println(this + " <= " + LabelUtil.getLabel(aValue));
}
List<@NonNull Object> valueAndConsumingInvocations = new ArrayList<>();
valueAndConsumingInvocations.add(aValue); // VALUE_INDEX
diff --git a/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/internal/evaluation/ConnectionLinkage.java b/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/internal/evaluation/ConnectionLinkage.java
deleted file mode 100644
index f1ecc3817..000000000
--- a/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/internal/evaluation/ConnectionLinkage.java
+++ /dev/null
@@ -1,18 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2016 Willink Transformations and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * E.D.Willink - Initial API and implementation
- *******************************************************************************/
-package org.eclipse.qvtd.runtime.internal.evaluation;
-
-import org.eclipse.jdt.annotation.NonNull;
-
-class ConnectionLinkage
-{
- @NonNull ConnectionLinkage nextConnection = this;
-} \ No newline at end of file
diff --git a/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/internal/evaluation/IncrementalInvocationManager.java b/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/internal/evaluation/IncrementalInvocationManager.java
index e5391629c..c5fa434bf 100644
--- a/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/internal/evaluation/IncrementalInvocationManager.java
+++ b/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/internal/evaluation/IncrementalInvocationManager.java
@@ -10,9 +10,15 @@
*******************************************************************************/
package org.eclipse.qvtd.runtime.internal.evaluation;
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.ocl.pivot.evaluation.Executor;
+
/**
* InvocationManager supervises and provides thread safety for the lists of blocked and waiting invocations.
*/
public class IncrementalInvocationManager extends AbstractInvocationManagerInternal
{
+ public IncrementalInvocationManager(@NonNull Executor executor) {
+ super(executor);
+ }
} \ No newline at end of file
diff --git a/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/internal/evaluation/IncrementalObjectManager.java b/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/internal/evaluation/IncrementalObjectManager.java
index c4be78867..8fce944fa 100644
--- a/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/internal/evaluation/IncrementalObjectManager.java
+++ b/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/internal/evaluation/IncrementalObjectManager.java
@@ -22,6 +22,7 @@ import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.ocl.pivot.oclstdlib.OCLstdlibPackage;
+import org.eclipse.ocl.pivot.utilities.LabelUtil;
import org.eclipse.qvtd.runtime.evaluation.AbstractObjectManager;
import org.eclipse.qvtd.runtime.evaluation.AbstractSlotState;
import org.eclipse.qvtd.runtime.evaluation.AbstractTransformer;
@@ -631,7 +632,7 @@ public class IncrementalObjectManager extends AbstractObjectManager
public synchronized void assigned(@NonNull Object eObject, /*@NonNull*/ EStructuralFeature eFeature, @Nullable Object ecoreValue, @Nullable Object childKey) {
assert eFeature != null;
if (debugInvocations) {
- AbstractTransformer.INVOCATIONS.println("assigned " + eFeature.getEContainingClass().getName() + "::" + eFeature.getName() + " for " + eObject + " = " + ecoreValue);
+ AbstractTransformer.INVOCATIONS.println("assigned " + eFeature.getEContainingClass().getName() + "::" + eFeature.getName() + " for " + LabelUtil.getLabel(eObject) + " = " + LabelUtil.getLabel(ecoreValue));
}
Map<EStructuralFeature, BasicSlotState> objectState = getObjectState(eObject);
BasicSlotState slotState = objectState.get(eFeature);
@@ -821,7 +822,7 @@ public class IncrementalObjectManager extends AbstractObjectManager
public synchronized void getting(@NonNull Object eObject, /*@NonNull*/ EStructuralFeature eFeature, boolean isOpposite) {
assert eFeature != null;
if (debugInvocations) {
- AbstractTransformer.INVOCATIONS.println("getting " + eFeature.getEContainingClass().getName() + "::" + eFeature.getName() + " for " + eObject);
+ AbstractTransformer.INVOCATIONS.println("getting " + eFeature.getEContainingClass().getName() + "::" + eFeature.getName() + " for " + LabelUtil.getLabel(eObject));
}
SlotState slotState = getSlotState(eObject, eFeature);
slotState.getting(eObject, eFeature);
diff --git a/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/internal/evaluation/LazyInvocationManager.java b/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/internal/evaluation/LazyInvocationManager.java
index 9ec164b11..3f768a968 100644
--- a/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/internal/evaluation/LazyInvocationManager.java
+++ b/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/internal/evaluation/LazyInvocationManager.java
@@ -10,9 +10,15 @@
*******************************************************************************/
package org.eclipse.qvtd.runtime.internal.evaluation;
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.ocl.pivot.evaluation.Executor;
+
/**
* InvocationManager supervises and provides thread safety for the lists of blocked and waiting invocations.
*/
public class LazyInvocationManager extends AbstractInvocationManagerInternal
{
+ public LazyInvocationManager(@NonNull Executor executor) {
+ super(executor);
+ }
} \ No newline at end of file
diff --git a/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/internal/evaluation/LazyObjectManager.java b/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/internal/evaluation/LazyObjectManager.java
index 15705ceda..84beab98d 100644
--- a/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/internal/evaluation/LazyObjectManager.java
+++ b/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/internal/evaluation/LazyObjectManager.java
@@ -32,6 +32,7 @@ import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.ocl.pivot.internal.utilities.PivotConstantsInternal;
import org.eclipse.ocl.pivot.oclstdlib.OCLstdlibPackage;
+import org.eclipse.ocl.pivot.utilities.LabelUtil;
import org.eclipse.ocl.pivot.utilities.ValueUtil;
import org.eclipse.ocl.pivot.values.IntegerValue;
import org.eclipse.ocl.pivot.values.UnlimitedNaturalValue;
@@ -723,7 +724,7 @@ public class LazyObjectManager extends AbstractObjectManager
public synchronized void assigned(@NonNull Object eObject, /*@NonNull*/ EStructuralFeature eFeature, @Nullable Object ecoreValue, @Nullable Object childKey) {
assert eFeature != null;
if (debugInvocations) {
- AbstractTransformer.INVOCATIONS.println("assigned " + eFeature.getEContainingClass().getName() + "::" + eFeature.getName() + " for " + eObject + " = " + ecoreValue);
+ AbstractTransformer.INVOCATIONS.println("assigned " + eFeature.getEContainingClass().getName() + "::" + eFeature.getName() + " for " + LabelUtil.getLabel(eObject) + " = " + LabelUtil.getLabel(ecoreValue));
}
Map<@NonNull EStructuralFeature, @NonNull SlotState> objectState = getObjectState(eObject);
SlotState slotState = objectState.get(eFeature);
@@ -1003,7 +1004,7 @@ public class LazyObjectManager extends AbstractObjectManager
public synchronized void getting(@NonNull Object eObject, /*@NonNull*/ EStructuralFeature eFeature, boolean isOpposite) {
assert eFeature != null;
if (debugInvocations) {
- AbstractTransformer.INVOCATIONS.println("getting " + eFeature.getEContainingClass().getName() + "::" + eFeature.getName() + (isOpposite ? "<opposite> " : "") + " for " + eObject);
+ AbstractTransformer.INVOCATIONS.println("getting " + eFeature.getEContainingClass().getName() + "::" + eFeature.getName() + (isOpposite ? "<opposite> " : "") + " for " + LabelUtil.getLabel(eObject));
}
if (isOpposite) {
eFeature = getEOppositeReference((EReference) eFeature);
diff --git a/tests/org.eclipse.qvtd.xtext.qvtimperative.tests/src/org/eclipse/qvtd/xtext/qvtimperative/tests/QVTiCompilerTests.java b/tests/org.eclipse.qvtd.xtext.qvtimperative.tests/src/org/eclipse/qvtd/xtext/qvtimperative/tests/QVTiCompilerTests.java
index 54e612ba3..d4fda4589 100644
--- a/tests/org.eclipse.qvtd.xtext.qvtimperative.tests/src/org/eclipse/qvtd/xtext/qvtimperative/tests/QVTiCompilerTests.java
+++ b/tests/org.eclipse.qvtd.xtext.qvtimperative.tests/src/org/eclipse/qvtd/xtext/qvtimperative/tests/QVTiCompilerTests.java
@@ -49,7 +49,6 @@ import org.eclipse.qvtd.xtext.qvtbase.tests.LoadTestCase;
import org.eclipse.qvtd.xtext.qvtbase.tests.utilities.TestsXMLUtil;
import org.eclipse.qvtd.xtext.qvtimperative.tests.ManualUML2RDBMS.ManualRDBMSNormalizer;
import org.eclipse.qvtd.xtext.qvtimperative.tests.SimpleUML2RDBMS.SimpleRDBMSNormalizer;
-
import junit.framework.TestCase;
/**
@@ -319,4 +318,44 @@ public class QVTiCompilerTests extends LoadTestCase
myQVT.saveOutput(tx, "talltree", outputModelURI, referenceModelURI, null);
myQVT.dispose();
}
+
+ /* public void testCG_Tree2TallTreeInstall_qvti() throws Exception {
+ // AbstractTransformer.INVOCATIONS.setState(true);
+ MyQVT myQVT = createQVT();
+ URI genModelURI = getProjectFileURI("Tree2TallTree/Tree2TallTree.genmodel");
+ URI transformURI = getProjectFileURI("Tree2TallTree/Tree2TallTreeInstall.qvti");
+
+ URI inputModelURI = getProjectFileURI("Tree2TallTree/Tree.xmi");
+ URI outputModelURI = getProjectFileURI("Tree2TallTree/Tree2TallTree.xmi");
+ URI referenceModelURI = getProjectFileURI("Tree2TallTree/TallTreeValidate.xmi");
+ Transformation asTransformation = myQVT.loadTransformation(transformURI, genModelURI);
+ Class<? extends Transformer> txClass = myQVT.generateCode(asTransformation, true);
+ Transformer tx = myQVT.createTransformer(txClass);
+ myQVT.loadInput(tx, "tree", inputModelURI);
+ tx.run();
+ myQVT.saveOutput(tx, "talltree", outputModelURI, referenceModelURI, null);
+ myQVT.dispose();
+ } */
+
+ /* public void testCG_Tree2TallTreeInstallManual_qvti() throws Exception {
+ AbstractTransformer.APPENDS.setState(true);
+ AbstractTransformer.CONSUMES.setState(true);
+ AbstractTransformer.EXCEPTIONS.setState(true);
+ AbstractTransformer.INVOCATIONS.setState(true);
+ MyQVT myQVT = createQVT();
+ // URI genModelURI = getProjectFileURI("Tree2TallTree/Tree2TallTree.genmodel");
+ // URI transformURI = getProjectFileURI("Tree2TallTree/Tree2TallTreeInstall.qvti");
+
+ URI inputModelURI = getProjectFileURI("Tree2TallTree/Tree.xmi");
+ URI outputModelURI = getProjectFileURI("Tree2TallTree/Tree2TallTree.xmi");
+ URI referenceModelURI = getProjectFileURI("Tree2TallTree/TallTreeValidate.xmi");
+ // Transformation asTransformation = myQVT.loadTransformation(transformURI, genModelURI);
+ Class<? extends Transformer> txClass = Tree2TallTreeInstallManual.class;
+ Transformer tx = myQVT.createTransformer(txClass);
+ myQVT.loadInput(tx, "tree", inputModelURI);
+ tx.run();
+ Execution2GraphVisitor.writeGraphMLfile(tx, getProjectFileURI("Tree2TallTree/Tree2TallTreeInstallManual-execution.graphml"));
+ myQVT.saveOutput(tx, "talltree", outputModelURI, referenceModelURI, null);
+ myQVT.dispose();
+ } */
}
diff --git a/tests/org.eclipse.qvtd.xtext.qvtimperative.tests/src/org/eclipse/qvtd/xtext/qvtimperative/tests/Tree2TallTree/Tree2TallTreeInstall.qvti b/tests/org.eclipse.qvtd.xtext.qvtimperative.tests/src/org/eclipse/qvtd/xtext/qvtimperative/tests/Tree2TallTree/Tree2TallTreeInstall.qvti
new file mode 100644
index 000000000..f4e53f6de
--- /dev/null
+++ b/tests/org.eclipse.qvtd.xtext.qvtimperative.tests/src/org/eclipse/qvtd/xtext/qvtimperative/tests/Tree2TallTree/Tree2TallTreeInstall.qvti
@@ -0,0 +1,55 @@
+import 'Tree.ecore'::tree;
+import 'TallTree.ecore'::talltree;
+import 'Tree2TallTree.ecore'::tree2talltree;
+
+transformation Tree2TallTreeInstall {
+ check tree imports tree;
+ enforce talltree imports talltree;
+ tree2talltree imports tree2talltree;
+}
+
+map __root__ in Tree2TallTreeInstall {
+ buffer nodes := tree.objectsOfKind(Node)->sortedBy(name);
+ buffer node2tallNodes : Sequence(tree2talltree::Node2TallNode);
+ install Node2MiddleNode {
+ node consumes nodes;
+ node2tallNodes appendsTo node2tallNodes;
+ }
+ install Edge2MiddleEdge {
+ node consumes nodes;
+ }
+ install MiddleNode2TallNode {
+ node2tallNode consumes node2tallNodes;
+ }
+}
+
+map Node2MiddleNode in Tree2TallTreeInstall {
+ guard:tree node : Node;
+ append node2tallNodes : Sequence(tree2talltree::Node2TallNode);
+ new:tree2talltree node2tallNode : Node2TallNode;
+ set node2tallNode.node := node;
+ set node2tallNode.name := node.name;
+ add node2tallNodes += node2tallNode;
+}
+
+map Edge2MiddleEdge in Tree2TallTreeInstall {
+ guard:tree node : Node;
+ var node2tallNode : Node2TallNode := node.Node2TallNode;
+ check node.parent <> null;
+ notify set node2tallNode.parent := node.parent.Node2TallNode;
+-- node2tallNode.name := node.name;
+}
+
+map MiddleNode2TallNode in Tree2TallTreeInstall {
+ guard:tree2talltree node2tallNode : Node2TallNode;
+ var tallNode_name : String := node2tallNode.name;
+ observe Node2TallNode::children, Node2TallNode::tallNode
+ var tallNode_children : Set(TallNode) := node2tallNode.children?.tallNode->asSet();
+ observe Node2TallNode::children, Node2TallNode::tallNode, TallNode::height
+ var tallNode_height : Integer := if node2tallNode.children->notEmpty() then node2tallNode.children.tallNode.height->max() + 1 else 0 endif;
+ new:talltree tallNode : TallNode;
+ notify set node2tallNode.tallNode := tallNode;
+ set tallNode.name := tallNode_name;
+ set tallNode.children := tallNode_children;
+ notify set tallNode.height := tallNode_height;
+}
diff --git a/tests/org.eclipse.qvtd.xtext.qvtimperative.tests/src/org/eclipse/qvtd/xtext/qvtimperative/tests/Tree2TallTree/Tree2TallTreeInstallManual.java b/tests/org.eclipse.qvtd.xtext.qvtimperative.tests/src/org/eclipse/qvtd/xtext/qvtimperative/tests/Tree2TallTree/Tree2TallTreeInstallManual.java
new file mode 100644
index 000000000..cfee5f673
--- /dev/null
+++ b/tests/org.eclipse.qvtd.xtext.qvtimperative.tests/src/org/eclipse/qvtd/xtext/qvtimperative/tests/Tree2TallTree/Tree2TallTreeInstallManual.java
@@ -0,0 +1,511 @@
+/*******************************************************************************
+ * «codeGenHelper.getCopyright(' * ')»
+ *
+ * This code is 100% auto-generated
+ * using: org.eclipse.qvtd.codegen.qvti.java.QVTiCodeGenerator
+ *
+ * Do not edit it.
+ ********************************************************************************/
+
+package org.eclipse.qvtd.xtext.qvtimperative.tests.Tree2TallTree;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.eclipse.emf.ecore.EcorePackage;
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.jdt.annotation.Nullable;
+import org.eclipse.ocl.pivot.evaluation.Executor;
+import org.eclipse.ocl.pivot.ids.ClassId;
+import org.eclipse.ocl.pivot.ids.IdManager;
+import org.eclipse.ocl.pivot.ids.IdResolver;
+import org.eclipse.ocl.pivot.ids.TypeId;
+import org.eclipse.ocl.pivot.internal.library.executor.ExecutorSingleIterationManager;
+import org.eclipse.ocl.pivot.library.AbstractBinaryOperation;
+import org.eclipse.ocl.pivot.library.LibraryIteration;
+import org.eclipse.ocl.pivot.library.collection.CollectionAsSetOperation;
+import org.eclipse.ocl.pivot.library.collection.CollectionExcludingOperation;
+import org.eclipse.ocl.pivot.library.collection.CollectionMaxOperation;
+import org.eclipse.ocl.pivot.library.collection.CollectionNotEmptyOperation;
+import org.eclipse.ocl.pivot.library.numeric.NumericPlusOperation;
+import org.eclipse.ocl.pivot.oclstdlib.OCLstdlibTables;
+import org.eclipse.ocl.pivot.utilities.ClassUtil;
+import org.eclipse.ocl.pivot.utilities.ValueUtil;
+import org.eclipse.ocl.pivot.values.BagValue;
+import org.eclipse.ocl.pivot.values.IntegerValue;
+import org.eclipse.ocl.pivot.values.InvalidValueException;
+import org.eclipse.ocl.pivot.values.OrderedSetValue;
+import org.eclipse.ocl.pivot.values.SetValue;
+import org.eclipse.qvtd.runtime.evaluation.AbstractInvocation;
+import org.eclipse.qvtd.runtime.evaluation.AbstractTransformer;
+import org.eclipse.qvtd.runtime.evaluation.Connection;
+import org.eclipse.qvtd.runtime.evaluation.Interval;
+import org.eclipse.qvtd.runtime.evaluation.InvocationConstructor;
+import org.eclipse.qvtd.runtime.evaluation.InvocationManager;
+import org.eclipse.qvtd.runtime.evaluation.ObjectManager;
+import org.eclipse.qvtd.runtime.evaluation.TransformationExecutor;
+import org.eclipse.qvtd.runtime.internal.evaluation.AbstractInvocationConstructor;
+import org.eclipse.qvtd.runtime.internal.evaluation.IncrementalInvocationManager;
+import org.eclipse.qvtd.runtime.internal.evaluation.IncrementalObjectManager;
+import org.eclipse.qvtd.runtime.library.model.ModelObjectsOfKindOperation;
+
+import tree2talltree.talltree.TallNode;
+import tree2talltree.talltree.TalltreeFactory;
+import tree2talltree.talltree.TalltreePackage;
+import tree2talltree.tree.Node;
+import tree2talltree.tree.TreePackage;
+import tree2talltree.tree2talltree.Node2TallNode;
+import tree2talltree.tree2talltree.Tree2talltreeFactory;
+import tree2talltree.tree2talltree.Tree2talltreePackage;
+
+/**
+ * The Tree2TallTreeInstall transformation:
+ * <p>
+ * Construct with an evaluator
+ * <br>
+ * Populate each input model with {@link addRootObjects(String,List)}
+ * <br>
+ * {@link run()}
+ * <br>
+ * Extract each output model with {@link getRootObjects(String)}
+ */
+@SuppressWarnings("nls")
+public class Tree2TallTreeInstallManual extends AbstractTransformer
+{
+ public static final /*@NonInvalid*/ org.eclipse.ocl.pivot.ids.@org.eclipse.jdt.annotation.NonNull RootPackageId PACKid_$metamodel$ = IdManager.getRootPackageId("$metamodel$");
+ public static final /*@NonInvalid*/ org.eclipse.ocl.pivot.ids.@org.eclipse.jdt.annotation.NonNull NsURIPackageId PACKid_http_c_s_s_www_eclipse_org_s_emf_s_2002_s_Ecore = IdManager.getNsURIPackageId("http://www.eclipse.org/emf/2002/Ecore", null, EcorePackage.eINSTANCE);
+ public static final /*@NonInvalid*/ org.eclipse.ocl.pivot.ids.@org.eclipse.jdt.annotation.NonNull NsURIPackageId PACKid_http_c_s_s_www_eclipse_org_s_qvt_s_2015_s_QVTbaseLibrary = IdManager.getNsURIPackageId("http://www.eclipse.org/qvt/2015/QVTbaseLibrary", "qvtbaselib", null);
+ public static final /*@NonInvalid*/ org.eclipse.ocl.pivot.ids.@org.eclipse.jdt.annotation.NonNull NsURIPackageId PACKid_http_c_s_s_www_eclipse_org_s_qvt_s_examples_s_0_1_s_List2List = IdManager.getNsURIPackageId("http://www.eclipse.org/qvt/examples/0.1/List2List", null, Tree2talltreePackage.eINSTANCE);
+ public static final /*@NonInvalid*/ org.eclipse.ocl.pivot.ids.@org.eclipse.jdt.annotation.NonNull NsURIPackageId PACKid_http_c_s_s_www_eclipse_org_s_qvt_s_examples_s_0_1_s_TallTree = IdManager.getNsURIPackageId("http://www.eclipse.org/qvt/examples/0.1/TallTree", null, TalltreePackage.eINSTANCE);
+ public static final /*@NonInvalid*/ org.eclipse.ocl.pivot.ids.@org.eclipse.jdt.annotation.NonNull NsURIPackageId PACKid_http_c_s_s_www_eclipse_org_s_qvt_s_examples_s_0_1_s_Tree = IdManager.getNsURIPackageId("http://www.eclipse.org/qvt/examples/0.1/Tree", null, TreePackage.eINSTANCE);
+ public static final /*@NonInvalid*/ org.eclipse.ocl.pivot.ids.@org.eclipse.jdt.annotation.NonNull ClassId CLSSid_Class = PACKid_$metamodel$.getClassId("Class", 0);
+ public static final /*@NonInvalid*/ org.eclipse.ocl.pivot.ids.@org.eclipse.jdt.annotation.NonNull ClassId CLSSid_Model = PACKid_http_c_s_s_www_eclipse_org_s_qvt_s_2015_s_QVTbaseLibrary.getClassId("Model", 0);
+ public static final /*@NonInvalid*/ org.eclipse.ocl.pivot.ids.@org.eclipse.jdt.annotation.NonNull ClassId CLSSid_Node = PACKid_http_c_s_s_www_eclipse_org_s_qvt_s_examples_s_0_1_s_Tree.getClassId("Node", 0);
+ public static final /*@NonInvalid*/ org.eclipse.ocl.pivot.ids.@org.eclipse.jdt.annotation.NonNull ClassId CLSSid_Node2TallNode = PACKid_http_c_s_s_www_eclipse_org_s_qvt_s_examples_s_0_1_s_List2List.getClassId("Node2TallNode", 0);
+ public static final /*@NonInvalid*/ org.eclipse.ocl.pivot.ids.@org.eclipse.jdt.annotation.NonNull ClassId CLSSid_TallNode = PACKid_http_c_s_s_www_eclipse_org_s_qvt_s_examples_s_0_1_s_TallTree.getClassId("TallNode", 0);
+ public static final /*@NonInvalid*/ org.eclipse.ocl.pivot.ids.@org.eclipse.jdt.annotation.NonNull DataTypeId DATAid_EInt = PACKid_http_c_s_s_www_eclipse_org_s_emf_s_2002_s_Ecore.getDataTypeId("EInt", 0);
+ public static final /*@NonInvalid*/ org.eclipse.ocl.pivot.values.@org.eclipse.jdt.annotation.NonNull IntegerValue INT_0 = ValueUtil.integerValueOf("0");
+ public static final /*@NonInvalid*/ org.eclipse.ocl.pivot.values.@org.eclipse.jdt.annotation.NonNull IntegerValue INT_1 = ValueUtil.integerValueOf("1");
+ public static final /*@NonInvalid*/ org.eclipse.ocl.pivot.ids.@org.eclipse.jdt.annotation.NonNull CollectionTypeId BAG_CLSSid_TallNode = TypeId.BAG.getSpecializedId(CLSSid_TallNode);
+ public static final /*@NonInvalid*/ org.eclipse.ocl.pivot.ids.@org.eclipse.jdt.annotation.NonNull CollectionTypeId BAG_DATAid_EInt = TypeId.BAG.getSpecializedId(DATAid_EInt);
+ public static final /*@NonInvalid*/ org.eclipse.ocl.pivot.ids.@org.eclipse.jdt.annotation.NonNull CollectionTypeId ORD_CLSSid_Node = TypeId.ORDERED_SET.getSpecializedId(CLSSid_Node);
+ public static final /*@NonInvalid*/ org.eclipse.ocl.pivot.ids.@org.eclipse.jdt.annotation.NonNull CollectionTypeId SEQ_CLSSid_Node2TallNode = TypeId.SEQUENCE.getSpecializedId(CLSSid_Node2TallNode);
+ public static final /*@NonInvalid*/ org.eclipse.ocl.pivot.ids.@org.eclipse.jdt.annotation.NonNull CollectionTypeId SET_CLSSid_Node = TypeId.SET.getSpecializedId(CLSSid_Node);
+ public static final /*@NonInvalid*/ org.eclipse.ocl.pivot.ids.@org.eclipse.jdt.annotation.NonNull CollectionTypeId SET_CLSSid_Node2TallNode = TypeId.SET.getSpecializedId(CLSSid_Node2TallNode);
+ public static final /*@NonInvalid*/ org.eclipse.ocl.pivot.ids.@org.eclipse.jdt.annotation.NonNull CollectionTypeId SET_CLSSid_TallNode = TypeId.SET.getSpecializedId(CLSSid_TallNode);
+
+ /*
+ * Property-source to Property-target unnavigable navigation caches
+ */
+ protected final @NonNull Map<Node,Node2TallNode> OPPOSITE_OF_Node2TallNode_node = new HashMap<Node,Node2TallNode>();
+
+ /*
+ * Array of the ClassIds of each class for which allInstances() may be invoked. Array index is the ClassIndex.
+ */
+ private static final @NonNull ClassId[] classIndex2classId = new @NonNull ClassId[]{
+ CLSSid_Node // 0 => Node
+ };
+
+ /*
+ * Mapping from each ClassIndex to all the ClassIndexes to which an object of the outer index
+ * may contribute results to an allInstances() invocation.
+ * Non trivial inner arrays arise when one ClassId is a derivation of another and so an
+ * instance of the derived classId contributes to derived and inherited ClassIndexes.
+ */
+ private final static int @NonNull [] @NonNull [] classIndex2allClassIndexes = new int @NonNull [] @NonNull [] {
+ {0} // 0 : Node -> {Node}
+ };
+
+ protected final AbstractInvocationConstructor.@NonNull Incremental CTOR_Root;
+ protected final AbstractInvocationConstructor.@NonNull Incremental CTOR_Node2MiddleNode;
+ protected final AbstractInvocationConstructor.@NonNull Incremental CTOR_Edge2MiddleEdge;
+ protected final AbstractInvocationConstructor.@NonNull Incremental CTOR_MiddleNode2TallNode;
+
+ protected final @NonNull Interval interval0;
+ protected final @NonNull Interval interval1;
+ protected final @NonNull Interval interval2;
+ protected final @NonNull Interval interval3;
+
+ public Tree2TallTreeInstallManual(final @NonNull TransformationExecutor executor) {
+ super(executor, new @NonNull String[] {"tree", "talltree", "tree2talltree"}, null, classIndex2classId, classIndex2allClassIndexes);
+ interval0 = invocationManager.createInterval();
+ interval1 = invocationManager.createInterval();
+ interval2 = invocationManager.createInterval();
+ interval3 = invocationManager.createInterval();
+ CTOR_Root = new AbstractInvocationConstructor.Incremental(interval0, "__root__")
+ {
+ @Override
+ public @NonNull MAP___root__ newInstance(@NonNull Object @NonNull [] values) {
+ return new MAP___root__(interval, this, values);
+ }
+ };
+ CTOR_Node2MiddleNode = new AbstractInvocationConstructor.Incremental(interval1, "Node2MiddleNode")
+ {
+ @Override
+ public @NonNull MAP_Node2MiddleNode newInstance(@NonNull Object @NonNull [] values) {
+ return new MAP_Node2MiddleNode(interval, this, values);
+ }
+ };
+ CTOR_Edge2MiddleEdge = new AbstractInvocationConstructor.Incremental(interval2, "Edge2MiddleEdge")
+ {
+ @Override
+ public @NonNull MAP_Edge2MiddleEdge newInstance(@NonNull Object @NonNull [] values) {
+ return new MAP_Edge2MiddleEdge(interval, this, values);
+ }
+ };
+ CTOR_MiddleNode2TallNode = new AbstractInvocationConstructor.Incremental(interval3, "MiddleNode2TallNode")
+ {
+ @Override
+ public @NonNull MAP_MiddleNode2TallNode newInstance(@NonNull Object @NonNull [] values) {
+ return new MAP_MiddleNode2TallNode(interval, this, values);
+ }
+ };
+ }
+
+ @Override
+ protected @NonNull InvocationManager createInvocationManager() {
+ return new IncrementalInvocationManager(executor);
+ }
+
+ @Override
+ protected @NonNull ObjectManager createObjectManager() {
+ return new IncrementalObjectManager((IncrementalInvocationManager)invocationManager);
+ }
+
+ @Override
+ public boolean run() {
+ CTOR_Root.connect(null, null);
+ CTOR_Root.getInstance(new @NonNull Object[]{});
+ // new MAP___root__(new @NonNull Object[0]);
+ // invocationManager.setWorkToDoAt(0);
+ return invocationManager.flush();
+ }
+
+ /**
+ *
+ * map __root__ in Tree2TallTreeInstall {
+ *
+ * nodes : OrderedSet(tree::Node)node2tallNodes : Sequence(tree2talltree::Node2TallNode)install Node2MiddleNode {
+ * node consumes nodes : OrderedSet(tree::Node);
+ * node2tallNodes appendsTo node2tallNodes;
+ * }
+ * install Edge2MiddleEdge {
+ * node consumes nodes : OrderedSet(tree::Node);
+ * }
+ * install MiddleNode2TallNode {
+ * node2tallNode consumes node2tallNodes : Sequence(tree2talltree::Node2TallNode);
+ * }
+ */
+ protected class MAP___root__ extends AbstractInvocation.Incremental
+ {
+ protected final @NonNull Connection nodes;
+
+ public MAP___root__(@NonNull Interval interval, InvocationConstructor.@org.eclipse.jdt.annotation.NonNull Incremental constructor, @NonNull Object @NonNull [] boundValues) {
+ super(interval, constructor);
+ nodes = interval.createConnection("nodes", ORD_CLSSid_Node, false);
+ }
+
+ @Override
+ public boolean execute() {
+ try {
+ final /*@NonInvalid*/ org.eclipse.ocl.pivot.ids.@org.eclipse.jdt.annotation.NonNull IdResolver idResolver = executor.getIdResolver();
+ final /*@NonInvalid*/ org.eclipse.ocl.pivot.@org.eclipse.jdt.annotation.NonNull Class TYP_tree_c_c_Node_0 = idResolver.getClass(CLSSid_Node, null);
+ final /*@NonInvalid*/ org.eclipse.ocl.pivot.@org.eclipse.jdt.annotation.NonNull StandardLibrary standardLibrary = idResolver.getStandardLibrary();
+ // connection variables
+ final /*@NonInvalid*/ org.eclipse.ocl.pivot.values.@org.eclipse.jdt.annotation.NonNull SetValue objectsOfKind = ModelObjectsOfKindOperation.INSTANCE.evaluate(executor, SET_CLSSid_Node, models[0/*tree*/], TYP_tree_c_c_Node_0);
+ final org.eclipse.ocl.pivot.@org.eclipse.jdt.annotation.NonNull Class TYPE_sortedBy_0 = executor.getStaticTypeOf(objectsOfKind);
+ final LibraryIteration.@org.eclipse.jdt.annotation.NonNull LibraryIterationExtension IMPL_sortedBy_0 = (LibraryIteration.LibraryIterationExtension)TYPE_sortedBy_0.lookupImplementation(standardLibrary, OCLstdlibTables.Operations._Set__sortedBy);
+ final @NonNull Object ACC_sortedBy_0 = IMPL_sortedBy_0.createAccumulatorValue(executor, ORD_CLSSid_Node, TypeId.STRING);
+ /**
+ * Implementation of the iterator body.
+ */
+ final @NonNull AbstractBinaryOperation BODY_sortedBy_0 = new AbstractBinaryOperation()
+ {
+ /**
+ * name
+ */
+ @Override
+ public @Nullable Object evaluate(final @NonNull Executor executor, final @NonNull TypeId typeId, final @Nullable Object objectsOfKind, final /*@NonInvalid*/ java.lang.@org.eclipse.jdt.annotation.Nullable Object _1) {
+ final /*@NonInvalid*/ tree2talltree.tree.@org.eclipse.jdt.annotation.Nullable Node symbol_4 = (Node)_1;
+ if (symbol_4 == null) {
+ throw new InvalidValueException("Null source for \'\'http://www.eclipse.org/qvt/examples/0.1/Tree\'::Node::name\'");
+ }
+ @SuppressWarnings("null")
+ final /*@Thrown*/ java.lang.@org.eclipse.jdt.annotation.NonNull String name = symbol_4.getName();
+ objectManager.got(MAP___root__.this, symbol_4, TreePackage.Literals.NODE__NAME, name);
+ return name;
+ }
+ };
+ final @NonNull ExecutorSingleIterationManager MGR_sortedBy_0 = new ExecutorSingleIterationManager(executor, ORD_CLSSid_Node, BODY_sortedBy_0, objectsOfKind, ACC_sortedBy_0);
+ final /*@Thrown*/ org.eclipse.ocl.pivot.values.@org.eclipse.jdt.annotation.NonNull OrderedSetValue sortedBy = ClassUtil.nonNullState((OrderedSetValue)IMPL_sortedBy_0.evaluateIteration(MGR_sortedBy_0));
+ for (tree2talltree.tree.@org.eclipse.jdt.annotation.NonNull Node iterator : ValueUtil.typedIterable(Node.class, sortedBy)) {
+ nodes.append(iterator);
+ }
+ final @NonNull Connection node2tallNodes_1 = interval2.createConnection("node2tallNodes_1", SEQ_CLSSid_Node2TallNode, false);
+ // mapping statements
+ CTOR_Node2MiddleNode.connect(new @NonNull Connection[]{nodes}, new @NonNull Connection[]{node2tallNodes_1});
+ CTOR_Edge2MiddleEdge.connect(new @NonNull Connection[]{nodes}, null);
+ CTOR_MiddleNode2TallNode.connect(new @NonNull Connection[]{node2tallNodes_1}, null);
+ final /*@Thrown*/ java.lang.@org.eclipse.jdt.annotation.Nullable Boolean __root__ = ValueUtil.TRUE_VALUE;
+ return __root__;
+ } catch (Throwable e) {
+ return handleExecutionFailure("MAP___root__", e);
+ }
+ }
+
+ @Override
+ public boolean isEqual(@NonNull IdResolver idResolver, @NonNull Object @NonNull [] thoseValues) {
+ return true;
+ }
+ }
+
+ /**
+ *
+ * map Node2MiddleNode in Tree2TallTreeInstall {
+ * guard:tree node : tree::Node[?];
+ * append node2tallNodes : Sequence(tree2talltree::Node2TallNode);
+ * new:tree2talltree node2tallNode : tree2talltree::Node2TallNode[?];
+ * set node2tallNode.node := node;
+ * set node2tallNode.name := node.name;
+ * add node2tallNodes += node2tallNode;
+ *
+ */
+ protected class MAP_Node2MiddleNode extends AbstractInvocation.Incremental
+ {
+ protected final /*@NonInvalid*/ tree2talltree.tree.@org.eclipse.jdt.annotation.NonNull Node node;
+ protected final @NonNull Connection node2tallNodes;
+
+ public MAP_Node2MiddleNode(@NonNull Interval interval, InvocationConstructor.@org.eclipse.jdt.annotation.NonNull Incremental constructor, @NonNull Object @NonNull [] boundValues) {
+ super(interval, constructor);
+ node = (Node)boundValues[0];
+ node2tallNodes = (Connection)boundValues[1];
+ }
+
+ @Override
+ public boolean execute() {
+ try {
+ // creations
+ final /*@Thrown*/ tree2talltree.tree2talltree.@org.eclipse.jdt.annotation.Nullable Node2TallNode node2tallNode_0 = Tree2talltreeFactory.eINSTANCE.createNode2TallNode();
+ assert node2tallNode_0 != null;
+ models[2/*tree2talltree*/].add(node2tallNode_0);
+ objectManager.created(this, node2tallNode_0);
+ // mapping statements
+ OPPOSITE_OF_Node2TallNode_node.put(node, node2tallNode_0);
+ node2tallNode_0.setNode(node);
+ objectManager.assigned(this, node2tallNode_0, Tree2talltreePackage.Literals.NODE2_TALL_NODE__NODE, node, null);
+ @SuppressWarnings("null")
+ final /*@Thrown*/ java.lang.@org.eclipse.jdt.annotation.NonNull String name = node.getName();
+ objectManager.got(MAP_Node2MiddleNode.this, node, TreePackage.Literals.NODE__NAME, name);
+ node2tallNode_0.setName(name);
+ objectManager.assigned(this, node2tallNode_0, Tree2talltreePackage.Literals.NODE2_TALL_NODE__NAME, name, null);
+ node2tallNodes.append(node2tallNode_0);
+ final /*@Thrown*/ java.lang.@org.eclipse.jdt.annotation.Nullable Boolean Node2MiddleNode = ValueUtil.TRUE_VALUE;
+ return Node2MiddleNode;
+ } catch (Throwable e) {
+ return handleExecutionFailure("MAP_Node2MiddleNode", e);
+ }
+ }
+
+ @Override
+ public boolean isEqual(@NonNull IdResolver idResolver, @NonNull Object @NonNull [] thoseValues) {
+ return idResolver.oclEquals(node, thoseValues[0])
+ && idResolver.oclEquals(node2tallNodes, thoseValues[1]);
+ }
+ }
+
+ /**
+ *
+ * map Edge2MiddleEdge in Tree2TallTreeInstall {
+ * guard:tree node : tree::Node[?];
+ * var node2tallNode : tree2talltree::Node2TallNode[?] := node.Node2TallNode;
+ * check node.parent <> null;
+ * notify set node2tallNode.parent := node.parent.Node2TallNode;
+ *
+ */
+ protected class MAP_Edge2MiddleEdge extends AbstractInvocation.Incremental
+ {
+ protected final /*@NonInvalid*/ tree2talltree.tree.@org.eclipse.jdt.annotation.NonNull Node node_0;
+
+ public MAP_Edge2MiddleEdge(@NonNull Interval interval, InvocationConstructor.@org.eclipse.jdt.annotation.NonNull Incremental constructor, @NonNull Object @NonNull [] boundValues) {
+ super(interval, constructor);
+ node_0 = (Node)boundValues[0];
+ }
+
+ @Override
+ public boolean execute() {
+ try {
+ final /*@Thrown*/ tree2talltree.tree2talltree.@org.eclipse.jdt.annotation.NonNull Node2TallNode Node2TallNode = ClassUtil.nonNullState (OPPOSITE_OF_Node2TallNode_node.get(node_0));
+ objectManager.got(MAP_Edge2MiddleEdge.this, node_0, Tree2talltreePackage.Literals.NODE2_TALL_NODE__NODE, Node2TallNode);
+ final /*@Thrown*/ tree2talltree.tree.@org.eclipse.jdt.annotation.Nullable Node parent = node_0.getParent();
+ objectManager.got(MAP_Edge2MiddleEdge.this, node_0, TreePackage.Literals.NODE__PARENT, parent);
+ final /*@Thrown*/ boolean ne = parent != null;
+ /*@Thrown*/ java.lang.@org.eclipse.jdt.annotation.Nullable Boolean symbol_2;
+ if (ne) {
+ // mapping statements
+ if (parent == null) {
+ throw new InvalidValueException("Null source for \'\'http://www.eclipse.org/qvt/examples/0.1/Tree\'::Node::Node2TallNode\'");
+ }
+ final /*@Thrown*/ tree2talltree.tree2talltree.@org.eclipse.jdt.annotation.NonNull Node2TallNode Node2TallNode_0 = ClassUtil.nonNullState (OPPOSITE_OF_Node2TallNode_node.get(parent));
+ objectManager.got(MAP_Edge2MiddleEdge.this, parent, Tree2talltreePackage.Literals.NODE2_TALL_NODE__NODE, Node2TallNode_0);
+ Node2TallNode.setParent(Node2TallNode_0);
+ objectManager.assigned(this, Node2TallNode, Tree2talltreePackage.Literals.NODE2_TALL_NODE__PARENT, Node2TallNode_0, null);
+ final /*@Thrown*/ java.lang.@org.eclipse.jdt.annotation.Nullable Boolean Edge2MiddleEdge = ValueUtil.TRUE_VALUE;
+ symbol_2 = Edge2MiddleEdge;
+ }
+ else {
+ symbol_2 = ValueUtil.FALSE_VALUE;
+ }
+ return symbol_2;
+ } catch (Throwable e) {
+ return handleExecutionFailure("MAP_Edge2MiddleEdge", e);
+ }
+ }
+
+ @Override
+ public boolean isEqual(@NonNull IdResolver idResolver, @NonNull Object @NonNull [] thoseValues) {
+ return idResolver.oclEquals(node_0, thoseValues[0]);
+ }
+ }
+
+ /**
+ *
+ * map MiddleNode2TallNode in Tree2TallTreeInstall {
+ *
+ * guard:tree2talltree node2tallNode : tree2talltree::Node2TallNode[?];
+ * var tallNode_name : String[?] := node2tallNode.name;
+ * var tallNode_children : Set(talltree::TallNode) := node2tallNode.children?.tallNode->asSet()
+ * ;
+ * var tallNode_height : Integer[?] := if node2tallNode.children->notEmpty()
+ * then node2tallNode.children.tallNode.height->max() + 1
+ * else 0
+ * endif;
+ * new:talltree tallNode : talltree::TallNode[?];
+ * notify set node2tallNode.tallNode := tallNode;
+ * set tallNode.name := tallNode_name;
+ * set tallNode.children := tallNode_children;
+ * notify set tallNode.height := tallNode_height;
+ *
+ */
+ protected class MAP_MiddleNode2TallNode extends AbstractInvocation.Incremental
+ {
+ protected final /*@NonInvalid*/ tree2talltree.tree2talltree.@org.eclipse.jdt.annotation.NonNull Node2TallNode node2tallNode;
+
+ public MAP_MiddleNode2TallNode(@NonNull Interval interval, InvocationConstructor.@org.eclipse.jdt.annotation.NonNull Incremental constructor, @NonNull Object @NonNull [] boundValues) {
+ super(interval, constructor);
+ node2tallNode = (Node2TallNode)boundValues[0];
+ }
+
+ @Override
+ public boolean execute() {
+ try {
+ final /*@NonInvalid*/ org.eclipse.ocl.pivot.ids.@org.eclipse.jdt.annotation.NonNull IdResolver idResolver = executor.getIdResolver();
+ @SuppressWarnings("null")
+ final /*@Thrown*/ java.lang.@org.eclipse.jdt.annotation.NonNull String name = node2tallNode.getName();
+ objectManager.got(MAP_MiddleNode2TallNode.this, node2tallNode, Tree2talltreePackage.Literals.NODE2_TALL_NODE__NAME, name);
+ objectManager.getting(node2tallNode, Tree2talltreePackage.Literals.NODE2_TALL_NODE__CHILDREN, false);
+ @SuppressWarnings("null")
+ final /*@Thrown*/ java.util.@org.eclipse.jdt.annotation.NonNull List<Node2TallNode> children_0 = node2tallNode.getChildren();
+ objectManager.got(MAP_MiddleNode2TallNode.this, node2tallNode, Tree2talltreePackage.Literals.NODE2_TALL_NODE__CHILDREN, children_0);
+ final /*@Thrown*/ org.eclipse.ocl.pivot.values.@org.eclipse.jdt.annotation.NonNull SetValue BOXED_children_0 = idResolver.createSetOfAll(SET_CLSSid_Node2TallNode, children_0);
+ final /*@Thrown*/ org.eclipse.ocl.pivot.values.@org.eclipse.jdt.annotation.NonNull SetValue safe_collect_sources = (SetValue)CollectionExcludingOperation.INSTANCE.evaluate(BOXED_children_0, (Object)null);
+ /*@Thrown*/ BagValue.@org.eclipse.jdt.annotation.NonNull Accumulator accumulator = ValueUtil.createBagAccumulatorValue(BAG_CLSSid_TallNode);
+ @NonNull Iterator<Object> ITERATOR__1 = safe_collect_sources.iterator();
+ /*@Thrown*/ org.eclipse.ocl.pivot.values.@org.eclipse.jdt.annotation.NonNull BagValue collect;
+ while (true) {
+ if (!ITERATOR__1.hasNext()) {
+ collect = accumulator;
+ break;
+ }
+ @SuppressWarnings("null")
+ /*@NonInvalid*/ tree2talltree.tree2talltree.@org.eclipse.jdt.annotation.NonNull Node2TallNode _1 = (Node2TallNode)ITERATOR__1.next();
+ /**
+ * tallNode
+ */
+ objectManager.getting(_1, Tree2talltreePackage.Literals.NODE2_TALL_NODE__TALL_NODE, false);
+ @SuppressWarnings("null")
+ final /*@Thrown*/ tree2talltree.talltree.@org.eclipse.jdt.annotation.NonNull TallNode tallNode_0 = _1.getTallNode();
+ objectManager.got(MAP_MiddleNode2TallNode.this, _1, Tree2talltreePackage.Literals.NODE2_TALL_NODE__TALL_NODE, tallNode_0);
+ //
+ accumulator.add(tallNode_0);
+ }
+ final /*@Thrown*/ org.eclipse.ocl.pivot.values.@org.eclipse.jdt.annotation.NonNull SetValue asSet = CollectionAsSetOperation.INSTANCE.evaluate(collect);
+ final /*@Thrown*/ boolean notEmpty = CollectionNotEmptyOperation.INSTANCE.evaluate(BOXED_children_0).booleanValue();
+ /*@Thrown*/ org.eclipse.ocl.pivot.values.@org.eclipse.jdt.annotation.NonNull IntegerValue symbol_0;
+ if (notEmpty) {
+ /*@Thrown*/ BagValue.@org.eclipse.jdt.annotation.NonNull Accumulator accumulator_0 = ValueUtil.createBagAccumulatorValue(BAG_CLSSid_TallNode);
+ @NonNull Iterator<Object> ITERATOR__1_0 = BOXED_children_0.iterator();
+ /*@Thrown*/ org.eclipse.ocl.pivot.values.@org.eclipse.jdt.annotation.NonNull BagValue collect_1;
+ while (true) {
+ if (!ITERATOR__1_0.hasNext()) {
+ collect_1 = accumulator_0;
+ break;
+ }
+ @SuppressWarnings("null")
+ /*@NonInvalid*/ tree2talltree.tree2talltree.@org.eclipse.jdt.annotation.NonNull Node2TallNode _1_0 = (Node2TallNode)ITERATOR__1_0.next();
+ /**
+ * tallNode
+ */
+ objectManager.getting(_1_0, Tree2talltreePackage.Literals.NODE2_TALL_NODE__TALL_NODE, false);
+ @SuppressWarnings("null")
+ final /*@Thrown*/ tree2talltree.talltree.@org.eclipse.jdt.annotation.NonNull TallNode tallNode_1 = _1_0.getTallNode();
+ objectManager.got(MAP_MiddleNode2TallNode.this, _1_0, Tree2talltreePackage.Literals.NODE2_TALL_NODE__TALL_NODE, tallNode_1);
+ //
+ accumulator_0.add(tallNode_1);
+ }
+ /*@Thrown*/ BagValue.@org.eclipse.jdt.annotation.NonNull Accumulator accumulator_1 = ValueUtil.createBagAccumulatorValue(BAG_DATAid_EInt);
+ @NonNull Iterator<Object> ITERATOR__1_1 = collect_1.iterator();
+ /*@Thrown*/ org.eclipse.ocl.pivot.values.@org.eclipse.jdt.annotation.NonNull BagValue collect_0;
+ while (true) {
+ if (!ITERATOR__1_1.hasNext()) {
+ collect_0 = accumulator_1;
+ break;
+ }
+ @SuppressWarnings("null")
+ /*@NonInvalid*/ tree2talltree.talltree.@org.eclipse.jdt.annotation.NonNull TallNode _1_1 = (TallNode)ITERATOR__1_1.next();
+ /**
+ * height
+ */
+ objectManager.getting(_1_1, TalltreePackage.Literals.TALL_NODE__HEIGHT, false);
+ final /*@Thrown*/ int height = _1_1.getHeight();
+ objectManager.got(MAP_MiddleNode2TallNode.this, _1_1, TalltreePackage.Literals.TALL_NODE__HEIGHT, height);
+ final /*@Thrown*/ org.eclipse.ocl.pivot.values.@org.eclipse.jdt.annotation.NonNull IntegerValue BOXED_height = ValueUtil.integerValueOf(height);
+ //
+ accumulator_1.add(BOXED_height);
+ }
+ final /*@Thrown*/ org.eclipse.ocl.pivot.values.@org.eclipse.jdt.annotation.NonNull IntegerValue max = (IntegerValue)CollectionMaxOperation.INSTANCE.evaluate(collect_0);
+ final /*@Thrown*/ org.eclipse.ocl.pivot.values.@org.eclipse.jdt.annotation.NonNull IntegerValue sum = (IntegerValue)NumericPlusOperation.INSTANCE.evaluate(max, INT_1);
+ symbol_0 = sum;
+ }
+ else {
+ symbol_0 = INT_0;
+ }
+ // creations
+ final /*@Thrown*/ tree2talltree.talltree.@org.eclipse.jdt.annotation.Nullable TallNode tallNode = TalltreeFactory.eINSTANCE.createTallNode();
+ assert tallNode != null;
+ models[1/*talltree*/].add(tallNode);
+ objectManager.created(this, tallNode);
+ // mapping statements
+ node2tallNode.setTallNode(tallNode);
+ objectManager.assigned(this, node2tallNode, Tree2talltreePackage.Literals.NODE2_TALL_NODE__TALL_NODE, tallNode, null);
+ tallNode.setName(name);
+ objectManager.assigned(this, tallNode, TalltreePackage.Literals.TALL_NODE__NAME, name, null);
+ final /*@Thrown*/ java.util.@org.eclipse.jdt.annotation.NonNull List<TallNode> ECORE_asSet = ((IdResolver.IdResolverExtension)idResolver).ecoreValueOfAll(TallNode.class, asSet);
+ tallNode.getChildren().addAll(ECORE_asSet);
+ objectManager.assigned(this, tallNode, TalltreePackage.Literals.TALL_NODE__CHILDREN, ECORE_asSet, null);
+ final int ECORE_symbol_0 = ValueUtil.intValueOf(symbol_0);
+ tallNode.setHeight(ECORE_symbol_0);
+ objectManager.assigned(this, tallNode, TalltreePackage.Literals.TALL_NODE__HEIGHT, ECORE_symbol_0, null);
+ final /*@Thrown*/ java.lang.@org.eclipse.jdt.annotation.Nullable Boolean MiddleNode2TallNode = ValueUtil.TRUE_VALUE;
+ return MiddleNode2TallNode;
+ } catch (Throwable e) {
+ return handleExecutionFailure("MAP_MiddleNode2TallNode", e);
+ }
+ }
+
+ @Override
+ public boolean isEqual(@NonNull IdResolver idResolver, @NonNull Object @NonNull [] thoseValues) {
+ return idResolver.oclEquals(node2tallNode, thoseValues[0]);
+ }
+ }
+}

Back to the top