Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEd Willink2016-12-12 20:12:44 +0000
committerEd Willink2016-12-20 21:48:41 +0000
commit7058469018fbf7794a34664d9e57d857353c494f (patch)
tree1d5f1280a0203da2c66d29ca3044ed9ecd102888
parenta683d2c73813087c92d40c7cadc377cc017cc3e9 (diff)
downloadorg.eclipse.qvtd-7058469018fbf7794a34664d9e57d857353c494f.tar.gz
org.eclipse.qvtd-7058469018fbf7794a34664d9e57d857353c494f.tar.xz
org.eclipse.qvtd-7058469018fbf7794a34664d9e57d857353c494f.zip
[500962] Support and test incremental for object add/delete
-rw-r--r--plugins/org.eclipse.qvtd.codegen/src/org/eclipse/qvtd/codegen/qvti/java/QVTiCG2JavaVisitor.java265
-rw-r--r--plugins/org.eclipse.qvtd.codegen/src/org/eclipse/qvtd/codegen/qvti/java/QVTiGlobalContext.java4
-rw-r--r--plugins/org.eclipse.qvtd.pivot.qvtimperative/src/org/eclipse/qvtd/pivot/qvtimperative/evaluation/EvaluationStatus2GraphVisitor.java232
-rw-r--r--plugins/org.eclipse.qvtd.pivot.qvtimperative/src/org/eclipse/qvtd/pivot/qvtimperative/evaluation/Execution2GraphVisitor.java28
-rw-r--r--plugins/org.eclipse.qvtd.pivot.qvtimperative/src/org/eclipse/qvtd/pivot/qvtimperative/evaluation/QVTiIncrementalExecutor.java22
-rw-r--r--plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/evaluation/AbstractComputation.java14
-rw-r--r--plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/evaluation/AbstractInvocation.java57
-rw-r--r--plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/evaluation/AbstractSlotState.java2
-rw-r--r--plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/evaluation/Connection.java4
-rw-r--r--plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/evaluation/Execution.java4
-rw-r--r--plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/evaluation/Invocation.java4
-rw-r--r--plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/evaluation/InvocationConstructor.java11
-rw-r--r--plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/evaluation/ObjectManager.java2
-rw-r--r--plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/evaluation/StrictIncrementalConnection.java22
-rw-r--r--plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/evaluation/Transformer.java1
-rw-r--r--plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/internal/evaluation/AbstractConnectionInternal.java5
-rw-r--r--plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/internal/evaluation/AbstractIncrementalConnectionInternal.java11
-rw-r--r--plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/internal/evaluation/AbstractIntervalInternal.java23
-rw-r--r--plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/internal/evaluation/AbstractInvocationConstructor.java101
-rw-r--r--plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/internal/evaluation/AbstractInvocationManagerInternal.java11
-rw-r--r--plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/internal/evaluation/AbstractTransformerInternal.java29
-rw-r--r--plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/internal/evaluation/IncrementalConnectionInternal.java31
-rw-r--r--plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/internal/evaluation/IncrementalObjectManager.java39
-rw-r--r--plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/internal/evaluation/LazyObjectManager.java55
-rw-r--r--plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/internal/evaluation/ModificationMonitor.java110
-rw-r--r--plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/internal/evaluation/StrictIncrementalConnectionInternal.java2
-rw-r--r--tests/org.eclipse.qvtd.xtext.qvtimperative.tests/.classpath1
-rw-r--r--tests/org.eclipse.qvtd.xtext.qvtimperative.tests/src/org/eclipse/qvtd/xtext/qvtimperative/tests/QVTiCompilerTests.java168
-rw-r--r--tests/org.eclipse.qvtd.xtext.qvtimperative.tests/src/org/eclipse/qvtd/xtext/qvtimperative/tests/QVTiInterpreterTests.java20
-rw-r--r--tests/org.eclipse.qvtd.xtext.qvtimperative.tests/src/org/eclipse/qvtd/xtext/qvtimperative/tests/Tree2TallTree/Tree2TallTree.qvti26
-rw-r--r--tests/org.eclipse.qvtd.xtext.qvtimperative.tests/src/org/eclipse/qvtd/xtext/qvtimperative/tests/Tree2TallTree/Tree2TallTreeInstall.qvti55
-rw-r--r--tests/org.eclipse.qvtd.xtext.qvtimperative.tests/src/org/eclipse/qvtd/xtext/qvtimperative/tests/Tree2TallTree/samples/TallTreeValidate.xmi (renamed from tests/org.eclipse.qvtd.xtext.qvtimperative.tests/src/org/eclipse/qvtd/xtext/qvtimperative/tests/Tree2TallTree/TallTreeValidate.xmi)32
-rw-r--r--tests/org.eclipse.qvtd.xtext.qvtimperative.tests/src/org/eclipse/qvtd/xtext/qvtimperative/tests/Tree2TallTree/samples/TallTreeValidateChanged.xmi (renamed from tests/org.eclipse.qvtd.xtext.qvtimperative.tests/src/org/eclipse/qvtd/xtext/qvtimperative/tests/Tree2TallTree/TallTreeValidate2.xmi)32
-rw-r--r--tests/org.eclipse.qvtd.xtext.qvtimperative.tests/src/org/eclipse/qvtd/xtext/qvtimperative/tests/Tree2TallTree/samples/TallTreeValidateCleared.xmi2
-rw-r--r--tests/org.eclipse.qvtd.xtext.qvtimperative.tests/src/org/eclipse/qvtd/xtext/qvtimperative/tests/Tree2TallTree/samples/TallTreeValidateDeleted.xmi13
-rw-r--r--tests/org.eclipse.qvtd.xtext.qvtimperative.tests/src/org/eclipse/qvtd/xtext/qvtimperative/tests/Tree2TallTree/samples/Tree.xmi (renamed from tests/org.eclipse.qvtd.xtext.qvtimperative.tests/src/org/eclipse/qvtd/xtext/qvtimperative/tests/Tree2TallTree/Tree.xmi)26
36 files changed, 902 insertions, 562 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 2d8cb3f43..8e716744d 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
@@ -266,7 +266,8 @@ public class QVTiCG2JavaVisitor extends CG2JavaVisitor<@NonNull QVTiCodeGenerato
js.append(");\n");
//
if (isIncremental) {
- js.append("objectManager.created(");
+ js.append(QVTiGlobalContext.OBJECT_MANAGER_NAME);
+ js.append(".created(");
js.appendThis(getThisName(cgRealizedVariable));
js.append(", ");
js.appendValueName(cgRealizedVariable);
@@ -392,7 +393,8 @@ public class QVTiCG2JavaVisitor extends CG2JavaVisitor<@NonNull QVTiCodeGenerato
CGValuedElement cgInit = getExpression(QVTiCGUtil.getOwnedInitValue(cgPropertyAssignment));
EPackage ePackage = ClassUtil.nonNullModel(eStructuralFeature.getEContainingClass().getEPackage());
if (isIncremental || ((SetStatement)cgPropertyAssignment.getAst()).isIsNotify()) {
- js.append("objectManager.assigned(");
+ js.append(QVTiGlobalContext.OBJECT_MANAGER_NAME);
+ js.append(".assigned(");
if (isIncremental) {
js.appendThis(getThisName(cgPropertyAssignment));
js.append(", ");
@@ -414,7 +416,8 @@ public class QVTiCG2JavaVisitor extends CG2JavaVisitor<@NonNull QVTiCodeGenerato
CGValuedElement cgInit = getExpression(QVTiCGUtil.getOwnedInitValue(cgPropertyAssignment));
EPackage ePackage = ClassUtil.nonNullModel(eStructuralFeature.getEContainingClass().getEPackage());
if (isIncremental || ((SetStatement)cgPropertyAssignment.getAst()).isIsNotify()) {
- js.append("objectManager.assigned(");
+ js.append(QVTiGlobalContext.OBJECT_MANAGER_NAME);
+ js.append(".assigned(");
if (isIncremental) {
js.appendThis(getThisName(cgPropertyAssignment));
js.append(", ");
@@ -661,6 +664,11 @@ public class QVTiCG2JavaVisitor extends CG2JavaVisitor<@NonNull QVTiCodeGenerato
ElementId elementId = cgFunction.getTypeId().getElementId();
js.append(" {\n");
js.pushIndentation(null);
+ // if (isIncremental) {
+ // js.append("super(\"");
+ // js.append(getFunctionName(cgFunction));
+ // js.append("\");\n");
+ // }
// js.appendCastParameters(localContext2, cgParameters);
// JavaDependencyVisitor dependencyVisitor = new JavaDependencyVisitor(localContext2, null);
// dependencyVisitor.visit(body);
@@ -771,6 +779,11 @@ public class QVTiCG2JavaVisitor extends CG2JavaVisitor<@NonNull QVTiCodeGenerato
String functionName = getFunctionName(cgFunction);
js.append(" {\n");
js.pushIndentation(null);
+ if (isIncremental) {
+ js.append("super(\"");
+ js.append(functionName);
+ js.append("\");\n");
+ }
EClassifier eClassifier = ClassUtil.nonNullState(cgShadowExp.getEcoreClassifier());
if (eClassifier instanceof EDataType) {
CGShadowPart cgShadowPart = ClassUtil.nullFree(cgShadowExp.getParts()).get(0);
@@ -877,6 +890,11 @@ public class QVTiCG2JavaVisitor extends CG2JavaVisitor<@NonNull QVTiCodeGenerato
js.appendIsRequired(true);
js.append(" [] boundValues) {\n");
js.pushIndentation(null);
+ if (isIncremental) {
+ js.append("super(\"");
+ js.append(functionName);
+ js.append("\");\n");
+ }
js.appendThis(functionName);
js.append(".self = (");
js.appendClassReference(cgClass);
@@ -1069,7 +1087,8 @@ public class QVTiCG2JavaVisitor extends CG2JavaVisitor<@NonNull QVTiCodeGenerato
if (isHazardous) {
EPackage ePackage = ClassUtil.nonNullModel(eStructuralFeature.getEContainingClass().getEPackage());
//
- js.append("objectManager.getting(");
+ js.append(QVTiGlobalContext.OBJECT_MANAGER_NAME);
+ js.append(".getting(");
js.appendValueName(source);
js.append(", ");
js.appendClassReference(genModelHelper.getQualifiedPackageInterfaceName(ePackage));
@@ -1085,7 +1104,8 @@ public class QVTiCG2JavaVisitor extends CG2JavaVisitor<@NonNull QVTiCodeGenerato
if (useGot) {
EPackage ePackage = ClassUtil.nonNullModel(eStructuralFeature.getEContainingClass().getEPackage());
//
- js.append("objectManager.got(");
+ js.append(QVTiGlobalContext.OBJECT_MANAGER_NAME);
+ js.append(".got(");
// if (localPrefix != null) {
// js.append(localPrefix);
// js.append(".");
@@ -1349,7 +1369,7 @@ public class QVTiCG2JavaVisitor extends CG2JavaVisitor<@NonNull QVTiCodeGenerato
protected void doMappingConnectionVariable(@NonNull CGGuardVariable cgFreeVariable) {
if (cgFreeVariable instanceof CGConnectionVariable) {
js.append("final ");
- js.appendClassReference(true, Connection.class);
+ js.appendClassReference(true, isIncremental ? Connection.Incremental.class : Connection.class);
js.append(" ");
js.append(getValueName(cgFreeVariable));
}
@@ -1359,7 +1379,7 @@ public class QVTiCG2JavaVisitor extends CG2JavaVisitor<@NonNull QVTiCodeGenerato
}
protected void doMappingConstructor(@NonNull CGMapping cgMapping) {
- List<@NonNull CGGuardVariable> cgFreeVariables = ClassUtil.nullFree(cgMapping.getOwnedGuardVariables());
+ Iterable<@NonNull CGGuardVariable> cgGuardVariables = QVTiCGUtil.getOwnedGuardVariables(cgMapping);
// if (js.isUseNullAnnotations()) {
// js.append("@SuppressWarnings(\"null\")\n"); // Accurate casts are too hard
// }
@@ -1369,6 +1389,10 @@ public class QVTiCG2JavaVisitor extends CG2JavaVisitor<@NonNull QVTiCodeGenerato
js.appendClassReference(true, isIncremental ? InvocationConstructor.Incremental.class : InvocationConstructor.class);
js.append(" ");
js.append(QVTiGlobalContext.CONSTRUCTOR_NAME);
+ if (isIncremental) {
+ js.append(", int ");
+ js.append(QVTiGlobalContext.INVOCATION_HASH_CODE_NAME);
+ }
js.append(", ");
js.appendIsRequired(true);
js.append(" Object ");
@@ -1378,23 +1402,27 @@ public class QVTiCG2JavaVisitor extends CG2JavaVisitor<@NonNull QVTiCodeGenerato
// if (isIncremental) {
js.append("super(");
js.append(QVTiGlobalContext.CONSTRUCTOR_NAME);
+ if (isIncremental) {
+ js.append(", ");
+ js.append(QVTiGlobalContext.INVOCATION_HASH_CODE_NAME);
+ }
js.append(");\n");
//
int i = 0;
- for (@NonNull CGGuardVariable cgFreeVariable : cgFreeVariables) {
- String valueName = getValueName(cgFreeVariable);
+ for (@NonNull CGGuardVariable cgGuardVariable : cgGuardVariables) {
+ String valueName = getValueName(cgGuardVariable);
js.append(valueName);
js.append(" = ");
// js.appendClassCast(cgFreeVariable);
- if (cgFreeVariable instanceof CGConnectionVariable) {
+ if (cgGuardVariable instanceof CGConnectionVariable) {
js.append("(");
// js.appendClassReference(null, cgFreeVariable);
// js.append(".Accumulator)"); // FIXME Embed properly as a nested typeid
- js.appendClassReference(null, Connection.class);
+ js.appendClassReference(null, isIncremental ? Connection.Incremental.class : Connection.class);
js.append(")"); // FIXME Embed properly as a nested typeid
}
else{
- js.appendClassCast(cgFreeVariable);
+ js.appendClassCast(cgGuardVariable);
}
js.append("boundValues[" + i++);
js.append("];\n");
@@ -1413,8 +1441,10 @@ public class QVTiCG2JavaVisitor extends CG2JavaVisitor<@NonNull QVTiCodeGenerato
js.appendClassReference(constructorClass);
js.append("(invocationManager, ");
js.appendString(QVTiCGUtil.getName(cgMapping));
- js.append(", ");
- js.appendBooleanString(QVTiCGUtil.getAST(cgMapping).isIsStrict());
+ if (!isIncremental) {
+ js.append(", ");
+ js.appendBooleanString(QVTiCGUtil.getAST(cgMapping).isIsStrict());
+ }
js.append(")\n");
js.append("{\n");
js.pushIndentation(null);
@@ -1422,6 +1452,11 @@ public class QVTiCG2JavaVisitor extends CG2JavaVisitor<@NonNull QVTiCodeGenerato
js.append("public ");
js.appendIsRequired(true);
js.append(" " + getMappingName(cgMapping) + " newInstance(");
+ if (isIncremental) {
+ js.append("int ");
+ js.append(QVTiGlobalContext.INVOCATION_HASH_CODE_NAME);
+ js.append(", ");
+ }
js.appendIsRequired(true);
js.append(" ");
js.appendClassReference(Object.class);
@@ -1430,9 +1465,12 @@ public class QVTiCG2JavaVisitor extends CG2JavaVisitor<@NonNull QVTiCodeGenerato
js.append(" [] values) {\n");
js.pushIndentation(null);
js.append("return new " + getMappingName(cgMapping) + "(");
- // if (isIncremental) {
- js.append("this, ");
- // }
+ js.append("this");
+ if (isIncremental) {
+ js.append(", ");
+ js.append(QVTiGlobalContext.INVOCATION_HASH_CODE_NAME);
+ }
+ js.append(", ");
js.append("values);\n");
js.popIndentation();
js.append("}\n");
@@ -1442,6 +1480,109 @@ public class QVTiCG2JavaVisitor extends CG2JavaVisitor<@NonNull QVTiCodeGenerato
}
}
+ protected void doMappingDestroy(@NonNull CGMapping cgMapping) {
+ js.append("/*\n");
+ js.append(" * Eliminate all trace of the construction and execution of this invocation.\n");
+ js.append(" */\n");
+ js.append("@Override\n");
+ js.append("public synchronized void destroy() {\n");
+ js.pushIndentation(null);
+ js.append("/*\n");
+ js.append(" * Remove this invocation from the invocation cache.\n");
+ js.append(" * Revoke all object property assignments.\n");
+ js.append(" * Revoke all consumed input objects.\n");
+ js.append(" */\n");
+ js.append("super.destroy();\n");
+ /* Iterable<@NonNull CGGuardVariable> ownedGuardVariables = QVTiCGUtil.getOwnedGuardVariables(cgMapping);
+ if (!Iterables.isEmpty(ownedGuardVariables)) {
+ boolean firstConsume = true;
+ int i = 0;
+ for (@NonNull CGGuardVariable cgGuardVariable : ownedGuardVariables) {
+ if (!(cgGuardVariable instanceof CGConnectionVariable)) {
+ if (firstConsume) {
+ js.append("/*\n");
+ js.append(" * Revoke all consumed input objects.\n");
+ js.append(" * /\n");
+ js.appendClassReference(List.class, Connection.Incremental.class);
+ js.append(" consumedConnections = ");
+ js.append(QVTiGlobalContext.CONSTRUCTOR_NAME);
+ js.append(".getConsumedConnections();\n");
+ firstConsume = false;
+ }
+ js.append("consumedConnections.get(" + i++ + ").revokeConsumer(");
+ js.appendValueName(cgGuardVariable);
+ js.append(", this);\n");
+ }
+ }
+ } */
+ boolean firstAppend = true;
+ for (@NonNull EObject eObject : new TreeIterable(cgMapping, false)) {
+ if (eObject instanceof CGConnectionAssignment) {
+ if (firstAppend) {
+ js.append("/*\n");
+ js.append(" * Revoke all appended output objects.\n");
+ js.append(" */\n");
+ firstAppend = false;
+ }
+ CGConnectionAssignment cgConnectionAssignment = (CGConnectionAssignment)eObject;
+ js.append("if (this.");
+ js.appendValueName(cgConnectionAssignment);
+ js.append(" != null) {\n");
+ js.pushIndentation(null);
+ js.append("this.");
+ js.appendValueName(cgConnectionAssignment.getConnectionVariable());
+ js.append(".revoke(");
+ js.appendValueName(cgConnectionAssignment);
+ js.append(");\n");
+ js.append("this.");
+ js.appendValueName(cgConnectionAssignment);
+ js.append(" = null;\n");
+ js.popIndentation();
+ js.append("}\n");
+ }
+ }
+ Iterable<@NonNull CGRealizedVariable> ownedRealizedVariables = QVTiCGUtil.getOwnedRealizedVariables(cgMapping);
+ if (!Iterables.isEmpty(ownedRealizedVariables)) {
+ js.append("/*\n");
+ js.append(" * Destroy all created objects.\n");
+ js.append(" */\n");
+ for (@NonNull CGRealizedVariable cgRealizedVariable : ownedRealizedVariables) {
+ 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.append(QVTiGlobalContext.OBJECT_MANAGER_NAME);
+ js.append(".destroyed(");
+ js.appendValueName(cgRealizedVariable);
+ js.append(");\n");
+ js.append("this.");
+ js.appendValueName(cgRealizedVariable);
+ js.append(" = null;\n");
+ js.popIndentation();
+ js.append("}\n");
+ }
+ }
+ js.popIndentation();
+ js.append("}\n");
+ }
+
protected boolean doMappingFields(@NonNull CGMapping cgMapping) {
boolean needsNewLine = false;
for (@NonNull CGGuardVariable cgVariable : ClassUtil.nullFree(cgMapping.getOwnedGuardVariables())) {
@@ -1462,42 +1603,62 @@ public class QVTiCG2JavaVisitor extends CG2JavaVisitor<@NonNull QVTiCodeGenerato
js.append(";\n");
needsNewLine = true;
}
+ for (@NonNull EObject eObject : new TreeIterable(cgMapping, false)) {
+ if (eObject instanceof CGConnectionAssignment) {
+ CGConnectionAssignment cgConnectionAssignment = (CGConnectionAssignment)eObject;
+ js.append("protected ");
+ js.appendClassReference(false, Object.class);
+ js.append(" ");
+ js.appendValueName(cgConnectionAssignment);
+ js.append(" = null;\n");
+ needsNewLine = true;
+ }
+ }
}
return needsNewLine;
}
- protected void doMappingRevokeInvocation(@NonNull CGMapping cgMapping) {
+ protected void doMappingGetBoundValue(@NonNull CGMapping cgMapping) {
+ Iterable<@NonNull CGGuardVariable> cgGuardVariables = QVTiCGUtil.getOwnedGuardVariables(cgMapping);
+ js.append("/*\n");
+ js.append(" * Return the index'th bound value.\n");
+ js.append(" */\n");
js.append("@Override\n");
- js.append("public void revokeInvocation() {\n");
+ js.append("public ");
+ js.appendIsRequired(true);
+ js.append(" ");
+ js.appendClassReference(Object.class);
+ js.append(" getBoundValue(int index) {\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("switch(index) {\n");
+ js.pushIndentation(null);
+ int i = 0;
+ for (@NonNull CGGuardVariable cgGuardVariable : cgGuardVariables) {
+ String valueName = getValueName(cgGuardVariable);
+ js.append("case " + i++ + ": return ");
+ js.append(valueName);
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");
+ js.append("throw new ");
+ js.appendClassReference(IllegalArgumentException.class);
+ js.append("();\n");
+ js.popIndentation();
+ js.append("}\n");
+ }
+
+ protected void doMappingGetBoundValues(@NonNull CGMapping cgMapping) {
+ Iterable<@NonNull CGGuardVariable> cgGuardVariables = QVTiCGUtil.getOwnedGuardVariables(cgMapping);
+ js.append("/*\n");
+ js.append(" * Return the number of bound values.\n");
+ js.append(" */\n");
+ js.append("@Override\n");
+ js.append("public int getBoundValues() {\n");
+ js.pushIndentation(null);
+ js.append("return " + Iterables.size(cgGuardVariables) + ";\n");
+ js.popIndentation();
+ js.append("}\n");
}
protected void doOppositeCaches(@NonNull QVTiTransformationAnalysis transformationAnalysis) {
@@ -1825,6 +1986,10 @@ public class QVTiCG2JavaVisitor extends CG2JavaVisitor<@NonNull QVTiCodeGenerato
BoxedDescriptor concreteBoxedDescriptor = context.getBoxedDescriptor(concreteElementTypeId);
BoxedDescriptor abstractBoxedDescriptor = concreteBoxedDescriptor;
if (!(initValue.getASTypeId() instanceof CollectionTypeId)) {
+ if (isIncremental) {
+ js.appendValueName(cgConnectionAssignment);
+ js.append(" = ");
+ }
js.appendReferenceTo(cgConnectionAssignment.getConnectionVariable());
js.append(".appendElement(");
js.appendValueName(initValue);
@@ -2173,16 +2338,22 @@ public class QVTiCG2JavaVisitor extends CG2JavaVisitor<@NonNull QVTiCodeGenerato
js.append("\n");
}
doMappingConstructor(cgMapping);
+ if (isIncremental) {
+ js.append("\n");
+ doMappingDestroy(cgMapping);
+ }
js.append("\n");
js.append("@Override\n");
js.append("public boolean execute() ");
doMappingBody(cgMapping, true);
- js.append("\n");
- doIsEqual(cgFreeVariables);
- if (isIncremental && !Iterables.isEmpty(QVTiCGUtil.getOwnedRealizedVariables(cgMapping))) {
+ if (isIncremental) {
js.append("\n");
- doMappingRevokeInvocation(cgMapping);
+ doMappingGetBoundValue(cgMapping);
+ js.append("\n");
+ doMappingGetBoundValues(cgMapping);
}
+ js.append("\n");
+ doIsEqual(cgFreeVariables);
js.popClassBody(false);
}
else {
diff --git a/plugins/org.eclipse.qvtd.codegen/src/org/eclipse/qvtd/codegen/qvti/java/QVTiGlobalContext.java b/plugins/org.eclipse.qvtd.codegen/src/org/eclipse/qvtd/codegen/qvti/java/QVTiGlobalContext.java
index 7f2b8af2a..4ea2ba86e 100644
--- a/plugins/org.eclipse.qvtd.codegen/src/org/eclipse/qvtd/codegen/qvti/java/QVTiGlobalContext.java
+++ b/plugins/org.eclipse.qvtd.codegen/src/org/eclipse/qvtd/codegen/qvti/java/QVTiGlobalContext.java
@@ -26,6 +26,8 @@ import org.eclipse.ocl.pivot.Property;
public class QVTiGlobalContext extends JavaGlobalContext<@NonNull QVTiCodeGenerator>
{
public static final @NonNull String CONSTRUCTOR_NAME = "constructor";
+ public static final @NonNull String INVOCATION_HASH_CODE_NAME = "invocationHashCode";
+ public static final @NonNull String OBJECT_MANAGER_NAME = "objectManager";
public static final @NonNull String MODELS_NAME = "models";
/**
@@ -38,7 +40,9 @@ public class QVTiGlobalContext extends JavaGlobalContext<@NonNull QVTiCodeGenera
nameManager.reserveName(JavaConstants.EXECUTOR_NAME, null);
nameManager.reserveName(JavaConstants.EVALUATION_CACHE_NAME, null);
nameManager.reserveName(CONSTRUCTOR_NAME, null);
+ nameManager.reserveName(INVOCATION_HASH_CODE_NAME, null);
nameManager.reserveName(MODELS_NAME, null);
+ nameManager.reserveName(OBJECT_MANAGER_NAME, null);
}
public @NonNull String addOppositeProperty(@NonNull Property pivotProperty) {
diff --git a/plugins/org.eclipse.qvtd.pivot.qvtimperative/src/org/eclipse/qvtd/pivot/qvtimperative/evaluation/EvaluationStatus2GraphVisitor.java b/plugins/org.eclipse.qvtd.pivot.qvtimperative/src/org/eclipse/qvtd/pivot/qvtimperative/evaluation/EvaluationStatus2GraphVisitor.java
deleted file mode 100644
index 1d3b3af67..000000000
--- a/plugins/org.eclipse.qvtd.pivot.qvtimperative/src/org/eclipse/qvtd/pivot/qvtimperative/evaluation/EvaluationStatus2GraphVisitor.java
+++ /dev/null
@@ -1,232 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2015 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.pivot.qvtimperative.evaluation;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import org.eclipse.emf.ecore.EClassifier;
-import org.eclipse.emf.ecore.EDataType;
-import org.eclipse.emf.ecore.EReference;
-import org.eclipse.emf.ecore.EStructuralFeature;
-import org.eclipse.jdt.annotation.NonNull;
-import org.eclipse.jdt.annotation.Nullable;
-import org.eclipse.qvtd.pivot.qvtbase.graphs.GraphBuilder;
-import org.eclipse.qvtd.pivot.qvtimperative.evaluationstatus.AssociationStatus;
-import org.eclipse.qvtd.pivot.qvtimperative.evaluationstatus.AttributeStatus;
-import org.eclipse.qvtd.pivot.qvtimperative.evaluationstatus.ClassStatus;
-import org.eclipse.qvtd.pivot.qvtimperative.evaluationstatus.ElementStatus;
-import org.eclipse.qvtd.pivot.qvtimperative.evaluationstatus.EvaluationElement;
-import org.eclipse.qvtd.pivot.qvtimperative.evaluationstatus.MappingStatus;
-import org.eclipse.qvtd.pivot.qvtimperative.evaluationstatus.PropertyStatus;
-import org.eclipse.qvtd.pivot.qvtimperative.evaluationstatus.TransformationStatus;
-import org.eclipse.qvtd.pivot.qvtimperative.evaluationstatus.util.AbstractExtendingEvaluationStatusVisitor;
-
-public class EvaluationStatus2GraphVisitor extends AbstractExtendingEvaluationStatusVisitor<String, GraphBuilder>
-{
- protected static @NonNull String NULL_PLACEHOLDER = "\"<null>\""; //$NON-NLS-1$
-
- private Map<AssociationStatus, String> associationId = new HashMap<AssociationStatus, String>();
- private Map<ClassStatus, String> classId = new HashMap<ClassStatus, String>();
- private Map<MappingStatus, String> mappingId = new HashMap<MappingStatus, String>();
-// private Map<String, String> propertyId2associationId = new HashMap<String, String>();
-// private Map<String, PropertyStatus> associationId2propertyStatus = new HashMap<String, PropertyStatus>();
-
- public EvaluationStatus2GraphVisitor(@NonNull GraphBuilder context) {
- super(context);
- }
-
- protected @NonNull String getAssociationColor(@NonNull AssociationStatus associationStatus) {
- if (associationStatus.isIsInput()) {
- return associationStatus.isIsOutput() ? "#ccffff" : "#ccff00";
- }
- else {
- return associationStatus.isIsOutput() ? "#cc80ff" : "#cc0000";
- }
- }
-
- protected @NonNull String getAssociationId(@NonNull AssociationStatus object) {
- String id = associationId.get(object);
- if (id == null) {
- id = "a" + associationId.size()+1;
- associationId.put(object, id);
- }
- return id;
- }
-
- protected String getAssociationLabel(@NonNull AssociationStatus associationStatus) {
- EReference forwardReference = associationStatus.getForwardEReference();
- EReference oppositeReference = forwardReference.getEOpposite();
- String firstName = forwardReference.getName();
- String secondName = oppositeReference.getName();
- boolean swap = false;
- if (forwardReference.isMany() != oppositeReference.isMany()) {
- swap = forwardReference.isMany();
- }
- else {
- swap = firstName.compareTo(secondName) > 0;
- }
- return swap ? secondName + " / " + firstName : firstName + " / " + secondName;
- }
-
- protected @NonNull String getAttributeId(@NonNull AttributeStatus attributeStatus) {
- ClassStatus classStatus = attributeStatus.getOwningClassStatus();
- assert classStatus != null;
- return getClassId(classStatus) + "-" + attributeStatus.getEFeature().getName();
- }
-
- protected @NonNull String getClassColor(@NonNull ClassStatus classStatus) {
- if (classStatus.isIsInput()) {
- return classStatus.isIsOutput() ? "#ccffff" : "#ccff00";
- }
- else {
- return classStatus.isIsOutput() ? "#cc80ff" : "#cc0000";
- }
- }
-
- protected @NonNull String getClassId(@NonNull ClassStatus object) {
- String id = classId.get(object);
- if (id == null) {
- id = object.getType().getName() + "-" + (classId.size() + 1);
- classId.put(object, id);
- }
- return id;
- }
-
- protected @NonNull String getMappingId(@NonNull MappingStatus object) {
- String id = mappingId.get(object);
- if (id == null) {
- id = object.getReferredMappingCall().getReferredMapping().getName() + "-" + (mappingId.size() + 1);
- mappingId.put(object, id);
- }
- return id;
- }
-
- protected @NonNull String getPropertyId(@NonNull PropertyStatus object) {
- if (object instanceof AssociationStatus) {
- return getAssociationId((AssociationStatus) object);
- }
- else if (object instanceof AttributeStatus) {
- return getAttributeId((AttributeStatus)object);
- }
- else {
- throw new UnsupportedOperationException();
- }
- }
-
- @Override
- public String visiting(@NonNull EvaluationElement visitable) {
-// append(visitable.getClass().getName());
- return null;
- }
-
- @Override
- public @Nullable String visitAssociationStatus(@NonNull AssociationStatus object) {
- String associationId = getAssociationId(object);
- String fillColor = object.isIsError() ? "#ff0000" : getAssociationColor(object);
- String label = getAssociationLabel(object);
- context.appendNode(associationId, "rectangle", fillColor, 30, 100, label);
- for (ClassStatus classStatus : object.getFromClassStatuses()) {
- if (classStatus != null) {
- String classId = getClassId(classStatus);
- context.appendEdge(classId, associationId, "#339966", "line","diamond", "none");
- }
- }
- for (ClassStatus classStatus : object.getToClassStatuses()) {
- if (classStatus != null) {
- String classId = getClassId(classStatus);
- context.appendEdge(classId, associationId, "#339966", "line","diamond", "none");
- }
- }
- return null;
- }
-
- @Override
- public @Nullable String visitAttributeStatus(@NonNull AttributeStatus object) {
- ClassStatus classStatus = object.getOwningClassStatus();
- assert classStatus != null;
- String classId = getClassId(classStatus);
- String attributeId = getAttributeId(object);
- String fillColor = object.isIsError() ? "#ff0000" : getClassColor(classStatus);
- EStructuralFeature eFeature = object.getEFeature();
- String label = eFeature.getName();
- EClassifier type = eFeature.getEType();
-// if (type instanceof DataType) {
-// Type behavioralType = ((DataType)type).getBehavioralClass();
-// if (behavioralType != null) {
-// type = behavioralType;
-// }
-// }
- if (type instanceof EDataType) {
- label = label + "\n" + String.valueOf(object.getObject());
- }
- context.appendNode(attributeId, "rectangle", fillColor, 30, 50, label);
- context.appendEdge(classId, attributeId, "#339966", "line","diamond", "none");
- return null;
- }
-
- @Override
- public @Nullable String visitClassStatus(@NonNull ClassStatus object) {
- String classId = getClassId(object);
- context.appendNode(classId, "rectangle", getClassColor(object), 30, 120, classId.replace("-", "\n"));
- for (AttributeStatus attributeStatus : object.getOwnedAttributeStatuses()) {
- attributeStatus.accept(this);
- }
- return null;
- }
-
- @Override
- public @Nullable String visitMappingStatus(@NonNull MappingStatus object) {
- String mappingId = getMappingId(object);
- context.appendNode(mappingId, "hexagon", "#ffcc00", 30, 150, mappingId.replace("-", "\n"));
- for (ElementStatus inputStatus : object.getInputs()) {
- if (inputStatus instanceof ClassStatus) {
- ClassStatus classStatus = (ClassStatus)inputStatus;
- String classId = getClassId(classStatus);
- context.appendEdge(classId, mappingId, "#000000", "line","none", "standard");
- }
- else if (inputStatus instanceof PropertyStatus) {
- PropertyStatus propertyStatus = (PropertyStatus)inputStatus;
- String propertyId = getPropertyId(propertyStatus);
- context.appendEdge(propertyId, mappingId, "#000000", "dashed","none", "standard");
- }
- }
- for (ElementStatus outputStatus : object.getOutputs()) {
- if (outputStatus instanceof ClassStatus) {
- ClassStatus classStatus = (ClassStatus)outputStatus;
- String classId = getClassId(classStatus);
- context.appendEdge(mappingId, classId, "#000000", "line","none", "standard");
- }
- else if (outputStatus instanceof PropertyStatus) {
- PropertyStatus propertyStatus = (PropertyStatus)outputStatus;
- String propertyId = getPropertyId(propertyStatus);
- context.appendEdge(mappingId, propertyId, "#000000", "dashed","none", "standard");
- }
- }
- return null;
- }
-
- @Override
- public @Nullable String visitTransformationStatus(@NonNull TransformationStatus object) {
- context.open();
- for (ClassStatus classStatus : object.getOwnedClassStatuses()) {
- classStatus.accept(this);
- }
- for (MappingStatus mappingStatus : object.getOwnedMappingStatuses()) {
- mappingStatus.accept(this);
- }
- for (AssociationStatus associationStatus : object.getOwnedAssociationStatuses()) {
- associationStatus.accept(this);
- }
- context.close();
- return null;
- }
-}
diff --git a/plugins/org.eclipse.qvtd.pivot.qvtimperative/src/org/eclipse/qvtd/pivot/qvtimperative/evaluation/Execution2GraphVisitor.java b/plugins/org.eclipse.qvtd.pivot.qvtimperative/src/org/eclipse/qvtd/pivot/qvtimperative/evaluation/Execution2GraphVisitor.java
index 2879918d1..b13ecb791 100644
--- a/plugins/org.eclipse.qvtd.pivot.qvtimperative/src/org/eclipse/qvtd/pivot/qvtimperative/evaluation/Execution2GraphVisitor.java
+++ b/plugins/org.eclipse.qvtd.pivot.qvtimperative/src/org/eclipse/qvtd/pivot/qvtimperative/evaluation/Execution2GraphVisitor.java
@@ -220,7 +220,7 @@ public class Execution2GraphVisitor extends AbstractExecutionVisitor<@Nullable O
public void appendNode(@NonNull GraphStringBuilder s, @NonNull String nodeName) {
s.setLabel(label);
s.setShape("ellipse");
- s.setColor("brown");
+ s.setColor("blue");
s.appendAttributedNode(nodeName);
}
};
@@ -419,7 +419,7 @@ public class Execution2GraphVisitor extends AbstractExecutionVisitor<@Nullable O
Object value = object.getValue(i);
if (value != null) {
GraphNode objectNode = getObjectNode(value);
- appendEdge(connectionNode, objectNode, "brown", "dotted");
+ appendEdge(connectionNode, objectNode, "blue", "dotted");
// for (@NonNull Invocation invocation : object.getConsumers(i)) {
// GraphNode consumerNode = getInvocationNode(invocation);
// }
@@ -502,8 +502,22 @@ public class Execution2GraphVisitor extends AbstractExecutionVisitor<@Nullable O
@Override
public @Nullable String visitInvocation(@NonNull Invocation object) {
- @SuppressWarnings("unused")
GraphNode invocationNode = getInvocationNode(object);
+ if (object instanceof Invocation.Incremental) {
+ Invocation.Incremental invocation = (Invocation.Incremental)object;
+ int iMax = invocation.getBoundValues();
+ for (int i = 0; i < iMax; i++) {
+ Object boundObject = invocation.getBoundValue(i);
+ if (boundObject instanceof Connection) {
+ GraphNode connectionNode = getConnectionNode((Connection) boundObject);
+ appendEdge(invocationNode, connectionNode, "green", "dotted");
+ }
+ else {
+ GraphNode objectNode = getObjectNode(boundObject);
+ appendEdge(objectNode, invocationNode, "cyan", null);
+ }
+ }
+ }
/* context.appendNode(mappingId, "hexagon", "#ffcc00", 30, 150, mappingId.replace("-", "\n"));
for (ElementStatus inputStatus : object.getInputs()) {
if (inputStatus instanceof ClassStatus) {
@@ -537,7 +551,7 @@ public class Execution2GraphVisitor extends AbstractExecutionVisitor<@Nullable O
GraphNode invokerNode = getInvocationConstructorNode(object);
GraphNode intervalNode = getIntervalNode(object.getInterval());
appendEdge(invokerNode, intervalNode, "black", "dashed");
- for (@NonNull Invocation invocation : object.getInvocations()) {
+ for (@NonNull Invocation invocation : object.debugGetInvocations()) {
GraphNode invocationNode = getInvocationNode(invocation);
appendEdge(invokerNode, invocationNode, "orange", "dotted");
}
@@ -593,10 +607,10 @@ public class Execution2GraphVisitor extends AbstractExecutionVisitor<@Nullable O
GraphNode slotNode = getSlotNode(slotState);
slotState.accept(this);
for (@NonNull Invocation invocation : slotState.getSources()) {
- appendEdge(getInvocationNode(invocation), slotNode, "green", null);
+ appendEdge(getInvocationNode(invocation), slotNode, "green", "dashed");
}
for (@NonNull Execution invocation : slotState.getTargets()) {
- appendEdge(slotNode, getExecutionNode(invocation), "cyan", null);
+ appendEdge(slotNode, getExecutionNode(invocation), "cyan", "dashed");
}
Iterables.addAll(allExecutions, slotState.getTargets());
}
@@ -607,7 +621,7 @@ public class Execution2GraphVisitor extends AbstractExecutionVisitor<@Nullable O
for (SlotState.@NonNull Incremental slotState : slots) {
GraphNode slotNode = getSlotNode(slotState);
slotState.accept(this);
- appendEdge(objectNode, slotNode, "blue", null);
+ appendEdge(objectNode, slotNode, "blue", "dashed");
}
}
}
diff --git a/plugins/org.eclipse.qvtd.pivot.qvtimperative/src/org/eclipse/qvtd/pivot/qvtimperative/evaluation/QVTiIncrementalExecutor.java b/plugins/org.eclipse.qvtd.pivot.qvtimperative/src/org/eclipse/qvtd/pivot/qvtimperative/evaluation/QVTiIncrementalExecutor.java
index c8227f3d1..3abc70689 100644
--- a/plugins/org.eclipse.qvtd.pivot.qvtimperative/src/org/eclipse/qvtd/pivot/qvtimperative/evaluation/QVTiIncrementalExecutor.java
+++ b/plugins/org.eclipse.qvtd.pivot.qvtimperative/src/org/eclipse/qvtd/pivot/qvtimperative/evaluation/QVTiIncrementalExecutor.java
@@ -77,15 +77,15 @@ public class QVTiIncrementalExecutor extends BasicQVTiExecutor
public InterpretedInvocationConstructor(@NonNull QVTiIncrementalExecutor executor, @NonNull Mapping asMapping,
@NonNull MappingCall mappingCall, @NonNull EvaluationVisitor undecoratedVisitor) {
- super(executor.getInvocationManager(), QVTimperativeUtil.getName(asMapping), asMapping.isIsStrict());
+ super(executor.getInvocationManager(), QVTimperativeUtil.getName(asMapping));
this.executor = executor;
this.mappingCall = mappingCall;
this.undecoratedVisitor = undecoratedVisitor;
}
@Override
- public @NonNull Invocation newInstance(@NonNull Object @NonNull [] theseValues) {
- return new InterpretedInvocation(this, theseValues);
+ public @NonNull Invocation newInstance(int invocationHashCode, @NonNull Object @NonNull [] theseValues) {
+ return new InterpretedInvocation(this, invocationHashCode, theseValues);
}
private Object internalExecuteInvocation(@NonNull InterpretedInvocation invocation, @NonNull Object @NonNull [] theseValues) {
@@ -97,8 +97,8 @@ public class QVTiIncrementalExecutor extends BasicQVTiExecutor
{
protected final @NonNull Object @NonNull [] theseValues;
- public InterpretedInvocation(@NonNull InterpretedInvocationConstructor constructor, @NonNull Object @NonNull [] theseValues) {
- super(constructor);
+ public InterpretedInvocation(@NonNull InterpretedInvocationConstructor constructor, int invocationHashCode, @NonNull Object @NonNull [] theseValues) {
+ super(constructor, invocationHashCode);
int iMax = theseValues.length;
this.theseValues = new @NonNull Object[iMax];
for (int i = 0; i < iMax; i++) {
@@ -113,6 +113,16 @@ public class QVTiIncrementalExecutor extends BasicQVTiExecutor
}
@Override
+ public @NonNull Object getBoundValue(int index) {
+ return theseValues[index];
+ }
+
+ @Override
+ public int getBoundValues() {
+ return theseValues.length;
+ }
+
+ @Override
public boolean isEqual(@NonNull IdResolver idResolver, @NonNull Object @NonNull [] thoseValues) {
int iMax = thoseValues.length;
if (iMax != theseValues.length) {
@@ -192,7 +202,7 @@ public class QVTiIncrementalExecutor extends BasicQVTiExecutor
{
@Override
public @NonNull Computation newInstance(@Nullable Object @NonNull [] theseValues) {
- Computation.Incremental computation = new AbstractComputation.Incremental()
+ Computation.Incremental computation = new AbstractComputation.Incremental(PivotUtil.getName(asFunction))
{
protected Object result = QVTiIncrementalExecutor.super.internalExecuteFunctionCallExp(operationCallExp, asFunction, theseValues);
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 eb3395025..47bf86b56 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
@@ -26,8 +26,13 @@ public abstract class AbstractComputation implements Computation
{
public static final @NonNull List<@NonNull Object> EMPTY_OBJECT_LIST = Collections.emptyList();
+ protected final @NonNull String name;
private Set<SlotState.@NonNull Incremental> readSlots = null;
+ protected Incremental(@NonNull String name) {
+ this.name = name;
+ }
+
@Override
public void addReadSlot(SlotState.@NonNull Incremental readSlot) {
if (readSlots == null) {
@@ -43,13 +48,18 @@ public abstract class AbstractComputation implements Computation
}
@Override
- public void revokeExecution() {
+ public void destroy() {
// TODO Auto-generated method stub
}
@Override
- public void revokeInvocation() {
+ public @NonNull String getName() {
+ return name;
+ }
+
+ @Override
+ public void revoke() {
// TODO Auto-generated method stub
}
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 307f916d7..70ba1c3ce 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
@@ -17,6 +17,7 @@ import java.util.Set;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.ocl.pivot.ids.TypeId;
+import org.eclipse.qvtd.runtime.internal.evaluation.AbstractIntervalInternal;
import org.eclipse.qvtd.runtime.internal.evaluation.AbstractInvocationInternal;
/**
@@ -29,16 +30,19 @@ public abstract class AbstractInvocation extends AbstractInvocationInternal
public static final @NonNull List<@NonNull Object> EMPTY_OBJECT_LIST = Collections.emptyList();
public static final @NonNull List<SlotState.@NonNull Incremental> EMPTY_SLOT_LIST = Collections.emptyList();
- protected final @NonNull InvocationConstructor constructor;
+ protected final InvocationConstructor.@NonNull Incremental constructor;
+ private final int invocationHashCode;
protected final int sequence;
private Set<@NonNull Object> createdObjects = null;
private Set<SlotState.@NonNull Incremental> readSlots = null;
private Set<SlotState.@NonNull Incremental> writeSlots = null;
+ private boolean isDestroyed = false;
- protected Incremental(InvocationConstructor.@NonNull Incremental constructor) {
+ protected Incremental(InvocationConstructor.@NonNull Incremental constructor, int invocationHashCode) {
super(constructor);
this.constructor = constructor;
+ this.invocationHashCode = invocationHashCode;
this.sequence = constructor.nextSequence();
}
@@ -77,6 +81,33 @@ public abstract class AbstractInvocation extends AbstractInvocationInternal
}
@Override
+ public void destroy() {
+ isDestroyed = true;
+ ((AbstractIntervalInternal)interval).destroy(this);
+ constructor.destroy(this, invocationHashCode);
+ if (AbstractTransformer.INVOCATIONS.isActive()) {
+ AbstractTransformer.INVOCATIONS.println("destroy " + this);
+ }
+ if (writeSlots != null) {
+ for (SlotState.@NonNull Incremental writeSlot : writeSlots) {
+ writeSlot.revokeAssigned();
+ }
+ }
+ /*
+ * Revoke all consumed input objects.
+ */
+ int i = 0;
+ for (Connection.@NonNull Incremental consumedConnection : constructor.getConsumedConnections()) {
+ consumedConnection.revokeConsumer(getBoundValue(i), this);
+ }
+ }
+
+ @Override
+ public InvocationConstructor.@NonNull Incremental getConstructor() {
+ return constructor;
+ }
+
+ @Override
public @NonNull Iterable<@NonNull Object> getCreatedObjects() {
return createdObjects != null ? createdObjects : EMPTY_OBJECT_LIST;
}
@@ -99,29 +130,29 @@ public abstract class AbstractInvocation extends AbstractInvocationInternal
}
@Override
- public void revokeExecution() {
- if (writeSlots != null) {
- for (SlotState.@NonNull Incremental writeSlot : writeSlots) {
- writeSlot.revokeAssigned();
- }
+ public void revoke() {
+ if (AbstractTransformer.INVOCATIONS.isActive()) {
+ AbstractTransformer.INVOCATIONS.println("revoke " + this);
}
- interval.queue(this);
- }
-
- @Override
- public void revokeInvocation() {
if (writeSlots != null) {
for (SlotState.@NonNull Incremental writeSlot : writeSlots) {
writeSlot.revokeAssigned();
}
}
- interval.queue(this);
+ if (!isDestroyed) {
+ interval.queue(this);
+ }
}
@Override
public @NonNull String toString() {
return getName();
}
+
+ @Override
+ public void unblock() {
+ super.unblock();
+ }
}
protected AbstractInvocation(@NonNull InvocationConstructor constructor) {
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 8668c73e1..c58d4d5bc 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
@@ -61,7 +61,7 @@ public abstract class AbstractSlotState implements SlotState
protected void revokeTargets() {
for (Execution.@NonNull Incremental target : getTargets()) {
- target.revokeExecution();
+ target.revoke();
}
}
}
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 2133f0555..1484228bc 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
@@ -70,6 +70,8 @@ public interface Connection extends ExecutionVisitable, Nameable
* so that their appends are also revoked.
*/
void revoke(@NonNull Object connectionKey);
+
+ void revokeConsumer(@NonNull Object anElement, Invocation.@NonNull Incremental invocation);
}
void addAppender(@NonNull InvocationConstructor appendingInvoker);
@@ -84,6 +86,8 @@ public interface Connection extends ExecutionVisitable, Nameable
*/
@NonNull Object appendElement(@NonNull Object anElement);
+ int debugGetSize();
+
int getCapacity();
@NonNull Iterable<@NonNull InvocationConstructor> getConsumers();
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 4263778af..84c21d068 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
@@ -30,13 +30,13 @@ public interface Execution extends ExecutionVisitable, Nameable
* Revoke the consequences of a previous execution in preparation for a new execution.
* This reverts all assigned slot states back to REASSIGNABLE.
*/
- void revokeExecution();
+ void revoke();
/**
* Revoke the consequences of a previous execution that will not be re-executed.
* All created objects are revoked.
*/
- void revokeInvocation();
+ void destroy();
}
@Override
diff --git a/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/evaluation/Invocation.java b/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/evaluation/Invocation.java
index aad465730..a99b73c6f 100644
--- a/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/evaluation/Invocation.java
+++ b/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/evaluation/Invocation.java
@@ -49,8 +49,10 @@ public interface Invocation extends Execution
{
void addCreatedObject(@NonNull Object createdObject);
void addWriteSlot(SlotState.@NonNull Incremental writeSlot);
+ @NonNull Object getBoundValue(int index);
+ int getBoundValues();
+ InvocationConstructor.@NonNull Incremental getConstructor();
@NonNull Iterable<SlotState.@NonNull Incremental> getReadSlots();
@NonNull Iterable<SlotState.@NonNull Incremental> getWriteSlots();
- // void invalidate();
}
} \ No newline at end of file
diff --git a/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/evaluation/InvocationConstructor.java b/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/evaluation/InvocationConstructor.java
index 55a96ecd7..e1d27625b 100644
--- a/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/evaluation/InvocationConstructor.java
+++ b/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/evaluation/InvocationConstructor.java
@@ -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.utilities.Nameable;
@@ -22,6 +24,11 @@ public interface InvocationConstructor extends ExecutionVisitable, Nameable
{
public interface Incremental extends InvocationConstructor
{
+ void addConsumedConnection(Connection.@NonNull Incremental connection);
+
+ void destroy(AbstractInvocation.@NonNull Incremental incremental, int invocationHashCode);
+
+ @NonNull List<Connection.@NonNull Incremental> getConsumedConnections();
int nextSequence();
}
@@ -30,9 +37,9 @@ public interface InvocationConstructor extends ExecutionVisitable, Nameable
void addConsumedConnection(@NonNull Connection connection);
- @NonNull Interval getInterval();
+ @NonNull Iterable<@NonNull Invocation> debugGetInvocations();
- @NonNull Iterable<@NonNull Invocation> getInvocations();
+ @NonNull Interval getInterval();
@Override
@NonNull String getName();
diff --git a/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/evaluation/ObjectManager.java b/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/evaluation/ObjectManager.java
index b23adb716..1dfcbe3d3 100644
--- a/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/evaluation/ObjectManager.java
+++ b/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/evaluation/ObjectManager.java
@@ -40,6 +40,8 @@ public interface ObjectManager extends ExecutionVisitable
*/
void created(Invocation.@NonNull Incremental invocation, @NonNull Object eObject);
+ void destroyed(@NonNull Object eObject);
+
@NonNull Iterable<@NonNull ? extends Object> getObjects();
@NonNull Iterable<@NonNull ? extends SlotState> getSlotStates(@NonNull Object object);
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 ca62a88c9..7339e8942 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
@@ -45,9 +45,9 @@ public class StrictIncrementalConnection extends StrictIncrementalConnectionInte
if (count <= 0) {
listOfValueAndConsumingInvocations.set(i, null);
int jMax = valueAndConsumingInvocations.size();
- for (int j = INDEX_INDEX+1; j < jMax; j++) {
+ for (int j = COUNT_INDEX+1; j < jMax; j++) {
AbstractInvocation.Incremental consumingInvocation = (AbstractInvocation.Incremental) valueAndConsumingInvocations.get(j);
- consumingInvocation.revokeExecution();
+ consumingInvocation.revoke();
}
}
else {
@@ -57,4 +57,22 @@ public class StrictIncrementalConnection extends StrictIncrementalConnectionInte
}
}
}
+
+ @Override
+ public void revokeConsumer(@NonNull Object anElement, Invocation.@NonNull Incremental invocation) { // FIXME Use connectionKey
+ for (int i = 0; i < listOfValueAndConsumingInvocations.size(); i++) {
+ List<@NonNull Object> valueAndConsumingInvocations = listOfValueAndConsumingInvocations.get(i);
+ if ((valueAndConsumingInvocations != null) && (valueAndConsumingInvocations.get(VALUE_INDEX) == anElement)) {
+ int jMax = valueAndConsumingInvocations.size();
+ for (int j = COUNT_INDEX+1; j < jMax; j++) {
+ AbstractInvocation.Incremental consumingInvocation = (AbstractInvocation.Incremental) valueAndConsumingInvocations.get(j);
+ if (consumingInvocation == invocation) {
+ valueAndConsumingInvocations.remove(j);
+ break;
+ }
+ }
+ break;
+ }
+ }
+ }
} \ No newline at end of file
diff --git a/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/evaluation/Transformer.java b/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/evaluation/Transformer.java
index 0a56a9c0b..57c0b7a6d 100644
--- a/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/evaluation/Transformer.java
+++ b/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/evaluation/Transformer.java
@@ -48,5 +48,6 @@ public interface Transformer extends ExecutionVisitable
@NonNull ObjectManager getObjectManager();
@NonNull Collection<@NonNull ? extends EObject> getRootEObjects(@NonNull String modelName);
@NonNull Collection<@NonNull Object> getRootObjects(@NonNull String modelName);
+ @NonNull TypedModelInstance getTypedModelInstance(@NonNull String modelName);
boolean run() throws Exception;
}
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 514c509e8..3f42278e7 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
@@ -59,6 +59,11 @@ public abstract class AbstractConnectionInternal extends AbstractConnection
}
@Override
+ public int debugGetSize() {
+ return values.size();
+ }
+
+ @Override
public int getCapacity() {
return values.size();
}
diff --git a/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/internal/evaluation/AbstractIncrementalConnectionInternal.java b/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/internal/evaluation/AbstractIncrementalConnectionInternal.java
index 6b8c13363..7b00eb9e4 100644
--- a/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/internal/evaluation/AbstractIncrementalConnectionInternal.java
+++ b/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/internal/evaluation/AbstractIncrementalConnectionInternal.java
@@ -148,6 +148,17 @@ public abstract class AbstractIncrementalConnectionInternal extends AbstractConn
}
@Override
+ public int debugGetSize() {
+ int size = 0;
+ for (@Nullable List<@NonNull Object> valueAndConsumingInvocations : listOfValueAndConsumingInvocations) {
+ if (valueAndConsumingInvocations != null) {
+ size++;
+ }
+ }
+ return size;
+ }
+
+ @Override
public @NonNull Iterable<@NonNull InvocationConstructor> getAppenders() {
return appenders;
}
diff --git a/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/internal/evaluation/AbstractIntervalInternal.java b/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/internal/evaluation/AbstractIntervalInternal.java
index b87f37981..98b3b6c18 100644
--- a/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/internal/evaluation/AbstractIntervalInternal.java
+++ b/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/internal/evaluation/AbstractIntervalInternal.java
@@ -125,6 +125,29 @@ public abstract class AbstractIntervalInternal implements Interval
return connection;
}
+ public synchronized void destroy(@NonNull Invocation invocation) {
+ assert invocation.getInterval() == this;
+ if (debugInvocations) {
+ AbstractTransformer.INVOCATIONS.println("destroy " + invocation);
+ }
+ AbstractInvocationInternal castInvocation = (AbstractInvocationInternal) invocation;
+ assert blockedInvocations != castInvocation;
+ if (waitingInvocations == castInvocation) {
+ waitingInvocations = castInvocation.next;
+ if (waitingInvocations == castInvocation) {
+ waitingInvocations = null;
+ }
+ }
+ AbstractInvocationInternal prevInvocation = castInvocation.prev;
+ if (prevInvocation != castInvocation) {
+ AbstractInvocationInternal nextInvocation = castInvocation.next;
+ prevInvocation.next = nextInvocation;
+ nextInvocation.prev = prevInvocation;
+ castInvocation.next = castInvocation;
+ castInvocation.prev = castInvocation;
+ }
+ }
+
@Override
public boolean flush() {
while (headConnection != null) {
diff --git a/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/internal/evaluation/AbstractInvocationConstructor.java b/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/internal/evaluation/AbstractInvocationConstructor.java
index 8bbfe1d18..a8922812b 100644
--- a/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/internal/evaluation/AbstractInvocationConstructor.java
+++ b/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/internal/evaluation/AbstractInvocationConstructor.java
@@ -14,11 +14,11 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
-
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.ocl.pivot.evaluation.Executor;
import org.eclipse.ocl.pivot.ids.IdResolver;
+import org.eclipse.qvtd.runtime.evaluation.AbstractInvocation;
import org.eclipse.qvtd.runtime.evaluation.Connection;
import org.eclipse.qvtd.runtime.evaluation.ExecutionVisitor;
import org.eclipse.qvtd.runtime.evaluation.Interval;
@@ -32,8 +32,30 @@ public abstract class AbstractInvocationConstructor implements InvocationConstru
{
protected int sequence = 0;
- public Incremental(@NonNull InvocationManager invocationManager, @NonNull String name, boolean isStrict) {
- super(invocationManager, name, isStrict);
+ /**
+ * List of consumed connections.
+ */
+ private final @NonNull List<Connection.@NonNull Incremental> consumedConnections = new ArrayList<>();
+
+ public Incremental(@NonNull InvocationManager invocationManager, @NonNull String name) {
+ super(invocationManager, name, true);
+ }
+
+ @Override
+ public synchronized void addConsumedConnection(Connection.@NonNull Incremental connection) {
+ // assert !consumedConnections.contains(connection);
+ consumedConnections.add(connection);
+ super.addConsumedConnection(connection);
+ }
+
+ @Override
+ public @NonNull List<Connection.@NonNull Incremental> getConsumedConnections() {
+ return consumedConnections;
+ }
+
+ @Override
+ protected final @NonNull Invocation newInstance(@NonNull Object @NonNull [] values) {
+ throw new IllegalStateException("Incremental invocations require an invocationHashCode.");
}
@Override
@@ -254,7 +276,7 @@ public abstract class AbstractInvocationConstructor implements InvocationConstru
/**
* Flattened copy of hashCode2invocations.values(). Not maintained until actually requested.
*/
- private /*@LazyNonNull*/ List<@NonNull Invocation> allInvocations = null;
+ // private /*@LazyNonNull*/ List<@NonNull Invocation> allInvocations = null;
/**
* The number of values required to match the Mapping.ownedParameters.
@@ -319,8 +341,6 @@ public abstract class AbstractInvocationConstructor implements InvocationConstru
@Override
public synchronized void addConsumedConnection(@NonNull Connection connection) {
assert values == null;
- // assert !consumedConnections.contains(connection);
- // consumedConnections.add(connection);
connection.addConsumer(this);
if (firstConsumer != null) {
firstConsumer.appendConsumer(valuesCount, connection);
@@ -332,27 +352,42 @@ public abstract class AbstractInvocationConstructor implements InvocationConstru
valuesCount++;
}
+ // @Override
+ public synchronized void destroy(AbstractInvocation.@NonNull Incremental invocation, int invocationHashCode) {
+ Object zeroOrMoreInvocations = hashCode2invocations.get(invocationHashCode);
+ if (zeroOrMoreInvocations instanceof Invocation) {
+ Invocation oneInvocation = (Invocation)zeroOrMoreInvocations;
+ if (oneInvocation == invocation) {
+ hashCode2invocations.remove(invocationHashCode);
+ }
+ }
+ else if (zeroOrMoreInvocations instanceof List<?>) {
+ @SuppressWarnings("unchecked")@NonNull List<@NonNull Invocation> zeroOrMoreInvocations2 = (List<@NonNull Invocation>)zeroOrMoreInvocations;
+ zeroOrMoreInvocations2.remove(invocation);
+ if (zeroOrMoreInvocations2.size() == 1) {
+ hashCode2invocations.put(invocationHashCode, zeroOrMoreInvocations2.get(0));
+ }
+ }
+ }
+
@Override
public @NonNull Interval getInterval() {
return interval;
}
@Override
- public @NonNull Iterable<@NonNull Invocation> getInvocations() {
- List<@NonNull Invocation> allInvocations2 = allInvocations;
- if (allInvocations2 == null) {
- allInvocations2 = allInvocations = new ArrayList<>();
- for (Object zeroOrMoreInvocations : hashCode2invocations.values()) {
- if (zeroOrMoreInvocations instanceof Invocation) {
- allInvocations2.add((Invocation)zeroOrMoreInvocations);
- }
- else if (zeroOrMoreInvocations instanceof List<?>) {
- @SuppressWarnings("unchecked")@NonNull List<@NonNull Invocation> zeroOrMoreInvocations2 = (List<@NonNull Invocation>)zeroOrMoreInvocations;
- allInvocations2.addAll(zeroOrMoreInvocations2);
- }
+ public @NonNull Iterable<@NonNull Invocation> debugGetInvocations() {
+ List<@NonNull Invocation> allInvocations = new ArrayList<>();
+ for (Object zeroOrMoreInvocations : hashCode2invocations.values()) {
+ if (zeroOrMoreInvocations instanceof Invocation) {
+ allInvocations.add((Invocation)zeroOrMoreInvocations);
+ }
+ else if (zeroOrMoreInvocations instanceof List<?>) {
+ @SuppressWarnings("unchecked")@NonNull List<@NonNull Invocation> zeroOrMoreInvocations2 = (List<@NonNull Invocation>)zeroOrMoreInvocations;
+ allInvocations.addAll(zeroOrMoreInvocations2);
}
}
- return allInvocations2;
+ return allInvocations;
}
@Override
@@ -368,12 +403,12 @@ public abstract class AbstractInvocationConstructor implements InvocationConstru
public @NonNull Invocation invoke(@NonNull Object @NonNull ... argValues) {
Invocation theInvocation;
if (isStrict) {
- int hashCode = 0;
- for (@Nullable Object argValue : argValues) {
- hashCode = 3 * hashCode + idResolver.oclHashCode(argValue);
+ int invocationHashCode = 0;
+ for (@NonNull Object argValue : argValues) {
+ invocationHashCode = 3 * invocationHashCode + idResolver.oclHashCode(argValue);
}
synchronized (hashCode2invocations) {
- Object zeroOrMoreInvocations = hashCode2invocations.get(hashCode);
+ Object zeroOrMoreInvocations = hashCode2invocations.get(invocationHashCode);
Invocation oneInvocation = null;
List<@NonNull Invocation> twoOrMoreInvocations = null;
if (zeroOrMoreInvocations instanceof Invocation) {
@@ -391,16 +426,16 @@ public abstract class AbstractInvocationConstructor implements InvocationConstru
}
}
}
- theInvocation = newInstance(argValues);
+ theInvocation = newInstance(invocationHashCode, argValues);
if (zeroOrMoreInvocations == null) {
- hashCode2invocations.put(hashCode, theInvocation);
+ hashCode2invocations.put(invocationHashCode, theInvocation);
}
else if (twoOrMoreInvocations == null) {
twoOrMoreInvocations = new ArrayList<@NonNull Invocation>(4);
assert oneInvocation != null;
twoOrMoreInvocations.add(oneInvocation);
twoOrMoreInvocations.add(theInvocation);
- hashCode2invocations.put(hashCode, twoOrMoreInvocations);
+ hashCode2invocations.put(invocationHashCode, twoOrMoreInvocations);
}
else {
twoOrMoreInvocations.add(theInvocation);
@@ -410,9 +445,9 @@ public abstract class AbstractInvocationConstructor implements InvocationConstru
else {
theInvocation = newInstance(argValues);
}
- if (allInvocations != null) {
- allInvocations.add(theInvocation);
- }
+ // if (allInvocations != null) {
+ // allInvocations.add(theInvocation);
+ // }
interval.queue(theInvocation);
return theInvocation;
}
@@ -433,6 +468,14 @@ public abstract class AbstractInvocationConstructor implements InvocationConstru
*/
protected abstract @NonNull Invocation newInstance(@NonNull Object @NonNull [] values);
+ /**
+ * Create the mapping instance. In due course, its execute() method is invoked.
+ * Eventually the invocationHashCode may be used to facilitate destroy().
+ */
+ protected @NonNull Invocation newInstance(int invocationHashCode, @NonNull Object @NonNull [] values) {
+ return newInstance(values);
+ }
+
@Override
public void propagate() {
@NonNull Object[] values2 = values;
diff --git a/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/internal/evaluation/AbstractInvocationManagerInternal.java b/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/internal/evaluation/AbstractInvocationManagerInternal.java
index 127591bba..1a4730ac1 100644
--- a/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/internal/evaluation/AbstractInvocationManagerInternal.java
+++ b/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/internal/evaluation/AbstractInvocationManagerInternal.java
@@ -18,8 +18,11 @@ import org.eclipse.ocl.pivot.evaluation.Executor;
import org.eclipse.qvtd.runtime.evaluation.AbstractInvocationManager;
import org.eclipse.qvtd.runtime.evaluation.DefaultInterval;
import org.eclipse.qvtd.runtime.evaluation.Interval;
+import org.eclipse.qvtd.runtime.evaluation.Invocation;
import org.eclipse.qvtd.runtime.evaluation.InvocationConstructor;
+import com.google.common.collect.Iterables;
+
/**
* InvocationManager supervises and provides thread safety for the lists of blocked and waiting invocations.
*/
@@ -70,6 +73,14 @@ public abstract class AbstractInvocationManagerInternal extends AbstractInvocati
return invoker;
} */
+ public @NonNull Iterable<@NonNull Invocation> debugGetAllInvocations() {
+ List<@NonNull Invocation> allInvocations = new ArrayList<>();
+ for (@NonNull InvocationConstructor invoker : invokers) {
+ Iterables.addAll(allInvocations, invoker.debugGetInvocations());
+ }
+ return allInvocations;
+ }
+
@Override
public boolean flush() {
for (int index = nextIndex; index < intervals.size(); index = nextIndex) {
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 a405199f0..2cded70b5 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
@@ -123,7 +123,8 @@ public abstract class AbstractTransformerInternal /*extends AbstractModelManager
Set<@NonNull Integer> allClassIndexes = eClass2allClassIndexes.get(eClass);
if (allClassIndexes != null) {
for (@NonNull Integer classIndex : allClassIndexes) {
- ((Connection.Incremental)classIndex2connection[classIndex]).removeElement(eObject);
+ Connection.Incremental connection = (Connection.Incremental)classIndex2connection[classIndex];
+ connection.removeElement(eObject);
}
}
}
@@ -190,7 +191,7 @@ public abstract class AbstractTransformerInternal /*extends AbstractModelManager
for (int i = 0; i < classIds; i++) {
@NonNull
ClassId classId = classIndex2classId[i];
- classIndex2connection[i] = transformer.createConnection(name + "-" + classId, classId, false);
+ classIndex2connection[i] = transformer.createConnection(name /*+ "-" + classId*/, classId, false);
}
}
@@ -266,9 +267,9 @@ public abstract class AbstractTransformerInternal /*extends AbstractModelManager
isNotContainedCount++;
assert !potentialOrphanObjects.contains(eObject);
potentialOrphanObjects.add(eObject);
- EClass eClass = transformer.eClass(eObject);
- accumulateEObject1(eObject, eClass);
}
+ EClass eClass = transformer.eClass(eObject);
+ accumulateEObject1(eObject, eClass);
}
/**
@@ -580,11 +581,7 @@ public abstract class AbstractTransformerInternal /*extends AbstractModelManager
*/
@Override
public void addRootObjects(@NonNull String modelName, @NonNull Iterable<@NonNull ? extends Object> eRootObjects) {
- Integer modelIndex = modelIndexes.get(modelName);
- if (modelIndex == null) {
- throw new IllegalStateException("Unknown model name '" + modelName + "'");
- }
- models[modelIndex].addRootObjects(eRootObjects);
+ getTypedModelInstance(modelName).addRootObjects(eRootObjects);
}
protected @NonNull Connection createConnection(@NonNull String name, @NonNull TypeId typeId, boolean isStrict) {
@@ -740,12 +737,9 @@ public abstract class AbstractTransformerInternal /*extends AbstractModelManager
*/
@Override
public @NonNull Collection<@NonNull EObject> getRootEObjects(@NonNull String modelName) {
- Integer modelIndex = modelIndexes.get(modelName);
- if (modelIndex == null) {
- throw new IllegalStateException("Unknown model name '" + modelName + "'");
- }
+ Model model = getTypedModelInstance(modelName);
List<@NonNull EObject> rootEObjects = new ArrayList<>();
- for (@NonNull Object rootObject : models[modelIndex].getRootObjects()) {
+ for (@NonNull Object rootObject : model.getRootObjects()) {
if (rootObject instanceof EObject) {
rootEObjects.add((EObject)rootObject);
}
@@ -758,11 +752,16 @@ public abstract class AbstractTransformerInternal /*extends AbstractModelManager
*/
@Override
public @NonNull Collection<@NonNull Object> getRootObjects(@NonNull String modelName) {
+ return getTypedModelInstance(modelName).getRootObjects();
+ }
+
+ @Override
+ public @NonNull Model getTypedModelInstance(@NonNull String modelName) {
Integer modelIndex = modelIndexes.get(modelName);
if (modelIndex == null) {
throw new IllegalStateException("Unknown model name '" + modelName + "'");
}
- return models[modelIndex].getRootObjects();
+ return models[modelIndex];
}
/**
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 aaad51458..f3bb68e8b 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
@@ -63,6 +63,11 @@ public class IncrementalConnectionInternal extends AbstractIncrementalConnection
}
}
+ @Override
+ public void consume(int elementIndex, @NonNull Invocation invocation) {
+ super.consume(elementIndex, invocation);
+ }
+
/**
* Remove, inverse append, the old anElement. The old value is removed,
* its consumingInvocations are revoked so that their appends are also revoked.
@@ -76,7 +81,7 @@ public class IncrementalConnectionInternal extends AbstractIncrementalConnection
int jMax = valueAndConsumingInvocations.size();
for (int j = INDEX_INDEX+1; j < jMax; j++) {
AbstractInvocation.Incremental consumingInvocation = (AbstractInvocation.Incremental) valueAndConsumingInvocations.get(j);
- consumingInvocation.revokeExecution();
+ consumingInvocation.destroy();
}
break;
}
@@ -103,8 +108,8 @@ public class IncrementalConnectionInternal extends AbstractIncrementalConnection
}
/**
- * Revoke, inverse append, the old value at connectionKey. The old value is removed,
- * its consumingInvocations are revoked so that their appends are also revoked.
+ * Revoke, inverse append, the old value at connectionKey. The old object at copnnectionKey no longer exists.
+ * Its consumingInvocations are destroyed.
*/
@Override
public synchronized void revoke(@NonNull Object connectionKey) {
@@ -114,7 +119,25 @@ public class IncrementalConnectionInternal extends AbstractIncrementalConnection
int iMax = valueAndConsumingInvocations.size();
for (int i = INDEX_INDEX+1; i < iMax; i++) {
AbstractInvocation.Incremental consumingInvocation = (AbstractInvocation.Incremental) valueAndConsumingInvocations.get(i);
- consumingInvocation.revokeExecution();
+ consumingInvocation.destroy();
+ }
+ }
+
+ @Override
+ public void revokeConsumer(@NonNull Object anElement, Invocation.@NonNull Incremental invocation) { // FIXME Use connectionKey
+ for (int i = 0; i < listOfValueAndConsumingInvocations.size(); i++) {
+ List<@NonNull Object> valueAndConsumingInvocations = listOfValueAndConsumingInvocations.get(i);
+ if ((valueAndConsumingInvocations != null) && (valueAndConsumingInvocations.get(VALUE_INDEX) == anElement)) {
+ int jMax = valueAndConsumingInvocations.size();
+ for (int j = INDEX_INDEX+1; j < jMax; j++) {
+ AbstractInvocation.Incremental consumingInvocation = (AbstractInvocation.Incremental) valueAndConsumingInvocations.get(j);
+ if (consumingInvocation == invocation) {
+ valueAndConsumingInvocations.remove(j);
+ break;
+ }
+ }
+ break;
+ }
}
}
} \ 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 f4a43b0e5..9bdf22f50 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
@@ -21,6 +21,7 @@ import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
+import org.eclipse.ocl.pivot.internal.utilities.PivotUtilInternal;
import org.eclipse.ocl.pivot.oclstdlib.OCLstdlibPackage;
import org.eclipse.ocl.pivot.utilities.LabelUtil;
import org.eclipse.qvtd.runtime.evaluation.AbstractObjectManager;
@@ -42,7 +43,7 @@ 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
- REASSIGNABLE, // No assignment has been performed by a re-execution, object reads are blocked (collections reads may be 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;
@@ -137,8 +138,11 @@ public class IncrementalObjectManager extends AbstractObjectManager
@Override
public void revokeAssigned() {
- assert isAssigned();
+ SlotMode mode2 = mode;
mode = SlotMode.REASSIGNABLE;
+ if (mode2 == SlotMode.ASSIGNED) {
+ revokeTargets();
+ }
}
@Override
@@ -425,7 +429,7 @@ public class IncrementalObjectManager extends AbstractObjectManager
}
}
// super.assigned(objectManager, eObject, eFeature, ecoreValue);
- assignedElement(eObject, (EReference)eFeature, (EObject)ecoreValue);
+ assignedElement(eObject, (EReference)eFeature, /*(EObject)*/ecoreValue);
}
public void assignedElement(@NonNull Object eContainer, @NonNull EReference eReference, Object eObject) {
@@ -726,6 +730,19 @@ public class IncrementalObjectManager extends AbstractObjectManager
invocation.addWriteSlot(slotState);
}
+ public @Nullable Map<@NonNull EStructuralFeature, @NonNull BasicSlotState> basicGetObjectState(@NonNull Object eObject) {
+ return object2feature2slotState.get(eObject);
+ }
+
+ public @Nullable BasicSlotState basicGetSlotState(@NonNull Object eObject, @NonNull EStructuralFeature eFeature) {
+ assert eFeature != null;
+ Map<EStructuralFeature, BasicSlotState> objectState = basicGetObjectState(eObject);
+ if (objectState == null) {
+ return null;
+ }
+ return objectState.get(eFeature);
+ }
+
@NonNull BasicSlotState createManyToManySlotState(
@NonNull Object eObject, @NonNull EReference eFeature, @NonNull EReference eOppositeFeature) {
throw new UnsupportedOperationException();
@@ -769,7 +786,13 @@ public class IncrementalObjectManager extends AbstractObjectManager
invocation.addCreatedObject(eObject);
}
- public @NonNull Map<EStructuralFeature, BasicSlotState> getObjectState(@NonNull Object eObject) {
+ @Override
+ public void destroyed(@NonNull Object eObject) {
+ PivotUtilInternal.resetContainer((EObject) eObject);
+ object2feature2slotState.remove(eObject);
+ }
+
+ public @NonNull Map<@NonNull EStructuralFeature, @NonNull BasicSlotState> getObjectState(@NonNull Object eObject) {
Map<@NonNull EStructuralFeature, @NonNull BasicSlotState> feature2state = object2feature2slotState.get(eObject);
if (feature2state == null) {
feature2state = new HashMap<@NonNull EStructuralFeature, @NonNull BasicSlotState>();
@@ -856,9 +879,11 @@ public class IncrementalObjectManager extends AbstractObjectManager
}
public void modified(@NonNull Object eObject, @NonNull EStructuralFeature eFeature) {
- BasicSlotState slotState = getSlotState(eObject, eFeature);
- for (Execution.@NonNull Incremental execution : slotState.getTargets()) {
- execution.revokeExecution();
+ BasicSlotState slotState = basicGetSlotState(eObject, eFeature);
+ if (slotState != null) {
+ for (Execution.@NonNull Incremental execution : slotState.getTargets()) {
+ execution.revoke();
+ }
}
}
} \ No newline at end of file
diff --git a/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/internal/evaluation/LazyObjectManager.java b/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/internal/evaluation/LazyObjectManager.java
index 8f93ab3a6..2560cacc3 100644
--- a/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/internal/evaluation/LazyObjectManager.java
+++ b/plugins/org.eclipse.qvtd.runtime/src/org/eclipse/qvtd/runtime/internal/evaluation/LazyObjectManager.java
@@ -160,15 +160,15 @@ public class LazyObjectManager extends AbstractObjectManager
public synchronized void assigned(@NonNull LazyObjectManager objectManager, @NonNull Object eObject, @NonNull EStructuralFeature eFeature, @Nullable Object ecoreValue) {
switch (mode) {
- case ASSIGNABLE:
- mode = SlotMode.ASSIGNED;
- unblock(objectManager);
- break;
- case ASSIGNED:
- if (!(eFeature instanceof EOppositeReferenceImpl)) {
- System.out.println("Re-assignment of " + eFeature.getEContainingClass().getName() + "::" + eFeature.getName() + " for " + eObject + " with " + ecoreValue);
- }
- break;
+ case ASSIGNABLE:
+ mode = SlotMode.ASSIGNED;
+ unblock(objectManager);
+ break;
+ case ASSIGNED:
+ if (!(eFeature instanceof EOppositeReferenceImpl)) {
+ System.out.println("Re-assignment of " + eFeature.getEContainingClass().getName() + "::" + eFeature.getName() + " for " + eObject + " with " + ecoreValue);
+ }
+ break;
}
}
@@ -194,10 +194,10 @@ public class LazyObjectManager extends AbstractObjectManager
@Override
public synchronized void getting(@NonNull Object eObject, @NonNull EStructuralFeature eFeature) {
switch (mode) {
- case ASSIGNABLE:
- throw new InvocationFailedException(this);
- case ASSIGNED:
- break;
+ case ASSIGNABLE:
+ throw new InvocationFailedException(this);
+ case ASSIGNED:
+ break;
}
}
@@ -511,24 +511,24 @@ public class LazyObjectManager extends AbstractObjectManager
public void assignedElement(@NonNull Object eContainer, @NonNull EReference eReference, Object eObject) {
// super.assigned(objectManager, eContainer, eReference, eObject);
switch (mode) {
- case ASSIGNABLE:
- mode = SlotMode.ASSIGNED;
- unblock(LazyObjectManager.this);
- break;
- case ASSIGNED:
- break;
+ case ASSIGNABLE:
+ mode = SlotMode.ASSIGNED;
+ unblock(LazyObjectManager.this);
+ break;
+ case ASSIGNED:
+ break;
}
}
@Override
public synchronized void getting(@NonNull Object eObject, @NonNull EStructuralFeature eFeature) {
switch (mode) {
- case ASSIGNABLE:
- mode = SlotMode.ASSIGNED;
- unblock(LazyObjectManager.this);
- break;
- case ASSIGNED:
- break;
+ case ASSIGNABLE:
+ mode = SlotMode.ASSIGNED;
+ unblock(LazyObjectManager.this);
+ break;
+ case ASSIGNED:
+ break;
}
}
}
@@ -892,6 +892,11 @@ public class LazyObjectManager extends AbstractObjectManager
// Ignore incremental API
}
+ @Override
+ public void destroyed(@NonNull Object eObject) {
+ // Ignore incremental API
+ }
+
protected @NonNull EReference getEOppositeReference(@NonNull EReference eReference) {
EReference eOppositeReference = eReference.getEOpposite();
if (eOppositeReference == null) {
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
index 7b0274c3e..70a0f4be9 100644
--- 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
@@ -1,5 +1,7 @@
package org.eclipse.qvtd.runtime.internal.evaluation;
+import java.util.ArrayDeque;
+import java.util.Deque;
import java.util.List;
import org.eclipse.emf.common.notify.Adapter;
@@ -11,7 +13,9 @@ 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.AbstractTransformer;
import org.eclipse.qvtd.runtime.evaluation.TransformationExecutor;
+import org.eclipse.qvtd.runtime.evaluation.TypedModelInstance;
/**
* An adapter implementation for tracking resource modification.
@@ -30,7 +34,7 @@ public class ModificationMonitor implements Adapter
return null;
}
- public static @NonNull ModificationMonitor getModificationMonitor(@NonNull Resource resource, @NonNull TransformationExecutor executor) {
+ public static @NonNull ModificationMonitor getModificationMonitor(@NonNull TypedModelInstance typedModelInstance, @NonNull Resource resource, @NonNull TransformationExecutor executor) {
List<Adapter> eAdapters = resource.eAdapters();
for (Adapter eAdapter : eAdapters) {
if (eAdapter instanceof ModificationMonitor) {
@@ -40,7 +44,7 @@ public class ModificationMonitor implements Adapter
}
}
}
- ModificationMonitor monitor = new ModificationMonitor(resource, executor);
+ ModificationMonitor monitor = new ModificationMonitor(typedModelInstance, resource, executor);
for (@NonNull EObject eObject : new TreeIterable(resource)) {
eObject.eAdapters().add(monitor);
}
@@ -48,12 +52,41 @@ public class ModificationMonitor implements Adapter
return monitor;
}
- private @NonNull Resource resource;
- private @NonNull TransformationExecutor executor;
+ private final AbstractTransformerInternal.Model.@NonNull Incremental typedModelInstance;
+ private final @NonNull Resource resource;
+ private final @NonNull TransformationExecutor executor;
+ private final AbstractTransformer.@NonNull Incremental transformer;
+ // private final @NonNull IncrementalInvocationManager invocationManager;
+ private final @NonNull IncrementalObjectManager objectManager;
+ private @Nullable Deque<@NonNull Notification> notifications = null;
+ private boolean isDisabled = false;
- public ModificationMonitor(@NonNull Resource resource, @NonNull TransformationExecutor executor) {
+ public ModificationMonitor(@NonNull TypedModelInstance typedModelInstance, @NonNull Resource resource, @NonNull TransformationExecutor executor) {
+ this.typedModelInstance = (AbstractTransformerInternal.Model.Incremental)typedModelInstance;
this.resource = resource;
this.executor = executor;
+ this.transformer = (AbstractTransformer.Incremental) executor.getTransformer();
+ // this.transformer = (AbstractTransformer.Incremental) typedModelInstance.getTransformer();
+ // this.invocationManager = (IncrementalInvocationManager) transformer.getInvocationManager();
+ this.objectManager = (IncrementalObjectManager) transformer.getObjectManager();
+ }
+
+ protected void addEObject(@NonNull EObject newValue) {
+ for (@NonNull EObject eObject : new TreeIterable(newValue, true)) {
+ eObject.eAdapters().add(this);
+ }
+ typedModelInstance.add(newValue, false);
+ for (@NonNull EObject eObject : new TreeIterable(newValue, false)) {
+ typedModelInstance.add(eObject, true);
+ }
+ }
+
+ public void dispose() {
+ isDisabled = true;
+ Deque<@NonNull Notification> notifications2 = notifications;
+ if (notifications2 != null) {
+ notifications2.clear();
+ }
}
public @NonNull TransformationExecutor getExecutor() {
@@ -73,22 +106,55 @@ public class ModificationMonitor implements Adapter
@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:
+ if (isDisabled) {
+ return;
+ }
+ assert notification != null;
+ if (notification.isTouch()) {
+ return;
+ }
+ Deque<@NonNull Notification> notifications2 = notifications;
+ assert notifications2 == null;
+ if (notifications2 != null) {
+ notifications2.add(notification);
+ return;
+ }
+ notifications2 = notifications = new ArrayDeque<>();
+ do {
+ int eventType = notification.getEventType();
+ switch (eventType) {
+ case Notification.ADD: {
+ EObject object2 = (EObject) notification.getNewValue();
+ assert object2 != null;
+ addEObject(object2);
+ break;
+ }
case Notification.REMOVE: {
+ EObject object2 = (EObject) notification.getOldValue();
+ assert object2 != null;
+ removeEObject(object2);
+ break;
+ }
+ case Notification.ADD_MANY: {
+ for (Object object : (Iterable<?>)notification.getNewValue()) {
+ EObject object2 = (EObject) object;
+ assert object2 != null;
+ addEObject(object2);
+ }
break;
}
- case Notification.ADD_MANY:
case Notification.REMOVE_MANY: {
+ for (Object object : (Iterable<?>)notification.getOldValue()) {
+ EObject object2 = (EObject) object;
+ assert object2 != null;
+ removeEObject(object2);
+ }
break;
}
case Notification.SET:
case Notification.UNSET: {
+ Object notifier = notification.getNotifier();
+ assert notifier != null;
Object feature = notification.getFeature();
if (feature instanceof EStructuralFeature) {
objectManager.modified(notifier, (EStructuralFeature)feature);
@@ -96,6 +162,24 @@ public class ModificationMonitor implements Adapter
break;
}
}
+ notification = notifications2.peek() != null ? notifications2.pop() : null;
+ } while (notification != null);
+ notifications = null;
+ }
+
+ protected void removeEObject(@NonNull EObject oldValue) {
+ for (EObject eObject : new TreeIterable(oldValue, true)) {
+ eObject.eAdapters().remove(this);
+ }
+ // if (feature instanceof EReference) {
+ // EReference eReference = (EReference)feature;
+ // if (eReference.isContainment()) {
+ IncrementalObjectManager objectManager = (IncrementalObjectManager)executor.getTransformer().getObjectManager();
+ // }
+ // }
+ for (EObject eObject : new TreeIterable(oldValue, true)) {
+ typedModelInstance.remove(eObject);
+ objectManager.destroyed(eObject);
}
}
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 98ea08109..36c5c4427 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
@@ -128,7 +128,7 @@ public abstract class StrictIncrementalConnectionInternal extends AbstractIncrem
int iMax = valueAndConsumingInvocations.size();
for (int i = COUNT_INDEX+1; i < iMax; i++) {
AbstractInvocation.Incremental consumingInvocation = (AbstractInvocation.Incremental) valueAndConsumingInvocations.get(i);
- consumingInvocation.revokeExecution();
+ consumingInvocation.revoke();
}
}
} \ No newline at end of file
diff --git a/tests/org.eclipse.qvtd.xtext.qvtimperative.tests/.classpath b/tests/org.eclipse.qvtd.xtext.qvtimperative.tests/.classpath
index dab1cc829..b6d3429da 100644
--- a/tests/org.eclipse.qvtd.xtext.qvtimperative.tests/.classpath
+++ b/tests/org.eclipse.qvtd.xtext.qvtimperative.tests/.classpath
@@ -12,5 +12,6 @@
</classpathentry>
<classpathentry excluding="**/*.launch" kind="src" path="src"/>
<classpathentry kind="src" path="src-gen"/>
+ <!--classpathentry kind="src" path="test-gen"/-->
<classpathentry kind="output" path="bin"/>
</classpath>
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 fbfb35bcc..69fdb45c4 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
@@ -12,6 +12,9 @@ package org.eclipse.qvtd.xtext.qvtimperative.tests;
import java.io.File;
import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
import java.util.Map;
import org.eclipse.emf.codegen.ecore.genmodel.GenModel;
@@ -22,12 +25,14 @@ 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;
+import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.ocl.examples.codegen.dynamic.OCL2JavaFileObject;
import org.eclipse.ocl.examples.xtext.tests.TestUtil;
import org.eclipse.ocl.pivot.internal.manager.MetamodelManagerInternal;
import org.eclipse.ocl.pivot.internal.utilities.OCLInternal;
+import org.eclipse.ocl.pivot.internal.utilities.PivotUtilInternal;
import org.eclipse.ocl.pivot.internal.validation.PivotEObjectValidator;
import org.eclipse.ocl.pivot.oclstdlib.OCLstdlibTables;
import org.eclipse.ocl.pivot.resource.ASResource;
@@ -48,8 +53,16 @@ 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.AbstractTransformer;
+import org.eclipse.qvtd.runtime.evaluation.Connection;
+import org.eclipse.qvtd.runtime.evaluation.Interval;
+import org.eclipse.qvtd.runtime.evaluation.Invocation;
+import org.eclipse.qvtd.runtime.evaluation.InvocationManager;
+import org.eclipse.qvtd.runtime.evaluation.ObjectManager;
import org.eclipse.qvtd.runtime.evaluation.TransformationExecutor;
import org.eclipse.qvtd.runtime.evaluation.Transformer;
+import org.eclipse.qvtd.runtime.evaluation.TypedModelInstance;
+import org.eclipse.qvtd.runtime.internal.evaluation.AbstractInvocationManagerInternal;
import org.eclipse.qvtd.runtime.internal.evaluation.ModificationMonitor;
import org.eclipse.qvtd.xtext.qvtbase.tests.LoadTestCase;
import org.eclipse.qvtd.xtext.qvtbase.tests.ModelNormalizer;
@@ -57,6 +70,8 @@ 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 com.google.common.collect.Iterables;
+
import junit.framework.TestCase;
/**
@@ -204,6 +219,20 @@ public class QVTiCompilerTests extends LoadTestCase
}
}
+ protected void checkCleared(@NonNull TransformationExecutor executor) {
+ AbstractInvocationManagerInternal invocationManager = (AbstractInvocationManagerInternal)executor.getTransformer().getInvocationManager();
+ Iterable<@NonNull Invocation> allInvocations = invocationManager.debugGetAllInvocations();
+ assertEquals("All invocations post-clear", 1, Iterables.size(allInvocations));
+ for (@NonNull Interval interval : invocationManager.getIntervals()) {
+ for (@NonNull Connection connection : interval.getConnections()) {
+ assertEquals("Connection '" + connection.getName() + "' post-clear", 0, connection.debugGetSize());
+ }
+ }
+ ObjectManager objectManager = executor.getTransformer().getObjectManager();
+ Iterable<@NonNull ? extends Object> allObjects = objectManager.getObjects();
+ assertEquals("All objects post-clear", 0, Iterables.size(allObjects));
+ }
+
protected @NonNull MyQVT createQVT() {
return new MyQVT(new MyQVTiEnvironmentFactory(getProjectMap(), null));
}
@@ -221,7 +250,7 @@ public class QVTiCompilerTests extends LoadTestCase
super.setUp();
}
- public void testCG_HSV2HSL_qvti() throws Exception {
+ public void testQVTiCompiler_HSV2HLS_CG() throws Exception {
MyQVT myQVT = createQVT();
URI transformURI = getProjectFileURI("HSV2HSL/HSV2HSL.qvti");
URI genModelURI = getProjectFileURI("HSV2HSL/HSV2HSL.genmodel");
@@ -237,7 +266,7 @@ public class QVTiCompilerTests extends LoadTestCase
myQVT.dispose();
}
- public void testCG_ClassesCS2AS_qvti() throws Exception {
+ public void testQVTiCompiler_ClassesCS2AS_CG() throws Exception {
MyQVT myQVT = createQVT();
URI transformURI = getProjectFileURI("ClassesCS2AS/ClassesCS2AS.qvti");
URI genModelURI = getProjectFileURI("ClassesCS2AS/ClassesCS2AS.genmodel");
@@ -246,7 +275,7 @@ public class QVTiCompilerTests extends LoadTestCase
myQVT.dispose();
}
- public void testCG_ClassesCS2AS_bug459225() throws Exception {
+ public void testQVTiCompiler_ClassesCS2AS_bug459225_CG() throws Exception {
MyQVT myQVT = createQVT();
URI transformURI = getProjectFileURI("ClassesCS2AS/bug459225/ClassesCS2AS.qvti");
URI genModelURI = getProjectFileURI("ClassesCS2AS/ClassesCS2AS.genmodel");
@@ -262,7 +291,7 @@ public class QVTiCompilerTests extends LoadTestCase
myQVT.dispose();
}
- public void testCG_ManualUML2RDBMS_qvti() throws Exception {
+ public void testQVTiCompiler_ManualUML2RDBMS_CG() throws Exception {
MyQVT myQVT = createQVT();
URI transformURI = getProjectFileURI("ManualUML2RDBMS/ManualUML2RDBMS.qvti");
URI genModelURI = getProjectFileURI("ManualUML2RDBMS/ManualUML2RDBMS.genmodel");
@@ -278,7 +307,7 @@ public class QVTiCompilerTests extends LoadTestCase
myQVT.dispose();
}
- public void testCG_SimpleUML2RDBMS_qvti() throws Exception {
+ public void testQVTiCompiler_SimpleUML2RDBMS_CG() throws Exception {
MyQVT myQVT = createQVT();
URI transformURI = getProjectFileURI("SimpleUML2RDBMS/SimpleUML2RDBMS.qvti");
URI genModelURI = getProjectFileURI("SimpleUML2RDBMS/SimpleUML2RDBMS.genmodel");
@@ -294,14 +323,14 @@ public class QVTiCompilerTests extends LoadTestCase
myQVT.dispose();
}
- public void testCG_Tree2TallTree_qvti() throws Exception {
+ public void testQVTiCompiler_Tree2TallTree_CG() throws Exception {
// AbstractTransformer.INVOCATIONS.setState(true);
MyQVT myQVT = createQVT();
URI genModelURI = getProjectFileURI("Tree2TallTree/Tree2TallTree.genmodel");
URI transformURI = getProjectFileURI("Tree2TallTree/Tree2TallTree.qvti");
- URI inputModelURI = getProjectFileURI("Tree2TallTree/Tree.xmi");
- URI outputModelURI = getProjectFileURI("Tree2TallTree/Tree2TallTree.xmi");
- URI referenceModelURI = getProjectFileURI("Tree2TallTree/TallTreeValidate.xmi");
+ URI inputModelURI = getProjectFileURI("Tree2TallTree/samples/Tree.xmi");
+ URI outputModelURI = getProjectFileURI("Tree2TallTree/samples/Tree2TallTree.xmi");
+ URI referenceModelURI = getProjectFileURI("Tree2TallTree/samples/TallTreeValidate.xmi");
Transformation asTransformation = myQVT.loadTransformation(transformURI, genModelURI);
Class<? extends Transformer> txClass = myQVT.generateCode(asTransformation, false);
Transformer tx = myQVT.createTransformer(txClass);
@@ -312,25 +341,25 @@ public class QVTiCompilerTests extends LoadTestCase
myQVT.dispose();
}
- public void testCG_Tree2TallTree_Incremental_qvti() throws Exception {
- // AbstractTransformer.INVOCATIONS.setState(true);
+ public void testQVTiCompiler_Tree2TallTree_Changed_CG() throws Exception {
MyQVT myQVT = createQVT();
URI genModelURI = getProjectFileURI("Tree2TallTree/Tree2TallTree.genmodel");
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");
+ URI inputModelURI = getProjectFileURI("Tree2TallTree/samples/Tree.xmi");
+ URI outputModelURI = getProjectFileURI("Tree2TallTree/samples/Tree2TallTree.xmi");
+ URI changedOutputModelURI = getProjectFileURI("Tree2TallTree/samples/Tree2TallTreeChanged.xmi");
+ URI referenceModelURI = getProjectFileURI("Tree2TallTree/samples/TallTreeValidate.xmi");
+ URI changedReferenceModelURI = getProjectFileURI("Tree2TallTree/samples/TallTreeValidateChanged.xmi");
Transformation asTransformation = myQVT.loadTransformation(transformURI, genModelURI);
Class<? extends Transformer> txClass = myQVT.generateCode(asTransformation, true);
Transformer tx = myQVT.createTransformer(txClass);
Resource inputResource = myQVT.loadInput(tx, "tree", inputModelURI);
tx.run();
- Execution2GraphVisitor.writeGraphMLfile(tx, getProjectFileURI("Tree2TallTree/Tree2TallTree-inc.graphml"));
+ Execution2GraphVisitor.writeGraphMLfile(tx, getProjectFileURI("Tree2TallTree/graphs/Tree2TallTree-inc.graphml"));
myQVT.saveOutput(tx, "talltree", outputModelURI, referenceModelURI, null);
TransformationExecutor executor = tx.getExecutor();
- @SuppressWarnings("unused") ModificationMonitor monitor = ModificationMonitor.getModificationMonitor(inputResource, executor);
+ TypedModelInstance treeModel = tx.getTypedModelInstance("tree");
+ @SuppressWarnings("unused") ModificationMonitor monitor = ModificationMonitor.getModificationMonitor(treeModel, inputResource, executor);
int gotOne = 0;
for (EObject eObject : new TreeIterable(inputResource)) {
EClass eClass = eObject.eClass();
@@ -345,12 +374,95 @@ public class QVTiCompilerTests extends LoadTestCase
}
assert gotOne == 1;
executor.getTransformer().getInvocationManager().flush();
- Execution2GraphVisitor.writeGraphMLfile(tx, getProjectFileURI("Tree2TallTree/Tree2TallTree-inc2.graphml"));
- myQVT.saveOutput(tx, "talltree", outputModelURI2, referenceModelURI2, null);
+ Execution2GraphVisitor.writeGraphMLfile(tx, getProjectFileURI("Tree2TallTree/graphs/Tree2TallTree-incChanged.graphml"));
+ myQVT.saveOutput(tx, "talltree", changedOutputModelURI, changedReferenceModelURI, null);
myQVT.dispose();
}
- /* public void testCG_Tree2TallTree_Incremental_qvti2() throws Exception {
+ public void testQVTiCompiler_Tree2TallTree_Copied_CG() throws Exception {
+ AbstractTransformer.INVOCATIONS.setState(true);
+ MyQVT myQVT = createQVT();
+ URI genModelURI = getProjectFileURI("Tree2TallTree/Tree2TallTree.genmodel");
+ URI transformURI = getProjectFileURI("Tree2TallTree/Tree2TallTree.qvti");
+ URI inputModelURI = getProjectFileURI("Tree2TallTree/samples/Tree.xmi");
+ URI outputModelURI = getProjectFileURI("Tree2TallTree/samples/Tree2TallTree.xmi");
+ URI clearedOutputModelURI = getProjectFileURI("Tree2TallTree/samples/Tree2TallTreeCleared.xmi");
+ URI copiedOutputModelURI = getProjectFileURI("Tree2TallTree/samples/Tree2TallTreeCopied.xmi");
+ URI referenceModelURI = getProjectFileURI("Tree2TallTree/samples/TallTreeValidate.xmi");
+ URI clearedReferenceModelURI = getProjectFileURI("Tree2TallTree/samples/TallTreeValidateCleared.xmi");
+ Transformation asTransformation = myQVT.loadTransformation(transformURI, genModelURI);
+ Class<? extends Transformer> txClass = myQVT.generateCode(asTransformation, true);
+ Transformer tx = myQVT.createTransformer(txClass);
+ Resource inputResource = myQVT.loadInput(tx, "tree", inputModelURI);
+ tx.run();
+ Execution2GraphVisitor.writeGraphMLfile(tx, getProjectFileURI("Tree2TallTree/graphs/Tree2TallTree-inc.graphml"));
+ myQVT.saveOutput(tx, "talltree", outputModelURI, referenceModelURI, null);
+ TransformationExecutor executor = tx.getExecutor();
+ TypedModelInstance treeModel = tx.getTypedModelInstance("tree");
+ @SuppressWarnings("unused") ModificationMonitor monitor = ModificationMonitor.getModificationMonitor(treeModel, inputResource, executor);
+ List<@NonNull EObject> contents = inputResource.getContents();
+ List<@NonNull EObject> oldContents = new ArrayList<>(contents);
+ Collection<@NonNull EObject> newContents = EcoreUtil.copyAll(oldContents);
+ contents.clear();
+
+ checkCleared(executor);
+ InvocationManager invocationManager = executor.getTransformer().getInvocationManager();
+
+ // oldContents.addAll(newContents);
+ invocationManager.flush();
+ Execution2GraphVisitor.writeGraphMLfile(tx, getProjectFileURI("Tree2TallTree/graphs/Tree2TallTree-incCleared.graphml"));
+ myQVT.saveOutput(tx, "talltree", clearedOutputModelURI, clearedReferenceModelURI, null);
+
+ contents.addAll(newContents);
+ invocationManager.flush();
+ Execution2GraphVisitor.writeGraphMLfile(tx, getProjectFileURI("Tree2TallTree/graphs/Tree2TallTree-incCopied.graphml"));
+ myQVT.saveOutput(tx, "talltree", copiedOutputModelURI, referenceModelURI, null);
+
+
+ myQVT.dispose();
+ }
+
+ public void testQVTiCompiler_Tree2TallTree_Deleted_CG() throws Exception {
+ AbstractTransformer.INVOCATIONS.setState(true);
+ MyQVT myQVT = createQVT();
+ URI genModelURI = getProjectFileURI("Tree2TallTree/Tree2TallTree.genmodel");
+ URI transformURI = getProjectFileURI("Tree2TallTree/Tree2TallTree.qvti");
+ URI inputModelURI = getProjectFileURI("Tree2TallTree/samples/Tree.xmi");
+ URI outputModelURI = getProjectFileURI("Tree2TallTree/samples/Tree2TallTree.xmi");
+ URI deletedOutputModelURI = getProjectFileURI("Tree2TallTree/samples/Tree2TallTreeDeleted.xmi");
+ URI referenceModelURI = getProjectFileURI("Tree2TallTree/samples/TallTreeValidate.xmi");
+ URI deletedReferenceModelURI = getProjectFileURI("Tree2TallTree/samples/TallTreeValidateDeleted.xmi");
+ Transformation asTransformation = myQVT.loadTransformation(transformURI, genModelURI);
+ Class<? extends Transformer> txClass = myQVT.generateCode(asTransformation, true);
+ Transformer tx = myQVT.createTransformer(txClass);
+ Resource inputResource = myQVT.loadInput(tx, "tree", inputModelURI);
+ tx.run();
+ Execution2GraphVisitor.writeGraphMLfile(tx, getProjectFileURI("Tree2TallTree/graphs/Tree2TallTree-inc.graphml"));
+ myQVT.saveOutput(tx, "talltree", outputModelURI, referenceModelURI, null);
+ TransformationExecutor executor = tx.getExecutor();
+ TypedModelInstance treeModel = tx.getTypedModelInstance("tree");
+ ModificationMonitor monitor = ModificationMonitor.getModificationMonitor(treeModel,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.1".equals(name)) {
+ gotOne++;
+ PivotUtilInternal.resetContainer(eObject);
+ }
+ }
+ }
+ assert gotOne == 1;
+ executor.getTransformer().getInvocationManager().flush();
+ Execution2GraphVisitor.writeGraphMLfile(tx, getProjectFileURI("Tree2TallTree/graphs/Tree2TallTree-incDeleted.graphml"));
+ myQVT.saveOutput(tx, "talltree", deletedOutputModelURI, deletedReferenceModelURI, null);
+ monitor.dispose();
+ myQVT.dispose();
+ }
+
+ /* public void testQVTiCompiler_Tree2TallTree_Incremental_CG2() throws Exception {
// AbstractTransformer.INVOCATIONS.setState(true);
MyQVT myQVT = createQVT();
URI genModelURI = getProjectFileURI("Tree2TallTree/Tree2TallTree.genmodel");
@@ -364,7 +476,7 @@ public class QVTiCompilerTests extends LoadTestCase
Transformer tx = myQVT.createTransformer(txClass);
Resource inputResource = myQVT.loadInput(tx, "tree", inputModelURI);
tx.run();
- Execution2GraphVisitor.writeGraphMLfile(tx, getProjectFileURI("Tree2TallTree/Tree2TallTree-inc.graphml"));
+ Execution2GraphVisitor.writeGraphMLfile(tx, getProjectFileURI("Tree2TallTree/graphs/Tree2TallTree-inc.graphml"));
myQVT.saveOutput(tx, "talltree", outputModelURI, referenceModelURI, null);
TransformationExecutor executor = tx.getExecutor();
ModificationMonitor monitor = ModificationMonitor.getModificationMonitor(inputResource, executor);
@@ -382,20 +494,20 @@ public class QVTiCompilerTests extends LoadTestCase
}
assert gotOne == 1;
executor.getTransformer().getInvocationManager().flush();
- Execution2GraphVisitor.writeGraphMLfile(tx, getProjectFileURI("Tree2TallTree/Tree2TallTree-inc2.graphml"));
+ Execution2GraphVisitor.writeGraphMLfile(tx, getProjectFileURI("Tree2TallTree/graphs/Tree2TallTree-inc2.graphml"));
myQVT.saveOutput(tx, "talltree", outputModelURI2, referenceModelURI2, null);
myQVT.dispose();
} */
- public void testCG_Tree2TallTreeInstall_qvti() throws Exception {
+ /* public void testQVTiCompiler_Tree2TallTreeInstall_CG() throws Exception {
// AbstractTransformer.INVOCATIONS.setState(true);
MyQVT myQVT = createQVT();
URI genModelURI = getProjectFileURI("Tree2TallTree/Tree2TallTree.genmodel");
URI transformURI = getProjectFileURI("Tree2TallTree/Tree2TallTreeInstall.qvti");
- URI inputModelURI = getProjectFileURI("Tree2TallTree/Tree.xmi");
- URI outputModelURI = getProjectFileURI("Tree2TallTree/Tree2TallTree.xmi");
- URI referenceModelURI = getProjectFileURI("Tree2TallTree/TallTreeValidate.xmi");
+ URI inputModelURI = getProjectFileURI("Tree2TallTree/samples/Tree.xmi");
+ URI outputModelURI = getProjectFileURI("Tree2TallTree/samples/Tree2TallTree.xmi");
+ URI referenceModelURI = getProjectFileURI("Tree2TallTree/samples/TallTreeValidate.xmi");
Transformation asTransformation = myQVT.loadTransformation(transformURI, genModelURI);
Class<? extends Transformer> txClass = myQVT.generateCode(asTransformation, true);
Transformer tx = myQVT.createTransformer(txClass);
@@ -403,5 +515,5 @@ public class QVTiCompilerTests extends LoadTestCase
tx.run();
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/QVTiInterpreterTests.java b/tests/org.eclipse.qvtd.xtext.qvtimperative.tests/src/org/eclipse/qvtd/xtext/qvtimperative/tests/QVTiInterpreterTests.java
index 529dfabaa..665bae913 100644
--- a/tests/org.eclipse.qvtd.xtext.qvtimperative.tests/src/org/eclipse/qvtd/xtext/qvtimperative/tests/QVTiInterpreterTests.java
+++ b/tests/org.eclipse.qvtd.xtext.qvtimperative.tests/src/org/eclipse/qvtd/xtext/qvtimperative/tests/QVTiInterpreterTests.java
@@ -190,7 +190,7 @@ public class QVTiInterpreterTests extends LoadTestCase
GraphMLBuilder s = new GraphMLBuilder();
//FIXME getTransformationStatus().accept(new EvaluationStatus2GraphVisitor(s));
File projectFile = getProjectFile();
- File graphFile = new File(projectFile.toString() + "/" + fileNamePrefix + transformation.getName() + "_" + mode + ".graphml");
+ File graphFile = new File(projectFile.toString() + "/" + fileNamePrefix + /*"graphs/" +*/ transformation.getName() + "_" + mode + ".graphml");
FileWriter writer = new FileWriter(graphFile);
writer.append(s.toString());
writer.close();
@@ -199,7 +199,7 @@ public class QVTiInterpreterTests extends LoadTestCase
public void writeExecutionGraphMLfile(@NonNull String suffix) {
@SuppressWarnings("null")@NonNull URI baseURI = getTransformation().eResource().getURI();
- URI graphmlURI = URI.createURI(getTransformation().getName().replace("\n", "_").replace("\\n", "_") + suffix + ".graphml").resolve(baseURI);
+ URI graphmlURI = URI.createURI(/*"graphs/" +*/ getTransformation().getName().replace("\n", "_").replace("\\n", "_") + suffix + ".graphml").resolve(baseURI);
try {
OutputStream outputStream = URIConverter.INSTANCE.createOutputStream(graphmlURI);
GraphMLStringBuilder s = new GraphMLStringBuilder();
@@ -347,10 +347,10 @@ public class QVTiInterpreterTests extends LoadTestCase
// myQVT.getEnvironmentFactory().setEvaluationTracingEnabled(true);
MyQvtiExecutor testEvaluator = myQVT.createEvaluator("Tree2TallTree", "Tree2TallTree.qvti", QVTiIncrementalExecutor.Mode.INCREMENTAL);
testEvaluator.saveTransformation(null);
- testEvaluator.loadModel("tree", "Tree.xmi");
- testEvaluator.createModel("tree2talltree", "Tree2TallTree.xmi");
- testEvaluator.createModel("talltree", "TallTree.xmi");
- testEvaluator.loadReference("talltree", "TallTreeValidate.xmi");
+ testEvaluator.loadModel("tree", "samples/Tree.xmi");
+ testEvaluator.createModel("tree2talltree", "samples/Tree2TallTree.xmi");
+ testEvaluator.createModel("talltree", "samples/TallTree.xmi");
+ testEvaluator.loadReference("talltree", "samples/TallTreeValidate.xmi");
testEvaluator.test();
testEvaluator.writeExecutionGraphMLfile("-execution");
testEvaluator.dispose();
@@ -370,10 +370,10 @@ public class QVTiInterpreterTests extends LoadTestCase
// myQVT.getEnvironmentFactory().setEvaluationTracingEnabled(true);
MyQvtiExecutor testEvaluator = myQVT.createEvaluator("Tree2TallTree", "Tree2TallTree.qvti", QVTiIncrementalExecutor.Mode.LAZY);
testEvaluator.saveTransformation(null);
- testEvaluator.loadModel("tree", "Tree.xmi");
- testEvaluator.createModel("tree2talltree", "Tree2TallTree.xmi");
- testEvaluator.createModel("talltree", "TallTree.xmi");
- testEvaluator.loadReference("talltree", "TallTreeValidate.xmi");
+ testEvaluator.loadModel("tree", "samples/Tree.xmi");
+ testEvaluator.createModel("tree2talltree", "samples/Tree2TallTree.xmi");
+ testEvaluator.createModel("talltree", "samples/TallTree.xmi");
+ testEvaluator.loadReference("talltree", "samples/TallTreeValidate.xmi");
testEvaluator.test();
testEvaluator.dispose();
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 e9e043b25..83e390a09 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,31 +9,27 @@ transformation Tree2TallTree {
}
map __root__ in Tree2TallTree {
--- buffer nodes := tree.objectsOfKind(Node)->sortedBy(name);
- buffer nodes := tree.objectsOfKind(Node);
- for node : tree::Node in nodes {
- call Node2MiddleNode {
- node iterates node;
- }
+ append nodes : tree::Node;
+ buffer node2tallNodes : tree2talltree::Node2TallNode;
+ install Node2MiddleNode {
+ node consumes nodes;
+ node2tallNodes appendsTo node2tallNodes;
}
- for node : tree::Node in nodes {
- call Edge2MiddleEdge {
- node iterates node;
- }
+ install Edge2MiddleEdge {
+ node consumes nodes;
}
--- for node2tallNode : tree2talltree::Node2TallNode in tree2talltree.objectsOfKind(Node2TallNode)->sortedBy(name) {
- for node2tallNode : tree2talltree::Node2TallNode in tree2talltree.objectsOfKind(Node2TallNode) {
- call MiddleNode2TallNode {
- node2tallNode iterates node2tallNode;
- }
+ install MiddleNode2TallNode {
+ node2tallNode consumes node2tallNodes;
}
}
map Node2MiddleNode in Tree2TallTree {
guard:tree node : Node;
+ append node2tallNodes : tree2talltree::Node2TallNode;
new:tree2talltree node2tallNode : Node2TallNode;
set node2tallNode.node := node;
set node2tallNode.name := node.name;
+ add node2tallNodes += node2tallNode;
}
map Edge2MiddleEdge in Tree2TallTree {
diff --git a/tests/org.eclipse.qvtd.xtext.qvtimperative.tests/src/org/eclipse/qvtd/xtext/qvtimperative/tests/Tree2TallTree/Tree2TallTreeInstall.qvti b/tests/org.eclipse.qvtd.xtext.qvtimperative.tests/src/org/eclipse/qvtd/xtext/qvtimperative/tests/Tree2TallTree/Tree2TallTreeInstall.qvti
deleted file mode 100644
index e20da977a..000000000
--- a/tests/org.eclipse.qvtd.xtext.qvtimperative.tests/src/org/eclipse/qvtd/xtext/qvtimperative/tests/Tree2TallTree/Tree2TallTreeInstall.qvti
+++ /dev/null
@@ -1,55 +0,0 @@
-import 'Tree.ecore'::tree;
-import 'TallTree.ecore'::talltree;
-import 'Tree2TallTree.ecore'::tree2talltree;
-
-transformation Tree2TallTreeInstall {
- check tree imports tree;
- enforce talltree imports talltree;
- tree2talltree imports tree2talltree;
-}
-
-map __root__ in Tree2TallTreeInstall {
- buffer nodes := tree.objectsOfKind(Node)->sortedBy(name);
- buffer node2tallNodes : tree2talltree::Node2TallNode;
- install Node2MiddleNode {
- node consumes nodes;
- node2tallNodes appendsTo node2tallNodes;
- }
- install Edge2MiddleEdge {
- node consumes nodes;
- }
- install MiddleNode2TallNode {
- node2tallNode consumes node2tallNodes;
- }
-}
-
-map Node2MiddleNode in Tree2TallTreeInstall {
- guard:tree node : Node;
- append node2tallNodes : tree2talltree::Node2TallNode;
- new:tree2talltree node2tallNode : Node2TallNode;
- set node2tallNode.node := node;
- set node2tallNode.name := node.name;
- add node2tallNodes += node2tallNode;
-}
-
-map Edge2MiddleEdge in Tree2TallTreeInstall {
- guard:tree node : Node;
- var node2tallNode : Node2TallNode := node.Node2TallNode;
- check node.parent <> null;
- notify set node2tallNode.parent := node.parent.Node2TallNode;
--- node2tallNode.name := node.name;
-}
-
-map MiddleNode2TallNode in Tree2TallTreeInstall {
- guard:tree2talltree node2tallNode : Node2TallNode;
- var tallNode_name : String := node2tallNode.name;
- observe Node2TallNode::children, Node2TallNode::tallNode
- var tallNode_children : Set(TallNode) := node2tallNode.children?.tallNode->asSet();
- observe Node2TallNode::children, Node2TallNode::tallNode, TallNode::height
- var tallNode_height : Integer := if node2tallNode.children->notEmpty() then node2tallNode.children.tallNode.height->max() + 1 else 0 endif;
- new:talltree tallNode : TallNode;
- notify set node2tallNode.tallNode := tallNode;
- set tallNode.name := tallNode_name;
- set tallNode.children := tallNode_children;
- notify set tallNode.height := tallNode_height;
-}
diff --git a/tests/org.eclipse.qvtd.xtext.qvtimperative.tests/src/org/eclipse/qvtd/xtext/qvtimperative/tests/Tree2TallTree/TallTreeValidate.xmi b/tests/org.eclipse.qvtd.xtext.qvtimperative.tests/src/org/eclipse/qvtd/xtext/qvtimperative/tests/Tree2TallTree/samples/TallTreeValidate.xmi
index 3e7b96d79..5b8623e1c 100644
--- a/tests/org.eclipse.qvtd.xtext.qvtimperative.tests/src/org/eclipse/qvtd/xtext/qvtimperative/tests/Tree2TallTree/TallTreeValidate.xmi
+++ b/tests/org.eclipse.qvtd.xtext.qvtimperative.tests/src/org/eclipse/qvtd/xtext/qvtimperative/tests/Tree2TallTree/samples/TallTreeValidate.xmi
@@ -1,16 +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="n1.1">
- <children
- height="0"
- name="n1.1.1"/>
- </children>
-</talltree:TallNode>
+<?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="n1.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/TallTreeValidate2.xmi b/tests/org.eclipse.qvtd.xtext.qvtimperative.tests/src/org/eclipse/qvtd/xtext/qvtimperative/tests/Tree2TallTree/samples/TallTreeValidateChanged.xmi
index 8f3351492..7351bcd94 100644
--- 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/samples/TallTreeValidateChanged.xmi
@@ -1,16 +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>
+<?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/samples/TallTreeValidateCleared.xmi b/tests/org.eclipse.qvtd.xtext.qvtimperative.tests/src/org/eclipse/qvtd/xtext/qvtimperative/tests/Tree2TallTree/samples/TallTreeValidateCleared.xmi
new file mode 100644
index 000000000..bf9abab34
--- /dev/null
+++ b/tests/org.eclipse.qvtd.xtext.qvtimperative.tests/src/org/eclipse/qvtd/xtext/qvtimperative/tests/Tree2TallTree/samples/TallTreeValidateCleared.xmi
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xmi:XMI xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI"/>
diff --git a/tests/org.eclipse.qvtd.xtext.qvtimperative.tests/src/org/eclipse/qvtd/xtext/qvtimperative/tests/Tree2TallTree/samples/TallTreeValidateDeleted.xmi b/tests/org.eclipse.qvtd.xtext.qvtimperative.tests/src/org/eclipse/qvtd/xtext/qvtimperative/tests/Tree2TallTree/samples/TallTreeValidateDeleted.xmi
new file mode 100644
index 000000000..6c47ae6ea
--- /dev/null
+++ b/tests/org.eclipse.qvtd.xtext.qvtimperative.tests/src/org/eclipse/qvtd/xtext/qvtimperative/tests/Tree2TallTree/samples/TallTreeValidateDeleted.xmi
@@ -0,0 +1,13 @@
+<?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="1"
+ name="n1">
+ <children
+ height="0"
+ name="n1.1">
+ </children>
+</talltree:TallNode>
diff --git a/tests/org.eclipse.qvtd.xtext.qvtimperative.tests/src/org/eclipse/qvtd/xtext/qvtimperative/tests/Tree2TallTree/Tree.xmi b/tests/org.eclipse.qvtd.xtext.qvtimperative.tests/src/org/eclipse/qvtd/xtext/qvtimperative/tests/Tree2TallTree/samples/Tree.xmi
index 0e1d7f79a..d90834c8d 100644
--- a/tests/org.eclipse.qvtd.xtext.qvtimperative.tests/src/org/eclipse/qvtd/xtext/qvtimperative/tests/Tree2TallTree/Tree.xmi
+++ b/tests/org.eclipse.qvtd.xtext.qvtimperative.tests/src/org/eclipse/qvtd/xtext/qvtimperative/tests/Tree2TallTree/samples/Tree.xmi
@@ -1,13 +1,13 @@
-<?xml version="1.0" encoding="ASCII"?>
-<tree:Node xmi:version="2.0"
- xmlns:xmi="http://www.omg.org/XMI"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xmlns:tree="http://www.eclipse.org/qvt/examples/0.1/Tree"
- xsi:schemaLocation="http://www.eclipse.org/qvt/examples/0.1/Tree Tree.ecore"
- name="n1">
- <children
- name="n1.1">
- <children
- name="n1.1.1"/>
- </children>
-</tree:Node>
+<?xml version="1.0" encoding="ASCII"?>
+<tree:Node xmi:version="2.0"
+ xmlns:xmi="http://www.omg.org/XMI"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:tree="http://www.eclipse.org/qvt/examples/0.1/Tree"
+ xsi:schemaLocation="http://www.eclipse.org/qvt/examples/0.1/Tree ../Tree.ecore"
+ name="n1">
+ <children
+ name="n1.1">
+ <children
+ name="n1.1.1"/>
+ </children>
+</tree:Node>

Back to the top