Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEd Willink2016-11-05 20:21:50 +0000
committerEd Willink2016-12-20 21:48:27 +0000
commit6ca7fee8ffebac38ad7e67a6e20afc6e53e59225 (patch)
treee55b12d8b826723a90d035d20be6def843ed181f
parent4ba6beeb41b6e650cdae972ffce067719fd40632 (diff)
downloadorg.eclipse.qvtd-6ca7fee8ffebac38ad7e67a6e20afc6e53e59225.tar.gz
org.eclipse.qvtd-6ca7fee8ffebac38ad7e67a6e20afc6e53e59225.tar.xz
org.eclipse.qvtd-6ca7fee8ffebac38ad7e67a6e20afc6e53e59225.zip
[500962] Test a working incremental execution of a property change
-rw-r--r--plugins/org.eclipse.qvtd.codegen/src/org/eclipse/qvtd/codegen/qvti/java/QVTiCG2JavaVisitor.java391
-rw-r--r--plugins/org.eclipse.qvtd.codegen/src/org/eclipse/qvtd/codegen/utilities/QVTiCGUtil.java72
-rw-r--r--plugins/org.eclipse.qvtd.pivot.qvtimperative/src/org/eclipse/qvtd/pivot/qvtimperative/evaluation/BasicQVTiExecutor.java2
-rw-r--r--plugins/org.eclipse.qvtd.pivot.qvtimperative/src/org/eclipse/qvtd/pivot/qvtimperative/evaluation/QVTiEvaluationVisitor.java4
-rw-r--r--plugins/org.eclipse.qvtd.pivot.qvtimperative/src/org/eclipse/qvtd/pivot/qvtimperative/utilities/QVTimperativeUtil.java4
-rw-r--r--plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/evaluation/AbstractComputation.java12
-rw-r--r--plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/evaluation/AbstractInvocation.java20
-rw-r--r--plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/evaluation/AbstractSlotState.java6
-rw-r--r--plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/evaluation/Connection.java14
-rw-r--r--plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/evaluation/Execution.java19
-rw-r--r--plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/evaluation/SlotState.java1
-rw-r--r--plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/evaluation/StrictIncrementalConnection.java29
-rw-r--r--plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/internal/evaluation/AbstractConnectionInternal.java10
-rw-r--r--plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/internal/evaluation/AbstractInvocationInternal.java4
-rw-r--r--plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/internal/evaluation/AbstractTransformerInternal.java71
-rw-r--r--plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/internal/evaluation/IncrementalConnectionInternal.java32
-rw-r--r--plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/internal/evaluation/IncrementalObjectManager.java29
-rw-r--r--plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/internal/evaluation/ModificationMonitor.java104
-rw-r--r--plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/internal/evaluation/StrictConnectionInternal.java20
-rw-r--r--plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/internal/evaluation/StrictIncrementalConnectionInternal.java18
-rw-r--r--tests/org.eclipse.qvtd.compiler.tests/src/org/eclipse/qvtd/compiler/tests/RuntimeConnectionTests.java2
-rw-r--r--tests/org.eclipse.qvtd.xtext.qvtimperative.tests/src/org/eclipse/qvtd/xtext/qvtimperative/tests/QVTiCompilerTests.java84
-rw-r--r--tests/org.eclipse.qvtd.xtext.qvtimperative.tests/src/org/eclipse/qvtd/xtext/qvtimperative/tests/RuntimeConnectionTests.java385
-rw-r--r--tests/org.eclipse.qvtd.xtext.qvtimperative.tests/src/org/eclipse/qvtd/xtext/qvtimperative/tests/Tree2TallTree/TallTreeValidate2.xmi16
-rw-r--r--tests/org.eclipse.qvtd.xtext.qvtimperative.tests/src/org/eclipse/qvtd/xtext/qvtimperative/tests/Tree2TallTree/Tree2TallTree.qvti6
-rw-r--r--tests/org.eclipse.qvtd.xtext.qvtimperative.tests/src/org/eclipse/qvtd/xtext/qvtimperative/tests/Tree2TallTree/Tree2TallTreeInstallManual.java504
26 files changed, 1079 insertions, 780 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 cf9d6028e..fc769dff3 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
@@ -131,6 +131,7 @@ import org.eclipse.qvtd.runtime.evaluation.TransformationExecutor;
import org.eclipse.qvtd.runtime.evaluation.Transformer;
import org.eclipse.qvtd.runtime.internal.evaluation.AbstractComputationConstructor;
import org.eclipse.qvtd.runtime.internal.evaluation.AbstractInvocationConstructor;
+import org.eclipse.qvtd.runtime.internal.evaluation.AbstractTransformerInternal.Model;
import com.google.common.collect.Iterables;
@@ -139,6 +140,49 @@ import com.google.common.collect.Iterables;
*/
public class QVTiCG2JavaVisitor extends CG2JavaVisitor<@NonNull QVTiCodeGenerator> implements QVTiCGModelVisitor<@NonNull Boolean>
{
+ protected static class AllInstancesAnalysis
+ {
+ protected final @NonNull Set<org.eclipse.ocl.pivot.@NonNull Class> allInstancesClasses;
+ protected final @NonNull Map<org.eclipse.ocl.pivot.@NonNull Class, @Nullable List<org.eclipse.ocl.pivot.@NonNull Class>> instancesClassAnalysis;
+ protected final @NonNull Map<org.eclipse.ocl.pivot.@NonNull Class, @NonNull Integer> instancesClass2index;
+ protected final @NonNull List<org.eclipse.ocl.pivot.@NonNull Class> sortedList;
+ private @NonNull String @Nullable [] names = null;
+
+ public AllInstancesAnalysis(@NonNull QVTiTransformationAnalysis transformationAnalysis, @NonNull Set<org.eclipse.ocl.pivot.@NonNull Class> allInstancesClasses) {
+ this.allInstancesClasses = allInstancesClasses;
+ this.instancesClassAnalysis = transformationAnalysis.getInstancesClassAnalysis(allInstancesClasses);
+ //
+ // Populate a mapping from instancesClass to linear index.
+ //
+ this.instancesClass2index = new HashMap<>(instancesClassAnalysis.size());
+ this.sortedList = new ArrayList<>(instancesClassAnalysis.keySet());
+ Collections.sort(sortedList, NameUtil.NameableComparator.INSTANCE);
+ for (int i = 0; i < sortedList.size(); i++) {
+ instancesClass2index.put(sortedList.get(i), i);
+ }
+ }
+
+ protected @NonNull Map<org.eclipse.ocl.pivot.@NonNull Class, @NonNull Integer> getInstancesClass2index() {
+ return instancesClass2index;
+ }
+
+ protected @NonNull Map<org.eclipse.ocl.pivot.@NonNull Class, @Nullable List<org.eclipse.ocl.pivot.@NonNull Class>> getInstancesClassAnalysis() {
+ return instancesClassAnalysis;
+ }
+
+ protected @NonNull String @NonNull [] getNames() {
+ return ClassUtil.nonNullState(names);
+ }
+
+ protected @NonNull List<org.eclipse.ocl.pivot.@NonNull Class> getSortedList() {
+ return sortedList;
+ }
+
+ public void setNames(@NonNull String[] names) {
+ this.names = names;
+ }
+ }
+
/**
* The run-time API version.
*
@@ -226,49 +270,6 @@ public class QVTiCG2JavaVisitor extends CG2JavaVisitor<@NonNull QVTiCodeGenerato
}
}
- protected static class AllInstancesAnalysis
- {
- protected final @NonNull Set<org.eclipse.ocl.pivot.@NonNull Class> allInstancesClasses;
- protected final @NonNull Map<org.eclipse.ocl.pivot.@NonNull Class, @Nullable List<org.eclipse.ocl.pivot.@NonNull Class>> instancesClassAnalysis;
- protected final @NonNull Map<org.eclipse.ocl.pivot.@NonNull Class, @NonNull Integer> instancesClass2index;
- protected final @NonNull List<org.eclipse.ocl.pivot.@NonNull Class> sortedList;
- private @NonNull String @Nullable [] names = null;
-
- public AllInstancesAnalysis(@NonNull QVTiTransformationAnalysis transformationAnalysis, @NonNull Set<org.eclipse.ocl.pivot.@NonNull Class> allInstancesClasses) {
- this.allInstancesClasses = allInstancesClasses;
- this.instancesClassAnalysis = transformationAnalysis.getInstancesClassAnalysis(allInstancesClasses);
- //
- // Populate a mapping from instancesClass to linear index.
- //
- this.instancesClass2index = new HashMap<>(instancesClassAnalysis.size());
- this.sortedList = new ArrayList<>(instancesClassAnalysis.keySet());
- Collections.sort(sortedList, NameUtil.NameableComparator.INSTANCE);
- for (int i = 0; i < sortedList.size(); i++) {
- instancesClass2index.put(sortedList.get(i), i);
- }
- }
-
- protected @NonNull Map<org.eclipse.ocl.pivot.@NonNull Class, @NonNull Integer> getInstancesClass2index() {
- return instancesClass2index;
- }
-
- protected @NonNull Map<org.eclipse.ocl.pivot.@NonNull Class, @Nullable List<org.eclipse.ocl.pivot.@NonNull Class>> getInstancesClassAnalysis() {
- return instancesClassAnalysis;
- }
-
- protected @NonNull String @NonNull [] getNames() {
- return ClassUtil.nonNullState(names);
- }
-
- protected @NonNull List<org.eclipse.ocl.pivot.@NonNull Class> getSortedList() {
- return sortedList;
- }
-
- public void setNames(@NonNull String[] names) {
- this.names = names;
- }
- }
-
protected @Nullable AllInstancesAnalysis doAllInstances(@NonNull QVTiTransformationAnalysis transformationAnalysis) {
Set<org.eclipse.ocl.pivot.@NonNull Class> allInstancesClasses = transformationAnalysis.getAllInstancesClasses();
if (allInstancesClasses.size() > 0) {
@@ -382,9 +383,9 @@ public class QVTiCG2JavaVisitor extends CG2JavaVisitor<@NonNull QVTiCodeGenerato
}
protected void doAssigned(@NonNull CGEcoreContainerAssignment cgPropertyAssignment) {
- EStructuralFeature eStructuralFeature = ClassUtil.nonNullModel(cgPropertyAssignment.getEStructuralFeature());
- CGValuedElement cgSlot = getExpression(cgPropertyAssignment.getOwnedSlotValue());
- CGValuedElement cgInit = getExpression(cgPropertyAssignment.getOwnedInitValue());
+ EStructuralFeature eStructuralFeature = QVTiCGUtil.getEStructuralFeature(cgPropertyAssignment);
+ CGValuedElement cgSlot = getExpression(QVTiCGUtil.getOwnedSlotValue(cgPropertyAssignment));
+ CGValuedElement cgInit = getExpression(QVTiCGUtil.getOwnedInitValue(cgPropertyAssignment));
EPackage ePackage = ClassUtil.nonNullModel(eStructuralFeature.getEContainingClass().getEPackage());
if (isIncremental || ((SetStatement)cgPropertyAssignment.getAst()).isIsNotify()) {
js.append("objectManager.assigned(");
@@ -404,9 +405,9 @@ public class QVTiCG2JavaVisitor extends CG2JavaVisitor<@NonNull QVTiCodeGenerato
}
protected void doAssigned(@NonNull CGEcorePropertyAssignment cgPropertyAssignment) {
- EStructuralFeature eStructuralFeature = ClassUtil.nonNullModel(cgPropertyAssignment.getEStructuralFeature());
- CGValuedElement cgSlot = getExpression(cgPropertyAssignment.getOwnedSlotValue());
- CGValuedElement cgInit = getExpression(cgPropertyAssignment.getOwnedInitValue());
+ EStructuralFeature eStructuralFeature = QVTiCGUtil.getEStructuralFeature(cgPropertyAssignment);
+ CGValuedElement cgSlot = getExpression(QVTiCGUtil.getOwnedSlotValue(cgPropertyAssignment));
+ CGValuedElement cgInit = getExpression(QVTiCGUtil.getOwnedInitValue(cgPropertyAssignment));
EPackage ePackage = ClassUtil.nonNullModel(eStructuralFeature.getEContainingClass().getEPackage());
if (isIncremental || ((SetStatement)cgPropertyAssignment.getAst()).isIsNotify()) {
js.append("objectManager.assigned(");
@@ -504,6 +505,36 @@ public class QVTiCG2JavaVisitor extends CG2JavaVisitor<@NonNull QVTiCodeGenerato
js.append("}\n");
} */
+ protected void doCreateRealizedVariable(@NonNull CGRealizedVariable cgRealizedVariable) {
+ if (isIncremental) {
+ js.appendClassReference(null, cgRealizedVariable);
+ js.append(" ");
+ js.appendValueName(cgRealizedVariable);
+ js.append(" = this.");
+ js.appendValueName(cgRealizedVariable);
+ js.append(";\n");
+ js.append("if (");
+ js.appendValueName(cgRealizedVariable);
+ js.append(" == null) {\n");
+ js.pushIndentation(null);
+ }
+ cgRealizedVariable.accept(this);
+ doAddRealization(cgRealizedVariable);
+ //
+ if (isIncremental) {
+ js.append("assert ");
+ js.appendValueName(cgRealizedVariable);
+ js.append(" != null;\n");
+ js.append("this.");
+ js.appendValueName(cgRealizedVariable);
+ js.append(" = ");
+ js.appendValueName(cgRealizedVariable);
+ js.append(";\n");
+ js.popIndentation();
+ js.append("}\n");
+ }
+ }
+
protected boolean doEcoreCreateClass(@NonNull CGValuedElement cgElement, @NonNull EClass eClass) {
String createMethodName = "create" + eClass.getName();
boolean doSetNonNull = false;
@@ -528,7 +559,16 @@ public class QVTiCG2JavaVisitor extends CG2JavaVisitor<@NonNull QVTiCodeGenerato
javaClass = null;
}
//
- js.appendDeclaration(cgElement);
+ CGMapping cgMapping = QVTiCGUtil.basicGetContainingCGMapping(cgElement);
+ if ((cgMapping == null) || !useClass(cgMapping) || !isIncremental) {
+ js.append("final ");
+ if (!doSetNonNull) {
+ js.appendSuppressWarningsNull(false);
+ }
+ js.appendClassReference(true, cgElement);
+ js.append(" ");
+ }
+ js.appendValueName(cgElement);
js.append(" = ");
js.appendClassReference(javaClass);
js.append(".eINSTANCE.");
@@ -649,7 +689,7 @@ public class QVTiCG2JavaVisitor extends CG2JavaVisitor<@NonNull QVTiCodeGenerato
}
else if (asTypeId instanceof CollectionTypeId) { // FIXME Fudge for body-less functions
if (js.isUseNullAnnotations()) {
- js.append("@SuppressWarnings(\"null\")");
+ js.appendSuppressWarningsNull(false);
js.appendIsRequired(true);
js.append(" ");
}
@@ -701,7 +741,7 @@ public class QVTiCG2JavaVisitor extends CG2JavaVisitor<@NonNull QVTiCodeGenerato
}
else if (asTypeId instanceof CollectionTypeId) { // FIXME Fudge for body-less functions
if (js.isUseNullAnnotations()) {
- js.append("@SuppressWarnings(\"null\")");
+ js.appendSuppressWarningsNull(false);
js.appendIsRequired(true);
js.append(" ");
}
@@ -854,9 +894,9 @@ public class QVTiCG2JavaVisitor extends CG2JavaVisitor<@NonNull QVTiCodeGenerato
protected void doFunctionConstructor(@NonNull CGFunction cgFunction, @NonNull CGShadowExp cgShadowExp, @NonNull String instanceName) {
// List<@NonNull CGParameter> cgParameters = ClassUtil.nullFree(cgFunction.getParameters());
- if (js.isUseNullAnnotations()) {
- js.append("@SuppressWarnings(\"null\")\n"); // Accurate casts are too hard
- }
+ // if (js.isUseNullAnnotations()) {
+ // js.append("@SuppressWarnings(\"null\")\n"); // Accurate casts are too hard
+ // }
js.append("public ");
js.append(getFunctionName(cgFunction));
js.append("(/*Nullable*/ Object ");
@@ -1122,9 +1162,8 @@ public class QVTiCG2JavaVisitor extends CG2JavaVisitor<@NonNull QVTiCodeGenerato
public @NonNull Boolean doMappingCall_Class(@NonNull CGMappingCall cgMappingCall) {
js.append("invocationManager.flush();\n");
- MappingCall pMappingCall = (MappingCall) cgMappingCall.getAst();
- Mapping pReferredMapping = pMappingCall.getReferredMapping();
- assert pReferredMapping != null;
+ MappingCall pMappingCall = QVTiCGUtil.getAST(cgMappingCall);
+ Mapping pReferredMapping = QVTimperativeUtil.getReferredMapping(pMappingCall);
CGMapping cgReferredMapping = analyzer.getMapping(pReferredMapping);
assert cgReferredMapping != null;
Iterable<@NonNull CGMappingCallBinding> cgMappingCallBindings = QVTiCGUtil.getOwnedMappingCallBindings(cgMappingCall);
@@ -1132,20 +1171,21 @@ public class QVTiCG2JavaVisitor extends CG2JavaVisitor<@NonNull QVTiCodeGenerato
// Set loopVariable non-null if it needs to be type-checked and cast to a narrower type.
//
for (@NonNull CGMappingCallBinding cgMappingCallBinding : cgMappingCallBindings) {
+ CGValuedElement ownedValue = cgMappingCallBinding.getOwnedValue();
TypeDescriptor checkedType = needsTypeCheck(cgMappingCallBinding);
if (checkedType != null) {
js.append("if (");
- js.appendValueName(cgMappingCallBinding.getOwnedValue());
+ js.appendValueName(ownedValue);
js.append(" instanceof ");
js.appendClassReference(checkedType);
js.append(") {\n");
js.pushIndentation(null);
}
- else if (!cgMappingCallBinding.isNonNull()) {
+ else if (!ownedValue.isNonNull()) {
Element asMappingParameterBinding = cgMappingCallBinding.getAst();
if (!(asMappingParameterBinding instanceof GuardParameterBinding)) { // FIXME this should be part of isNonNull
js.append("if (");
- js.appendValueName(cgMappingCallBinding.getOwnedValue());
+ js.appendValueName(ownedValue);
js.append(" != null) {\n");
js.pushIndentation(null);
}
@@ -1195,7 +1235,7 @@ public class QVTiCG2JavaVisitor extends CG2JavaVisitor<@NonNull QVTiCodeGenerato
js.popIndentation();
js.append("}\n");
}
- else if (!cgMappingCallBinding.isNonNull()) {
+ else if (!cgMappingCallBinding.getOwnedValue().isNonNull()) {
Element asMappingParameterBinding = cgMappingCallBinding.getAst();
if (!(asMappingParameterBinding instanceof GuardParameterBinding)) { // FIXME this should be part of isNonNull
js.popIndentation();
@@ -1208,16 +1248,15 @@ public class QVTiCG2JavaVisitor extends CG2JavaVisitor<@NonNull QVTiCodeGenerato
}
public @NonNull Boolean doMappingCall_Function(@NonNull CGMappingCall cgMappingCall) {
- MappingCall pMappingCall = (MappingCall) cgMappingCall.getAst();
- Mapping pReferredMapping = pMappingCall.getReferredMapping();
- assert pReferredMapping != null;
+ MappingCall pMappingCall = QVTiCGUtil.getAST(cgMappingCall);
+ Mapping pReferredMapping = QVTimperativeUtil.getReferredMapping(pMappingCall);
CGMapping cgReferredMapping = analyzer.getMapping(pReferredMapping);
assert cgReferredMapping != null;
- List<CGMappingCallBinding> cgMappingCallBindings = cgMappingCall.getOwnedMappingCallBindings();
+ Iterable<@NonNull CGMappingCallBinding> cgMappingCallBindings = QVTiCGUtil.getOwnedMappingCallBindings(cgMappingCall);
//
// Set loopVariable non-null if it needs to be type-checked and cast to a narrower type.
//
- for (@SuppressWarnings("null")@NonNull CGMappingCallBinding cgMappingCallBinding : cgMappingCallBindings) {
+ for (@NonNull CGMappingCallBinding cgMappingCallBinding : cgMappingCallBindings) {
MappingParameterBinding asMappingParameterBinding = (MappingParameterBinding)cgMappingCallBinding.getAst();
if (asMappingParameterBinding instanceof AppendParameterBinding) {
}
@@ -1258,7 +1297,7 @@ public class QVTiCG2JavaVisitor extends CG2JavaVisitor<@NonNull QVTiCodeGenerato
//
js.append(getMappingName(cgReferredMapping) + "(");
boolean isFirst = true;
- for (@SuppressWarnings("null")@NonNull CGMappingCallBinding cgMappingCallBinding : cgMappingCallBindings) {
+ for (@NonNull CGMappingCallBinding cgMappingCallBinding : cgMappingCallBindings) {
if (!isFirst) {
js.append(", ");
}
@@ -1281,7 +1320,7 @@ public class QVTiCG2JavaVisitor extends CG2JavaVisitor<@NonNull QVTiCodeGenerato
//
// End the type check.
//
- for (@SuppressWarnings("null")@NonNull CGMappingCallBinding cgMappingCallBinding : cgMappingCallBindings) {
+ for (@NonNull CGMappingCallBinding cgMappingCallBinding : cgMappingCallBindings) {
MappingParameterBinding asMappingParameterBinding = (MappingParameterBinding)cgMappingCallBinding.getAst();
if (asMappingParameterBinding instanceof AppendParameterBinding) {
}
@@ -1371,7 +1410,7 @@ public class QVTiCG2JavaVisitor extends CG2JavaVisitor<@NonNull QVTiCodeGenerato
js.append("(invocationManager, ");
js.appendString(QVTiCGUtil.getName(cgMapping));
js.append(", ");
- js.appendBooleanString(((Mapping)cgMapping.getAst()).isIsStrict());
+ js.appendBooleanString(QVTiCGUtil.getAST(cgMapping).isIsStrict());
js.append(")\n");
js.append("{\n");
js.pushIndentation(null);
@@ -1399,16 +1438,63 @@ public class QVTiCG2JavaVisitor extends CG2JavaVisitor<@NonNull QVTiCodeGenerato
}
}
- /* protected void doMappingConstructorInitializers(@NonNull CGTransformation cgTransformation) {
- String className = cgTransformation.getName();
- for (@NonNull CGMapping cgMapping : ClassUtil.nullFree(cgTransformation.getMappings())) {
- if (useClass(cgMapping) && (cgMapping.getFreeVariables().size() > 0)) {
- js.append(getMappingCtorName(cgMapping) + " = ");
- js.appendClassReference(ClassUtil.class);
- js.append(".nonNullState(" + getMappingName(cgMapping) + ".class.getConstructor(" + className + ".class, Object[].class));\n");
+ protected boolean doMappingFields(@NonNull CGMapping cgMapping) {
+ boolean needsNewLine = false;
+ for (@NonNull CGGuardVariable cgVariable : ClassUtil.nullFree(cgMapping.getOwnedGuardVariables())) {
+ js.append("protected ");
+ doMappingConnectionVariable(cgVariable);
+ js.append(";\n");
+ needsNewLine = true;
+ }
+ if (isIncremental) {
+ for (@NonNull CGRealizedVariable cgVariable : QVTiCGUtil.getOwnedRealizedVariables(cgMapping)) {
+ js.append("protected ");
+ js.appendClassReference(false, cgVariable);
+ js.append(" ");
+ js.appendValueName(cgVariable);
+ if (isIncremental) {
+ js.append(" = null");
+ }
+ js.append(";\n");
+ needsNewLine = true;
}
}
- } */
+ return needsNewLine;
+ }
+
+ protected void doMappingRevokeInvocation(@NonNull CGMapping cgMapping) {
+ js.append("@Override\n");
+ js.append("public void revokeInvocation() {\n");
+ js.pushIndentation(null);
+ js.append("super.revokeInvocation();\n");
+ for (@NonNull CGRealizedVariable cgRealizedVariable : QVTiCGUtil.getOwnedRealizedVariables(cgMapping)) {
+ CGTypedModel cgTypedModel = cgRealizedVariable.getTypedModel();
+ //
+ js.appendClassReference(null, cgRealizedVariable);
+ js.append(" ");
+ js.appendValueName(cgRealizedVariable);
+ js.append(" = this.");
+ js.appendValueName(cgRealizedVariable);
+ js.append(";\n");
+ js.append("if (");
+ js.appendValueName(cgRealizedVariable);
+ js.append(" != null) {\n");
+ js.pushIndentation(null);
+ js.append("((");
+ js.appendClassReference(Model.Incremental.class);
+ js.append(")");
+ js.append(QVTiGlobalContext.MODELS_NAME);
+ js.append("[");
+ appendModelIndex(cgTypedModel);
+ js.append("]).remove(");
+ js.appendValueName(cgRealizedVariable);
+ js.append(");\n");
+ js.popIndentation();
+ js.append("}\n");
+ }
+ js.popIndentation();
+ js.append("}\n");
+ }
protected void doOppositeCaches(@NonNull QVTiTransformationAnalysis transformationAnalysis) {
Map<@NonNull Property, @NonNull Integer> opposites = transformationAnalysis.getCaches();
@@ -1725,8 +1811,7 @@ public class QVTiCG2JavaVisitor extends CG2JavaVisitor<@NonNull QVTiCodeGenerato
@Override
public @NonNull Boolean visitCGConnectionAssignment(@NonNull CGConnectionAssignment cgConnectionAssignment) {
- CGValuedElement initValue = cgConnectionAssignment.getOwnedInitValue();
- assert initValue != null;
+ CGValuedElement initValue = QVTiCGUtil.getOwnedInitValue(cgConnectionAssignment);
if (!js.appendLocalStatements(initValue)) {
return false;
}
@@ -1737,7 +1822,7 @@ public class QVTiCG2JavaVisitor extends CG2JavaVisitor<@NonNull QVTiCodeGenerato
BoxedDescriptor abstractBoxedDescriptor = concreteBoxedDescriptor;
if (!(initValue.getASTypeId() instanceof CollectionTypeId)) {
js.appendReferenceTo(cgConnectionAssignment.getConnectionVariable());
- js.append(".append(");
+ js.append(".appendElement(");
js.appendValueName(initValue);
js.append(");\n");
}
@@ -1793,9 +1878,9 @@ public class QVTiCG2JavaVisitor extends CG2JavaVisitor<@NonNull QVTiCodeGenerato
// Property pivotProperty = cgPropertyCallExp.getReferredProperty();
// CGTypeId cgTypeId = analyzer.getTypeId(pivotProperty.getOwningType().getTypeId());
// JavaTypeDescriptor requiredTypeDescriptor = context.getJavaTypeDescriptor(cgTypeId, false);
- EStructuralFeature eStructuralFeature = ClassUtil.nonNullModel(cgPropertyAssignment.getEStructuralFeature());
- CGValuedElement cgSlot = getExpression(cgPropertyAssignment.getOwnedSlotValue());
- CGValuedElement cgInit = getExpression(cgPropertyAssignment.getOwnedInitValue());
+ EStructuralFeature eStructuralFeature = QVTiCGUtil.getEStructuralFeature(cgPropertyAssignment);
+ CGValuedElement cgSlot = getExpression(QVTiCGUtil.getOwnedSlotValue(cgPropertyAssignment));
+ CGValuedElement cgInit = getExpression(QVTiCGUtil.getOwnedInitValue(cgPropertyAssignment));
// Class<?> requiredJavaClass = requiredTypeDescriptor.getJavaClass();
// Method leastDerivedMethod = requiredJavaClass != null ? getLeastDerivedMethod(requiredJavaClass, getAccessor) : null;
// Class<?> unboxedSourceClass = leastDerivedMethod != null ? leastDerivedMethod.getDeclaringClass() : requiredJavaClass;
@@ -1836,9 +1921,9 @@ public class QVTiCG2JavaVisitor extends CG2JavaVisitor<@NonNull QVTiCodeGenerato
// Property pivotProperty = cgPropertyCallExp.getReferredProperty();
// CGTypeId cgTypeId = analyzer.getTypeId(pivotProperty.getOwningType().getTypeId());
// JavaTypeDescriptor requiredTypeDescriptor = context.getJavaTypeDescriptor(cgTypeId, false);
- EStructuralFeature eStructuralFeature = ClassUtil.nonNullModel(cgPropertyAssignment.getEStructuralFeature());
- CGValuedElement cgSlot = getExpression(cgPropertyAssignment.getOwnedSlotValue());
- CGValuedElement cgInit = getExpression(cgPropertyAssignment.getOwnedInitValue());
+ EStructuralFeature eStructuralFeature = QVTiCGUtil.getEStructuralFeature(cgPropertyAssignment);
+ CGValuedElement cgSlot = getExpression(QVTiCGUtil.getOwnedSlotValue(cgPropertyAssignment));
+ CGValuedElement cgInit = getExpression(QVTiCGUtil.getOwnedInitValue(cgPropertyAssignment));
// Class<?> requiredJavaClass = requiredTypeDescriptor.getJavaClass();
// Method leastDerivedMethod = requiredJavaClass != null ? getLeastDerivedMethod(requiredJavaClass, getAccessor) : null;
// Class<?> unboxedSourceClass = leastDerivedMethod != null ? leastDerivedMethod.getDeclaringClass() : requiredJavaClass;
@@ -1861,7 +1946,7 @@ public class QVTiCG2JavaVisitor extends CG2JavaVisitor<@NonNull QVTiCodeGenerato
if (!js.appendLocalStatements(source)) {
return false;
}
- EStructuralFeature eStructuralFeature = ClassUtil.nonNullState(cgPropertyCallExp.getEStructuralFeature());
+ EStructuralFeature eStructuralFeature = QVTiCGUtil.getEStructuralFeature(cgPropertyCallExp);
doGetting(cgPropertyCallExp, eStructuralFeature, false);
Boolean status = appendCGEcorePropertyCallExp(cgPropertyCallExp, source);
if (status != ValueUtil.TRUE_VALUE) {
@@ -1877,12 +1962,6 @@ public class QVTiCG2JavaVisitor extends CG2JavaVisitor<@NonNull QVTiCodeGenerato
if (doEcoreCreateClass(cgRealizedVariable, (EClass)eClassifier)) {
cgRealizedVariable.setNonNull();
}
- //
- js.append("assert ");
- js.appendValueName(cgRealizedVariable);
- js.append(" != null;\n");
- //
- doAddRealization(cgRealizedVariable);
return true;
}
@@ -2085,13 +2164,7 @@ public class QVTiCG2JavaVisitor extends CG2JavaVisitor<@NonNull QVTiCodeGenerato
js.append(" extends ");
js.appendClassReference(isIncremental ? AbstractInvocation.Incremental.class : AbstractInvocation.class);
js.pushClassBody(mappingName);
- boolean needsNewLine = false;
- for (@NonNull CGGuardVariable cgFreeVariable : cgFreeVariables) {
- js.append("protected ");
- doMappingConnectionVariable(cgFreeVariable);
- js.append(";\n");
- needsNewLine = true;
- }
+ boolean needsNewLine = doMappingFields(cgMapping);
if (needsNewLine) {
js.append("\n");
}
@@ -2102,6 +2175,10 @@ public class QVTiCG2JavaVisitor extends CG2JavaVisitor<@NonNull QVTiCodeGenerato
doMappingBody(cgMapping, true);
js.append("\n");
doIsEqual(cgFreeVariables);
+ if (isIncremental && !Iterables.isEmpty(QVTiCGUtil.getOwnedRealizedVariables(cgMapping))) {
+ js.append("\n");
+ doMappingRevokeInvocation(cgMapping);
+ }
js.popClassBody(false);
}
else {
@@ -2117,7 +2194,6 @@ public class QVTiCG2JavaVisitor extends CG2JavaVisitor<@NonNull QVTiCodeGenerato
js.append(") ");
doMappingBody(cgMapping, false);
-
}
}
finally {
@@ -2129,11 +2205,8 @@ public class QVTiCG2JavaVisitor extends CG2JavaVisitor<@NonNull QVTiCodeGenerato
@Override
public @NonNull Boolean visitCGMappingCall(@NonNull CGMappingCall cgMappingCall) {
- MappingCall pMappingCall = (MappingCall) cgMappingCall.getAst();
- Mapping pReferredMapping = pMappingCall.getReferredMapping();
- if (pReferredMapping == null) {
- return true;
- }
+ MappingCall pMappingCall = QVTiCGUtil.getAST(cgMappingCall);
+ Mapping pReferredMapping = QVTimperativeUtil.getReferredMapping(pMappingCall);
CGMapping cgReferredMapping = analyzer.getMapping(pReferredMapping);
if (cgReferredMapping == null) {
return true;
@@ -2163,9 +2236,9 @@ public class QVTiCG2JavaVisitor extends CG2JavaVisitor<@NonNull QVTiCodeGenerato
@Override
public @NonNull Boolean visitCGMappingExp(@NonNull CGMappingExp cgMappingExp) {
// assert cgMappingExp.getPredicates().isEmpty(); // Get rewritten during JavaPre pass
- CGMapping cgMapping = ClassUtil.nonNullState(QVTiCGUtil.getContainingCGMapping(cgMappingExp));
- List<@NonNull CGAccumulator> cgAccumulators = ClassUtil.nullFree(cgMappingExp.getOwnedAccumulators());
- if (cgAccumulators.size() > 0) {
+ CGMapping cgMapping = QVTiCGUtil.getContainingCGMapping(cgMappingExp);
+ Iterable<@NonNull CGAccumulator> cgAccumulators = QVTiCGUtil.getOwnedAccumulators(cgMappingExp);
+ if (!Iterables.isEmpty(cgAccumulators)) {
js.append("// connection variables\n");
for (@NonNull CGAccumulator cgAccumulator : cgAccumulators) {
Element ast = cgAccumulator.getAst();
@@ -2219,7 +2292,7 @@ public class QVTiCG2JavaVisitor extends CG2JavaVisitor<@NonNull QVTiCodeGenerato
js.append(") {\n");
js.pushIndentation(null);
js.appendReferenceTo(cgAccumulator);
- js.append(".append(");
+ js.append(".appendElement(");
js.append(iteratorName);
js.append(");\n");
js.popIndentation();
@@ -2227,22 +2300,22 @@ public class QVTiCG2JavaVisitor extends CG2JavaVisitor<@NonNull QVTiCodeGenerato
}
}
}
- List<@NonNull CGRealizedVariable> cgRealizedVariables = ClassUtil.nullFree(cgMapping.getOwnedRealizedVariables());
- if (cgRealizedVariables.size() > 0) {
+ Iterable<@NonNull CGRealizedVariable> cgRealizedVariables = QVTiCGUtil.getOwnedRealizedVariables(cgMapping);
+ if (!Iterables.isEmpty(cgRealizedVariables)) {
js.append("// creations\n");
for (@NonNull CGRealizedVariable cgRealizedVariable : cgRealizedVariables) {
- cgRealizedVariable.accept(this);
+ doCreateRealizedVariable(cgRealizedVariable);
}
}
- List<@NonNull CGPropertyAssignment> cgPropertyAssignments = ClassUtil.nullFree(cgMapping.getOwnedAssignments());
- if (cgPropertyAssignments.size() > 0) {
+ Iterable<@NonNull CGPropertyAssignment> cgPropertyAssignments = QVTiCGUtil.getOwnedAssignments(cgMapping);
+ if (!Iterables.isEmpty(cgPropertyAssignments)) {
js.append("// property assignments\n");
for (@NonNull CGPropertyAssignment cgAssignment : cgPropertyAssignments) {
cgAssignment.accept(this);
}
}
- List<@NonNull CGConnectionAssignment> cgConnectionAssignments = ClassUtil.nullFree(cgMapping.getOwnedConnectionAssignments());
- if (cgConnectionAssignments.size() > 0) {
+ Iterable<@NonNull CGConnectionAssignment> cgConnectionAssignments = QVTiCGUtil.getOwnedConnectionAssignments(cgMapping);
+ if (!Iterables.isEmpty(cgConnectionAssignments)) {
js.append("// connection assignments\n");
for (@NonNull CGConnectionAssignment cgConnectionAssignment : cgConnectionAssignments) {
cgConnectionAssignment.accept(this);
@@ -2309,14 +2382,12 @@ public class QVTiCG2JavaVisitor extends CG2JavaVisitor<@NonNull QVTiCodeGenerato
for (EObject eObject : new TreeIterable(body, false)) {
if (eObject instanceof CGMappingCall) {
CGMappingCall cgMappingCall = (CGMappingCall)eObject;
- MappingCall asMappingCall = (MappingCall) cgMappingCall.getAst();
- Mapping pReferredMapping = asMappingCall.getReferredMapping();
- if (pReferredMapping != null) {
- CGMapping cgReferredMapping = analyzer.getMapping(pReferredMapping);
- if ((cgReferredMapping != null) && useClass(cgReferredMapping)) {
- needsFlush = true;
- break;
- }
+ MappingCall asMappingCall = QVTiCGUtil.getAST(cgMappingCall);
+ Mapping pReferredMapping = QVTimperativeUtil.getReferredMapping(asMappingCall);
+ CGMapping cgReferredMapping = analyzer.getMapping(pReferredMapping);
+ if ((cgReferredMapping != null) && useClass(cgReferredMapping)) {
+ needsFlush = true;
+ break;
}
}
}
@@ -2328,22 +2399,20 @@ public class QVTiCG2JavaVisitor extends CG2JavaVisitor<@NonNull QVTiCodeGenerato
@Override
public @NonNull Boolean visitCGMiddlePropertyAssignment(@NonNull CGMiddlePropertyAssignment cgMiddlePropertyAssignment) {
- Property pReferredProperty = ClassUtil.nonNullModel(cgMiddlePropertyAssignment.getReferredProperty());
+ Property pReferredProperty = QVTiCGUtil.getReferredProperty(cgMiddlePropertyAssignment);
assert !pReferredProperty.isIsImplicit();
- CGValuedElement slotValue = cgMiddlePropertyAssignment.getOwnedSlotValue();
- CGValuedElement initValue = cgMiddlePropertyAssignment.getOwnedInitValue();
- if ((slotValue != null) && (initValue != null)) {
- Map<@NonNull Property, @NonNull String> oppositeProperties = getGlobalContext().getOppositeProperties();
- if (oppositeProperties != null) {
- String cacheName = oppositeProperties.get(pReferredProperty);
- if (cacheName != null) {
- js.append(cacheName);
- js.append(".put(");
- js.appendValueName(initValue);
- js.append(", ");
- js.appendValueName(slotValue);
- js.append(");\n");
- }
+ CGValuedElement slotValue = QVTiCGUtil.getOwnedSlotValue(cgMiddlePropertyAssignment);
+ CGValuedElement initValue = QVTiCGUtil.getOwnedInitValue(cgMiddlePropertyAssignment);
+ Map<@NonNull Property, @NonNull String> oppositeProperties = getGlobalContext().getOppositeProperties();
+ if (oppositeProperties != null) {
+ String cacheName = oppositeProperties.get(pReferredProperty);
+ if (cacheName != null) {
+ js.append(cacheName);
+ js.append(".put(");
+ js.appendValueName(initValue);
+ js.append(", ");
+ js.appendValueName(slotValue);
+ js.append(");\n");
}
}
return visitCGEcorePropertyAssignment(cgMiddlePropertyAssignment);
@@ -2390,22 +2459,20 @@ public class QVTiCG2JavaVisitor extends CG2JavaVisitor<@NonNull QVTiCodeGenerato
@Override
public @NonNull Boolean visitCGPropertyAssignment(@NonNull CGPropertyAssignment cgPropertyAssignment) {
CGExecutorProperty cgExecutorProperty = cgPropertyAssignment.getExecutorProperty();
- CGValuedElement slotValue = cgPropertyAssignment.getOwnedSlotValue();
- CGValuedElement initValue = cgPropertyAssignment.getOwnedInitValue();
- if ((slotValue != null) && (initValue != null)) {
- if (!js.appendLocalStatements(slotValue)) {
- return false;
- }
- if (!js.appendLocalStatements(initValue)) {
- return false;
- }
- js.appendReferenceTo(cgExecutorProperty);
- js.append(".initValue(");
- js.appendValueName(slotValue);
- js.append(", ");
- js.appendValueName(initValue);
- js.append(");\n");
+ CGValuedElement slotValue = QVTiCGUtil.getOwnedSlotValue(cgPropertyAssignment);
+ CGValuedElement initValue = QVTiCGUtil.getOwnedInitValue(cgPropertyAssignment);
+ if (!js.appendLocalStatements(slotValue)) {
+ return false;
+ }
+ if (!js.appendLocalStatements(initValue)) {
+ return false;
}
+ js.appendReferenceTo(cgExecutorProperty);
+ js.append(".initValue(");
+ js.appendValueName(slotValue);
+ js.append(", ");
+ js.appendValueName(initValue);
+ js.append(");\n");
return true;
}
@@ -2413,13 +2480,17 @@ public class QVTiCG2JavaVisitor extends CG2JavaVisitor<@NonNull QVTiCodeGenerato
public @NonNull Boolean visitCGRealizedVariable(@NonNull CGRealizedVariable cgRealizedVariable) {
TypeId typeId = cgRealizedVariable.getASTypeId();
if (typeId != null) {
- js.appendDeclaration(cgRealizedVariable);
+ CGMapping cgMapping = QVTiCGUtil.getOwningMapping(cgRealizedVariable);
+ if (useClass(cgMapping)) {
+ js.appendValueName(cgRealizedVariable);
+ }
+ else {
+ js.appendDeclaration(cgRealizedVariable);
+ }
js.append(" = ");
js.appendReferenceTo(cgRealizedVariable.getExecutorType());
js.append(".createInstance();\n");
}
- //
- doAddRealization(cgRealizedVariable);
return true;
}
@@ -2466,7 +2537,7 @@ public class QVTiCG2JavaVisitor extends CG2JavaVisitor<@NonNull QVTiCodeGenerato
js.append(" * <br>\n");
js.append(" * Extract each output model with {@link getRootObjects(String)}\n");
js.append(" */\n");
- js.append("@SuppressWarnings(\"nls\")\n");
+ js.append("@SuppressWarnings({\"nls\",\"unused\"})\n");
js.append("public class " + className + " extends ");
js.appendClassReference(getAbstractTransformationExecutorClass());
js.pushClassBody(className);
diff --git a/plugins/org.eclipse.qvtd.codegen/src/org/eclipse/qvtd/codegen/utilities/QVTiCGUtil.java b/plugins/org.eclipse.qvtd.codegen/src/org/eclipse/qvtd/codegen/utilities/QVTiCGUtil.java
index 042a4f0ad..260da702d 100644
--- a/plugins/org.eclipse.qvtd.codegen/src/org/eclipse/qvtd/codegen/utilities/QVTiCGUtil.java
+++ b/plugins/org.eclipse.qvtd.codegen/src/org/eclipse/qvtd/codegen/utilities/QVTiCGUtil.java
@@ -17,16 +17,22 @@ import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.ocl.examples.codegen.cgmodel.CGAccumulator;
import org.eclipse.ocl.examples.codegen.cgmodel.CGEcorePropertyCallExp;
import org.eclipse.ocl.examples.codegen.cgmodel.CGElement;
+import org.eclipse.ocl.examples.codegen.cgmodel.CGValuedElement;
import org.eclipse.ocl.examples.codegen.utilities.CGUtil;
import org.eclipse.ocl.pivot.VariableDeclaration;
+import org.eclipse.ocl.pivot.Property;
import org.eclipse.ocl.pivot.utilities.ClassUtil;
import org.eclipse.ocl.pivot.utilities.NameUtil;
+import org.eclipse.qvtd.codegen.qvticgmodel.CGConnectionAssignment;
import org.eclipse.qvtd.codegen.qvticgmodel.CGEcoreContainerAssignment;
import org.eclipse.qvtd.codegen.qvticgmodel.CGEcorePropertyAssignment;
import org.eclipse.qvtd.codegen.qvticgmodel.CGGuardVariable;
import org.eclipse.qvtd.codegen.qvticgmodel.CGMapping;
import org.eclipse.qvtd.codegen.qvticgmodel.CGMappingCall;
import org.eclipse.qvtd.codegen.qvticgmodel.CGMappingCallBinding;
+import org.eclipse.qvtd.codegen.qvticgmodel.CGMappingExp;
+import org.eclipse.qvtd.codegen.qvticgmodel.CGPropertyAssignment;
+import org.eclipse.qvtd.codegen.qvticgmodel.CGRealizedVariable;
import org.eclipse.qvtd.codegen.qvticgmodel.CGTransformation;
import org.eclipse.qvtd.codegen.qvticgmodel.CGTypedModel;
import org.eclipse.qvtd.pivot.qvtimperative.GuardParameter;
@@ -85,12 +91,36 @@ public class QVTiCGUtil extends CGUtil
return ClassUtil.nonNullState(cgPropertyCallExp.getEStructuralFeature());
}
+ public static @NonNull String getName(@NonNull CGAccumulator cgAccumulator) {
+ return ClassUtil.nonNullState(cgAccumulator.getName());
+ }
+
public static @NonNull String getName(@NonNull CGMapping cgMapping) {
return ClassUtil.nonNullState(cgMapping.getName());
}
- public static @NonNull String getName(@NonNull CGAccumulator cgAccumulator) {
- return ClassUtil.nonNullState(cgAccumulator.getName());
+ public static @NonNull Iterable<@NonNull CGAccumulator> getOwnedAccumulators(@NonNull CGMappingExp cgMappingExp) {
+ return ClassUtil.nullFree(cgMappingExp.getOwnedAccumulators());
+ }
+
+ public static @NonNull Iterable<@NonNull CGPropertyAssignment> getOwnedAssignments(@NonNull CGMapping cgMapping) {
+ return ClassUtil.nullFree(cgMapping.getOwnedAssignments());
+ }
+
+ public static @NonNull Iterable<@NonNull CGConnectionAssignment> getOwnedConnectionAssignments(@NonNull CGMapping cgMapping) {
+ return ClassUtil.nullFree(cgMapping.getOwnedConnectionAssignments());
+ }
+
+ public static @NonNull Iterable<@NonNull CGGuardVariable> getOwnedGuardVariables(@NonNull CGMapping cgRootMapping) {
+ return ClassUtil.nullFree(cgRootMapping.getOwnedGuardVariables());
+ }
+
+ public static @NonNull CGValuedElement getOwnedInitValue(@NonNull CGConnectionAssignment cgConnectionAssignment) {
+ return ClassUtil.nonNullState(cgConnectionAssignment.getOwnedInitValue());
+ }
+
+ public static @NonNull CGValuedElement getOwnedInitValue(@NonNull CGPropertyAssignment cgPropertyAssignment) {
+ return ClassUtil.nonNullState(cgPropertyAssignment.getOwnedInitValue());
}
public static @NonNull Iterable<@NonNull CGMappingCallBinding> getOwnedMappingCallBindings(@NonNull CGMappingCall cgMappingCall) {
@@ -101,6 +131,31 @@ public class QVTiCGUtil extends CGUtil
return ClassUtil.nullFree(cgTransformation.getOwnedMappings());
}
+ public static @NonNull Iterable<@NonNull CGRealizedVariable> getOwnedRealizedVariables(@NonNull CGMapping cgMapping) {
+ return ClassUtil.nullFree(cgMapping.getOwnedRealizedVariables());
+ }
+
+ public static @NonNull CGValuedElement getOwnedSlotValue(@NonNull CGPropertyAssignment cgPropertyAssignment) {
+ return ClassUtil.nonNullState(cgPropertyAssignment.getOwnedSlotValue());
+ }
+
+ public static @NonNull Iterable<@NonNull CGTypedModel> getOwnedTypedModels(@NonNull CGTransformation cgTransformation) {
+ return ClassUtil.nullFree(cgTransformation.getOwnedTypedModels());
+ }
+
+ public static @NonNull CGMapping getOwningMapping(@NonNull CGRealizedVariable cgRealizedVariable) {
+ return ClassUtil.nonNullState(cgRealizedVariable.getOwningMapping());
+ }
+
+ public static @NonNull CGTransformation getOwningTransformation(@NonNull CGMapping cgMapping) {
+ return ClassUtil.nonNullState(cgMapping.getOwningTransformation());
+
+ }
+
+ public static @NonNull Property getReferredProperty(@NonNull CGPropertyAssignment cgPropertyAssignment) {
+ return ClassUtil.nonNullState(cgPropertyAssignment.getReferredProperty());
+ }
+
public static @NonNull CGMapping getRootMapping(@NonNull CGTransformation cgTransformation) {
CGMapping cgRootMapping = NameUtil.getNameable(cgTransformation.getOwnedMappings(), QVTimperativeUtil.ROOT_MAPPING_NAME); // Obsolete relic
for (@NonNull CGMapping cgMapping : getOwnedMappings(cgTransformation)) {
@@ -130,17 +185,4 @@ public class QVTiCGUtil extends CGUtil
}
return cgRootMapping;
}
-
- public static @NonNull Iterable<@NonNull CGGuardVariable> getOwnedGuardVariables(@NonNull CGMapping cgRootMapping) {
- return ClassUtil.nullFree(cgRootMapping.getOwnedGuardVariables());
- }
-
- public static @NonNull Iterable<@NonNull CGTypedModel> getOwnedTypedModels(@NonNull CGTransformation cgTransformation) {
- return ClassUtil.nullFree(cgTransformation.getOwnedTypedModels());
- }
-
- public static @NonNull CGTransformation getOwningTransformation(@NonNull CGMapping cgMapping) {
- return ClassUtil.nonNullState(cgMapping.getOwningTransformation());
-
- }
}
diff --git a/plugins/org.eclipse.qvtd.pivot.qvtimperative/src/org/eclipse/qvtd/pivot/qvtimperative/evaluation/BasicQVTiExecutor.java b/plugins/org.eclipse.qvtd.pivot.qvtimperative/src/org/eclipse/qvtd/pivot/qvtimperative/evaluation/BasicQVTiExecutor.java
index 3465732fb..7b3783d8a 100644
--- a/plugins/org.eclipse.qvtd.pivot.qvtimperative/src/org/eclipse/qvtd/pivot/qvtimperative/evaluation/BasicQVTiExecutor.java
+++ b/plugins/org.eclipse.qvtd.pivot.qvtimperative/src/org/eclipse/qvtd/pivot/qvtimperative/evaluation/BasicQVTiExecutor.java
@@ -400,7 +400,7 @@ public abstract class BasicQVTiExecutor extends AbstractExecutor implements QVTi
Connection connection = rootInterval.createConnection(QVTimperativeUtil.getName(mappingParameter), type.getTypeId(), false);
Iterable<@NonNull ? extends Object> objectsOfKind = modelInstance.getObjectsOfKind(type);
for (@NonNull Object object : objectsOfKind) {
- connection.append(object);
+ connection.appendElement(object);
}
getEvaluationEnvironment().add(mappingParameter, connection);
}
diff --git a/plugins/org.eclipse.qvtd.pivot.qvtimperative/src/org/eclipse/qvtd/pivot/qvtimperative/evaluation/QVTiEvaluationVisitor.java b/plugins/org.eclipse.qvtd.pivot.qvtimperative/src/org/eclipse/qvtd/pivot/qvtimperative/evaluation/QVTiEvaluationVisitor.java
index c388c7280..6b6051245 100644
--- a/plugins/org.eclipse.qvtd.pivot.qvtimperative/src/org/eclipse/qvtd/pivot/qvtimperative/evaluation/QVTiEvaluationVisitor.java
+++ b/plugins/org.eclipse.qvtd.pivot.qvtimperative/src/org/eclipse/qvtd/pivot/qvtimperative/evaluation/QVTiEvaluationVisitor.java
@@ -101,7 +101,7 @@ public class QVTiEvaluationVisitor extends BasicEvaluationVisitor implements IQV
// }
// }
// else {
- connectionCollection.append(values);
+ connectionCollection.appendElement(values);
// }
return connectionCollection;
}
@@ -306,7 +306,7 @@ public class QVTiEvaluationVisitor extends BasicEvaluationVisitor implements IQV
if (initValue != null) {
for (Object value : (Iterable<?>)initValue) {
assert value != null;
- connection.append(value);
+ connection.appendElement(value);
}
}
}
diff --git a/plugins/org.eclipse.qvtd.pivot.qvtimperative/src/org/eclipse/qvtd/pivot/qvtimperative/utilities/QVTimperativeUtil.java b/plugins/org.eclipse.qvtd.pivot.qvtimperative/src/org/eclipse/qvtd/pivot/qvtimperative/utilities/QVTimperativeUtil.java
index 33c49f484..3d4769c9c 100644
--- a/plugins/org.eclipse.qvtd.pivot.qvtimperative/src/org/eclipse/qvtd/pivot/qvtimperative/utilities/QVTimperativeUtil.java
+++ b/plugins/org.eclipse.qvtd.pivot.qvtimperative/src/org/eclipse/qvtd/pivot/qvtimperative/utilities/QVTimperativeUtil.java
@@ -308,6 +308,10 @@ public class QVTimperativeUtil extends QVTbaseUtil
return (@NonNull Iterable<@NonNull ImperativeTypedModel>)modelParameter;
}
+ public static @NonNull Mapping getReferredMapping(MappingCall asMappingCall) {
+ return ClassUtil.nonNullState(asMappingCall.getReferredMapping());
+ }
+
public static @NonNull Mapping getRootMapping(@NonNull ImperativeTransformation asTransformation) {
Mapping asRootMapping = NameUtil.getNameable(getOwnedMappings(asTransformation), QVTimperativeUtil.ROOT_MAPPING_NAME); // Obsolete relic
for (@NonNull Mapping asMapping : getOwnedMappings(asTransformation)) {
diff --git a/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/evaluation/AbstractComputation.java b/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/evaluation/AbstractComputation.java
index 801e2ad5e..eb3395025 100644
--- a/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/evaluation/AbstractComputation.java
+++ b/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/evaluation/AbstractComputation.java
@@ -41,6 +41,18 @@ public abstract class AbstractComputation implements Computation
public @NonNull Iterable<@NonNull Object> getCreatedObjects() {
return /*createdObjects != null ? createdObjects :*/ EMPTY_OBJECT_LIST;
}
+
+ @Override
+ public void revokeExecution() {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void revokeInvocation() {
+ // TODO Auto-generated method stub
+
+ }
}
@Override
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 e391c45a5..307f916d7 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
@@ -99,6 +99,26 @@ public abstract class AbstractInvocation extends AbstractInvocationInternal
}
@Override
+ public void revokeExecution() {
+ if (writeSlots != null) {
+ for (SlotState.@NonNull Incremental writeSlot : writeSlots) {
+ writeSlot.revokeAssigned();
+ }
+ }
+ interval.queue(this);
+ }
+
+ @Override
+ public void revokeInvocation() {
+ if (writeSlots != null) {
+ for (SlotState.@NonNull Incremental writeSlot : writeSlots) {
+ writeSlot.revokeAssigned();
+ }
+ }
+ interval.queue(this);
+ }
+
+ @Override
public @NonNull String toString() {
return getName();
}
diff --git a/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/evaluation/AbstractSlotState.java b/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/evaluation/AbstractSlotState.java
index 33ed9e9a5..8668c73e1 100644
--- a/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/evaluation/AbstractSlotState.java
+++ b/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/evaluation/AbstractSlotState.java
@@ -58,6 +58,12 @@ public abstract class AbstractSlotState implements SlotState
public @NonNull Iterable<Execution.@NonNull Incremental> getTargets() {
return targets != null ? targets : EMPTY_EXECUTIONS_LIST;
}
+
+ protected void revokeTargets() {
+ for (Execution.@NonNull Incremental target : getTargets()) {
+ target.revokeExecution();
+ }
+ }
}
@Override
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 ba36c8104..2133f0555 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
@@ -41,6 +41,16 @@ public interface Connection extends ExecutionVisitable, Nameable
@NonNull Iterable<@NonNull InvocationConstructor> getAppenders();
/**
+ * Remove, inverse append, the old anElement.
+ *
+ * If the old value is a multiple value in a unique value connection, the multi-value count is decremented.
+ *
+ * Otherwise the old value is removed, its consumingInvocations are revoked
+ * so that their appends are also revoked.
+ */
+ void removeElement(@NonNull Object anElement);
+
+ /**
* Replace the old value at connectionKey by newValue.
*
* If the old value is a multiple value in a unique value connection, the multi-value count is decremented
@@ -67,12 +77,12 @@ public interface Connection extends ExecutionVisitable, Nameable
boolean addConsumer(@NonNull InvocationConstructor consumingInvoker);
/**
- * Append aValue to the contents, enforcing uniqueness if necessary, and waking up the overall
+ * Append anElement to the contents, enforcing uniqueness if necessary, and waking up the overall
* connection manager to schedule a propagate() to consumers when convenient.
*
* Return the new entry.
*/
- @NonNull Object append(@NonNull Object aValue);
+ @NonNull Object appendElement(@NonNull Object anElement);
int getCapacity();
diff --git a/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/evaluation/Execution.java b/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/evaluation/Execution.java
index 413b5b772..4263778af 100644
--- a/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/evaluation/Execution.java
+++ b/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/evaluation/Execution.java
@@ -15,7 +15,7 @@ import org.eclipse.ocl.pivot.utilities.Nameable;
/**
* An Execution identifies a unique execution and the objects/values that it uses.
- * Derived EXecutions support Mapping Invocations and unique Function Computations
+ * Derived Executions support Mapping Invocations and unique Function Computations
*
* @noimplement clients should derive from AbstractInvocation
*/
@@ -25,7 +25,20 @@ public interface Execution extends ExecutionVisitable, Nameable
{
void addReadSlot(SlotState.@NonNull Incremental readSlot);
@NonNull Iterable<@NonNull Object> getCreatedObjects();
- @Override
- @NonNull String getName();
+
+ /**
+ * Revoke the consequences of a previous execution in preparation for a new execution.
+ * This reverts all assigned slot states back to REASSIGNABLE.
+ */
+ void revokeExecution();
+
+ /**
+ * Revoke the consequences of a previous execution that will not be re-executed.
+ * All created objects are revoked.
+ */
+ void revokeInvocation();
}
+
+ @Override
+ @NonNull String getName();
} \ No newline at end of file
diff --git a/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/evaluation/SlotState.java b/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/evaluation/SlotState.java
index 7668dca99..b6af059d3 100644
--- a/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/evaluation/SlotState.java
+++ b/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/evaluation/SlotState.java
@@ -49,5 +49,6 @@ public interface SlotState extends ExecutionVisitable
@Nullable Object getValue();
@NonNull Iterable<Invocation.@NonNull Incremental> getSources();
@NonNull Iterable<Execution.@NonNull Incremental> getTargets();
+ void revokeAssigned();
}
}
diff --git a/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/evaluation/StrictIncrementalConnection.java b/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/evaluation/StrictIncrementalConnection.java
index 9b2eafd17..ca62a88c9 100644
--- a/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/evaluation/StrictIncrementalConnection.java
+++ b/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/evaluation/StrictIncrementalConnection.java
@@ -10,6 +10,8 @@
*******************************************************************************/
package org.eclipse.qvtd.runtime.evaluation;
+import java.util.List;
+
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.ocl.pivot.ids.TypeId;
import org.eclipse.qvtd.runtime.internal.evaluation.StrictIncrementalConnectionInternal;
@@ -28,4 +30,31 @@ public class StrictIncrementalConnection extends StrictIncrementalConnectionInte
public StrictIncrementalConnection(@NonNull Interval interval, @NonNull String name, @NonNull TypeId typeId) {
super(interval, name, typeId);
}
+
+ /**
+ * Remove, inverse append, the old anElement. The old value is removed,
+ * its consumingInvocations are revoked so that their appends are also revoked.
+ */
+ @Override
+ public synchronized void removeElement(@NonNull Object anElement) {
+ for (int i = 0; i < listOfValueAndConsumingInvocations.size(); i++) {
+ List<@NonNull Object> valueAndConsumingInvocations = listOfValueAndConsumingInvocations.get(i);
+ if ((valueAndConsumingInvocations != null) && (valueAndConsumingInvocations.get(VALUE_INDEX) == anElement)) {
+ Integer count = (Integer) valueAndConsumingInvocations.get(COUNT_INDEX);
+ assert count != null;
+ if (count <= 0) {
+ listOfValueAndConsumingInvocations.set(i, null);
+ int jMax = valueAndConsumingInvocations.size();
+ for (int j = INDEX_INDEX+1; j < jMax; j++) {
+ AbstractInvocation.Incremental consumingInvocation = (AbstractInvocation.Incremental) valueAndConsumingInvocations.get(j);
+ consumingInvocation.revokeExecution();
+ }
+ }
+ else {
+ valueAndConsumingInvocations.set(COUNT_INDEX, count-1);
+ }
+ break;
+ }
+ }
+ }
} \ No newline at end of file
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 ac67c953c..514c509e8 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
@@ -45,17 +45,17 @@ public abstract class AbstractConnectionInternal extends AbstractConnection
public void addAppender(@NonNull InvocationConstructor appendingInvoker) {}
/**
- * Append aValue to the contents, and waking up the overall
+ * Append anElement to the contents, and waking up the overall
* connection manager to schedule a propagate() to consumers when convenient.
*/
@Override
- public synchronized @NonNull Object append(@NonNull Object aValue) {
+ public synchronized @NonNull Object appendElement(@NonNull Object anElement) {
if (debugAppends) {
- AbstractTransformer.APPENDS.println(this + " <= " + LabelUtil.getLabel(aValue));
+ AbstractTransformer.APPENDS.println(this + " <= " + LabelUtil.getLabel(anElement));
}
- values.add(aValue);
+ values.add(anElement);
queue();
- return aValue;
+ return anElement;
}
@Override
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 6ac99e2ad..1dbb171cb 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
@@ -54,10 +54,6 @@ public abstract class AbstractInvocationInternal implements Invocation
next = this;
}
- public void revoke() {
- throw new UnsupportedOperationException();
- }
-
@Override
public String toString() {
return getClass().getSimpleName() + "@" + Integer.toHexString(System.identityHashCode(this));
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 64bdaf9ea..a025651cf 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
@@ -67,6 +67,11 @@ public abstract class AbstractTransformerInternal /*extends AbstractModelManager
}
@Override
+ protected @NonNull Connection createConnection(@NonNull String name, @NonNull TypeId typeId, boolean isStrict) {
+ return invocationManager.getRootInterval().createIncrementalConnection(name, typeId, isStrict);
+ }
+
+ @Override
protected @NonNull InvocationManager createInvocationManager() {
return new IncrementalInvocationManager(executor);
}
@@ -74,7 +79,7 @@ public abstract class AbstractTransformerInternal /*extends AbstractModelManager
@Override
protected @NonNull Model createModel(@NonNull String modelName, @NonNull PropertyId @Nullable [] propertyIndex2propertyId,
@NonNull ClassId @NonNull [] classIndex2classId, int @Nullable [] @NonNull [] classIndex2allClassIndexes) {
- return new Model(modelName, propertyIndex2propertyId, classIndex2classId, classIndex2allClassIndexes);
+ return new Model.Incremental(this, modelName, propertyIndex2propertyId, classIndex2classId, classIndex2allClassIndexes);
}
@Override
@@ -86,13 +91,13 @@ public abstract class AbstractTransformerInternal /*extends AbstractModelManager
private static final @NonNull List<@NonNull Integer> EMPTY_INDEX_LIST = Collections.emptyList();
private static final @NonNull List<@NonNull Object> EMPTY_EOBJECT_LIST = Collections.emptyList();
- protected class Model extends AbstractTypedModelInstance
+ public static class Model extends AbstractTypedModelInstance
{
- protected class Incremental extends Model
+ public static class Incremental extends Model
{
- public Incremental(@NonNull String name, @NonNull PropertyId @Nullable [] propertyIndex2propertyId,
+ public Incremental(@NonNull AbstractTransformerInternal transformer, @NonNull String name, @NonNull PropertyId @Nullable [] propertyIndex2propertyId,
@NonNull ClassId @NonNull [] classIndex2classId, int @Nullable [] @NonNull [] classIndex2allClassIndexes) {
- super(name, propertyIndex2propertyId, classIndex2classId, classIndex2allClassIndexes);
+ super(transformer, name, propertyIndex2propertyId, classIndex2classId, classIndex2allClassIndexes);
}
public void remove(@NonNull EObject eObject) {
@@ -122,12 +127,12 @@ public abstract class AbstractTransformerInternal /*extends AbstractModelManager
private void unaccumulateEObject(@Nullable Map<@NonNull EClass, @NonNull Set<@NonNull Integer>> eClass2allClassIndexes,
@Nullable Map<@NonNull EClass, @NonNull List<@NonNull Integer>> eClass2allPropertyIndexes, @Nullable Map<@NonNull EReference, @NonNull Integer> eReference2propertyIndex,
@NonNull Object eObject) {
- EClass eClass = eClass(eObject);
+ EClass eClass = transformer.eClass(eObject);
if (eClass2allClassIndexes != null) {
Set<@NonNull Integer> allClassIndexes = eClass2allClassIndexes.get(eClass);
if (allClassIndexes != null) {
for (@NonNull Integer classIndex : allClassIndexes) {
- ((Connection.Incremental)classIndex2connection[classIndex]).revoke(eObject);
+ ((Connection.Incremental)classIndex2connection[classIndex]).removeElement(eObject);
}
}
}
@@ -136,14 +141,14 @@ public abstract class AbstractTransformerInternal /*extends AbstractModelManager
assert eReference2propertyIndex2 != null;
List<@NonNull Integer> allPropertyIndexes = eClass2allPropertyIndexes.get(eClass);
if (allPropertyIndexes != null) {
- Map<@NonNull Object, @NonNull Object>[] object2oppositeObject2 = object2oppositeObject;
+ Map<@NonNull Object, @NonNull Object>[] object2oppositeObject2 = transformer.object2oppositeObject;
assert object2oppositeObject2 != null;
for (@NonNull Integer propertyIndex : allPropertyIndexes) {
- EReference @Nullable [] propertyIndex2eReference2 = propertyIndex2eReference;
+ EReference @Nullable [] propertyIndex2eReference2 = transformer.propertyIndex2eReference;
assert propertyIndex2eReference2 != null;
EReference eReference = propertyIndex2eReference2[propertyIndex];
if (eReference != null) {
- Object object = eGet(eObject, eReference);
+ Object object = transformer.eGet(eObject, eReference);
assert object != null;
object2oppositeObject2[propertyIndex].remove(object);
}
@@ -153,18 +158,20 @@ public abstract class AbstractTransformerInternal /*extends AbstractModelManager
}
}
+ protected final @NonNull AbstractTransformerInternal transformer;
protected final @NonNull String name;
- private @Nullable List<@NonNull Object> allEObjects = null;
+ protected @Nullable List<@NonNull Object> allEObjects = null;
private @Nullable List<@NonNull Object> rootEObjects = null;
- private final @NonNull Map<@NonNull EClass, @NonNull Set<@NonNull Integer>> eClass2allClassIndexes = new HashMap<>();
+ protected final @NonNull Map<@NonNull EClass, @NonNull Set<@NonNull Integer>> eClass2allClassIndexes = new HashMap<>();
/**
* All possible allInstances() returns indexed by the ClassIndex of the ClassId for which allInstances() may be invoked.
*/
- private final @NonNull Connection [] classIndex2connection;
+ protected final @NonNull Connection [] classIndex2connection;
- public Model(@NonNull String name, @NonNull PropertyId @Nullable [] propertyIndex2propertyId,
+ public Model(@NonNull AbstractTransformerInternal transformer, @NonNull String name, @NonNull PropertyId @Nullable [] propertyIndex2propertyId,
@NonNull ClassId @NonNull [] classIndex2classId, int @Nullable [] @NonNull [] classIndex2allClassIndexes) {
+ this.transformer = transformer;
this.name = name;
//
// Prepare the allInstances() fields
@@ -174,7 +181,7 @@ public abstract class AbstractTransformerInternal /*extends AbstractModelManager
for (int i = 0; i < classIds; i++) {
@NonNull
ClassId classId = classIndex2classId[i];
- classIndex2connection[i] = createConnection(name + "-" + classId, classId, false);
+ classIndex2connection[i] = transformer.createConnection(name + "-" + classId, classId, false);
}
}
@@ -185,11 +192,11 @@ public abstract class AbstractTransformerInternal /*extends AbstractModelManager
private void accumulateEObject1(@NonNull Object eObject, @NonNull EClass eClass) {
Set<@NonNull Integer> allClassIndexes = eClass2allClassIndexes.get(eClass);
if (allClassIndexes == null) {
- allClassIndexes = getClassIndexes(eClass);
+ allClassIndexes = transformer.getClassIndexes(eClass);
eClass2allClassIndexes.put(eClass, allClassIndexes);
}
for (@NonNull Integer classIndex : allClassIndexes) {
- classIndex2connection[classIndex].append(eObject);
+ classIndex2connection[classIndex].appendElement(eObject);
}
}
@@ -206,24 +213,24 @@ public abstract class AbstractTransformerInternal /*extends AbstractModelManager
assert eReference2propertyIndex2 != null;
List<@NonNull Integer> allPropertyIndexes = eClass2allPropertyIndexes.get(eClass);
if (allPropertyIndexes == null) {
- allPropertyIndexes = getOppositePropertyIndexes(eReference2propertyIndex2, eClass);
+ allPropertyIndexes = transformer.getOppositePropertyIndexes(eReference2propertyIndex2, eClass);
eClass2allPropertyIndexes.put(eClass, allPropertyIndexes);
}
- Map<@NonNull Object, @NonNull Object>[] object2oppositeObject2 = object2oppositeObject;
+ Map<@NonNull Object, @NonNull Object>[] object2oppositeObject2 = transformer.object2oppositeObject;
assert object2oppositeObject2 != null;
for (@NonNull Integer propertyIndex : allPropertyIndexes) {
- EReference @Nullable [] propertyIndex2eReference2 = propertyIndex2eReference;
+ EReference @Nullable [] propertyIndex2eReference2 = transformer.propertyIndex2eReference;
assert propertyIndex2eReference2 != null;
EReference eReference = propertyIndex2eReference2[propertyIndex];
if (eReference == null) {
- PropertyId @Nullable [] propertyIndex2propertyId2 = propertyIndex2propertyId;
+ PropertyId @Nullable [] propertyIndex2propertyId2 = transformer.propertyIndex2propertyId;
assert propertyIndex2propertyId2 != null;
PropertyId propertyId = propertyIndex2propertyId2[propertyIndex];
assert propertyId != null;
eReference = (EReference) NameUtil.getENamedElement(eClass.getEAllStructuralFeatures(), propertyId.getName());
assert eReference != null;
}
- Object object = eGet(eObject, eReference);
+ Object object = transformer.eGet(eObject, eReference);
assert object != null;
object2oppositeObject2[propertyIndex].put(object, eObject);
}
@@ -237,7 +244,7 @@ public abstract class AbstractTransformerInternal /*extends AbstractModelManager
rootEObjects = null;
assert !allEObjects2.contains(eObject);
allEObjects2.add(eObject);
- EClass eClass = eClass(eObject);
+ EClass eClass = transformer.eClass(eObject);
accumulateEObject1(eObject, eClass);
}
@@ -252,7 +259,7 @@ public abstract class AbstractTransformerInternal /*extends AbstractModelManager
allEObjects = null;
Map<@NonNull EClass, @NonNull List<@NonNull Integer>> eClass2allPropertyIndexes = null;
Map<@NonNull EReference, @NonNull Integer> eReference2propertyIndex = null;
- if (propertyIndex2propertyId != null) {
+ if (transformer.propertyIndex2propertyId != null) {
eClass2allPropertyIndexes = new HashMap<>();
eReference2propertyIndex = new HashMap<>();
}
@@ -264,15 +271,15 @@ public abstract class AbstractTransformerInternal /*extends AbstractModelManager
//
// Accumulate the root object and all its child objects in the allInstances() returns
//
- EClass eRootClass = eClass(eRootObject);
+ EClass eRootClass = transformer.eClass(eRootObject);
accumulateEObject1(eRootObject, eRootClass);
if (eClass2allPropertyIndexes != null) {
accumulateEObject2(eRootObject, eRootClass, eClass2allPropertyIndexes, eReference2propertyIndex);
}
- for (TreeIterator<? extends Object> tit = eAllContents(eRootObject); tit.hasNext(); ) {
+ for (TreeIterator<? extends Object> tit = transformer.eAllContents(eRootObject); tit.hasNext(); ) {
Object eObject = tit.next();
if (eObject != null) {
- EClass eClass = eClass(eObject);
+ EClass eClass = transformer.eClass(eObject);
accumulateEObject1(eObject, eClass);
if (eClass2allPropertyIndexes != null) {
accumulateEObject2(eObject, eClass, eClass2allPropertyIndexes, eReference2propertyIndex);
@@ -292,7 +299,7 @@ public abstract class AbstractTransformerInternal /*extends AbstractModelManager
for (@NonNull Object eRootObject : rootEObjects2) {
assert !allEObjects2.contains(eRootObject);
allEObjects2.add(eRootObject);
- for (TreeIterator<? extends Object> tit = eAllContents(eRootObject); tit.hasNext(); ) {
+ for (TreeIterator<? extends Object> tit = transformer.eAllContents(eRootObject); tit.hasNext(); ) {
Object eObject = tit.next();
if (eObject != null) {
assert !allEObjects2.contains(eObject);
@@ -312,7 +319,7 @@ public abstract class AbstractTransformerInternal /*extends AbstractModelManager
@Override
public @NonNull Iterable<@NonNull Object> getObjectsOfKind(org.eclipse.ocl.pivot.@NonNull Class type) {
TypeId classId = type.getTypeId();
- Integer classIndex = classId2classIndex.get(classId);
+ Integer classIndex = transformer.classId2classIndex.get(classId);
if (classIndex != null) {
Iterable<@NonNull Object> typedIterable = classIndex2connection[classIndex].typedIterable(Object.class);
// List<@NonNull Object> collection = new ArrayList<>();
@@ -360,7 +367,7 @@ public abstract class AbstractTransformerInternal /*extends AbstractModelManager
List<@NonNull Object> allEObjects2 = allEObjects;
if (allEObjects2 != null) {
for (@NonNull Object eObject : allEObjects2) {
- if (eContainer(eObject) == null) {
+ if (transformer.eContainer(eObject) == null) {
rootEObjects2.add(eObject);
}
}
@@ -383,7 +390,7 @@ public abstract class AbstractTransformerInternal /*extends AbstractModelManager
public <@NonNull T> Iterable<T> typedIterable(Class<T> javaClass, org.eclipse.ocl.pivot.@NonNull Class pivotType) {
TypeId typeId = pivotType.getTypeId();
- Integer classIndex = classId2classIndex.get(typeId);
+ Integer classIndex = transformer.classId2classIndex.get(typeId);
if (classIndex != null) {
Connection connection = classIndex2connection[classIndex];
return connection.typedIterable(javaClass);
@@ -559,7 +566,7 @@ public abstract class AbstractTransformerInternal /*extends AbstractModelManager
protected @NonNull Model createModel(@NonNull String modelName, @NonNull PropertyId @Nullable [] propertyIndex2propertyId,
@NonNull ClassId @NonNull [] classIndex2classId, int @Nullable [] @NonNull [] classIndex2allClassIndexes) {
- return new Model(modelName, propertyIndex2propertyId, classIndex2classId, classIndex2allClassIndexes);
+ return new Model(this, modelName, propertyIndex2propertyId, classIndex2classId, classIndex2allClassIndexes);
}
@Deprecated // Use createConnection
diff --git a/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/internal/evaluation/IncrementalConnectionInternal.java b/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/internal/evaluation/IncrementalConnectionInternal.java
index b847fd50f..aaad51458 100644
--- a/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/internal/evaluation/IncrementalConnectionInternal.java
+++ b/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/internal/evaluation/IncrementalConnectionInternal.java
@@ -37,16 +37,16 @@ public class IncrementalConnectionInternal extends AbstractIncrementalConnection
}
/**
- * Append aValue to the contents, and waking up the overall
+ * Append anElement to the contents, and waking up the overall
* connection manager to schedule a propagate() to consumers when convenient.
*/
@Override
- public synchronized @NonNull Object append(@NonNull Object aValue) {
+ public synchronized @NonNull Object appendElement(@NonNull Object anElement) {
if (debugAppends) {
- AbstractTransformer.APPENDS.println(this + " <= " + LabelUtil.getLabel(aValue));
+ AbstractTransformer.APPENDS.println(this + " <= " + LabelUtil.getLabel(anElement));
}
List<@NonNull Object> valueAndConsumingInvocations = new ArrayList<>();
- valueAndConsumingInvocations.add(aValue); // VALUE_INDEX
+ valueAndConsumingInvocations.add(anElement); // VALUE_INDEX
valueAndConsumingInvocations.add(listOfValueAndConsumingInvocations.size()); // INDEX_INDEX
listOfValueAndConsumingInvocations.add(valueAndConsumingInvocations);
queue();
@@ -64,6 +64,26 @@ public class IncrementalConnectionInternal extends AbstractIncrementalConnection
}
/**
+ * Remove, inverse append, the old anElement. The old value is removed,
+ * its consumingInvocations are revoked so that their appends are also revoked.
+ */
+ @Override
+ public synchronized void removeElement(@NonNull Object anElement) {
+ for (int i = 0; i < listOfValueAndConsumingInvocations.size(); i++) {
+ List<@NonNull Object> valueAndConsumingInvocations = listOfValueAndConsumingInvocations.get(i);
+ if ((valueAndConsumingInvocations != null) && (valueAndConsumingInvocations.get(VALUE_INDEX) == anElement)) {
+ listOfValueAndConsumingInvocations.set(i, null);
+ int jMax = valueAndConsumingInvocations.size();
+ for (int j = INDEX_INDEX+1; j < jMax; j++) {
+ AbstractInvocation.Incremental consumingInvocation = (AbstractInvocation.Incremental) valueAndConsumingInvocations.get(j);
+ consumingInvocation.revokeExecution();
+ }
+ break;
+ }
+ }
+ }
+
+ /**
* Replace the old value at connectionKey by newValue.The old value is removed,
* its consumingInvocations are invalidated so that they recompute with the newValue which replaces the old.
*/
@@ -93,8 +113,8 @@ public class IncrementalConnectionInternal extends AbstractIncrementalConnection
listOfValueAndConsumingInvocations.set(valueIndex, null); // Do not disrupt index equivalence.
int iMax = valueAndConsumingInvocations.size();
for (int i = INDEX_INDEX+1; i < iMax; i++) {
- AbstractInvocation consumingInvocation = (AbstractInvocation) valueAndConsumingInvocations.get(i);
- consumingInvocation.revoke();
+ AbstractInvocation.Incremental consumingInvocation = (AbstractInvocation.Incremental) valueAndConsumingInvocations.get(i);
+ consumingInvocation.revokeExecution();
}
}
} \ 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 cbcd0dedd..f4a43b0e5 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
@@ -41,7 +41,8 @@ public class IncrementalObjectManager extends AbstractObjectManager
{
public enum SlotMode {
ASSIGNABLE, // No assignment has been performed, object reads are blocked (collections reads may be unblocked)
- ASSIGNED // Last assignment has been performed, reads are unblocked
+ ASSIGNED, // Last assignment has been performed, reads are unblocked
+ REASSIGNABLE, // No assignment has been performed by a re-execution, object reads are blocked (collections reads may be unblocked)
}
protected final @NonNull Object eObject;
@@ -69,12 +70,20 @@ public class IncrementalObjectManager extends AbstractObjectManager
case ASSIGNABLE:
mode = SlotMode.ASSIGNED;
unblock(objectManager);
+ this.value = ecoreValue;
break;
case ASSIGNED:
System.out.println("Re-assignment of " + eFeature.getEContainingClass().getName() + "::" + eFeature.getName() + " for " + eObject + " with " + ecoreValue);
break;
+ case REASSIGNABLE:
+ mode = SlotMode.ASSIGNED;
+ if (this.value != ecoreValue) { // FIXME equals() ??
+ this.value = ecoreValue;
+ revokeTargets();
+ }
+ unblock(objectManager);
+ break;
}
- this.value = ecoreValue;
}
@Override
@@ -115,6 +124,7 @@ public class IncrementalObjectManager extends AbstractObjectManager
public synchronized void getting( @NonNull Object eObject, @NonNull EStructuralFeature eFeature) {
switch (mode) {
case ASSIGNABLE:
+ case REASSIGNABLE:
throw new InvocationFailedException(this);
case ASSIGNED:
break;
@@ -126,6 +136,12 @@ public class IncrementalObjectManager extends AbstractObjectManager
}
@Override
+ public void revokeAssigned() {
+ assert isAssigned();
+ mode = SlotMode.REASSIGNABLE;
+ }
+
+ @Override
public String toString() {
return getClass().getSimpleName() + "@" + Integer.toHexString(System.identityHashCode(this)) + "[" + eFeature.getEContainingClass().getName() + "::" + eFeature.getName() + " for " + eObject + "]";
}
@@ -416,6 +432,7 @@ public class IncrementalObjectManager extends AbstractObjectManager
// super.assigned(objectManager, eContainer, eReference, eObject);
switch (mode) {
case ASSIGNABLE:
+ case REASSIGNABLE:
mode = SlotMode.ASSIGNED;
unblock(IncrementalObjectManager.this);
break;
@@ -428,6 +445,7 @@ public class IncrementalObjectManager extends AbstractObjectManager
public synchronized void getting(@NonNull Object eObject, @NonNull EStructuralFeature eFeature) {
switch (mode) {
case ASSIGNABLE:
+ case REASSIGNABLE:
mode = SlotMode.ASSIGNED;
unblock(IncrementalObjectManager.this);
break;
@@ -836,4 +854,11 @@ public class IncrementalObjectManager extends AbstractObjectManager
BasicSlotState slotState = getSlotState(eObject, eFeature);
execution.addReadSlot(slotState);
}
+
+ public void modified(@NonNull Object eObject, @NonNull EStructuralFeature eFeature) {
+ BasicSlotState slotState = getSlotState(eObject, eFeature);
+ for (Execution.@NonNull Incremental execution : slotState.getTargets()) {
+ execution.revokeExecution();
+ }
+ }
} \ No newline at end of file
diff --git a/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/internal/evaluation/ModificationMonitor.java b/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/internal/evaluation/ModificationMonitor.java
new file mode 100644
index 000000000..7b0274c3e
--- /dev/null
+++ b/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/internal/evaluation/ModificationMonitor.java
@@ -0,0 +1,104 @@
+package org.eclipse.qvtd.runtime.internal.evaluation;
+
+import java.util.List;
+
+import org.eclipse.emf.common.notify.Adapter;
+import org.eclipse.emf.common.notify.Notification;
+import org.eclipse.emf.common.notify.Notifier;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.jdt.annotation.Nullable;
+import org.eclipse.ocl.pivot.utilities.TreeIterable;
+import org.eclipse.qvtd.runtime.evaluation.TransformationExecutor;
+
+/**
+ * An adapter implementation for tracking resource modification.
+ */
+public class ModificationMonitor implements Adapter
+{
+ public static @Nullable ModificationMonitor basicGetModificationMonitor(@NonNull Resource resource, @NonNull TransformationExecutor executor) {
+ for (Adapter eAdapter : resource.eAdapters()) {
+ if (eAdapter instanceof ModificationMonitor) {
+ ModificationMonitor monitor = (ModificationMonitor)eAdapter;
+ if (monitor.getExecutor() == executor) {
+ return monitor;
+ }
+ }
+ }
+ return null;
+ }
+
+ public static @NonNull ModificationMonitor getModificationMonitor(@NonNull Resource resource, @NonNull TransformationExecutor executor) {
+ List<Adapter> eAdapters = resource.eAdapters();
+ for (Adapter eAdapter : eAdapters) {
+ if (eAdapter instanceof ModificationMonitor) {
+ ModificationMonitor monitor = (ModificationMonitor)eAdapter;
+ if (monitor.getExecutor() == executor) {
+ return monitor;
+ }
+ }
+ }
+ ModificationMonitor monitor = new ModificationMonitor(resource, executor);
+ for (@NonNull EObject eObject : new TreeIterable(resource)) {
+ eObject.eAdapters().add(monitor);
+ }
+ eAdapters.add(monitor);
+ return monitor;
+ }
+
+ private @NonNull Resource resource;
+ private @NonNull TransformationExecutor executor;
+
+ public ModificationMonitor(@NonNull Resource resource, @NonNull TransformationExecutor executor) {
+ this.resource = resource;
+ this.executor = executor;
+ }
+
+ public @NonNull TransformationExecutor getExecutor() {
+ return executor;
+ }
+
+ @Override
+ public @NonNull Resource getTarget() {
+ return resource;
+ }
+
+ @Override
+ public boolean isAdapterForType(Object type) {
+ return type == ModificationMonitor.class;
+ }
+
+ @Override
+ public void notifyChanged(Notification notification)
+ {
+ if (!notification.isTouch())
+ {
+ Object notifier = notification.getNotifier();
+ assert notifier != null;
+ IncrementalObjectManager objectManager = (IncrementalObjectManager) executor.getTransformer().getObjectManager();
+ switch (notification.getEventType()) {
+ case Notification.ADD:
+ case Notification.REMOVE: {
+ break;
+ }
+ case Notification.ADD_MANY:
+ case Notification.REMOVE_MANY: {
+ break;
+ }
+ case Notification.SET:
+ case Notification.UNSET: {
+ Object feature = notification.getFeature();
+ if (feature instanceof EStructuralFeature) {
+ objectManager.modified(notifier, (EStructuralFeature)feature);
+ }
+ break;
+ }
+ }
+ }
+ }
+
+ @Override
+ public void setTarget(Notifier newTarget) {}
+}
diff --git a/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/internal/evaluation/StrictConnectionInternal.java b/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/internal/evaluation/StrictConnectionInternal.java
index 131889241..19ed2944d 100644
--- a/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/internal/evaluation/StrictConnectionInternal.java
+++ b/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/internal/evaluation/StrictConnectionInternal.java
@@ -42,28 +42,28 @@ public abstract class StrictConnectionInternal extends AbstractConnectionInterna
* connection manager to schedule a propagate() to consumers when convenient.
*/
@Override
- public synchronized @NonNull Object append(@NonNull Object aValue) {
+ public synchronized @NonNull Object appendElement(@NonNull Object anElement) {
if (debugAppends) {
- AbstractTransformer.APPENDS.println(this + " <= " + LabelUtil.getLabel(aValue));
+ AbstractTransformer.APPENDS.println(this + " <= " + LabelUtil.getLabel(anElement));
}
if (uniqueValues != null) {
- if (!uniqueValues.add(aValue)) {
- return aValue;
+ if (!uniqueValues.add(anElement)) {
+ return anElement;
}
}
else if (values.size() < 10) {
for (@NonNull Object value : values) {
- if (value.equals(aValue)) { // FIXME ==/oclEquals
- return aValue;
+ if (value.equals(anElement)) { // FIXME ==/oclEquals
+ return anElement;
}
}
}
- else if (!createUniqueValues().add(aValue)) {
- return aValue;
+ else if (!createUniqueValues().add(anElement)) {
+ return anElement;
}
- values.add(aValue);
+ values.add(anElement);
queue();
- return aValue;
+ return anElement;
}
private @NonNull Set<@NonNull Object> createUniqueValues() {
diff --git a/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/internal/evaluation/StrictIncrementalConnectionInternal.java b/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/internal/evaluation/StrictIncrementalConnectionInternal.java
index 9eb2eef62..98ea08109 100644
--- a/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/internal/evaluation/StrictIncrementalConnectionInternal.java
+++ b/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/internal/evaluation/StrictIncrementalConnectionInternal.java
@@ -42,22 +42,22 @@ public abstract class StrictIncrementalConnectionInternal extends AbstractIncrem
}
/**
- * Append aValue to the contents, enforcing uniqueness if necessary, and waking up the overall
+ * Append anElement to the contents, enforcing uniqueness if necessary, and waking up the overall
* connection manager to schedule a propagate() to consumers when convenient.
*/
@Override
- public synchronized @NonNull Object append(@NonNull Object aValue) {
+ public synchronized @NonNull Object appendElement(@NonNull Object anElement) {
if (debugAppends) {
- AbstractTransformer.APPENDS.println(this + " <= " + LabelUtil.getLabel(aValue));
+ AbstractTransformer.APPENDS.println(this + " <= " + LabelUtil.getLabel(anElement));
}
- List<@NonNull Object> valueAndConsumingInvocations = uniqueValues2valueAndConsumingInvocations.get(aValue);
+ List<@NonNull Object> valueAndConsumingInvocations = uniqueValues2valueAndConsumingInvocations.get(anElement);
if (valueAndConsumingInvocations == null) {
valueAndConsumingInvocations = new ArrayList<>();
- valueAndConsumingInvocations.add(aValue); // VALUE_INDEX
+ valueAndConsumingInvocations.add(anElement); // VALUE_INDEX
valueAndConsumingInvocations.add(listOfValueAndConsumingInvocations.size()); // INDEX_INDEX
valueAndConsumingInvocations.add(1); // COUNT_INDEX
listOfValueAndConsumingInvocations.add(valueAndConsumingInvocations);
- uniqueValues2valueAndConsumingInvocations.put(aValue, valueAndConsumingInvocations);
+ uniqueValues2valueAndConsumingInvocations.put(anElement, valueAndConsumingInvocations);
queue();
}
else {
@@ -95,7 +95,7 @@ public abstract class StrictIncrementalConnectionInternal extends AbstractIncrem
Integer count = (Integer) valueAndConsumingInvocations.get(COUNT_INDEX);
if (count > 1) {
valueAndConsumingInvocations.set(COUNT_INDEX, count-1);
- return append(newValue);
+ return appendElement(newValue);
}
valueAndConsumingInvocations.set(VALUE_INDEX, newValue);
int iMax = valueAndConsumingInvocations.size();
@@ -127,8 +127,8 @@ public abstract class StrictIncrementalConnectionInternal extends AbstractIncrem
listOfValueAndConsumingInvocations.set(valueIndex, null); // Do not disrupt index equivalence.
int iMax = valueAndConsumingInvocations.size();
for (int i = COUNT_INDEX+1; i < iMax; i++) {
- AbstractInvocation consumingInvocation = (AbstractInvocation) valueAndConsumingInvocations.get(i);
- consumingInvocation.revoke();
+ AbstractInvocation.Incremental consumingInvocation = (AbstractInvocation.Incremental) valueAndConsumingInvocations.get(i);
+ consumingInvocation.revokeExecution();
}
}
} \ No newline at end of file
diff --git a/tests/org.eclipse.qvtd.compiler.tests/src/org/eclipse/qvtd/compiler/tests/RuntimeConnectionTests.java b/tests/org.eclipse.qvtd.compiler.tests/src/org/eclipse/qvtd/compiler/tests/RuntimeConnectionTests.java
index 245d97e49..0e2d45160 100644
--- a/tests/org.eclipse.qvtd.compiler.tests/src/org/eclipse/qvtd/compiler/tests/RuntimeConnectionTests.java
+++ b/tests/org.eclipse.qvtd.compiler.tests/src/org/eclipse/qvtd/compiler/tests/RuntimeConnectionTests.java
@@ -208,7 +208,7 @@ public class RuntimeConnectionTests extends TestCase
}
public void append() {
- append(counter++);
+ appendElement(counter++);
}
}
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 4f5579cff..91c95a62b 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
@@ -17,6 +17,8 @@ import java.util.Map;
import org.eclipse.emf.codegen.ecore.genmodel.GenModel;
import org.eclipse.emf.codegen.ecore.genmodel.GenModelPackage;
import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.EAttribute;
+import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
@@ -31,6 +33,7 @@ import org.eclipse.ocl.pivot.oclstdlib.OCLstdlibTables;
import org.eclipse.ocl.pivot.resource.ASResource;
import org.eclipse.ocl.pivot.resource.ProjectManager;
import org.eclipse.ocl.pivot.utilities.ClassUtil;
+import org.eclipse.ocl.pivot.utilities.TreeIterable;
import org.eclipse.ocl.pivot.validation.ComposedEValidator;
import org.eclipse.ocl.xtext.base.services.BaseLinkingService;
import org.eclipse.ocl.xtext.base.utilities.BaseCSResource;
@@ -45,15 +48,15 @@ import org.eclipse.qvtd.pivot.qvtimperative.QVTimperativePackage;
import org.eclipse.qvtd.pivot.qvtimperative.evaluation.Execution2GraphVisitor;
import org.eclipse.qvtd.pivot.qvtimperative.evaluation.QVTiEnvironmentFactory;
import org.eclipse.qvtd.pivot.qvtimperative.evaluation.QVTiTransformationExecutor;
+import org.eclipse.qvtd.runtime.evaluation.TransformationExecutor;
import org.eclipse.qvtd.runtime.evaluation.Transformer;
+import org.eclipse.qvtd.runtime.internal.evaluation.ModificationMonitor;
import org.eclipse.qvtd.xtext.qvtbase.tests.LoadTestCase;
import org.eclipse.qvtd.xtext.qvtbase.tests.ModelNormalizer;
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 org.eclipse.qvtd.xtext.qvtimperative.tests.Tree2TallTree.Tree2TallTreeInstallManual;
-import cg_qvtimperative_tests._hsv2hls.hsv2hls;
import junit.framework.TestCase;
/**
@@ -142,9 +145,10 @@ public class QVTiCompilerTests extends LoadTestCase
return (QVTiEnvironmentFactory) super.getEnvironmentFactory();
}
- public void loadInput(@NonNull Transformer tx, @NonNull String inputModelName, URI inputModelURI) {
+ public @NonNull Resource loadInput(@NonNull Transformer tx, @NonNull String inputModelName, URI inputModelURI) {
Resource inputResource = getResourceSet().getResource(inputModelURI, true);
tx.addRootObjects(inputModelName, ClassUtil.nonNullState(inputResource.getContents()));
+ return inputResource;
}
public @NonNull Transformation loadTransformation(@NonNull URI transformURI, @NonNull URI genModelURI) throws Exception {
@@ -233,7 +237,7 @@ public class QVTiCompilerTests extends LoadTestCase
myQVT.dispose();
}
- public void testCG_HSV2HLS_qvti2() throws Exception {
+ /* public void testCG_HSV2HLS_qvti2() throws Exception {
MyQVT myQVT = createQVT();
URI inputModelURI = getProjectFileURI("HSV2HLS/HSVNode.xmi");
URI outputModelURI = getProjectFileURI("HSV2HLS/HLSNode.xmi");
@@ -243,7 +247,7 @@ public class QVTiCompilerTests extends LoadTestCase
tx.run();
myQVT.saveOutput(tx, "hls", outputModelURI, referenceModelURI, null);
myQVT.dispose();
- }
+ } */
public void testCG_ClassesCS2AS_qvti() throws Exception {
MyQVT myQVT = createQVT();
@@ -327,52 +331,88 @@ public class QVTiCompilerTests extends LoadTestCase
URI transformURI = getProjectFileURI("Tree2TallTree/Tree2TallTree.qvti");
URI inputModelURI = getProjectFileURI("Tree2TallTree/Tree.xmi");
URI outputModelURI = getProjectFileURI("Tree2TallTree/Tree2TallTree.xmi");
+ URI outputModelURI2 = getProjectFileURI("Tree2TallTree/Tree2TallTree2.xmi");
URI referenceModelURI = getProjectFileURI("Tree2TallTree/TallTreeValidate.xmi");
+ URI referenceModelURI2 = getProjectFileURI("Tree2TallTree/TallTreeValidate2.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);
+ Resource inputResource = myQVT.loadInput(tx, "tree", inputModelURI);
tx.run();
+ Execution2GraphVisitor.writeGraphMLfile(tx, getProjectFileURI("Tree2TallTree/Tree2TallTree-inc.graphml"));
myQVT.saveOutput(tx, "talltree", outputModelURI, referenceModelURI, null);
+ TransformationExecutor executor = tx.getExecutor();
+ @SuppressWarnings("unused") ModificationMonitor monitor = ModificationMonitor.getModificationMonitor(inputResource, executor);
+ int gotOne = 0;
+ for (EObject eObject : new TreeIterable(inputResource)) {
+ EClass eClass = eObject.eClass();
+ if ("Node".equals(eClass.getName())) {
+ EAttribute nameAttribute = (EAttribute) eClass.getEStructuralFeature("name");
+ Object name = eObject.eGet(nameAttribute);
+ if ("n1.1".equals(name)) {
+ gotOne++;
+ eObject.eSet(nameAttribute, "x1.1");
+ }
+ }
+ }
+ assert gotOne == 1;
+ executor.getTransformer().getInvocationManager().flush();
+ Execution2GraphVisitor.writeGraphMLfile(tx, getProjectFileURI("Tree2TallTree/Tree2TallTree-inc2.graphml"));
+ myQVT.saveOutput(tx, "talltree", outputModelURI2, referenceModelURI2, null);
myQVT.dispose();
}
- public void testCG_Tree2TallTreeInstall_qvti() throws Exception {
+ /* public void testCG_Tree2TallTree_Incremental_qvti2() throws Exception {
// AbstractTransformer.INVOCATIONS.setState(true);
MyQVT myQVT = createQVT();
URI genModelURI = getProjectFileURI("Tree2TallTree/Tree2TallTree.genmodel");
- URI transformURI = getProjectFileURI("Tree2TallTree/Tree2TallTreeInstall.qvti");
-
+ URI transformURI = getProjectFileURI("Tree2TallTree/Tree2TallTree.qvti");
URI inputModelURI = getProjectFileURI("Tree2TallTree/Tree.xmi");
URI outputModelURI = getProjectFileURI("Tree2TallTree/Tree2TallTree.xmi");
+ URI outputModelURI2 = getProjectFileURI("Tree2TallTree/Tree2TallTree2.xmi");
URI referenceModelURI = getProjectFileURI("Tree2TallTree/TallTreeValidate.xmi");
- Transformation asTransformation = myQVT.loadTransformation(transformURI, genModelURI);
- Class<? extends Transformer> txClass = myQVT.generateCode(asTransformation, true);
+ URI referenceModelURI2 = getProjectFileURI("Tree2TallTree/TallTreeValidate2.xmi");
+ Class<? extends Transformer> txClass = Tree2TallTree.class;
Transformer tx = myQVT.createTransformer(txClass);
- myQVT.loadInput(tx, "tree", inputModelURI);
+ Resource inputResource = myQVT.loadInput(tx, "tree", inputModelURI);
tx.run();
+ Execution2GraphVisitor.writeGraphMLfile(tx, getProjectFileURI("Tree2TallTree/Tree2TallTree-inc.graphml"));
myQVT.saveOutput(tx, "talltree", outputModelURI, referenceModelURI, null);
+ TransformationExecutor executor = tx.getExecutor();
+ ModificationMonitor monitor = ModificationMonitor.getModificationMonitor(inputResource, executor);
+ int gotOne = 0;
+ for (EObject eObject : new TreeIterable(inputResource)) {
+ EClass eClass = eObject.eClass();
+ if ("Node".equals(eClass.getName())) {
+ EAttribute nameAttribute = (EAttribute) eClass.getEStructuralFeature("name");
+ Object name = eObject.eGet(nameAttribute);
+ if ("n1.1".equals(name)) {
+ gotOne++;
+ eObject.eSet(nameAttribute, "x1.1");
+ }
+ }
+ }
+ assert gotOne == 1;
+ executor.getTransformer().getInvocationManager().flush();
+ Execution2GraphVisitor.writeGraphMLfile(tx, getProjectFileURI("Tree2TallTree/Tree2TallTree-inc2.graphml"));
+ myQVT.saveOutput(tx, "talltree", outputModelURI2, referenceModelURI2, null);
myQVT.dispose();
- }
+ } */
- public void testCG_Tree2TallTreeInstallManual_qvti() throws Exception {
- // AbstractTransformer.APPENDS.setState(true);
- // AbstractTransformer.CONSUMES.setState(true);
- // AbstractTransformer.EXCEPTIONS.setState(true);
+ 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 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;
+ 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();
- 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/RuntimeConnectionTests.java b/tests/org.eclipse.qvtd.xtext.qvtimperative.tests/src/org/eclipse/qvtd/xtext/qvtimperative/tests/RuntimeConnectionTests.java
new file mode 100644
index 000000000..11aa0c7ab
--- /dev/null
+++ b/tests/org.eclipse.qvtd.xtext.qvtimperative.tests/src/org/eclipse/qvtd/xtext/qvtimperative/tests/RuntimeConnectionTests.java
@@ -0,0 +1,385 @@
+/*******************************************************************************
+ * 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.xtext.qvtimperative.tests;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.jdt.annotation.Nullable;
+import org.eclipse.ocl.pivot.evaluation.Executor;
+import org.eclipse.ocl.pivot.evaluation.ModelManager;
+import org.eclipse.ocl.pivot.ids.TypeId;
+import org.eclipse.ocl.pivot.internal.evaluation.AbstractExecutor;
+import org.eclipse.ocl.pivot.internal.utilities.EnvironmentFactoryInternal.EnvironmentFactoryInternalExtension;
+import org.eclipse.ocl.pivot.utilities.EnvironmentFactory;
+import org.eclipse.ocl.pivot.utilities.OCL;
+import org.eclipse.qvtd.pivot.qvtimperative.evaluation.AbstractInterpretedInvocation;
+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.SimpleConnection;
+import org.eclipse.qvtd.runtime.internal.evaluation.AbstractInvocationConstructor;
+import org.eclipse.qvtd.runtime.internal.evaluation.AbstractInvocationManagerInternal;
+import org.junit.Test;
+
+import junit.framework.TestCase;
+
+
+public class RuntimeConnectionTests extends TestCase
+{
+ public static final class Tester
+ {
+ protected final @NonNull OCL ocl;
+ protected final @NonNull TestExecutor executor;
+ protected final @NonNull TestInvocationManager invocationManager;
+ protected final @NonNull TestInvocationConstructor invocationConstructor;
+ protected final @NonNull List<@NonNull TestConnection> testConnections = new ArrayList<>();
+
+ public Tester() {
+ ocl = OCL.newInstance();
+ executor = new TestExecutor(ocl.getEnvironmentFactory());
+ invocationManager = new TestInvocationManager(executor);
+ invocationConstructor = new TestInvocationConstructor(invocationManager, "name", false);
+ }
+
+ public void addConsumedConnection(@NonNull TestConnection testConnection) {
+ invocationConstructor.addConsumedConnection(testConnection);
+ testConnections.add(testConnection);
+ }
+
+ public void check() {
+ StringBuilder s = new StringBuilder();
+ check(0, "9", s);
+ check(s.toString());
+ }
+
+ private void check(int connectionIndex, @NonNull String partialString, @NonNull StringBuilder s) {
+ if (connectionIndex < testConnections.size()) {
+ for (int i = 0; i < testConnections.get(connectionIndex).counter; i++) {
+ check(connectionIndex+1, partialString + i, s);
+ }
+ }
+ else {
+ if (s.length() > 0) {
+ s.append(",");
+ }
+ s.append(partialString);
+ }
+ }
+
+ public void check(@Nullable String stringValue) {
+ invocationManager.flush();
+ if (stringValue != null) {
+ assertEquals(stringValue, invocationConstructor.stringValue());
+ }
+ int product = 1;
+ for (@NonNull TestConnection testConnection : testConnections) {
+ product *= testConnection.counter;
+ }
+ TestCase.assertEquals(product, invocationConstructor.allValues.size());
+ @NonNull Object[] values = new @NonNull Object[testConnections.size()];
+ invocationConstructor.check(0, values, testConnections);
+ }
+
+ public @NonNull TestConnection createConsumedConnection() {
+ String name = "connection" + testConnections.size();
+ TestConnection testConnection = new TestConnection(invocationManager.getRootInterval(), name, TypeId.INTEGER);
+ addConsumedConnection(testConnection);
+ return testConnection;
+ }
+
+ public void dispose() {
+ ocl.dispose();
+ }
+
+ public @NonNull TestInvocationConstructor getInvocationConstructor() {
+ return invocationConstructor;
+ }
+ }
+
+ public static final class TestExecutor extends AbstractExecutor
+ {
+ public TestExecutor(@NonNull EnvironmentFactory environmentFactory) {
+ super((@NonNull EnvironmentFactoryInternalExtension) environmentFactory);
+ }
+
+ @Override
+ public @NonNull ModelManager getModelManager() {
+ throw new UnsupportedOperationException();
+ }
+ }
+
+ public static final class TestInvocationManager extends AbstractInvocationManagerInternal
+ {
+ public TestInvocationManager(@NonNull Executor executor) {
+ super(executor);
+ }
+ }
+
+ public static final class TestInvocationConstructor extends AbstractInvocationConstructor
+ {
+ protected final @NonNull Set<@NonNull Integer> allValues = new HashSet<>();
+
+ public TestInvocationConstructor(@NonNull InvocationManager invocationManager, @NonNull String name, boolean isStrict) {
+ super(invocationManager, name, isStrict);
+ }
+
+ public void executed(@NonNull Object @NonNull [] values) {
+ int intValue = compositeValue(values);
+ boolean wasAdded = allValues.add(intValue);
+ TestCase.assertTrue(wasAdded);
+ }
+
+ public void check(int consumerIndex, @NonNull Object @NonNull [] values, @NonNull List<@NonNull TestConnection> testConnections) {
+ if (consumerIndex >= testConnections.size()) {
+ int intValue = compositeValue(values);
+ TestCase.assertTrue(allValues.contains(intValue));
+ }
+ else {
+ for (int i = 0; i < testConnections.get(consumerIndex).counter; i++) {
+ values[consumerIndex] = i;
+ check(consumerIndex+1, values, testConnections);
+ }
+ }
+ }
+
+ private int compositeValue(@NonNull Object @NonNull [] values) {
+ int intValue = 9;
+ for (@NonNull Object value : values) {
+ intValue = 10 * intValue + ((Integer)value).intValue();
+ }
+ return intValue;
+ }
+
+ @Override
+ public @NonNull Invocation newInstance(@NonNull Object @NonNull [] values) {
+ return new TestInvocation(this, values);
+ }
+
+ public @NonNull String stringValue() {
+ List<@NonNull Integer> intValues = new ArrayList<>(allValues);
+ Collections.sort(intValues);
+ StringBuilder s = new StringBuilder();
+ for (int i = 0; i < intValues.size(); i++) {
+ if (i != 0) {
+ s.append(",");
+ }
+ s.append(intValues.get(i));
+ }
+ return s.toString();
+ }
+ }
+
+ public static final class TestInvocation extends AbstractInterpretedInvocation
+ {
+ protected final @NonNull TestInvocationConstructor invocationConstructor;
+
+ public TestInvocation(@NonNull TestInvocationConstructor invocationConstructor, @NonNull Object @NonNull [] values) {
+ super(invocationConstructor, values);
+ this.invocationConstructor = invocationConstructor;
+ }
+
+ @Override
+ public boolean execute() throws InvocationFailedException {
+ invocationConstructor.executed(values);
+ return false;
+ }
+ }
+
+ public static final class TestConnection extends SimpleConnection
+ {
+ private Integer counter = 0;
+
+ public TestConnection(@NonNull Interval interval, @NonNull String name, @NonNull TypeId typeId) {
+ super(interval, name, typeId);
+ }
+
+ public void append() {
+ appendElement(counter++);
+ }
+ }
+
+ @Test
+ public void testRuntime_DoubleSimpleConnection() {
+ Tester tester = new Tester();
+ TestConnection connection0 = tester.createConsumedConnection();
+ TestConnection connection1 = tester.createConsumedConnection();
+ //
+ tester.check("");
+ //
+ tester.check("");
+ //
+ connection0.append();
+ tester.check("");
+ //
+ connection1.append();
+ tester.check("900");
+ //
+ tester.check("900");
+ //
+ connection1.append();
+ tester.check("900,901");
+ //
+ connection1.append();
+ tester.check("900,901,902");
+ //
+ connection0.append();
+ tester.check("900,901,902,910,911,912");
+ //
+ connection1.append();
+ tester.check("900,901,902,903,910,911,912,913");
+ //
+ connection0.append();
+ connection0.append();
+ connection0.append();
+ tester.check();
+ //
+ connection1.append();
+ connection1.append();
+ tester.check();
+ //
+ tester.check();
+ //
+ tester.dispose();
+ }
+
+ @Test
+ public void testRuntime_RedundantDoubleSimpleConnection() {
+ Tester tester = new Tester();
+ TestConnection connection0 = tester.createConsumedConnection();
+ tester.addConsumedConnection(connection0);
+ //
+ tester.check("");
+ //
+ tester.check("");
+ //
+ connection0.append();
+ tester.check("900");
+ //
+ tester.check("900");
+ //
+ connection0.append();
+ tester.check("900,901,910,911");
+ //
+ connection0.append();
+ tester.check("900,901,902,910,911,912,920,921,922");
+ //
+ connection0.append();
+ tester.check();
+ //
+ connection0.append();
+ tester.check();
+ //
+ connection0.append();
+ connection0.append();
+ connection0.append();
+ tester.check();
+ //
+ connection0.append();
+ connection0.append();
+ tester.check();
+ //
+ tester.check();
+ //
+ tester.dispose();
+ }
+
+ @Test
+ public void testRuntime_SingleSimpleConnection() {
+ Tester tester = new Tester();
+ TestConnection connection0 = tester.createConsumedConnection();
+ //
+ tester.check("");
+ //
+ tester.check("");
+ //
+ connection0.append();
+ tester.check("90");
+ //
+ tester.check("90");
+ //
+ connection0.append();
+ connection0.append();
+ tester.check("90,91,92");
+ //
+ connection0.append();
+ tester.check("90,91,92,93");
+ //
+ connection0.append();
+ connection0.append();
+ connection0.append();
+ tester.check("90,91,92,93,94,95,96");
+ //
+ tester.check();
+ //
+ tester.dispose();
+ }
+
+ @Test
+ public void testRuntime_TripleSimpleConnection() {
+ Tester tester = new Tester();
+ TestConnection connection0 = tester.createConsumedConnection();
+ TestConnection connection1 = tester.createConsumedConnection();
+ TestConnection connection2 = tester.createConsumedConnection();
+ //
+ tester.check("");
+ //
+ tester.check("");
+ //
+ connection0.append();
+ tester.check("");
+ //
+ connection1.append();
+ tester.check("");
+ //
+ connection2.append();
+ tester.check("9000");
+ //
+ tester.check("9000");
+ //
+ connection1.append();
+ tester.check("9000,9010");
+ //
+ connection1.append();
+ tester.check("9000,9010,9020");
+ //
+ connection0.append();
+ tester.check("9000,9010,9020,9100,9110,9120");
+ //
+ connection2.append();
+ tester.check("9000,9001,9010,9011,9020,9021,9100,9101,9110,9111,9120,9121");
+ //
+ connection0.append();
+ connection1.append();
+ connection0.append();
+ tester.check();
+ //
+ connection1.append();
+ connection1.append();
+ tester.check();
+ //
+ connection2.append();
+ connection2.append();
+ tester.check();
+ //
+ connection0.append();
+ tester.check();
+ //
+ tester.check();
+ //
+ tester.dispose();
+ }
+}
diff --git a/tests/org.eclipse.qvtd.xtext.qvtimperative.tests/src/org/eclipse/qvtd/xtext/qvtimperative/tests/Tree2TallTree/TallTreeValidate2.xmi b/tests/org.eclipse.qvtd.xtext.qvtimperative.tests/src/org/eclipse/qvtd/xtext/qvtimperative/tests/Tree2TallTree/TallTreeValidate2.xmi
new file mode 100644
index 000000000..8f3351492
--- /dev/null
+++ b/tests/org.eclipse.qvtd.xtext.qvtimperative.tests/src/org/eclipse/qvtd/xtext/qvtimperative/tests/Tree2TallTree/TallTreeValidate2.xmi
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="ASCII"?>
+<talltree:TallNode
+ xmi:version="2.0"
+ xmlns:xmi="http://www.omg.org/XMI"
+ xmlns:talltree="http://www.eclipse.org/qvt/examples/0.1/TallTree"
+ xsi:schemaLocation="http://www.eclipse.org/qvt/examples/0.1/TallTree TallTree.ecore"
+ height="2"
+ name="n1">
+ <children
+ height="1"
+ name="x1.1">
+ <children
+ height="0"
+ name="n1.1.1"/>
+ </children>
+</talltree:TallNode>
diff --git a/tests/org.eclipse.qvtd.xtext.qvtimperative.tests/src/org/eclipse/qvtd/xtext/qvtimperative/tests/Tree2TallTree/Tree2TallTree.qvti b/tests/org.eclipse.qvtd.xtext.qvtimperative.tests/src/org/eclipse/qvtd/xtext/qvtimperative/tests/Tree2TallTree/Tree2TallTree.qvti
index 62ef003b6..e9e043b25 100644
--- a/tests/org.eclipse.qvtd.xtext.qvtimperative.tests/src/org/eclipse/qvtd/xtext/qvtimperative/tests/Tree2TallTree/Tree2TallTree.qvti
+++ b/tests/org.eclipse.qvtd.xtext.qvtimperative.tests/src/org/eclipse/qvtd/xtext/qvtimperative/tests/Tree2TallTree/Tree2TallTree.qvti
@@ -9,7 +9,8 @@ transformation Tree2TallTree {
}
map __root__ in Tree2TallTree {
- buffer nodes := tree.objectsOfKind(Node)->sortedBy(name);
+-- buffer nodes := tree.objectsOfKind(Node)->sortedBy(name);
+ buffer nodes := tree.objectsOfKind(Node);
for node : tree::Node in nodes {
call Node2MiddleNode {
node iterates node;
@@ -20,7 +21,8 @@ map __root__ in Tree2TallTree {
node iterates node;
}
}
- for node2tallNode : tree2talltree::Node2TallNode in tree2talltree.objectsOfKind(Node2TallNode)->sortedBy(name) {
+-- for node2tallNode : tree2talltree::Node2TallNode in tree2talltree.objectsOfKind(Node2TallNode)->sortedBy(name) {
+ for node2tallNode : tree2talltree::Node2TallNode in tree2talltree.objectsOfKind(Node2TallNode) {
call MiddleNode2TallNode {
node2tallNode iterates node2tallNode;
}
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
deleted file mode 100644
index 576b59e54..000000000
--- a/tests/org.eclipse.qvtd.xtext.qvtimperative.tests/src/org/eclipse/qvtd/xtext/qvtimperative/tests/Tree2TallTree/Tree2TallTreeInstallManual.java
+++ /dev/null
@@ -1,504 +0,0 @@
-/*******************************************************************************
- * «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.List;
-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.StandardLibrary;
-import org.eclipse.ocl.pivot.evaluation.Executor;
-import org.eclipse.ocl.pivot.ids.ClassId;
-import org.eclipse.ocl.pivot.ids.CollectionTypeId;
-import org.eclipse.ocl.pivot.ids.DataTypeId;
-import org.eclipse.ocl.pivot.ids.IdManager;
-import org.eclipse.ocl.pivot.ids.IdResolver;
-import org.eclipse.ocl.pivot.ids.NsURIPackageId;
-import org.eclipse.ocl.pivot.ids.RootPackageId;
-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.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*/ @NonNull RootPackageId PACKid_$metamodel$ = IdManager.getRootPackageId("$metamodel$");
- public static final /*@NonInvalid*/ @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*/ @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*/ @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*/ @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*/ @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*/ @NonNull ClassId CLSSid_Class = PACKid_$metamodel$.getClassId("Class", 0);
- public static final /*@NonInvalid*/ @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*/ @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*/ @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*/ @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*/ @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*/ @NonNull IntegerValue INT_0 = ValueUtil.integerValueOf("0");
- public static final /*@NonInvalid*/ @NonNull IntegerValue INT_1 = ValueUtil.integerValueOf("1");
- public static final /*@NonInvalid*/ @NonNull CollectionTypeId BAG_CLSSid_TallNode = TypeId.BAG.getSpecializedId(CLSSid_TallNode);
- public static final /*@NonInvalid*/ @NonNull CollectionTypeId BAG_DATAid_EInt = TypeId.BAG.getSpecializedId(DATAid_EInt);
- public static final /*@NonInvalid*/ @NonNull CollectionTypeId ORD_CLSSid_Node = TypeId.ORDERED_SET.getSpecializedId(CLSSid_Node);
- public static final /*@NonInvalid*/ @NonNull CollectionTypeId SEQ_CLSSid_Node2TallNode = TypeId.SEQUENCE.getSpecializedId(CLSSid_Node2TallNode);
- public static final /*@NonInvalid*/ @NonNull CollectionTypeId SET_CLSSid_Node = TypeId.SET.getSpecializedId(CLSSid_Node);
- public static final /*@NonInvalid*/ @NonNull CollectionTypeId SET_CLSSid_Node2TallNode = TypeId.SET.getSpecializedId(CLSSid_Node2TallNode);
- public static final /*@NonInvalid*/ @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 = new AbstractInvocationConstructor.Incremental(invocationManager, "__root__", false)
- {
- @Override
- public @NonNull MAP___root__ newInstance(@NonNull Object @NonNull [] values) {
- return new MAP___root__(this, values);
- }
- };
-
- protected final AbstractInvocationConstructor.@NonNull Incremental CTOR_Node2MiddleNode = new AbstractInvocationConstructor.Incremental(invocationManager, "Node2MiddleNode", false)
- {
- @Override
- public @NonNull MAP_Node2MiddleNode newInstance(@NonNull Object @NonNull [] values) {
- return new MAP_Node2MiddleNode(this, values);
- }
- };
-
- protected final AbstractInvocationConstructor.@NonNull Incremental CTOR_Edge2MiddleEdge = new AbstractInvocationConstructor.Incremental(invocationManager, "Edge2MiddleEdge", false)
- {
- @Override
- public @NonNull MAP_Edge2MiddleEdge newInstance(@NonNull Object @NonNull [] values) {
- return new MAP_Edge2MiddleEdge(this, values);
- }
- };
-
- protected final AbstractInvocationConstructor.@NonNull Incremental CTOR_MiddleNode2TallNode = new AbstractInvocationConstructor.Incremental(invocationManager, "MiddleNode2TallNode", false)
- {
- @Override
- public @NonNull MAP_MiddleNode2TallNode newInstance(@NonNull Object @NonNull [] values) {
- return new MAP_MiddleNode2TallNode(this, values);
- }
- };
-
- public Tree2TallTreeInstallManual(final @NonNull TransformationExecutor executor) {
- super(executor, new @NonNull String[] {"tree", "talltree", "tree2talltree"}, null, classIndex2classId, classIndex2allClassIndexes);
- }
-
- @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.invoke();
- // 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
- {
- public MAP___root__(InvocationConstructor.@NonNull Incremental constructor, @NonNull Object @NonNull [] boundValues) {
- super(constructor);
- }
-
- @Override
- public boolean execute() {
- try {
- final /*@NonInvalid*/ @NonNull IdResolver idResolver = executor.getIdResolver();
- final /*@NonInvalid*/ org.eclipse.ocl.pivot.@NonNull Class TYP_tree_c_c_Node_0 = idResolver.getClass(CLSSid_Node, null);
- final /*@NonInvalid*/ @NonNull StandardLibrary standardLibrary = idResolver.getStandardLibrary();
- // connection variables
- final @NonNull Connection nodes = createConnection("nodes", ORD_CLSSid_Node, false);
- final /*@NonInvalid*/ @NonNull SetValue objectsOfKind = ModelObjectsOfKindOperation.INSTANCE.evaluate(executor, SET_CLSSid_Node, models[0/*tree*/], TYP_tree_c_c_Node_0);
- final org.eclipse.ocl.pivot.@NonNull Class TYPE_sortedBy_0 = executor.getStaticTypeOf(objectsOfKind);
- final LibraryIteration.@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*/ @Nullable Object _1) {
- final /*@NonInvalid*/ @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*/ @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*/ @NonNull OrderedSetValue sortedBy = ClassUtil.nonNullState((OrderedSetValue)IMPL_sortedBy_0.evaluateIteration(MGR_sortedBy_0));
- for (@NonNull Node iterator : ValueUtil.typedIterable(Node.class, sortedBy)) {
- nodes.append(iterator);
- }
- final Connection.@NonNull Incremental node2tallNodes_1 = createIncrementalConnection("node2tallNodes_1", SEQ_CLSSid_Node2TallNode, false);
- // mapping statements
- CTOR_Node2MiddleNode.addConsumedConnection(nodes);
- CTOR_Node2MiddleNode.addAppendedConnection(node2tallNodes_1);
- CTOR_Edge2MiddleEdge.addConsumedConnection(nodes);
- CTOR_MiddleNode2TallNode.addConsumedConnection(node2tallNodes_1);
- final /*@Thrown*/ @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*/ @NonNull Node node;
- protected final @NonNull Connection node2tallNodes;
-
- public MAP_Node2MiddleNode(InvocationConstructor.@NonNull Incremental constructor, @NonNull Object @NonNull [] boundValues) {
- super(constructor);
- node = (Node)boundValues[0];
- node2tallNodes = (Connection)boundValues[1];
- }
-
- @Override
- public boolean execute() {
- try {
- // creations
- final /*@Thrown*/ @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*/ @NonNull String name = node.getName();
- objectManager.got(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*/ @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*/ @NonNull Node node_0;
-
- public MAP_Edge2MiddleEdge(InvocationConstructor.@NonNull Incremental constructor, @NonNull Object @NonNull [] boundValues) {
- super(constructor);
- node_0 = (Node)boundValues[0];
- }
-
- @Override
- public boolean execute() {
- try {
- final /*@Thrown*/ @NonNull Node2TallNode Node2TallNode = ClassUtil.nonNullState (OPPOSITE_OF_Node2TallNode_node.get(node_0));
- objectManager.got(this, node_0, Tree2talltreePackage.Literals.NODE2_TALL_NODE__NODE, Node2TallNode);
- final /*@Thrown*/ @Nullable Node parent = node_0.getParent();
- objectManager.got(this, node_0, TreePackage.Literals.NODE__PARENT, parent);
- final /*@Thrown*/ boolean ne = parent != null;
- /*@Thrown*/ @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*/ @NonNull Node2TallNode Node2TallNode_0 = ClassUtil.nonNullState (OPPOSITE_OF_Node2TallNode_node.get(parent));
- objectManager.got(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*/ @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*/ @NonNull Node2TallNode node2tallNode;
-
- public MAP_MiddleNode2TallNode(InvocationConstructor.@NonNull Incremental constructor, @NonNull Object @NonNull [] boundValues) {
- super(constructor);
- node2tallNode = (Node2TallNode)boundValues[0];
- }
-
- @Override
- public boolean execute() {
- try {
- final /*@NonInvalid*/ @NonNull IdResolver idResolver = executor.getIdResolver();
- @SuppressWarnings("null")
- final /*@Thrown*/ @NonNull String name = node2tallNode.getName();
- objectManager.got(this, node2tallNode, Tree2talltreePackage.Literals.NODE2_TALL_NODE__NAME, name);
- objectManager.getting(node2tallNode, Tree2talltreePackage.Literals.NODE2_TALL_NODE__CHILDREN, false);
- @SuppressWarnings("null")
- final /*@Thrown*/ @NonNull List<Node2TallNode> children_0 = node2tallNode.getChildren();
- objectManager.got(this, node2tallNode, Tree2talltreePackage.Literals.NODE2_TALL_NODE__CHILDREN, children_0);
- final /*@Thrown*/ @NonNull SetValue BOXED_children_0 = idResolver.createSetOfAll(SET_CLSSid_Node2TallNode, children_0);
- final /*@Thrown*/ @NonNull SetValue safe_collect_sources = (SetValue)CollectionExcludingOperation.INSTANCE.evaluate(BOXED_children_0, (Object)null);
- /*@Thrown*/ BagValue.@NonNull Accumulator accumulator = ValueUtil.createBagAccumulatorValue(BAG_CLSSid_TallNode);
- @NonNull Iterator<Object> ITERATOR__1 = safe_collect_sources.iterator();
- /*@Thrown*/ @NonNull BagValue collect;
- while (true) {
- if (!ITERATOR__1.hasNext()) {
- collect = accumulator;
- break;
- }
- @SuppressWarnings("null")
- /*@NonInvalid*/ @NonNull Node2TallNode _1 = (Node2TallNode)ITERATOR__1.next();
- /**
- * tallNode
- */
- objectManager.getting(_1, Tree2talltreePackage.Literals.NODE2_TALL_NODE__TALL_NODE, false);
- @SuppressWarnings("null")
- final /*@Thrown*/ @NonNull TallNode tallNode_0 = _1.getTallNode();
- objectManager.got(this, _1, Tree2talltreePackage.Literals.NODE2_TALL_NODE__TALL_NODE, tallNode_0);
- //
- accumulator.add(tallNode_0);
- }
- final /*@Thrown*/ @NonNull SetValue asSet = CollectionAsSetOperation.INSTANCE.evaluate(collect);
- final /*@Thrown*/ boolean notEmpty = CollectionNotEmptyOperation.INSTANCE.evaluate(BOXED_children_0).booleanValue();
- /*@Thrown*/ @NonNull IntegerValue symbol_0;
- if (notEmpty) {
- /*@Thrown*/ BagValue.@NonNull Accumulator accumulator_0 = ValueUtil.createBagAccumulatorValue(BAG_CLSSid_TallNode);
- @NonNull Iterator<Object> ITERATOR__1_0 = BOXED_children_0.iterator();
- /*@Thrown*/ @NonNull BagValue collect_1;
- while (true) {
- if (!ITERATOR__1_0.hasNext()) {
- collect_1 = accumulator_0;
- break;
- }
- @SuppressWarnings("null")
- /*@NonInvalid*/ @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*/ @NonNull TallNode tallNode_1 = _1_0.getTallNode();
- objectManager.got(this, _1_0, Tree2talltreePackage.Literals.NODE2_TALL_NODE__TALL_NODE, tallNode_1);
- //
- accumulator_0.add(tallNode_1);
- }
- /*@Thrown*/ BagValue.@NonNull Accumulator accumulator_1 = ValueUtil.createBagAccumulatorValue(BAG_DATAid_EInt);
- @NonNull Iterator<Object> ITERATOR__1_1 = collect_1.iterator();
- /*@Thrown*/ @NonNull BagValue collect_0;
- while (true) {
- if (!ITERATOR__1_1.hasNext()) {
- collect_0 = accumulator_1;
- break;
- }
- @SuppressWarnings("null")
- /*@NonInvalid*/ @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(this, _1_1, TalltreePackage.Literals.TALL_NODE__HEIGHT, height);
- final /*@Thrown*/ @NonNull IntegerValue BOXED_height = ValueUtil.integerValueOf(height);
- //
- accumulator_1.add(BOXED_height);
- }
- final /*@Thrown*/ @NonNull IntegerValue max = (IntegerValue)CollectionMaxOperation.INSTANCE.evaluate(collect_0);
- final /*@Thrown*/ @NonNull IntegerValue sum = (IntegerValue)NumericPlusOperation.INSTANCE.evaluate(max, INT_1);
- symbol_0 = sum;
- }
- else {
- symbol_0 = INT_0;
- }
- // creations
- final /*@Thrown*/ @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*/ @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*/ @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