Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEd Willink2016-05-12 06:33:47 -0400
committerEd Willink2016-05-18 09:17:48 -0400
commit79712674e5b40d14fb4286fddaaa835aa0cd1684 (patch)
tree3e51309d901018d507e77b5bb130c4277309fba4
parent94c097d079762aa61913f23d5a2e4f885c4ace32 (diff)
downloadorg.eclipse.qvtd-79712674e5b40d14fb4286fddaaa835aa0cd1684.tar.gz
org.eclipse.qvtd-79712674e5b40d14fb4286fddaaa835aa0cd1684.tar.xz
org.eclipse.qvtd-79712674e5b40d14fb4286fddaaa835aa0cd1684.zip
[486722] Use singleton Functions to enforce QVTr Keys
-rw-r--r--plugins/org.eclipse.qvtd.codegen/src/org/eclipse/qvtd/codegen/qvti/analyzer/QVTiAS2CGVisitor.java10
-rw-r--r--plugins/org.eclipse.qvtd.codegen/src/org/eclipse/qvtd/codegen/qvti/java/QVTiCG2JavaVisitor.java809
-rw-r--r--plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtc2qvtu/QVTc2QVTu.java6
-rw-r--r--plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/AbstractNode.java9
-rw-r--r--plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/Nodes.java200
-rw-r--r--plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/SimpleMappingRegion.java20
-rw-r--r--plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/SimpleNavigationEdge.java1
-rw-r--r--plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/SimpleVariableNode.java2
-rw-r--r--plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvtc/AbstractQVTr2QVTcRelations.java75
-rw-r--r--plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvtc/KeyToFunctionForIdentification.java68
-rw-r--r--plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvtc/QVTrNameGenerator.java55
-rw-r--r--plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvtc/QVTrToQVTc.java112
-rw-r--r--plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvtc/VariablesAnalysis.java266
-rw-r--r--plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvts2qvti/BasicRegion2Mapping.java10
-rw-r--r--plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/utilities/JavaSourceFileObject.java8
-rw-r--r--plugins/org.eclipse.qvtd.cs2as.compiler/src/org/eclipse/qvtd/cs2as/compiler/internal/CS2ASJavaCompilerImpl.java4
-rw-r--r--plugins/org.eclipse.qvtd.pivot.qvtbase/src/org/eclipse/qvtd/pivot/qvtbase/utilities/QVTbaseHelper.java37
-rw-r--r--plugins/org.eclipse.qvtd.pivot.qvtbase/src/org/eclipse/qvtd/pivot/qvtbase/utilities/QVTbaseUtil.java15
-rw-r--r--plugins/org.eclipse.qvtd.pivot.qvtimperative/src/org/eclipse/qvtd/pivot/qvtimperative/evaluation/BasicQVTiExecutor.java25
19 files changed, 1263 insertions, 469 deletions
diff --git a/plugins/org.eclipse.qvtd.codegen/src/org/eclipse/qvtd/codegen/qvti/analyzer/QVTiAS2CGVisitor.java b/plugins/org.eclipse.qvtd.codegen/src/org/eclipse/qvtd/codegen/qvti/analyzer/QVTiAS2CGVisitor.java
index 3fd04fdfb..0b7c257d3 100644
--- a/plugins/org.eclipse.qvtd.codegen/src/org/eclipse/qvtd/codegen/qvti/analyzer/QVTiAS2CGVisitor.java
+++ b/plugins/org.eclipse.qvtd.codegen/src/org/eclipse/qvtd/codegen/qvti/analyzer/QVTiAS2CGVisitor.java
@@ -298,7 +298,15 @@ public class QVTiAS2CGVisitor extends AS2CGVisitor implements QVTimperativeVisit
}
List<@NonNull RealizedVariable> pRealizedVariables = new ArrayList<@NonNull RealizedVariable>();
for (@NonNull BottomPattern pBottomPattern : pBottomPatterns) {
- pRealizedVariables.addAll(ClassUtil.nullFree(pBottomPattern.getRealizedVariable()));
+ for (@NonNull RealizedVariable asRealizedVariable : ClassUtil.nullFree(pBottomPattern.getRealizedVariable())) {
+ OCLExpression asInit = asRealizedVariable.getOwnedInit();
+ if (asInit == null) {
+ pRealizedVariables.add(asRealizedVariable);
+ }
+ else {
+ cgLeafExp = createBooleanCGLetExp(cgMapping, cgLeafExp, asRealizedVariable, asInit);
+ }
+ }
}
Collections.sort(pRealizedVariables, NameUtil.NAMEABLE_COMPARATOR);
List<@NonNull CGValuedElement> cgRealizedVariables = ClassUtil.nullFree(cgMappingExp.getRealizedVariables());
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 605a25ae0..305d58938 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
@@ -21,6 +21,7 @@ import java.util.Map;
import java.util.Set;
import org.eclipse.emf.ecore.EClassifier;
+import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.jdt.annotation.NonNull;
@@ -31,10 +32,13 @@ import org.eclipse.ocl.examples.codegen.cgmodel.CGCollectionExp;
import org.eclipse.ocl.examples.codegen.cgmodel.CGEcorePropertyCallExp;
import org.eclipse.ocl.examples.codegen.cgmodel.CGExecutorProperty;
import org.eclipse.ocl.examples.codegen.cgmodel.CGIterator;
+import org.eclipse.ocl.examples.codegen.cgmodel.CGLetExp;
import org.eclipse.ocl.examples.codegen.cgmodel.CGNavigationCallExp;
import org.eclipse.ocl.examples.codegen.cgmodel.CGOperation;
import org.eclipse.ocl.examples.codegen.cgmodel.CGPackage;
import org.eclipse.ocl.examples.codegen.cgmodel.CGParameter;
+import org.eclipse.ocl.examples.codegen.cgmodel.CGShadowExp;
+import org.eclipse.ocl.examples.codegen.cgmodel.CGShadowPart;
import org.eclipse.ocl.examples.codegen.cgmodel.CGTypeId;
import org.eclipse.ocl.examples.codegen.cgmodel.CGValuedElement;
import org.eclipse.ocl.examples.codegen.generator.TypeDescriptor;
@@ -48,6 +52,8 @@ import org.eclipse.ocl.pivot.NavigationCallExp;
import org.eclipse.ocl.pivot.Operation;
import org.eclipse.ocl.pivot.Parameter;
import org.eclipse.ocl.pivot.Property;
+import org.eclipse.ocl.pivot.ShadowExp;
+import org.eclipse.ocl.pivot.ShadowPart;
import org.eclipse.ocl.pivot.Variable;
import org.eclipse.ocl.pivot.evaluation.Executor;
import org.eclipse.ocl.pivot.ids.ClassId;
@@ -55,6 +61,10 @@ import org.eclipse.ocl.pivot.ids.CollectionTypeId;
import org.eclipse.ocl.pivot.ids.ElementId;
import org.eclipse.ocl.pivot.ids.IdResolver;
import org.eclipse.ocl.pivot.ids.TypeId;
+import org.eclipse.ocl.pivot.internal.manager.PivotMetamodelManager;
+import org.eclipse.ocl.pivot.library.LibraryProperty;
+import org.eclipse.ocl.pivot.library.oclany.OclElementOclContainerProperty;
+import org.eclipse.ocl.pivot.oclstdlib.OCLstdlibPackage;
import org.eclipse.ocl.pivot.utilities.ClassUtil;
import org.eclipse.ocl.pivot.utilities.NameUtil;
import org.eclipse.ocl.pivot.utilities.ValueUtil;
@@ -84,11 +94,13 @@ import org.eclipse.qvtd.codegen.qvticgmodel.util.QVTiCGModelVisitor;
import org.eclipse.qvtd.codegen.utilities.QVTiCGUtil;
import org.eclipse.qvtd.pivot.qvtbase.Domain;
import org.eclipse.qvtd.pivot.qvtbase.Transformation;
+import org.eclipse.qvtd.pivot.qvtbase.TypedModel;
import org.eclipse.qvtd.pivot.qvtcorebase.Area;
import org.eclipse.qvtd.pivot.qvtcorebase.Assignment;
import org.eclipse.qvtd.pivot.qvtcorebase.BottomPattern;
import org.eclipse.qvtd.pivot.qvtcorebase.PropertyAssignment;
import org.eclipse.qvtd.pivot.qvtcorebase.RealizedVariable;
+import org.eclipse.qvtd.pivot.qvtcorebase.analysis.DomainUsage;
import org.eclipse.qvtd.pivot.qvtcorebase.utilities.QVTcoreBaseUtil;
import org.eclipse.qvtd.pivot.qvtimperative.ConnectionVariable;
import org.eclipse.qvtd.pivot.qvtimperative.ImperativeArea;
@@ -97,6 +109,7 @@ import org.eclipse.qvtd.pivot.qvtimperative.MappingCall;
import org.eclipse.qvtd.pivot.qvtimperative.MappingCallBinding;
import org.eclipse.qvtd.pivot.qvtimperative.evaluation.QVTiTransformationAnalysis;
import org.eclipse.qvtd.pivot.qvtimperative.utilities.QVTimperativeUtil;
+import org.eclipse.qvtd.runtime.evaluation.AbstractIdentification;
import org.eclipse.qvtd.runtime.evaluation.AbstractInvocation;
import org.eclipse.qvtd.runtime.evaluation.AbstractTransformer;
import org.eclipse.qvtd.runtime.evaluation.InvocationManager;
@@ -138,6 +151,29 @@ public class QVTiCG2JavaVisitor extends CG2JavaVisitor<@NonNull QVTiCodeGenerato
this.useGot = isIncremental;
}
+ protected void appendEcoreSet(@NonNull CGValuedElement cgSlot, @NonNull EStructuralFeature eStructuralFeature, @NonNull CGValuedElement cgInit) {
+ if (eStructuralFeature.isMany()) {
+ String getAccessor = genModelHelper.getGetAccessor(eStructuralFeature);
+ //
+ js.appendValueName(cgSlot);
+ js.append(".");
+ js.append(getAccessor);
+ js.append("().addAll(");
+ js.appendValueName(cgInit);
+ js.append(");\n");
+ }
+ else {
+ String setAccessor = genModelHelper.getSetAccessor(eStructuralFeature);
+ //
+ js.appendValueName(cgSlot);
+ js.append(".");
+ js.append(setAccessor);
+ js.append("(");
+ js.appendValueName(cgInit);
+ js.append(");\n");
+ }
+ }
+
protected void appendModelIndex(@Nullable CGTypedModel cgTypedModel) {
if (cgTypedModel == null) {
js.append("-1/*null*/");
@@ -394,34 +430,13 @@ public class QVTiCG2JavaVisitor extends CG2JavaVisitor<@NonNull QVTiCodeGenerato
js.append(", null, null");
}
js.append(");\n");
- for (@NonNull CGMapping cgMapping : ClassUtil.nullFree(cgTransformation.getMappings())) {
- if (useClass(cgMapping) && (cgMapping.getFreeVariables().size() > 0)) {
-// js.append("protected final ");
-// js.appendIsRequired(true);
-// js.append(" ");
-// js.appendClassReference(Constructor.class, false, cgMapping.getName());
- js.append(getMappingCtorName(cgMapping) + " = ");
- js.appendClassReference(ClassUtil.class);
- js.append(".nonNullState(" + getMappingName(cgMapping) + ".class.getConstructor(" + className + ".class, Object[].class));\n");
- }
- }
+ doMappingConstructorInitializers(cgTransformation);
+ doFunctionConstructorInitializers(cgTransformation);
js.popIndentation();
js.append("}\n");
}
- protected void doConstructorConstants(/*@NonNull*/ List<@NonNull CGMapping> cgMappings) {
- for (@NonNull CGMapping cgMapping : cgMappings) {
- if (useClass(cgMapping) && (cgMapping.getFreeVariables().size() > 0)) {
- js.append("protected final ");
- js.appendIsRequired(true);
- js.append(" ");
- js.appendClassReference(Constructor.class, false, getMappingName(cgMapping));
- js.append(" " + getMappingCtorName(cgMapping) + ";\n");
- }
- }
- }
-
- private void doCreateIncrementalManagers() {
+ protected void doCreateIncrementalManagers() {
js.append("protected ");
js.appendIsRequired(true);
js.append(" ");
@@ -449,6 +464,218 @@ public class QVTiCG2JavaVisitor extends CG2JavaVisitor<@NonNull QVTiCodeGenerato
js.append("}\n");
}
+ protected boolean doFunctionBody(@NonNull CGFunction cgFunction) {
+ CGValuedElement body = getExpression(cgFunction.getBody());
+ ElementId elementId = cgFunction.getTypeId().getElementId();
+ js.append(" {\n");
+ js.pushIndentation(null);
+// js.appendCastParameters(localContext2, cgParameters);
+// JavaDependencyVisitor dependencyVisitor = new JavaDependencyVisitor(localContext2, null);
+// dependencyVisitor.visit(body);
+// dependencyVisitor.visitAll(localContext2.getLocalVariables());
+// Iterable<CGValuedElement> sortedDependencies = dependencyVisitor.getSortedDependencies();
+// for (CGValuedElement cgElement : sortedDependencies) {
+// if (!cgElement.isInlined() && cgElement.isConstant() && !cgElement.isGlobal()) {
+// cgElement.accept(this);
+// }
+// }
+ // FIXME merge locals into AST as LetExps.
+ if (cgFunction.getBody() != null) {
+ if (!js.appendLocalStatements(body)) {
+ return false;
+ }
+ js.append("return ");
+ js.appendValueName(body);
+ js.append(";\n");
+ }
+ else {
+ TypeId asTypeId = cgFunction.getASTypeId();
+ if (asTypeId == TypeId.STRING) { // FIXME Fudge for body-less functions
+ js.append("return \"\";\n");
+ }
+ else if (asTypeId == TypeId.REAL) { // FIXME Fudge for body-less functions
+ js.append("return 0;\n");
+ }
+ else if (asTypeId == TypeId.INTEGER) { // FIXME Fudge for body-less functions
+ js.append("return 0;\n");
+ }
+ else if (asTypeId instanceof CollectionTypeId) { // FIXME Fudge for body-less functions
+ if (js.isUseNullAnnotations()) {
+ js.append("@SuppressWarnings(\"null\")");
+ js.appendIsRequired(true);
+ js.append(" ");
+ }
+ if (elementId != null) {
+ TypeDescriptor javaTypeDescriptor = context.getUnboxedDescriptor(elementId);
+ js.appendClassReference(javaTypeDescriptor);
+ }
+ js.append(" emptyList = ");
+ js.appendClassReference(Collections.class);
+ js.append(".emptyList();\n");
+ js.append("return emptyList;\n");
+ }
+ else { // FIXME Fudge for body-less functions
+ js.append("return \"\";\n");
+ }
+ }
+ js.popIndentation();
+ js.append("}\n");
+ return true;
+ }
+
+ protected boolean doFunctionBody2(@NonNull CGFunction cgFunction, @NonNull CGShadowExp cgShadowExp, @NonNull String instanceName) {
+ js.append(" {\n");
+ js.pushIndentation(null);
+ doEcoreCreate(cgShadowExp, ClassUtil.nonNullState(cgShadowExp.getEcoreClassifier()));
+ int index = 0;
+ for (@NonNull CGShadowPart cgShadowPart : ClassUtil.nullFree(cgShadowExp.getParts())) {
+ Property asProperty = ClassUtil.nonNullState(((ShadowPart)cgShadowPart.getAst()).getReferredProperty());
+ EStructuralFeature eStructuralFeature = ClassUtil.nonNullState(getESObject(asProperty));
+ js.appendValueName(cgShadowExp);
+ js.append(".");
+ if (eStructuralFeature.isMany()) {
+ String getAccessor = genModelHelper.getGetAccessor(eStructuralFeature);
+ //
+ js.append(getAccessor);
+ js.append("().addAll");
+ }
+ else {
+ String setAccessor = genModelHelper.getSetAccessor(eStructuralFeature);
+ //
+ js.append(setAccessor);
+ }
+ js.append("(");
+ js.appendClassCast(cgShadowPart);
+ js.append("boundValues[" + index++ + "]);\n");
+ }
+ //
+ js.append("this.");
+ js.append(instanceName);
+ js.append(" = ");
+ js.appendValueName(cgShadowExp);
+ js.append(";\n");
+ //
+ ShadowExp asShadowExp = (ShadowExp)ClassUtil.nonNullState(cgShadowExp.getAst());
+ DomainUsage usage = transformationAnalysis.getDomainUsageAnalysis().getUsage(asShadowExp);
+ TypedModel asTypedModel = ClassUtil.nonNullState(usage.getTypedModel(asShadowExp));
+ CGTypedModel cgTypedModel = context.getAnalyzer().getTypedModel(asTypedModel);
+ //
+ js.append(QVTiGlobalContext.MODELS_NAME);
+ js.append("[");
+ appendModelIndex(cgTypedModel);
+ js.append("].add(");
+ js.appendValueName(cgShadowExp);
+ js.append(");\n");
+ js.popIndentation();
+ js.append("}\n");
+ return true;
+ }
+
+ protected void doFunctionConstructor(@NonNull CGFunction cgFunction, @NonNull CGShadowExp cgShadowExp, @NonNull String instanceName) {
+// List<@NonNull CGParameter> cgParameters = ClassUtil.nullFree(cgFunction.getParameters());
+ js.append("public ");
+ js.append(getFunctionName(cgFunction));
+ js.append("(");
+ js.appendIsRequired(true);
+ js.append(" Object ");
+ js.appendIsRequired(true);
+ js.append(" [] boundValues) ");
+/* int i = 0;
+ for (@NonNull CGParameter cgParameter : cgParameters) {
+ String valueName = getValueName(cgParameter);
+ js.append(valueName);
+ js.append(" = ");
+// js.appendClassCast(cgFreeVariable);
+ if (cgParameter instanceof CGConnectionVariable) {
+ js.append("(");
+ js.appendClassReference(null, cgParameter);
+ js.append(".Accumulator)"); // FIXME Embed properly as a nested typeid
+ }
+ else{
+ js.appendClassCast(cgParameter);
+ }
+ js.append("boundValues[" + i++);
+ js.append("];\n");
+ } */
+ doFunctionBody2(cgFunction, cgShadowExp, instanceName);
+ }
+
+ protected void doFunctionConstructorConstants(/*@NonNull*/ List<@NonNull CGOperation> cgOperations) {
+ for (@NonNull CGOperation cgOperation : cgOperations) {
+ if (cgOperation instanceof CGFunction) {
+ CGFunction cgFunction = (CGFunction)cgOperation;
+ if (useClass(cgFunction) != null) {
+ js.append("protected final ");
+ js.appendIsRequired(true);
+ js.append(" ");
+ js.appendClassReference(Constructor.class, false, getFunctionName(cgFunction));
+ js.append(" " + getFunctionCtorName(cgFunction) + ";\n");
+ }
+ }
+ }
+ }
+
+ protected void doFunctionConstructorInitializers(@NonNull CGTransformation cgTransformation) {
+ String className = cgTransformation.getName();
+ for (@NonNull CGOperation cgOperation : ClassUtil.nullFree(cgTransformation.getOperations())) {
+ if (cgOperation instanceof CGFunction) {
+ CGFunction cgFunction = (CGFunction) cgOperation;
+ if (useClass(cgFunction) != null) {
+ js.append(getFunctionCtorName(cgFunction) + " = ");
+ js.appendClassReference(ClassUtil.class);
+ js.append(".nonNullState(" + getFunctionName(cgFunction) + ".class.getConstructor(" + className + ".class, " + "Object[].class));\n");
+ }
+ }
+ }
+ }
+
+ protected void doFunctionGetInstance(@NonNull CGFunction cgFunction, @NonNull String instanceName) {
+ js.append("public ");
+ js.appendTypeDeclaration(cgFunction);
+ js.append(" getInstance() {\n");
+ js.pushIndentation(null);
+ js.append("return " + instanceName + ";\n");
+ js.popIndentation();
+ js.append("}\n");
+ }
+
+ protected void doFunctionIsEqual(@NonNull CGShadowExp cgShadowExp, @NonNull String instanceName) {
+ js.append("public boolean isEqual(");
+ js.appendIsRequired(true);
+ js.append(" ");
+ js.appendClassReference(IdResolver.class);
+ js.append(" idResolver, ");
+ js.appendIsRequired(true);
+ js.append(" Object ");
+ js.appendIsRequired(true);
+ js.append(" [] thoseValues) {\n");
+ js.pushIndentation(null);
+ js.append("return ");
+ int index = 0;
+ for (@NonNull CGShadowPart cgShadowPart : ClassUtil.nullFree(cgShadowExp.getParts())) {
+ if (index > 0) {
+ js.append("\n && ");
+ }
+ js.append("idResolver.oclEquals(");
+ js.append(instanceName);
+ js.append(".");
+ Property asProperty = ClassUtil.nonNullState(((ShadowPart)cgShadowPart.getAst()).getReferredProperty());
+ EStructuralFeature eStructuralFeature = ClassUtil.nonNullState(getESObject(asProperty));
+ String getAccessor;
+ if (eStructuralFeature == OCLstdlibPackage.Literals.OCL_ELEMENT__OCL_CONTAINER) {
+ getAccessor = "eContainer";
+ }
+ else {
+ getAccessor = genModelHelper.getGetAccessor(eStructuralFeature);
+ }
+ js.append(getAccessor);
+ js.append("(), thoseValues[" + index++ + "])");
+ }
+ js.append(";\n");
+ js.popIndentation();
+ js.append("}\n");
+ }
+
protected void doGetting(@NonNull CGNavigationCallExp cgPropertyCallExp, @NonNull EStructuralFeature eStructuralFeature, boolean isOpposite) {
Element asPropertyCallExp = cgPropertyCallExp.getAst();
CGMapping cgMapping = QVTiCGUtil.getContainingCGMapping(cgPropertyCallExp);
@@ -489,6 +716,137 @@ public class QVTiCG2JavaVisitor extends CG2JavaVisitor<@NonNull QVTiCodeGenerato
}
}
+ protected void doIsEqual(@NonNull List<@NonNull ? extends CGParameter> cgFreeVariables) {
+ js.append("public boolean isEqual(");
+ js.appendIsRequired(true);
+ js.append(" ");
+ js.appendClassReference(IdResolver.class);
+ js.append(" idResolver, ");
+ js.appendIsRequired(true);
+ js.append(" Object ");
+ js.appendIsRequired(true);
+ js.append(" [] thoseValues) {\n");
+ js.pushIndentation(null);
+ js.append("return ");
+ int index = 0;
+ for (@NonNull CGParameter cgFreeVariable : cgFreeVariables) {
+ if (index > 0) {
+ js.append("\n && ");
+ }
+ js.append("idResolver.oclEquals(");
+ js.append(cgFreeVariable.getValueName());
+ js.append(", thoseValues[" + index++ + "])");
+ }
+ js.append(";\n");
+ js.popIndentation();
+ js.append("}\n");
+ }
+
+ protected void doMappingBody(@NonNull CGMapping cgMapping, boolean hasMappingClass) {
+ CGValuedElement cgBody = cgMapping.getBody();
+ js.append(" {\n");
+ js.pushIndentation(null);
+ if (cgBody.isInvalid()) {
+ js.append("return handleExecutionFailure(\"" + getMappingName(cgMapping) + "\", ");
+ js.appendValueName(cgBody);
+ js.append(");\n");
+ }
+ else {
+ js.append("try {\n");
+ js.pushIndentation(null);
+ String savedLocalPrefix = localPrefix;
+ try {
+ localPrefix = hasMappingClass ? cgMapping.getTransformation().getName() : localPrefix;
+ js.append("// predicates and unrealized variables\n");
+ if (!cgBody.isInlined()) {
+ cgBody.accept(this);
+ }
+ js.append("return ");
+ js.appendValueName(cgBody);
+ js.append(";\n");
+ }
+ finally {
+ localPrefix = savedLocalPrefix;
+ }
+ js.popIndentation();
+ js.append("} catch (Throwable e) {\n");
+ js.pushIndentation(null);
+ js.append("return handleExecutionFailure(\"" + getMappingName(cgMapping) + "\", e);\n");
+ js.popIndentation();
+ js.append("}\n");
+ }
+ js.popIndentation();
+ js.append("}\n");
+ }
+
+ protected void doMappingConnectionVariable(@NonNull CGGuardVariable cgFreeVariable) {
+ if (cgFreeVariable instanceof CGConnectionVariable) {
+ js.append("final ");
+ js.appendClassReference(null, cgFreeVariable);
+ js.append(".");
+ js.appendIsRequired(true);
+ js.append(" Accumulator "); // FIXME Embed properly as a nested typeid
+ js.append(getValueName(cgFreeVariable));
+ }
+ else{
+ js.appendDeclaration(cgFreeVariable);
+ }
+ }
+
+ protected void doMappingConstructor(@NonNull CGMapping cgMapping) {
+ List<@NonNull CGGuardVariable> cgFreeVariables = ClassUtil.nullFree(cgMapping.getFreeVariables());
+ js.append("public ");
+ js.append(getMappingName(cgMapping));
+ js.append("(");
+ js.appendIsRequired(true);
+ js.append(" Object ");
+ js.appendIsRequired(true);
+ js.append(" [] boundValues) {\n");
+ js.pushIndentation(null);
+ int i = 0;
+ for (@NonNull CGGuardVariable cgFreeVariable : cgFreeVariables) {
+ String valueName = getValueName(cgFreeVariable);
+ js.append(valueName);
+ js.append(" = ");
+// js.appendClassCast(cgFreeVariable);
+ if (cgFreeVariable instanceof CGConnectionVariable) {
+ js.append("(");
+ js.appendClassReference(null, cgFreeVariable);
+ js.append(".Accumulator)"); // FIXME Embed properly as a nested typeid
+ }
+ else{
+ js.appendClassCast(cgFreeVariable);
+ }
+ js.append("boundValues[" + i++);
+ js.append("];\n");
+ }
+ js.popIndentation();
+ js.append("}\n");
+ }
+
+ protected void doMappingConstructorConstants(/*@NonNull*/ List<@NonNull CGMapping> cgMappings) {
+ for (@NonNull CGMapping cgMapping : cgMappings) {
+ if (useClass(cgMapping) && (cgMapping.getFreeVariables().size() > 0)) {
+ js.append("protected final ");
+ js.appendIsRequired(true);
+ js.append(" ");
+ js.appendClassReference(Constructor.class, false, getMappingName(cgMapping));
+ js.append(" " + getMappingCtorName(cgMapping) + ";\n");
+ }
+ }
+ }
+
+ protected void doMappingConstructorInitializers(@NonNull CGTransformation cgTransformation) {
+ String className = cgTransformation.getName();
+ for (@NonNull CGMapping cgMapping : ClassUtil.nullFree(cgTransformation.getMappings())) {
+ if (useClass(cgMapping) && (cgMapping.getFreeVariables().size() > 0)) {
+ js.append(getMappingCtorName(cgMapping) + " = ");
+ js.appendClassReference(ClassUtil.class);
+ js.append(".nonNullState(" + getMappingName(cgMapping) + ".class.getConstructor(" + className + ".class, Object[].class));\n");
+ }
+ }
+ }
+
protected void doOppositeCaches(@NonNull QVTiTransformationAnalysis transformationAnalysis) {
Map<@NonNull Property, @NonNull Integer> opposites = transformationAnalysis.getCaches();
if (opposites.size() <= 0) {
@@ -601,6 +959,34 @@ public class QVTiCG2JavaVisitor extends CG2JavaVisitor<@NonNull QVTiCodeGenerato
return allImports;
}
+ @Override
+ protected @Nullable EStructuralFeature getESObject(@NonNull Property asProperty) {
+ EObject esObject = asProperty.getESObject();
+ if (esObject instanceof EStructuralFeature) {
+ return (EStructuralFeature)esObject;
+ }
+ Property oppositeProperty = asProperty.getOpposite();
+ if (oppositeProperty == null) {
+ return null;
+ }
+ if (!oppositeProperty.isIsComposite()) {
+ PivotMetamodelManager metamodelManager = analyzer.getCodeGenerator().getEnvironmentFactory().getMetamodelManager();
+ LibraryProperty libraryProperty = metamodelManager.getImplementation(null, null, asProperty);
+ if (!(libraryProperty instanceof OclElementOclContainerProperty)) {
+ return null;
+ }
+ }
+ return OCLstdlibPackage.Literals.OCL_ELEMENT__OCL_CONTAINER;
+ }
+
+ protected String getFunctionCtorName(@NonNull CGFunction cgFunction) {
+ return JavaStream.convertToJavaIdentifier("FTOR_" + cgFunction.getName());
+ }
+
+ protected @NonNull String getFunctionName(@NonNull CGFunction cgFunction) {
+ return JavaStream.convertToJavaIdentifier("FUN_" + cgFunction.getName());
+ }
+
protected @NonNull QVTiGlobalContext getGlobalContext() {
return (QVTiGlobalContext) globalContext;
}
@@ -635,7 +1021,18 @@ public class QVTiCG2JavaVisitor extends CG2JavaVisitor<@NonNull QVTiCodeGenerato
}
}
- private boolean useClass(@NonNull CGMapping cgMapping) {
+ protected @Nullable CGShadowExp useClass(@NonNull CGFunction cgFunction) {
+ CGValuedElement cgBody = cgFunction.getBody();
+ while (cgBody instanceof CGLetExp) {
+ cgBody = ((CGLetExp)cgBody).getIn();
+ }
+ if (cgBody instanceof CGShadowExp) {
+ return (CGShadowExp)cgBody; // FIXME replace with clearer strategy
+ }
+ return null;
+ }
+
+ protected boolean useClass(@NonNull CGMapping cgMapping) {
if (alwaysUseClasses) {
return true;
}
@@ -790,26 +1187,7 @@ public class QVTiCG2JavaVisitor extends CG2JavaVisitor<@NonNull QVTiCodeGenerato
if (!js.appendLocalStatements(cgInit)) {
return false;
}
- if (eStructuralFeature.isMany()) {
- String getAccessor = genModelHelper.getGetAccessor(eStructuralFeature);
- //
- js.appendValueName(cgSlot);
- js.append(".");
- js.append(getAccessor);
- js.append("().addAll(");
- js.appendValueName(cgInit);
- js.append(");\n");
- }
- else {
- String setAccessor = genModelHelper.getSetAccessor(eStructuralFeature);
- //
- js.appendValueName(cgSlot);
- js.append(".");
- js.append(setAccessor);
- js.append("(");
- js.appendValueName(cgInit);
- js.append(");\n");
- }
+ appendEcoreSet(cgSlot, eStructuralFeature, cgInit);
doAssigned(cgPropertyAssignment);
return true;
}
@@ -833,7 +1211,21 @@ public class QVTiCG2JavaVisitor extends CG2JavaVisitor<@NonNull QVTiCodeGenerato
@Override
public @NonNull Boolean visitCGEcoreRealizedVariable(@NonNull CGEcoreRealizedVariable cgRealizedVariable) {
- EClassifier eClassifier = cgRealizedVariable.getEClassifier();
+ EClassifier eClassifier = ClassUtil.nonNullState(cgRealizedVariable.getEClassifier());
+ if (doEcoreCreate(cgRealizedVariable, eClassifier)) {
+ cgRealizedVariable.setNonNull();
+ }
+ //
+ js.append("assert ");
+ js.appendValueName(cgRealizedVariable);
+ js.append(" != null;\n");
+ //
+ doAddRealization(cgRealizedVariable);
+ return true;
+ }
+
+ protected boolean doEcoreCreate(@NonNull CGValuedElement cgElement, @NonNull EClassifier eClassifier) {
+ boolean doSetNonNull = false;
EPackage ePackage = eClassifier.getEPackage();
String createMethodName = "create" + eClassifier.getName();
String javaClass;
@@ -844,7 +1236,7 @@ public class QVTiCG2JavaVisitor extends CG2JavaVisitor<@NonNull QVTiCodeGenerato
Method factoryMethod = context.getLeastDerivedMethod(factoryClass, createMethodName);
if (factoryMethod != null) {
if (context.getIsNonNull(factoryMethod) == Boolean.TRUE) {
- cgRealizedVariable.setNonNull();
+ doSetNonNull = true;
};
}
}
@@ -856,7 +1248,7 @@ public class QVTiCG2JavaVisitor extends CG2JavaVisitor<@NonNull QVTiCodeGenerato
javaClass = null;
}
//
- js.appendDeclaration(cgRealizedVariable);
+ js.appendDeclaration(cgElement);
js.append(" = ");
js.appendClassReference(javaClass);
// js.appendReferenceTo(localContext.getExecutorType(cgRealizedVariable.getPivotTypeId()));
@@ -864,12 +1256,7 @@ public class QVTiCG2JavaVisitor extends CG2JavaVisitor<@NonNull QVTiCodeGenerato
js.append(createMethodName);
js.append("();\n");
//
- js.append("assert ");
- js.appendValueName(cgRealizedVariable);
- js.append(" != null;\n");
- //
- doAddRealization(cgRealizedVariable);
- return true;
+ return doSetNonNull;
}
@Override
@@ -877,84 +1264,64 @@ public class QVTiCG2JavaVisitor extends CG2JavaVisitor<@NonNull QVTiCodeGenerato
JavaLocalContext<?> localContext2 = globalContext.getLocalContext(cgFunction);
if (localContext2 != null) {
localContext = localContext2;
+// localContext.
try {
+ final String instanceName = getSymbolName(null, "instance");
List<CGParameter> cgParameters = cgFunction.getParameters();
- CGValuedElement body = getExpression(cgFunction.getBody());
//
- js.append("protected ");
- js.appendIsRequired(cgFunction.isRequired());
- // js.append(" ");
- // js.appendIsCaught(!cgOperation.isInvalid(), cgOperation.isInvalid());
- js.append(" ");
- ElementId elementId = cgFunction.getTypeId().getElementId();
- if (elementId != null) {
- TypeDescriptor javaTypeDescriptor = context.getUnboxedDescriptor(elementId);
- js.appendClassReference(javaTypeDescriptor);
- }
- js.append(" ");
- js.append(cgFunction.getName());
- js.append("(");
- boolean isFirst = true;
- for (@SuppressWarnings("null")@NonNull CGParameter cgParameter : cgParameters) {
- if (!isFirst) {
- js.append(", ");
- }
- js.appendDeclaration(cgParameter);
- isFirst = false;
+ js.appendCommentWithOCL(null, cgFunction.getAst());
+ CGShadowExp cgShadowExp = useClass(cgFunction);
+ if (cgShadowExp != null) {
+// Type
+ js.append("protected class ");
+ js.append(getFunctionName(cgFunction));
+ js.append(" extends ");
+ js.appendClassReference(/*isIncremental ? AbstractIdentification.Incremental.class :*/ AbstractIdentification.class);
+ js.append("\n");
+ js.append("{\n");
+ js.pushIndentation(null);
+ js.append("protected final ");
+ js.appendTypeDeclaration(cgFunction);
+ js.append(" " + instanceName + ";\n");
+ js.append("\n");
+ doFunctionConstructor(cgFunction, cgShadowExp, instanceName);
+ js.append("\n");
+ doFunctionGetInstance(cgFunction, instanceName);
+ js.append("\n");
+// js.append("public boolean execute() throws ");
+// js.appendClassReference(ReflectiveOperationException.class);
+// doFunctionBody(cgFunction, true);
+// js.append("\n");
+ doFunctionIsEqual(cgShadowExp, instanceName);
+ js.popIndentation();
+ js.append("}\n");
}
- js.append(") {\n");
- js.pushIndentation(null);
-// js.appendCastParameters(localContext2, cgParameters);
-// JavaDependencyVisitor dependencyVisitor = new JavaDependencyVisitor(localContext2, null);
-// dependencyVisitor.visit(body);
-// dependencyVisitor.visitAll(localContext2.getLocalVariables());
-// Iterable<CGValuedElement> sortedDependencies = dependencyVisitor.getSortedDependencies();
-// for (CGValuedElement cgElement : sortedDependencies) {
-// if (!cgElement.isInlined() && cgElement.isConstant() && !cgElement.isGlobal()) {
-// cgElement.accept(this);
-// }
-// }
- // FIXME merge locals into AST as LetExps.
- if (cgFunction.getBody() != null) {
- if (!js.appendLocalStatements(body)) {
- return false;
- }
- js.append("return ");
- js.appendValueName(body);
- js.append(";\n");
+ else {
+ //
+ js.append("protected ");
+ js.appendIsRequired(cgFunction.isRequired());
+ // js.append(" ");
+ // js.appendIsCaught(!cgOperation.isInvalid(), cgOperation.isInvalid());
+ js.append(" ");
+ ElementId elementId = cgFunction.getTypeId().getElementId();
+ if (elementId != null) {
+ TypeDescriptor javaTypeDescriptor = context.getUnboxedDescriptor(elementId);
+ js.appendClassReference(javaTypeDescriptor);
}
- else {
- TypeId asTypeId = cgFunction.getASTypeId();
- if (asTypeId == TypeId.STRING) { // FIXME Fudge for body-less functions
- js.append("return \"\";\n");
- }
- else if (asTypeId == TypeId.REAL) { // FIXME Fudge for body-less functions
- js.append("return 0;\n");
- }
- else if (asTypeId == TypeId.INTEGER) { // FIXME Fudge for body-less functions
- js.append("return 0;\n");
- }
- else if (asTypeId instanceof CollectionTypeId) { // FIXME Fudge for body-less functions
- if (js.isUseNullAnnotations()) {
- js.append("@SuppressWarnings(\"null\")");
- js.appendIsRequired(true);
- js.append(" ");
- }
- if (elementId != null) {
- TypeDescriptor javaTypeDescriptor = context.getUnboxedDescriptor(elementId);
- js.appendClassReference(javaTypeDescriptor);
- }
- js.append(" emptyList = ");
- js.appendClassReference(Collections.class);
- js.append(".emptyList();\n");
- js.append("return emptyList;\n");
- }
- else { // FIXME Fudge for body-less functions
- js.append("return \"\";\n");
+ js.append(" ");
+ js.append(cgFunction.getName());
+ js.append("(");
+ boolean isFirst = true;
+ for (@SuppressWarnings("null")@NonNull CGParameter cgParameter : cgParameters) {
+ if (!isFirst) {
+ js.append(", ");
}
+ js.appendDeclaration(cgParameter);
+ isFirst = false;
}
- js.popIndentation();
- js.append("}\n");
+ js.append(")");
+ return doFunctionBody(cgFunction);
+ }
}
finally {
localContext = null;
@@ -966,6 +1333,8 @@ public class QVTiCG2JavaVisitor extends CG2JavaVisitor<@NonNull QVTiCodeGenerato
@Override
public @NonNull Boolean visitCGFunctionCallExp(@NonNull CGFunctionCallExp cgFunctionCallExp) {
Operation pOperation = cgFunctionCallExp.getReferredOperation();
+ CGFunction cgFunction = ClassUtil.nonNullState(cgFunctionCallExp.getFunction());
+ boolean isIdentifiedInstance = useClass(cgFunction) != null;
List<CGValuedElement> cgArguments = cgFunctionCallExp.getArguments();
List<Parameter> pParameters = pOperation.getOwnedParameters();
//
@@ -978,8 +1347,15 @@ public class QVTiCG2JavaVisitor extends CG2JavaVisitor<@NonNull QVTiCodeGenerato
//
js.appendDeclaration(cgFunctionCallExp);
js.append(" = ");
- js.append(cgFunctionCallExp.getReferredOperation().getName());
- js.append("(");
+ if (isIdentifiedInstance) {
+ js.append("getIdentification(");
+ js.append(getFunctionCtorName(cgFunction));
+ js.append(", ");
+ }
+ else {
+ js.append(pOperation.getName());
+ js.append("(");
+ }
int iMax = Math.min(pParameters.size(), cgArguments.size());
for (int i = 0; i < iMax; i++) {
if (i > 0) {
@@ -992,7 +1368,11 @@ public class QVTiCG2JavaVisitor extends CG2JavaVisitor<@NonNull QVTiCodeGenerato
TypeDescriptor parameterTypeDescriptor = context.getUnboxedDescriptor(pParameter.getTypeId());
js.appendReferenceTo(parameterTypeDescriptor, argument);
}
- js.append(");\n");
+ js.append(")");
+ if (isIdentifiedInstance) {
+ js.append(".getInstance()");
+ }
+ js.append(";\n");
return true;
}
@@ -1012,8 +1392,7 @@ public class QVTiCG2JavaVisitor extends CG2JavaVisitor<@NonNull QVTiCodeGenerato
if (localContext2 != null) {
localContext = localContext2;
try {
- CGValuedElement cgBody = cgMapping.getBody();
- List<CGGuardVariable> cgFreeVariables = cgMapping.getFreeVariables();
+ List<@NonNull CGGuardVariable> cgFreeVariables = ClassUtil.nullFree(cgMapping.getFreeVariables());
//
js.appendCommentWithOCL(null, cgMapping.getAst());
if (useClass(cgMapping) && (cgFreeVariables.size() > 0)) {
@@ -1024,162 +1403,37 @@ public class QVTiCG2JavaVisitor extends CG2JavaVisitor<@NonNull QVTiCodeGenerato
js.append("\n");
js.append("{\n");
js.pushIndentation(null);
- for (@SuppressWarnings("null")@NonNull CGGuardVariable cgFreeVariable : cgFreeVariables) {
+ for (@NonNull CGGuardVariable cgFreeVariable : cgFreeVariables) {
js.append("protected ");
-// js.appendDeclaration(cgFreeVariable);
- if (cgFreeVariable instanceof CGConnectionVariable) {
- js.append("final ");
- js.appendClassReference(null, cgFreeVariable);
- js.append(".");
- js.appendIsRequired(true);
- js.append(" Accumulator "); // FIXME Embed properly as a nested typeid
- js.append(getValueName(cgFreeVariable));
- }
- else{
- js.appendDeclaration(cgFreeVariable);
- }
+ doMappingConnectionVariable(cgFreeVariable);
js.append(";\n");
}
js.append("\n");
-// js.append("@SuppressWarnings(\"null\")\n");
- js.append("public ");
- js.append(getMappingName(cgMapping));
- js.append("(");
- js.appendIsRequired(true);
- js.append(" Object ");
- js.appendIsRequired(true);
- js.append(" [] boundValues) {\n");
- js.pushIndentation(null);
- int i = 0;
- for (@SuppressWarnings("null")@NonNull CGGuardVariable cgFreeVariable : cgFreeVariables) {
- String valueName = getValueName(cgFreeVariable);
- js.append(valueName);
- js.append(" = ");
-// js.appendClassCast(cgFreeVariable);
- if (cgFreeVariable instanceof CGConnectionVariable) {
- js.append("(");
- js.appendClassReference(null, cgFreeVariable);
- js.append(".Accumulator)"); // FIXME Embed properly as a nested typeid
- }
- else{
- js.appendClassCast(cgFreeVariable);
- }
- js.append("boundValues[" + i++);
- js.append("];\n");
- }
- js.popIndentation();
- js.append("}\n");
+ doMappingConstructor(cgMapping);
js.append("\n");
js.append("public boolean execute() throws ");
js.appendClassReference(ReflectiveOperationException.class);
- js.append(" {\n");
- js.pushIndentation(null);
- if (cgBody.isInvalid()) {
- js.append("return handleExecutionFailure(\"" + getMappingName(cgMapping) + "\", ");
- js.appendValueName(cgBody);
- js.append(");\n");
- }
- else {
- js.append("try {\n");
- js.pushIndentation(null);
- String savedLocalPrefix = localPrefix;
- try {
- localPrefix = cgMapping.getTransformation().getName();
- js.append("// predicates and unrealized variables\n");
- if (!cgBody.isInlined()) {
- cgBody.accept(this);
- }
- js.append("return ");
- js.appendValueName(cgBody);
- js.append(";\n");
- }
- finally {
- localPrefix = savedLocalPrefix;
- }
- js.popIndentation();
- js.append("} catch (Throwable e) {\n");
- js.pushIndentation(null);
- js.append("return handleExecutionFailure(\"" + getMappingName(cgMapping) + "\", e);\n");
- js.popIndentation();
- js.append("}\n");
- }
- js.popIndentation();
- js.append("}\n");
+ doMappingBody(cgMapping, true);
js.append("\n");
- js.append("public boolean isEqual(");
- js.appendIsRequired(true);
- js.append(" ");
- js.appendClassReference(IdResolver.class);
- js.append(" idResolver, ");
- js.appendIsRequired(true);
- js.append(" Object ");
- js.appendIsRequired(true);
- js.append(" [] thoseValues) {\n");
- js.pushIndentation(null);
- js.append("return ");
- int index = 0;
- for (@SuppressWarnings("null")@NonNull CGGuardVariable cgFreeVariable : cgFreeVariables) {
- if (index > 0) {
- js.append("\n && ");
- }
- js.append("idResolver.oclEquals(");
- js.append(cgFreeVariable.getValueName());
- js.append(", thoseValues[" + index++ + "])");
- }
- js.append(";\n");
- js.popIndentation();
- js.append("}\n");
+ doIsEqual(cgFreeVariables);
js.popIndentation();
js.append("}\n");
}
else {
js.append("protected boolean " + getMappingName(cgMapping) + "(");
boolean isFirst = true;
- for (@SuppressWarnings("null")@NonNull CGGuardVariable cgFreeVariable : cgFreeVariables) {
+ for (@NonNull CGGuardVariable cgFreeVariable : cgFreeVariables) {
if (!isFirst) {
js.append(", ");
}
- if (cgFreeVariable instanceof CGConnectionVariable) {
- js.append("final ");
- js.appendClassReference(null, cgFreeVariable);
- js.append(".");
- js.appendIsRequired(true);
- js.append(" Accumulator "); // FIXME Embed properly as a nested typeid
- js.append(getValueName(cgFreeVariable));
- }
- else{
- js.appendDeclaration(cgFreeVariable);
- }
+ doMappingConnectionVariable(cgFreeVariable);
isFirst = false;
}
js.append(") throws ");
js.appendClassReference(ReflectiveOperationException.class);
- js.append(" {\n");
- js.pushIndentation(null);
- if (cgBody.isInvalid()) {
- js.append("return handleExecutionFailure(\"" + getMappingName(cgMapping) + "\", ");
- js.appendValueName(cgBody);
- js.append(");\n");
- }
- else {
- js.append("try {\n");
- js.pushIndentation(null);
- js.append("// predicates and unrealized variables\n");
- if (!cgBody.isInlined()) {
- cgBody.accept(this);
- }
- js.append("return ");
- js.appendValueName(cgBody);
- js.append(";\n");
- js.popIndentation();
- js.append("} catch (Throwable e) {\n");
- js.pushIndentation(null);
- js.append("return handleExecutionFailure(\"" + getMappingName(cgMapping) + "\", e);\n");
- js.popIndentation();
- js.append("}\n");
- }
- js.popIndentation();
- js.append("}\n");
+
+ doMappingBody(cgMapping, false);
+
}
}
finally {
@@ -1188,7 +1442,7 @@ public class QVTiCG2JavaVisitor extends CG2JavaVisitor<@NonNull QVTiCodeGenerato
}
return true;
}
-
+
@Override
public @NonNull Boolean visitCGMappingCall(@NonNull CGMappingCall cgMappingCall) {
MappingCall pMappingCall = (MappingCall) cgMappingCall.getAst();
@@ -1511,6 +1765,22 @@ public class QVTiCG2JavaVisitor extends CG2JavaVisitor<@NonNull QVTiCodeGenerato
}
@Override
+ public @NonNull Boolean visitCGShadowExp(@NonNull CGShadowExp cgShadowExp) {
+ super.visitCGShadowExp(cgShadowExp);
+ ShadowExp asShadowExp = (ShadowExp)ClassUtil.nonNullState(cgShadowExp.getAst());
+ DomainUsage usage = transformationAnalysis.getDomainUsageAnalysis().getUsage(asShadowExp);
+ TypedModel asTypedModel = ClassUtil.nonNullState(usage.getTypedModel(asShadowExp));
+ CGTypedModel cgTypedModel = context.getAnalyzer().getTypedModel(asTypedModel);
+ js.append(QVTiGlobalContext.MODELS_NAME);
+ js.append("[");
+ appendModelIndex(cgTypedModel);
+ js.append("].add(");
+ js.appendValueName(cgShadowExp);
+ js.append(");\n");
+ return true;
+ }
+
+ @Override
public @NonNull Boolean visitCGTransformation(@NonNull CGTransformation cgTransformation) {
js.appendClassHeader(cgTransformation.getContainingPackage());
@SuppressWarnings("null")@NonNull Transformation transformation = (Transformation) cgTransformation.getAst();
@@ -1548,7 +1818,10 @@ public class QVTiCG2JavaVisitor extends CG2JavaVisitor<@NonNull QVTiCodeGenerato
}
@NonNull String @Nullable [] allInstancesNames = doAllInstances(transformationAnalysis);
js.append("\n");
- doConstructorConstants(ClassUtil.nullFree(cgTransformation.getMappings()));
+ List<@NonNull CGMapping> cgMappings = ClassUtil.nullFree(cgTransformation.getMappings());
+ List<CGOperation> cgOperations = cgTransformation.getOperations();
+ doMappingConstructorConstants(cgMappings);
+ doFunctionConstructorConstants(ClassUtil.nullFree(cgOperations));
js.append("\n");
doConstructor(cgTransformation, oppositeIndex2propertyIdName, allInstancesNames);
js.append("\n");
@@ -1557,7 +1830,7 @@ public class QVTiCG2JavaVisitor extends CG2JavaVisitor<@NonNull QVTiCodeGenerato
js.append("\n");
}
doRun(cgTransformation);
- for (@NonNull CGOperation cgOperation : ClassUtil.nullFree(cgTransformation.getOperations())) {
+ for (@NonNull CGOperation cgOperation : ClassUtil.nullFree(cgOperations)) {
js.append("\n");
cgOperation.accept(this);
}
diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtc2qvtu/QVTc2QVTu.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtc2qvtu/QVTc2QVTu.java
index 0c3233ff0..1b0528672 100644
--- a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtc2qvtu/QVTc2QVTu.java
+++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtc2qvtu/QVTc2QVTu.java
@@ -485,9 +485,9 @@ public class QVTc2QVTu extends AbstractQVTc2QVTc
// if (isMiddleDomain(targetArea) /*&& !(value instanceof VariableExp)*/ && allMatchReferencedOutputDomainVariables(value)) { // isRtoM
// return null;
// }
- if ((targetArea instanceof Mapping) && anyReferencedBottomMiddleDomainVariables(value)) { // isMtoM
- return null;
- }
+// if ((targetArea instanceof Mapping) && anyReferencedBottomMiddleDomainVariables(value)) { // isMtoM
+// return null;
+// }
return super.visitVariableAssignment(vaIn);
}
}
diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/AbstractNode.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/AbstractNode.java
index 7e6681990..361d7b5e5 100644
--- a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/AbstractNode.java
+++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/AbstractNode.java
@@ -507,9 +507,14 @@ public abstract class AbstractNode implements Node
@Override
public final boolean isClassNode() {
-// boolean isClassNode1 = nodeRole.isClassNode(); // FIXME OperationNode
- boolean isClassNode2 = !(classDatumAnalysis.getClassDatum().getType() instanceof DataType) && !isNull();
+ boolean isClassNode1 = nodeRole.isClassNode(); // FIXME OperationNode / InternalNode
+ boolean isClassNode2 = !(classDatumAnalysis.getClassDatum().getType() instanceof DataType) && !isNull();// && !isOperation();
// assert isClassNode1 == isClassNode2;
+ if (isClassNode1 != isClassNode2) {
+// System.err.println("Inconsistent isClassNode for " + this);
+ isClassNode1 = nodeRole.isClassNode();
+ isClassNode2 = !(classDatumAnalysis.getClassDatum().getType() instanceof DataType) && !isNull();// && !isOperation();
+ }
return isClassNode2;
}
diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/Nodes.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/Nodes.java
index 6661843c2..9fde4d1e8 100644
--- a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/Nodes.java
+++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/Nodes.java
@@ -15,6 +15,8 @@ import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.ocl.pivot.CallExp;
import org.eclipse.ocl.pivot.DataType;
import org.eclipse.ocl.pivot.NavigationCallExp;
+import org.eclipse.ocl.pivot.Operation;
+import org.eclipse.ocl.pivot.OperationCallExp;
import org.eclipse.ocl.pivot.Property;
import org.eclipse.ocl.pivot.Type;
import org.eclipse.ocl.pivot.TypedElement;
@@ -58,17 +60,22 @@ public class Nodes
public static abstract class AbstractVariableNodeRole extends AbstractSimpleNodeRole
{
- protected AbstractVariableNodeRole(@NonNull Phase phase) {
+ protected final boolean isClassNode;
+
+ protected AbstractVariableNodeRole(@NonNull Phase phase, boolean isClassNode) {
super(phase);
+ this.isClassNode = isClassNode;
}
public @NonNull SimpleNode createSimpleNode(@NonNull SimpleRegion region, @NonNull VariableDeclaration variable) {
+ assert isClassNode == !(variable.getType() instanceof DataType);
return new SimpleVariableNode(this, region, variable);
}
@Override
public boolean isClassNode() {
- return true;
+// return !(classDatumAnalysis.getClassDatum().getType() instanceof DataType);
+ return isClassNode;
}
}
@@ -409,8 +416,8 @@ public class Nodes
{
private static abstract class AbstractGuardNodeRole extends AbstractVariableNodeRole
{
- protected AbstractGuardNodeRole(@NonNull Phase phase) {
- super(phase);
+ protected AbstractGuardNodeRole(@NonNull Phase phase, boolean isClassNode) {
+ super(phase, isClassNode);
}
@Override
@@ -441,8 +448,8 @@ public class Nodes
{
private final @NonNull HeadNodeRole headNode;
- protected GuardNodeRole(@NonNull Phase phase, @NonNull HeadNodeRole headNode) {
- super(phase);
+ protected GuardNodeRole(@NonNull Phase phase, @NonNull HeadNodeRole headNode, boolean isClassNode) {
+ super(phase, isClassNode);
this.headNode = headNode;
}
@@ -466,7 +473,7 @@ public class Nodes
private static final class HeadNodeRole extends AbstractGuardNodeRole
{
protected HeadNodeRole(@NonNull Phase phase) {
- super(phase);
+ super(phase, true);
}
@Override
@@ -487,18 +494,30 @@ public class Nodes
}
private static final @NonNull HeadNodeRole LOADED_HEAD = new HeadNodeRole(Role.Phase.LOADED);
- private static final @NonNull GuardNodeRole LOADED_GUARD = new GuardNodeRole(Role.Phase.LOADED, LOADED_HEAD);
+ private static final @NonNull GuardNodeRole LOADED_ATTRIBUTE_GUARD = new GuardNodeRole(Role.Phase.LOADED, LOADED_HEAD,false);
+ private static final @NonNull GuardNodeRole LOADED_CLASS_GUARD = new GuardNodeRole(Role.Phase.LOADED, LOADED_HEAD, true);
private static final @NonNull HeadNodeRole PREDICATED_HEAD = new HeadNodeRole(Role.Phase.PREDICATED);
- private static final @NonNull GuardNodeRole PREDICATED_GUARD = new GuardNodeRole(Role.Phase.PREDICATED, PREDICATED_HEAD);
+ private static final @NonNull GuardNodeRole PREDICATED_ATTRIBUTE_GUARD = new GuardNodeRole(Role.Phase.PREDICATED, PREDICATED_HEAD, false);
+ private static final @NonNull GuardNodeRole PREDICATED_CLASS_GUARD = new GuardNodeRole(Role.Phase.PREDICATED, PREDICATED_HEAD, true);
+
+ private final @Nullable Boolean isClassNode;
+
+ public GuardNodeRoleFactory(@Nullable Boolean isClassNode) {
+ this.isClassNode = isClassNode;
+ }
public @NonNull SimpleNode createSimpleNode(@NonNull SimpleRegion region, @NonNull VariableDeclaration guardVariable) {
DomainUsage domainUsage = region.getSchedulerConstants().getDomainUsage(guardVariable);
boolean isEnforceable = domainUsage.isOutput();
+ Boolean resolvedIsClassNode = isClassNode;
+ if (resolvedIsClassNode == null) {
+ resolvedIsClassNode = !(guardVariable.getType() instanceof DataType);
+ }
if (!isEnforceable) {
- return LOADED_GUARD.createSimpleNode(region, guardVariable);
+ return (resolvedIsClassNode ? LOADED_CLASS_GUARD : LOADED_ATTRIBUTE_GUARD).createSimpleNode(region, guardVariable);
}
else {
- return PREDICATED_GUARD.createSimpleNode(region, guardVariable);
+ return (resolvedIsClassNode ? PREDICATED_CLASS_GUARD : PREDICATED_ATTRIBUTE_GUARD).createSimpleNode(region, guardVariable);
}
}
}
@@ -507,8 +526,8 @@ public class Nodes
{
private static final class IteratorNodeRole extends AbstractVariableNodeRole
{
- protected IteratorNodeRole(@NonNull Phase phase) {
- super(phase);
+ protected IteratorNodeRole(@NonNull Phase phase, boolean isClassNode) {
+ super(phase, isClassNode);
}
// @Override
@@ -537,19 +556,32 @@ public class Nodes
// }
}
- public static final @NonNull AbstractVariableNodeRole CONSTANT_ITERATOR = new IteratorNodeRole(Role.Phase.CONSTANT);
- public static final @NonNull AbstractVariableNodeRole LOADED_ITERATOR = new IteratorNodeRole(Role.Phase.LOADED);
- public static final @NonNull AbstractVariableNodeRole PREDICATED_ITERATOR = new IteratorNodeRole(Role.Phase.PREDICATED);
+ private static final @NonNull AbstractVariableNodeRole CONSTANT_ATTRIBUTE_ITERATOR = new IteratorNodeRole(Role.Phase.CONSTANT, false);
+ private static final @NonNull AbstractVariableNodeRole CONSTANT_CLASS_ITERATOR = new IteratorNodeRole(Role.Phase.CONSTANT, true);
+ private static final @NonNull AbstractVariableNodeRole LOADED_ATTRIBUTE_ITERATOR = new IteratorNodeRole(Role.Phase.LOADED, false);
+ private static final @NonNull AbstractVariableNodeRole LOADED_CLASS_ITERATOR = new IteratorNodeRole(Role.Phase.LOADED, true);
+ private static final @NonNull AbstractVariableNodeRole PREDICATED_ATTRIBUTE_ITERATOR = new IteratorNodeRole(Role.Phase.PREDICATED, false);
+ private static final @NonNull AbstractVariableNodeRole PREDICATED_CLASS_ITERATOR = new IteratorNodeRole(Role.Phase.PREDICATED, true);
+
+ private final @Nullable Boolean isClassNode;
+
+ public IteratorNodeRoleFactory(@Nullable Boolean isClassNode) {
+ this.isClassNode = isClassNode;
+ }
public @NonNull SimpleNode createSimpleNode(@NonNull SimpleRegion region, @NonNull Variable iterator, @NonNull SimpleNode sourceNode) {
+ Boolean resolvedIsClassNode = isClassNode;
+ if (resolvedIsClassNode == null) {
+ resolvedIsClassNode = !(iterator.getType() instanceof DataType);
+ }
if (sourceNode.isConstant()) {
- return CONSTANT_ITERATOR.createSimpleNode(region, iterator);
+ return (resolvedIsClassNode ? CONSTANT_CLASS_ITERATOR : CONSTANT_ATTRIBUTE_ITERATOR).createSimpleNode(region, iterator);
}
else if (sourceNode.isLoaded()) {
- return LOADED_ITERATOR.createSimpleNode(region, iterator);
+ return (resolvedIsClassNode ? LOADED_CLASS_ITERATOR : LOADED_ATTRIBUTE_ITERATOR).createSimpleNode(region, iterator);
}
else {
- return PREDICATED_ITERATOR.createSimpleNode(region, iterator);
+ return (resolvedIsClassNode ? PREDICATED_CLASS_ITERATOR : PREDICATED_ATTRIBUTE_ITERATOR).createSimpleNode(region, iterator);
}
}
}
@@ -560,8 +592,8 @@ public class Nodes
{
private boolean isNavigable;
- protected LetVariableNodeRole(@NonNull Phase phase, boolean isNavigable) {
- super(phase);
+ protected LetVariableNodeRole(@NonNull Phase phase, boolean isNavigable, boolean isClassNode) {
+ super(phase, isClassNode);
this.isNavigable = isNavigable;
}
@@ -581,34 +613,50 @@ public class Nodes
}
}
- public static final @NonNull AbstractVariableNodeRole CONSTANT_NAVIGABLE_LET = new LetVariableNodeRole(Role.Phase.CONSTANT, true);
- public static final @NonNull AbstractVariableNodeRole CONSTANT_UNNAVIGABLE_LET = new LetVariableNodeRole(Role.Phase.CONSTANT, false);
- public static final @NonNull AbstractVariableNodeRole LOADED_NAVIGABLE_LET = new LetVariableNodeRole(Role.Phase.LOADED, true);
- public static final @NonNull AbstractVariableNodeRole LOADED_UNNAVIGABLE_LET = new LetVariableNodeRole(Role.Phase.LOADED, false);
- public static final @NonNull AbstractVariableNodeRole PREDICATED_NAVIGABLE_LET = new LetVariableNodeRole(Role.Phase.PREDICATED, true);
- public static final @NonNull AbstractVariableNodeRole PREDICATED_UNNAVIGABLE_LET = new LetVariableNodeRole(Role.Phase.PREDICATED, false);
+ private static final @NonNull AbstractVariableNodeRole CONSTANT_NAVIGABLE_ATTRIBUTE_LET = new LetVariableNodeRole(Role.Phase.CONSTANT, true, false);
+ private static final @NonNull AbstractVariableNodeRole CONSTANT_NAVIGABLE_CLASS_LET = new LetVariableNodeRole(Role.Phase.CONSTANT, true, true);
+ private static final @NonNull AbstractVariableNodeRole CONSTANT_UNNAVIGABLE_ATTRIBUTE_LET = new LetVariableNodeRole(Role.Phase.CONSTANT, false, false);
+ private static final @NonNull AbstractVariableNodeRole CONSTANT_UNNAVIGABLE_CLASS_LET = new LetVariableNodeRole(Role.Phase.CONSTANT, false, true);
+ private static final @NonNull AbstractVariableNodeRole LOADED_NAVIGABLE_ATTRIBUTE_LET = new LetVariableNodeRole(Role.Phase.LOADED, true, false);
+ private static final @NonNull AbstractVariableNodeRole LOADED_NAVIGABLE_CLASS_LET = new LetVariableNodeRole(Role.Phase.LOADED, true, true);
+ private static final @NonNull AbstractVariableNodeRole LOADED_UNNAVIGABLE_ATTRIBUTE_LET = new LetVariableNodeRole(Role.Phase.LOADED, false, false);
+ private static final @NonNull AbstractVariableNodeRole LOADED_UNNAVIGABLE_CLASS_LET = new LetVariableNodeRole(Role.Phase.LOADED, false, true);
+ private static final @NonNull AbstractVariableNodeRole PREDICATED_NAVIGABLE_ATTRIBUTE_LET = new LetVariableNodeRole(Role.Phase.PREDICATED, true, false);
+ private static final @NonNull AbstractVariableNodeRole PREDICATED_NAVIGABLE_CLASS_LET = new LetVariableNodeRole(Role.Phase.PREDICATED, true, true);
+ private static final @NonNull AbstractVariableNodeRole PREDICATED_UNNAVIGABLE_ATTRIBUTE_LET = new LetVariableNodeRole(Role.Phase.PREDICATED, false, false);
+ private static final @NonNull AbstractVariableNodeRole PREDICATED_UNNAVIGABLE_CLASS_LET = new LetVariableNodeRole(Role.Phase.PREDICATED, false, true);
+
+ private final @Nullable Boolean isClassNode;
+
+ public LetNodeRoleFactory(@Nullable Boolean isClassNode) {
+ this.isClassNode = isClassNode;
+ }
public @NonNull SimpleNode createSimpleNode(@NonNull SimpleRegion region, @NonNull Variable letVariable, @NonNull SimpleNode inNode) {
+ Boolean resolvedIsClassNode = isClassNode;
+ if (resolvedIsClassNode == null) {
+ resolvedIsClassNode = !(letVariable.getType() instanceof DataType);
+ }
if (inNode.isNavigable()) {
if (inNode.isConstant()) {
- return CONSTANT_NAVIGABLE_LET.createSimpleNode(region, letVariable);
+ return (resolvedIsClassNode ? CONSTANT_NAVIGABLE_CLASS_LET : CONSTANT_NAVIGABLE_ATTRIBUTE_LET).createSimpleNode(region, letVariable);
}
else if (inNode.isLoaded()) {
- return LOADED_NAVIGABLE_LET.createSimpleNode(region, letVariable);
+ return (resolvedIsClassNode ? LOADED_NAVIGABLE_CLASS_LET : LOADED_NAVIGABLE_ATTRIBUTE_LET).createSimpleNode(region, letVariable);
}
else {
- return PREDICATED_NAVIGABLE_LET.createSimpleNode(region, letVariable);
+ return (resolvedIsClassNode ? PREDICATED_NAVIGABLE_CLASS_LET : PREDICATED_NAVIGABLE_ATTRIBUTE_LET).createSimpleNode(region, letVariable);
}
}
else {
if (inNode.isConstant()) {
- return CONSTANT_UNNAVIGABLE_LET.createSimpleNode(region, letVariable);
+ return (resolvedIsClassNode ? CONSTANT_UNNAVIGABLE_CLASS_LET : CONSTANT_UNNAVIGABLE_ATTRIBUTE_LET).createSimpleNode(region, letVariable);
}
else if (inNode.isLoaded()) {
- return LOADED_UNNAVIGABLE_LET.createSimpleNode(region, letVariable);
+ return (resolvedIsClassNode ? LOADED_UNNAVIGABLE_CLASS_LET : LOADED_UNNAVIGABLE_ATTRIBUTE_LET).createSimpleNode(region, letVariable);
}
else {
- return PREDICATED_UNNAVIGABLE_LET.createSimpleNode(region, letVariable);
+ return (resolvedIsClassNode ? PREDICATED_UNNAVIGABLE_CLASS_LET : PREDICATED_UNNAVIGABLE_ATTRIBUTE_LET).createSimpleNode(region, letVariable);
}
}
}
@@ -700,6 +748,15 @@ public class Nodes
}
}
}
+ if (typedElement instanceof OperationCallExp) {
+ Operation asOperation = ((OperationCallExp)typedElement).getReferredOperation();
+ if (QVTbaseUtil.isIdentification(asOperation)) {
+ DomainUsage usage = region.getSchedulerConstants().getDomainUsage(typedElement);
+ if (!usage.isInput()) {
+ isRealized = true;
+ }
+ }
+ }
if (isRealized) {
return REALIZED_OPERATION.createSimpleNode(region, name, typedElement);
}
@@ -715,15 +772,36 @@ public class Nodes
}
}
- private static final class ParameterNodeRole extends AbstractVariableNodeRole
- {
- protected ParameterNodeRole() {
- super(Role.Phase.PREDICATED);
+ public static final class ParameterNodeRoleFactory
+ {
+ private static final class ParameterNodeRole extends AbstractVariableNodeRole
+ {
+ protected ParameterNodeRole(boolean isClassNode) {
+ super(Role.Phase.PREDICATED, isClassNode);
+ }
+
+ @Override
+ public boolean isHead() {
+ return true;
+ }
}
- @Override
- public boolean isHead() {
- return true;
+
+ private static final @NonNull ParameterNodeRole ATTRIBUTE_PARAMETER = new ParameterNodeRole(false);
+ private static final @NonNull ParameterNodeRole CLASS_PARAMETER = new ParameterNodeRole(true);
+
+ private final @Nullable Boolean isClassNode;
+
+ public ParameterNodeRoleFactory(@Nullable Boolean isClassNode) {
+ this.isClassNode = isClassNode;
+ }
+
+ public @NonNull SimpleNode createSimpleNode(@NonNull SimpleRegion region, @NonNull String name, @NonNull ClassDatumAnalysis classDatumAnalysis) {
+ Boolean resolvedIsClassNode = isClassNode;
+ if (resolvedIsClassNode == null) {
+ resolvedIsClassNode = !(classDatumAnalysis.getClassDatum().getType() instanceof DataType);
+ }
+ return (resolvedIsClassNode ? CLASS_PARAMETER : ATTRIBUTE_PARAMETER).createSimpleNode(region, name, classDatumAnalysis);
}
}
@@ -813,7 +891,7 @@ public class Nodes
private static final class RealizedVariableNodeRole extends AbstractVariableNodeRole
{
protected RealizedVariableNodeRole() {
- super(Role.Phase.REALIZED);
+ super(Role.Phase.REALIZED, true);
}
@Override
@@ -1028,11 +1106,31 @@ public class Nodes
return ERROR_COLOR;
}
}
-
- private static final class UnrealizedVariableNodeRole extends AbstractVariableNodeRole
- {
- protected UnrealizedVariableNodeRole() {
- super(Role.Phase.LOADED);
+
+ public static final class UnrealizedVariableNodeRoleFactory
+ {
+ private static final class UnrealizedVariableNodeRole extends AbstractVariableNodeRole
+ {
+ protected UnrealizedVariableNodeRole(boolean isClassNode) {
+ super(Role.Phase.LOADED, isClassNode);
+ }
+ }
+
+ private static final @NonNull UnrealizedVariableNodeRole UNREALIZED_ATTRIBUTE_VARIABLE = new UnrealizedVariableNodeRole(false);
+ private static final @NonNull UnrealizedVariableNodeRole UNREALIZED_CLASS_VARIABLE = new UnrealizedVariableNodeRole(true);
+
+ private final @Nullable Boolean isClassNode;
+
+ public UnrealizedVariableNodeRoleFactory(@Nullable Boolean isClassNode) {
+ this.isClassNode = isClassNode;
+ }
+
+ public @NonNull SimpleNode createSimpleNode(@NonNull SimpleRegion region, @NonNull Variable variable) {
+ Boolean resolvedIsClassNode = isClassNode;
+ if (resolvedIsClassNode == null) {
+ resolvedIsClassNode = !(variable.getType() instanceof DataType);
+ }
+ return (resolvedIsClassNode ? UNREALIZED_CLASS_VARIABLE : UNREALIZED_ATTRIBUTE_VARIABLE).createSimpleNode(region, variable);
}
}
@@ -1041,16 +1139,16 @@ public class Nodes
public static final @NonNull ElementNodeRoleFactory ELEMENT = new ElementNodeRoleFactory();
public static final @NonNull NodeRole ERROR = new ErrorNodeRole();
public static final @NonNull NodeRole EXTRA_GUARD = new AttributeNodeRoleFactory.ExtraGuardNodeRole();
- public static final @NonNull GuardNodeRoleFactory GUARD = new GuardNodeRoleFactory();
+ public static final @NonNull GuardNodeRoleFactory GUARD = new GuardNodeRoleFactory(null);
public static final @NonNull PortNodeRoleFactory INPUT = new PortNodeRoleFactory(); //true);
- public static final @NonNull IteratorNodeRoleFactory ITERATOR = new IteratorNodeRoleFactory();
- public static final @NonNull LetNodeRoleFactory LET = new LetNodeRoleFactory();
+ public static final @NonNull IteratorNodeRoleFactory ITERATOR = new IteratorNodeRoleFactory(null);
+ public static final @NonNull LetNodeRoleFactory LET = new LetNodeRoleFactory(null);
public static final @NonNull AttributeNodeRoleFactory NAVIGABLE_ATTRIBUTE = new AttributeNodeRoleFactory(true);
public static final @NonNull StepNodeRoleFactory NAVIGABLE_STEP = new StepNodeRoleFactory(true);
public static final @NonNull NullNodeRole NULL = new NullNodeRole();
public static final @NonNull OperationNodeRoleFactory OPERATION = new OperationNodeRoleFactory();
// public static final @NonNull PortNodeRoleFactory OUTPUT = new PortNodeRoleFactory(false);
- public static final @NonNull AbstractVariableNodeRole PARAMETER = new ParameterNodeRole();
+ public static final @NonNull ParameterNodeRoleFactory PARAMETER = new ParameterNodeRoleFactory(null);
public static final AttributeNodeRoleFactory.@NonNull RealizedAttributeNodeRole REALIZED_ATTRIBUTE = new AttributeNodeRoleFactory.RealizedAttributeNodeRole();
public static final @NonNull AbstractVariableNodeRole REALIZED_VARIABLE = new RealizedVariableNodeRole();
public static final @NonNull StepNodeRoleFactory STEP = new StepNodeRoleFactory(null);
@@ -1058,5 +1156,5 @@ public class Nodes
public static final @NonNull NodeRole UNKNOWN = new UnknownNodeRole();
public static final @NonNull AttributeNodeRoleFactory UNNAVIGABLE_ATTRIBUTE = new AttributeNodeRoleFactory(false);
public static final @NonNull StepNodeRoleFactory UNNAVIGABLE_STEP = new StepNodeRoleFactory(false);
- public static final @NonNull AbstractVariableNodeRole UNREALIZED_VARIABLE = new UnrealizedVariableNodeRole();
+ public static final @NonNull UnrealizedVariableNodeRoleFactory UNREALIZED_VARIABLE = new UnrealizedVariableNodeRoleFactory(null);
} \ No newline at end of file
diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/SimpleMappingRegion.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/SimpleMappingRegion.java
index 130757d73..21d575b2a 100644
--- a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/SimpleMappingRegion.java
+++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/SimpleMappingRegion.java
@@ -35,6 +35,7 @@ import org.eclipse.ocl.pivot.utilities.ClassUtil;
import org.eclipse.ocl.pivot.utilities.PivotUtil;
import org.eclipse.qvtd.pivot.qvtbase.Domain;
import org.eclipse.qvtd.pivot.qvtbase.Predicate;
+import org.eclipse.qvtd.pivot.qvtbase.utilities.QVTbaseUtil;
import org.eclipse.qvtd.pivot.qvtcorebase.AbstractMapping;
import org.eclipse.qvtd.pivot.qvtcorebase.Assignment;
import org.eclipse.qvtd.pivot.qvtcorebase.BottomPattern;
@@ -251,6 +252,7 @@ public class SimpleMappingRegion extends AbstractMappingRegion implements Simple
}
public void addVariableNode(@NonNull VariableDeclaration typedElement, @NonNull SimpleNode simpleNode) {
+// assert !simpleNode.isOperation(); // FIXME testExample2_V2 violates this for an intermediate "if"
variable2simpleNode.put(typedElement, simpleNode);
}
@@ -330,6 +332,24 @@ public class SimpleMappingRegion extends AbstractMappingRegion implements Simple
private @NonNull SimpleNode analyzeVariable(@NonNull Variable variable, @NonNull OCLExpression ownedInit) {
SimpleNode initNode = ownedInit.accept(expressionAnalyzer);
assert initNode != null;
+ if ((ownedInit instanceof OperationCallExp) && initNode.isOperation()) {
+ if (QVTbaseUtil.isIdentification(((OperationCallExp)ownedInit).getReferredOperation())) {
+ SimpleNode stepNode = Nodes.REALIZED_VARIABLE.createSimpleNode(this, variable);
+ Edges.RESULT.createSimpleEdge(this, initNode, null, stepNode);
+ initNode = stepNode;
+ }
+// else if (variable.getType() instanceof CollectionType) {
+// SimpleNode stepNode = Nodes.ATTRIBUTE.createSimpleNode(this, variable, (OperationCallExp)ownedInit);
+// Edges.RESULT.createSimpleEdge(this, initNode, null, stepNode);
+// initNode = stepNode;
+// }
+ else {
+// SimpleNode stepNode = Nodes.STEP.createSimpleNode(this, variable.getName(), (OperationCallExp)ownedInit, initNode);
+ SimpleNode stepNode = Nodes.UNREALIZED_VARIABLE.createSimpleNode(this, variable);
+ Edges.RESULT.createSimpleEdge(this, initNode, null, stepNode);
+ initNode = stepNode;
+ }
+ }
initNode.addTypedElement(variable);
addVariableNode(variable, initNode);
return initNode;
diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/SimpleNavigationEdge.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/SimpleNavigationEdge.java
index a95de47e2..e5f7f392a 100644
--- a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/SimpleNavigationEdge.java
+++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/SimpleNavigationEdge.java
@@ -19,6 +19,7 @@ public class SimpleNavigationEdge extends AbstractNavigationEdge implements Simp
{
public SimpleNavigationEdge(EdgeRole.@NonNull Navigation edgeRole, @NonNull SimpleRegion region, @NonNull SimpleNode sourceNode, @NonNull Property source2targetProperty, @NonNull SimpleNode targetNode) {
super(edgeRole, region, sourceNode, source2targetProperty, targetNode);
+// assert !sourceNode.isOperation(); // FIXME testExample2_V2 violates this to cast an intermediate "if"
}
@Override
diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/SimpleVariableNode.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/SimpleVariableNode.java
index 818b1197a..a16347060 100644
--- a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/SimpleVariableNode.java
+++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/SimpleVariableNode.java
@@ -40,6 +40,6 @@ public class SimpleVariableNode extends AbstractSimpleNode
@Override
public @NonNull String toString() {
- return getNodeRole().toString() + "(" + variable.toString() + ")";
+ return getNodeRole().toString() + "(" + (variable != null ? variable.toString() : name) + ")";
}
} \ No newline at end of file
diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvtc/AbstractQVTr2QVTcRelations.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvtc/AbstractQVTr2QVTcRelations.java
index 3b6d77555..18634904e 100644
--- a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvtc/AbstractQVTr2QVTcRelations.java
+++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvtc/AbstractQVTr2QVTcRelations.java
@@ -78,7 +78,7 @@ import org.eclipse.qvtd.pivot.qvttemplate.TemplateExp;
protected final @NonNull CoreDomain cOtherDomain;
protected final @NonNull GuardPattern cOtherGuardPattern;
protected final @NonNull BottomPattern cOtherBottomPattern;
- protected final @NonNull Set<@NonNull Variable> rOtherBoundVariables; // All variables defined in this other domain
+ protected final @NonNull Map<@NonNull Variable, @Nullable TemplateExp> rOtherBoundVariables; // All variables defined in this other domain
protected final @NonNull Set<@NonNull Variable> rOtherReferredVariables; // All variables defined or referenced in this other domain
protected final @NonNull List<@NonNull Variable> rOtherRootVariables; // The template expression variable (the root variable of this other domain pattern)
@@ -92,13 +92,13 @@ import org.eclipse.qvtd.pivot.qvttemplate.TemplateExp;
this.cOtherGuardPattern = ClassUtil.nonNullState(cOtherDomain.getGuardPattern());
this.cOtherBottomPattern = ClassUtil.nonNullState(cOtherDomain.getBottomPattern());
- this.rOtherBoundVariables = new HashSet<@NonNull Variable>();
+ this.rOtherBoundVariables = new HashMap<@NonNull Variable, @Nullable TemplateExp>();
VariablesAnalysis.gatherBoundVariables(rOtherBoundVariables, rOtherDomain);
this.rOtherReferredVariables = new HashSet<@NonNull Variable>();
VariablesAnalysis.gatherReferredVariables(rOtherReferredVariables, rOtherDomain);
this.rOtherRootVariables = getRootVariables(rOtherDomain);
- for (@NonNull Variable rVariable : rOtherBoundVariables) {
+ for (@NonNull Variable rVariable : rOtherBoundVariables.keySet()) {
variablesAnalysis.getVariableAnalysis(rVariable).setOtherBound(cOtherDomain);
}
for (@NonNull Variable rVariable : rOtherReferredVariables) {
@@ -110,7 +110,7 @@ import org.eclipse.qvtd.pivot.qvttemplate.TemplateExp;
}
// new
- private void mapOtherCollectionTemplateExpression(@NonNull Variable cTemplateVariable, @NonNull Property traceProperty, @NonNull CollectionTemplateExp cte) throws CompilerChainException {
+ private void mapOtherCollectionTemplateExpression(@NonNull Variable cTemplateVariable, @NonNull Property partProperty, @NonNull CollectionTemplateExp cte) throws CompilerChainException {
/**
* Each PropertyTemplateItem whose value is a CollectionTemplateExp
* converts to a VariableAssignment and Predicates.
@@ -119,7 +119,7 @@ import org.eclipse.qvtd.pivot.qvttemplate.TemplateExp;
*/
Variable vcte = ClassUtil.nonNullState(cte.getBindsTo());
Variable mvcte = variablesAnalysis.getCoreVariable(vcte);
- NavigationCallExp pce = createNavigationCallExp(createVariableExp(cTemplateVariable), traceProperty);
+ NavigationCallExp pce = createNavigationCallExp(createVariableExp(cTemplateVariable), partProperty);
VariableAssignment a = createVariableAssignment(mvcte, pce);
cMiddleBottomPattern.getAssignment().add(a);
/**
@@ -238,7 +238,7 @@ import org.eclipse.qvtd.pivot.qvttemplate.TemplateExp;
}
// loop body of RDomainPatternToMDBottomPatternComposite
- private void mapOtherObjectTemplateExpression(@NonNull Variable cTemplateVariable, @NonNull Property traceProperty, @NonNull ObjectTemplateExp pte) throws CompilerChainException {
+ private void mapOtherObjectTemplateExpression(@NonNull Variable rTemplateVariable, @NonNull Property partProperty, @NonNull ObjectTemplateExp pte) throws CompilerChainException {
/**
* Each PropertyTemplateItem whose value is an ObjectTemplateExp
* converts to a PropertyAssignment.
@@ -248,22 +248,22 @@ import org.eclipse.qvtd.pivot.qvttemplate.TemplateExp;
Variable vpte = ClassUtil.nonNullState(pte.getBindsTo());
Variable mvpte = variablesAnalysis.getCoreVariable(vpte);
mapOtherTemplateExpression(pte);
- qvtr2qvtc.addNavigationAssignment(cMiddleBottomPattern, cTemplateVariable, traceProperty, createVariableExp(mvpte));
+ variablesAnalysis.addNavigationAssignment(rTemplateVariable, partProperty, createVariableExp(mvpte));
}
// loop body of RDomainPatternToMDBottomPatternSimpleNonVarExpr
- private void mapOtherSimpleNonVariableExpression(@NonNull Variable cTemplateVariable, @NonNull Property traceProperty, @NonNull OCLExpression ptv) {
+ private void mapOtherSimpleNonVariableExpression(@NonNull Variable rTemplateVariable, @NonNull Property partProperty, @NonNull OCLExpression ptv) {
/**
* Each PropertyTemplateItem whose value is not a TemplateExp and not a VariableExp
* converts to a PropertyAssignment.
*
* ve1:T{tp = me} => ve1.tp := me;
*/
- qvtr2qvtc.addNavigationAssignment(cMiddleBottomPattern, cTemplateVariable, traceProperty, mapExpression(ptv));
+ variablesAnalysis.addNavigationAssignment(rTemplateVariable, partProperty, mapExpression(ptv));
}
// body of RDomainPatternToMDBottomPatternSimpleSharedVarExpr and RDomainPatternToMDBottomPatternSimpleUnSharedVarExpr
- private void mapOtherSimpleVariableExpression(@NonNull Variable cTemplateVariable, @NonNull Property traceProperty, @NonNull VariableExp e) {
+ private void mapOtherSimpleVariableExpression(@NonNull Variable rTemplateVariable, @NonNull Property partProperty, @NonNull VariableExp e) {
/**
* Each PropertyTemplateItem whose value is a simple VariableExp
* converts to a domain(unshared) / middle(shared) PropertyAssignment.
@@ -272,8 +272,8 @@ import org.eclipse.qvtd.pivot.qvttemplate.TemplateExp;
*/
Variable rVariable/*vpte*/ = ClassUtil.nonNullState((Variable) e.getReferredVariable());
Variable cVariable/*mvpte*/ = variablesAnalysis.getCoreVariable(rVariable);
- BottomPattern cBottomPattern = rSharedVariables.contains(rVariable) ? cMiddleBottomPattern : cEnforcedBottomPattern;
- qvtr2qvtc.addNavigationAssignment(cBottomPattern, cTemplateVariable, traceProperty, createVariableExp(cVariable));
+// BottomPattern cBottomPattern = rSharedVariables.contains(rVariable) ? cMiddleBottomPattern : cEnforcedBottomPattern;
+ variablesAnalysis.addNavigationAssignment(rTemplateVariable, partProperty, createVariableExp(cVariable));
}
// RDomainPatternToMDBottomPattern
@@ -281,21 +281,20 @@ import org.eclipse.qvtd.pivot.qvttemplate.TemplateExp;
Variable rTemplateVariable = ClassUtil.nonNullState(rTemplateExpression.getBindsTo());
if (rTemplateExpression instanceof ObjectTemplateExp) {
for (@NonNull PropertyTemplateItem propertyTemplateItem : ClassUtil.nullFree(((ObjectTemplateExp)rTemplateExpression).getPart())) {
- Property rProperty = ClassUtil.nonNullState(propertyTemplateItem.getReferredProperty());
+ Property partProperty = ClassUtil.nonNullState(propertyTemplateItem.getReferredProperty());
Variable cTemplateVariable = variablesAnalysis.getCoreVariable(rTemplateVariable);
- Property traceProperty = qvtr2qvtc.getProperty(cTemplateVariable.getType(), rProperty);
OCLExpression propertyTemplateValue = ClassUtil.nonNullState(propertyTemplateItem.getValue());
if (propertyTemplateValue instanceof VariableExp) {
- mapOtherSimpleVariableExpression(cTemplateVariable, traceProperty, (VariableExp)propertyTemplateValue);
+ mapOtherSimpleVariableExpression(rTemplateVariable, partProperty, (VariableExp)propertyTemplateValue);
}
else if (propertyTemplateValue instanceof CollectionTemplateExp) {
- mapOtherCollectionTemplateExpression(cTemplateVariable, traceProperty, (CollectionTemplateExp)propertyTemplateValue);
+ mapOtherCollectionTemplateExpression(cTemplateVariable, partProperty, (CollectionTemplateExp)propertyTemplateValue);
}
else if (propertyTemplateValue instanceof ObjectTemplateExp) {
- mapOtherObjectTemplateExpression(cTemplateVariable, traceProperty, (ObjectTemplateExp)propertyTemplateValue);
+ mapOtherObjectTemplateExpression(rTemplateVariable, partProperty, (ObjectTemplateExp)propertyTemplateValue);
}
else {
- mapOtherSimpleNonVariableExpression(cTemplateVariable, traceProperty, propertyTemplateValue);
+ mapOtherSimpleNonVariableExpression(rTemplateVariable, partProperty, propertyTemplateValue);
}
}
}
@@ -340,7 +339,7 @@ import org.eclipse.qvtd.pivot.qvttemplate.TemplateExp;
protected final @NonNull RelationDomain rEnforcedDomain; // rd: This source enforced domain
protected final @NonNull TypedModel rEnforcedTypedModel; // rEnforcedDomain.getTypedModel()
protected final @NonNull String rEnforcedDomainName; // rEnforcedDomain.getName()
- protected final @NonNull Set<@NonNull Variable> rEnforcedBoundVariables; // All variables defined in this domain
+ protected final @NonNull Map<@NonNull Variable, @Nullable TemplateExp> rEnforcedBoundVariables; // All variables defined in this domain
protected final @NonNull Set<@NonNull Variable> rEnforcedReferredVariables; // All variables defined or referenced in this domain
protected final @NonNull List<@NonNull/*Object*/TemplateExp> rEnforcedTemplateExpressions; // te: The template expression defining the enforced domain pattern
protected final @NonNull List<@NonNull Variable> rEnforcedRootVariables; // tev: The template expression variable (the root variable of the enforced domain pattern)
@@ -366,7 +365,7 @@ import org.eclipse.qvtd.pivot.qvttemplate.TemplateExp;
public AbstractEnforceableRelationDomain2CoreMapping(@NonNull RelationDomain rEnforcedDomain, @NonNull String cMappingName) {
this.rEnforcedDomain = rEnforcedDomain;
//
- this.rEnforcedBoundVariables = new HashSet<@NonNull Variable>();
+ this.rEnforcedBoundVariables = new HashMap<@NonNull Variable, @Nullable TemplateExp>();
VariablesAnalysis.gatherBoundVariables(rEnforcedBoundVariables, rEnforcedDomain);
this.rEnforcedReferredVariables = new HashSet<@NonNull Variable>();
VariablesAnalysis.gatherReferredVariables(rEnforcedReferredVariables, rEnforcedDomain);
@@ -384,11 +383,8 @@ import org.eclipse.qvtd.pivot.qvttemplate.TemplateExp;
this.cEnforcedGuardPattern = ClassUtil.nonNullState(cEnforcedDomain.getGuardPattern());
this.cEnforcedBottomPattern = ClassUtil.nonNullState(cEnforcedDomain.getBottomPattern());
//
- this.variablesAnalysis = new VariablesAnalysis(qvtr2qvtc, cEnforcedDomain);
- //
- String middleRealizedVariableName = variablesAnalysis.getUniqueVariableName("trace", this);
- this.cMiddleRealizedVariable = qvtr2qvtc.helper.createRealizedVariable(middleRealizedVariableName, traceClass);
- cMiddleBottomPattern.getRealizedVariable().add(cMiddleRealizedVariable);
+ this.variablesAnalysis = new VariablesAnalysis(qvtr2qvtc, cEnforcedDomain, traceClass);
+ this.cMiddleRealizedVariable = variablesAnalysis.getMiddleRealizedVariable();
// putTrace(cMiddleRealizedVariable, cMiddleBottomPattern);
//
this.otherDomain2coreDomains = new ArrayList<@NonNull AbstractOtherRelationDomain2CoreDomain>();
@@ -410,8 +406,9 @@ import org.eclipse.qvtd.pivot.qvttemplate.TemplateExp;
for (@NonNull Variable rVariable : rWhereVariables) {
variablesAnalysis.getVariableAnalysis(rVariable).setIsWhere();
}
- for (@NonNull Variable rVariable : rEnforcedBoundVariables) {
- variablesAnalysis.getVariableAnalysis(rVariable).setIsEnforcedBound();
+ for (@NonNull Variable rVariable : rEnforcedBoundVariables.keySet()) {
+ Key rKey = qvtr2qvtc.getKeyForType(ClassUtil.nonNullState(rVariable.getType()));
+ variablesAnalysis.getVariableAnalysis(rVariable).setIsEnforcedBound(rEnforcedBoundVariables.get(rVariable), rKey);
}
for (@NonNull Variable rVariable : rEnforcedReferredVariables) {
variablesAnalysis.getVariableAnalysis(rVariable).setIsEnforcedReferred();
@@ -420,6 +417,7 @@ import org.eclipse.qvtd.pivot.qvttemplate.TemplateExp;
variablesAnalysis.getVariableAnalysis(rVariable).setIsRoot();
}
//
+ variablesAnalysis.toString(); // FIXME debugging
for (@NonNull VariableAnalysis analysis : variablesAnalysis.getAnalyses()) {
Variable rVariable = analysis.getRelationVariable();
Variable cVariable = analysis.synthesize();
@@ -442,7 +440,7 @@ import org.eclipse.qvtd.pivot.qvttemplate.TemplateExp;
}
// Quad call of RDomainPatternExprToMappingXXXX
- private void addPropertyAssignmentToMiddleBottomPattern(@NonNull Variable rTargetVariable, @NonNull Property rTargetProperty, @NonNull OCLExpression rExpression) throws CompilerChainException {
+ private void addPropertyAssignmentToMiddleBottomPattern(@NonNull Variable rTargetVariable, @NonNull Property targetProperty, @NonNull OCLExpression rExpression) throws CompilerChainException {
Variable cTargetVariable = null;
OCLExpression cExpression = null;
if (rExpression instanceof ObjectTemplateExp) {
@@ -476,8 +474,7 @@ import org.eclipse.qvtd.pivot.qvttemplate.TemplateExp;
cExpression = mapExpression(rExpression);
}
if ((cTargetVariable != null) && (cExpression != null)) {
- Property cTargetProperty = qvtr2qvtc.getProperty(cTargetVariable.getType(), rTargetProperty);
- qvtr2qvtc.addNavigationAssignment(cMiddleBottomPattern, cTargetVariable, cTargetProperty, cExpression);
+ variablesAnalysis.addNavigationAssignment(rTargetVariable, targetProperty, cExpression);
}
}
@@ -568,11 +565,11 @@ import org.eclipse.qvtd.pivot.qvttemplate.TemplateExp;
protected void mapEnforcedObjectTemplateExpression(@NonNull ObjectTemplateExp rEnforcedObjectTemplateExpression, Key key) throws CompilerChainException {
Variable rTemplateVariable/*v*/ = ClassUtil.nonNullState(rEnforcedObjectTemplateExpression.getBindsTo());
for (@NonNull PropertyTemplateItem pt : ClassUtil.nullFree(rEnforcedObjectTemplateExpression.getPart())) {
- Property rPartProperty = ClassUtil.nonNullState(pt.getReferredProperty());
+ Property partProperty = ClassUtil.nonNullState(pt.getReferredProperty());
OCLExpression rPartValue/*pte*/ = ClassUtil.nonNullState(pt.getValue());
- if ((key != null) && key.getPart().contains(rPartProperty)) {
+ if ((key != null) && key.getPart().contains(partProperty)) {
// body of RDomainToMDBottomForEnforcementOfIdentityProp
- addPropertyAssignmentToMiddleBottomPattern(rTemplateVariable, rPartProperty, rPartValue);
+ addPropertyAssignmentToMiddleBottomPattern(rTemplateVariable, partProperty, rPartValue);
}
else if (rPartValue instanceof TemplateExp) {
// body of RDomainToMDBottomForEnforcementOfNonIdentityPropObject
@@ -580,11 +577,10 @@ import org.eclipse.qvtd.pivot.qvttemplate.TemplateExp;
Variable pv = ClassUtil.nonNullState(pte.getBindsTo());
/*Realized*/Variable cTargetVariable/*mpv*/ = variablesAnalysis.getCoreVariable(pv); //rWhenVariables.contains(pv) ? getCoreVariable(pv) : whenRealizedVariable(cEnforcedBottomPattern, pv);
Variable cTemplateVariable/*mv*/ = variablesAnalysis.getCoreVariable(rTemplateVariable);
- Property cTargetProperty = qvtr2qvtc.getProperty(cTemplateVariable.getType(), rPartProperty);
- qvtr2qvtc.addNavigationAssignment(cMiddleBottomPattern, cTemplateVariable, cTargetProperty, createVariableExp(cTargetVariable));
+ variablesAnalysis.addNavigationAssignment(rTemplateVariable, partProperty, createVariableExp(cTargetVariable));
mapEnforcedTemplateExpression(pte);
// Property cTargetProperty2 = qvtr2qvtc.getProperty(cMiddleRealizedVariable.getType(), cTargetVariable);
-// qvtr2qvtc.addNavigationAssignment(cMiddleBottomPattern, cMiddleRealizedVariable, cTargetProperty2, createVariableExp(cTargetVariable));
+// variablesAnalysis.addNavigationAssignment(rMiddleRealizedVariable, cTargetProperty2, createVariableExp(cTargetVariable));
}
else {
// body of RDomainToMDBottomForEnforcementOfNonIdentityPropPrimitive
@@ -602,8 +598,7 @@ import org.eclipse.qvtd.pivot.qvttemplate.TemplateExp;
cEnforcedGuardPattern.getBindsTo().add(cReferredVariable);
}
}
- Property cTargetProperty = qvtr2qvtc.getProperty(cTemplateVariable.getType(), rPartProperty);
- qvtr2qvtc.addNavigationAssignment(cMiddleBottomPattern, cTemplateVariable, cTargetProperty, mapExpression(rPartValue));
+ variablesAnalysis.addNavigationAssignment(rTemplateVariable, partProperty, mapExpression(rPartValue));
}
}
}
@@ -635,7 +630,7 @@ import org.eclipse.qvtd.pivot.qvttemplate.TemplateExp;
// RDomainVarToMDBottomAssignmnetForEnforcement
Variable cTemplateVariable = variablesAnalysis.getCoreVariable(rTemplateVariable);
Property cTargetProperty = qvtr2qvtc.getProperty(cMiddleRealizedVariable.getType(), rTemplateVariable);
- qvtr2qvtc.addNavigationAssignment(cMiddleBottomPattern, cMiddleRealizedVariable, cTargetProperty, createVariableExp(cTemplateVariable));
+ variablesAnalysis.addTraceNavigationAssignment(cTargetProperty, createVariableExp(cTemplateVariable));
}
// 15
@@ -703,7 +698,7 @@ import org.eclipse.qvtd.pivot.qvttemplate.TemplateExp;
Property cProperty = qvtr2qvtc.basicGetProperty(cMiddleRealizedVariable.getType(), rDomainVariable);
if (cProperty != null) { // null for dead variables
Variable cVariable = variablesAnalysis.getCoreVariable(rDomainVariable);
- qvtr2qvtc.addNavigationAssignment(cMiddleBottomPattern, cMiddleRealizedVariable, cProperty, createVariableExp(cVariable));
+ variablesAnalysis.addTraceNavigationAssignment(cProperty, createVariableExp(cVariable));
}
// }
/* else if (dvte instanceof CollectionTemplateExp) {
diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvtc/KeyToFunctionForIdentification.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvtc/KeyToFunctionForIdentification.java
new file mode 100644
index 000000000..ce22f67f6
--- /dev/null
+++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvtc/KeyToFunctionForIdentification.java
@@ -0,0 +1,68 @@
+/*******************************************************************************
+ * Copyright (c) 2016 Willink Transformations and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * E.D.Willink - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.qvtd.compiler.internal.qvtr2qvtc;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.ocl.pivot.OCLExpression;
+import org.eclipse.ocl.pivot.Property;
+import org.eclipse.ocl.pivot.ShadowPart;
+import org.eclipse.ocl.pivot.utilities.ClassUtil;
+import org.eclipse.ocl.pivot.utilities.NameUtil;
+import org.eclipse.qvtd.compiler.CompilerChainException;
+import org.eclipse.qvtd.pivot.qvtbase.Function;
+import org.eclipse.qvtd.pivot.qvtbase.FunctionParameter;
+import org.eclipse.qvtd.pivot.qvtcore.utilities.QVTcoreHelper;
+import org.eclipse.qvtd.pivot.qvtrelation.Key;
+
+/**
+ * KeyToMappingForIdentification synthesizes a Core constructor function/querythat enforces the uniqueness of a realized variable
+ * with respect to its key parts.
+ */
+public class KeyToFunctionForIdentification
+{
+ protected final @NonNull QVTrToQVTc qvtr2qvtc;
+ protected final @NonNull Key rKey;
+
+ public KeyToFunctionForIdentification(@NonNull QVTrToQVTc qvtr2qvtc, @NonNull Key rKey) {
+ this.qvtr2qvtc = qvtr2qvtc;
+ this.rKey = rKey;
+ }
+
+ public @NonNull Function transform() throws CompilerChainException {
+ QVTcoreHelper helper = qvtr2qvtc.getHelper();
+ String functionName = qvtr2qvtc.createKeyFunctionName(rKey);
+ List<@NonNull FunctionParameter> asParameters = new ArrayList<@NonNull FunctionParameter>();
+ List<@NonNull ShadowPart> asShadowParts = new ArrayList<@NonNull ShadowPart>();
+ for (@NonNull Property keyProperty : ClassUtil.nullFree(rKey.getPart())) {
+ FunctionParameter cParameter = helper.createFunctionParameter(keyProperty);
+ asParameters.add(cParameter);
+ ShadowPart asShadowPart = helper.createShadowPart(keyProperty, helper.createVariableExp(cParameter));
+ asShadowParts.add(asShadowPart);
+ }
+ for (@NonNull Property keyOppositeProperty : ClassUtil.nullFree(rKey.getOppositePart())) {
+ Property keyProperty = ClassUtil.nonNullState(keyOppositeProperty.getOpposite());
+ FunctionParameter cParameter = helper.createFunctionParameter(keyProperty);
+ asParameters.add(cParameter);
+ ShadowPart asShadowPart = helper.createShadowPart(keyProperty, helper.createVariableExp(cParameter));
+ asShadowParts.add(asShadowPart);
+ }
+ Collections.sort(asParameters, NameUtil.NAMEABLE_COMPARATOR);
+ org.eclipse.ocl.pivot.@NonNull Class identifiedClass = ClassUtil.nonNullState(rKey.getIdentifies());
+ Function cFunction = helper.createFunction(functionName, identifiedClass, true, asParameters);
+ OCLExpression asShadowExp = helper.createShadowExp(identifiedClass, asShadowParts);
+ cFunction.setQueryExpression(asShadowExp);
+ return cFunction;
+ }
+}
diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvtc/QVTrNameGenerator.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvtc/QVTrNameGenerator.java
new file mode 100644
index 000000000..8ae9867de
--- /dev/null
+++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvtc/QVTrNameGenerator.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Copyright (c) 2016 Willink Transformations and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * E.D.Willink - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.qvtd.compiler.internal.qvtr2qvtc;
+
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.ocl.pivot.Variable;
+import org.eclipse.ocl.pivot.utilities.ClassUtil;
+import org.eclipse.qvtd.pivot.qvtrelation.Key;
+import org.eclipse.qvtd.pivot.qvtrelation.Relation;
+
+/**
+ * QVTrNameGenerator localizes the name generation functionality to facilitate a chnage / rewrite.
+ */
+public class QVTrNameGenerator
+{
+ public static final @NonNull String IDENTIFIED_INSTANCE_VARIABLE_NAME = "identifiedInstance";
+ public static final @NonNull String KEYED_INSTANCE_PROPERTY_NAME = "instance";
+ public static final @NonNull String KEY2INSTANCE_VARIABLE_NAME = "key2instance";
+
+ protected final @NonNull QVTrToQVTc qvtr2qvtc;
+
+ public QVTrNameGenerator(@NonNull QVTrToQVTc qvtr2qvtc) {
+ this.qvtr2qvtc = qvtr2qvtc;
+ }
+
+ public @NonNull String createKeyFunctionName(@NonNull Key rKey) {
+ org.eclipse.ocl.pivot.@NonNull Class identifiedClass = ClassUtil.nonNullState(rKey.getIdentifies());
+ return "Key2" + identifiedClass.getName();
+ }
+
+// public @NonNull String createKey2InstanceClassName(org.eclipse.ocl.pivot.@NonNull Class identifiedClass) {
+// return "Key2" + identifiedClass.getName();
+// }
+
+// public @NonNull String createKey2InstanceMappingName(org.eclipse.ocl.pivot.@NonNull Class identifiedClass, @NonNull TypedModel typedModel) {
+// String rEnforcedDomainName = ClassUtil.nonNullState(typedModel.getName());
+// return "Key2" + identifiedClass.getName() + "_" + rEnforcedDomainName;
+// }
+
+ public @NonNull String createKeyedVariableName(@NonNull Variable identifiedVariable) {
+ return identifiedVariable.getName() + "_key";
+ }
+
+ public @NonNull String createTraceClassName(@NonNull Relation relation) {
+ return "T" + relation.getName();
+ }
+}
diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvtc/QVTrToQVTc.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvtc/QVTrToQVTc.java
index c7ac2500b..64c840e4b 100644
--- a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvtc/QVTrToQVTc.java
+++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvtc/QVTrToQVTc.java
@@ -62,8 +62,6 @@ import org.eclipse.ocl.pivot.StandardLibrary;
import org.eclipse.ocl.pivot.Type;
import org.eclipse.ocl.pivot.TypedElement;
import org.eclipse.ocl.pivot.Variable;
-import org.eclipse.ocl.pivot.VariableDeclaration;
-import org.eclipse.ocl.pivot.VariableExp;
import org.eclipse.ocl.pivot.internal.ecore.as2es.AS2Ecore;
import org.eclipse.ocl.pivot.internal.utilities.EnvironmentFactoryInternal;
import org.eclipse.ocl.pivot.util.DerivedConstants;
@@ -76,6 +74,7 @@ import org.eclipse.qvtd.compiler.CompilerChainException;
import org.eclipse.qvtd.compiler.CompilerConstants;
import org.eclipse.qvtd.compiler.internal.utilities.CompilerUtil;
import org.eclipse.qvtd.pivot.qvtbase.Domain;
+import org.eclipse.qvtd.pivot.qvtbase.Function;
import org.eclipse.qvtd.pivot.qvtbase.Pattern;
import org.eclipse.qvtd.pivot.qvtbase.Predicate;
import org.eclipse.qvtd.pivot.qvtbase.Rule;
@@ -86,14 +85,11 @@ import org.eclipse.qvtd.pivot.qvtcore.CoreModel;
import org.eclipse.qvtd.pivot.qvtcore.Mapping;
import org.eclipse.qvtd.pivot.qvtcore.QVTcoreFactory;
import org.eclipse.qvtd.pivot.qvtcore.utilities.QVTcoreHelper;
-import org.eclipse.qvtd.pivot.qvtcorebase.Assignment;
import org.eclipse.qvtd.pivot.qvtcorebase.BottomPattern;
import org.eclipse.qvtd.pivot.qvtcorebase.CoreDomain;
import org.eclipse.qvtd.pivot.qvtcorebase.GuardPattern;
-import org.eclipse.qvtd.pivot.qvtcorebase.NavigationAssignment;
import org.eclipse.qvtd.pivot.qvtcorebase.QVTcoreBaseFactory;
import org.eclipse.qvtd.pivot.qvtcorebase.RealizedVariable;
-import org.eclipse.qvtd.pivot.qvtcorebase.utilities.QVTcoreBaseUtil;
import org.eclipse.qvtd.pivot.qvtrelation.DomainPattern;
import org.eclipse.qvtd.pivot.qvtrelation.Key;
import org.eclipse.qvtd.pivot.qvtrelation.Relation;
@@ -135,6 +131,7 @@ public class QVTrToQVTc
private final @NonNull Resource qvtrResource;
private final @NonNull Resource qvtcResource;
protected final @NonNull QVTcoreHelper helper;
+ protected final @NonNull QVTrNameGenerator nameGenerator;
/**
* Optional configuration of the NsURI of the trace package.
@@ -147,9 +144,9 @@ public class QVTrToQVTc
// private final @NonNull List<@NonNull Transformation> coreTransformations = new ArrayList<@NonNull Transformation>();
/**
- * Mapping from each relation to its corresponding trace class.
+ * Mapping from each key to its corresponding identification constructor function.
*/
- private final @NonNull Map<@NonNull Relation, org.eclipse.ocl.pivot.@NonNull Class> relation2traceClass = new HashMap<@NonNull Relation, org.eclipse.ocl.pivot.@NonNull Class>();
+ private final @NonNull Map<@NonNull Key, @NonNull Function> key2function = new HashMap<@NonNull Key, @NonNull Function>();
// Un-navigable opposites
//
@@ -157,6 +154,11 @@ public class QVTrToQVTc
// FIXME can there be two keys for the same Class?
//
private final @NonNull Map<org.eclipse.ocl.pivot.@NonNull Class, @NonNull Key> class2key = new HashMap<org.eclipse.ocl.pivot.@NonNull Class, @NonNull Key>();
+
+ /**
+ * Mapping from each relation to its corresponding trace class.
+ */
+ private final @NonNull Map<@NonNull Relation, org.eclipse.ocl.pivot.@NonNull Class> relation2traceClass = new HashMap<@NonNull Relation, org.eclipse.ocl.pivot.@NonNull Class>();
/**
* Map from each relation to all the expressions that call the relation.
@@ -213,6 +215,7 @@ public class QVTrToQVTc
this.qvtcResource = qvtcResource;
// this.traceResource = traceResource;
this.helper = new QVTcoreHelper(environmentFactory);
+ this.nameGenerator = new QVTrNameGenerator(this);
this.coreModel = QVTcoreFactory.eINSTANCE.createCoreModel();
// Create a cache of opposite relations and copy imports
@@ -232,31 +235,6 @@ public class QVTrToQVTc
}
}
}
-
- /**
- * Add the NavigationAssignment "cVariable.cProperty := cExpression" to the cBottomPattern inverting the usage
- * of a Collection element assignment to "cExpression.cOppositeProperty := cVariable".
- */
- public void addNavigationAssignment(@NonNull BottomPattern cBottomPattern, @NonNull Variable cVariable, @NonNull Property cProperty, @NonNull OCLExpression cExpression) {
- if (!cProperty.isIsMany() || (cExpression.getType() instanceof CollectionType)) {
- VariableExp cSlotVariableExp = helper.createVariableExp(cVariable);
- NavigationAssignment cAssignment = helper.createNavigationAssignment(cSlotVariableExp, cProperty, cExpression);
- System.out.println("addPropertyAssignment " + cAssignment);
- assertNewAssignment(cBottomPattern.getAssignment(), cAssignment);
- cBottomPattern.getAssignment().add(cAssignment);
- return;
- }
- Property cOppositeProperty = cProperty.getOpposite();
- if ((cOppositeProperty != null) && (cExpression instanceof VariableExp) && (!cOppositeProperty.isIsMany() || (cVariable.getType() instanceof CollectionType))) {
- VariableExp cSlotVariableExp = (VariableExp)cExpression;
- NavigationAssignment cAssignment = helper.createNavigationAssignment(cSlotVariableExp, cOppositeProperty, helper.createVariableExp(cVariable));
- System.out.println("addOppositePropertyAssignment " + cAssignment);
- assertNewAssignment(cBottomPattern.getAssignment(), cAssignment);
- cBottomPattern.getAssignment().add(cAssignment);
- return;
- }
- throw new IllegalStateException("Unsupported collection assign " + cVariable + "." + cProperty + ":=" + cExpression);
- }
protected void analyzeInvocations(@NonNull Relation callingRelation) {
Pattern wherePattern = callingRelation.getWhere();
@@ -299,28 +277,6 @@ public class QVTrToQVTc
}
relation2rootVariables.put(relation, rootVariables);
}
-
- private void assertNewAssignment(@NonNull List<Assignment> oldAssignments, @NonNull NavigationAssignment newAssignment) {
-// if ("tr.action := sm".equals(newAssignment.toString())) {
-// newAssignment.toString();
-// }
- OCLExpression newSlotExpression = newAssignment.getSlotExpression();
- if (newSlotExpression instanceof VariableExp) {
- VariableDeclaration newVariable = ((VariableExp)newSlotExpression).getReferredVariable();
- Property targetProperty = QVTcoreBaseUtil.getTargetProperty(newAssignment);
- for (Assignment oldAssignment : oldAssignments) {
- if (oldAssignment instanceof NavigationAssignment) {
- if (QVTcoreBaseUtil.getTargetProperty((NavigationAssignment)oldAssignment) == targetProperty) {
- OCLExpression oldSlotExpression = ((NavigationAssignment)oldAssignment).getSlotExpression();
- if (oldSlotExpression instanceof VariableExp) {
- VariableDeclaration oldVariable = ((VariableExp)oldSlotExpression).getReferredVariable();
- assert oldVariable != newVariable : "Repeated assignment: \"" + oldAssignment + "\", \"" + newAssignment + "\"";
- }
- }
- }
- }
- }
- }
public @Nullable Property basicGetProperty(/*@NonNull*/ Type aClass, @NonNull NamedElement rNamedElement) throws CompilerChainException {
/*@NonNull*/ String name = rNamedElement.getName();
@@ -342,6 +298,14 @@ public class QVTrToQVTc
return coreDomain;
}
+ public @NonNull String createKeyFunctionName(@NonNull Key rKey) {
+ return nameGenerator.createKeyFunctionName(rKey);
+ }
+
+ public @NonNull String createKeyedVariableName(@NonNull Variable identifiedVariable) {
+ return nameGenerator.createKeyedVariableName(identifiedVariable);
+ }
+
/**
* Create the name Mapping for a coreTransformation.
*/
@@ -377,6 +341,10 @@ public class QVTrToQVTc
return realizedVariable;
}
+ public @NonNull String createTraceClassName(@NonNull Relation relation) {
+ return nameGenerator.createTraceClassName(relation);
+ }
+
// Save the qvtc resource
public void dispose() {
// What about the trace model? we need to separate them
@@ -481,6 +449,10 @@ public class QVTrToQVTc
return class2key.get(type);
}
+ /*public*/ @NonNull Function getKeyFunction(@NonNull Key key) {
+ return ClassUtil.nonNullState(key2function.get(key));
+ }
+
public Predicate getPredicateForRelationCallExp(RelationCallExp ri) {
// TODO Auto-generated method stub
return null;
@@ -501,7 +473,11 @@ public class QVTrToQVTc
* @throws CompilerChainException if no such property
*/
protected @NonNull Property getProperty(/*@NonNull*/ Type aClass, @NonNull NamedElement rNamedElement) throws CompilerChainException {
- return getProperty(aClass, rNamedElement.getName());
+ Property property = getProperty(aClass, rNamedElement.getName());
+ if (rNamedElement instanceof Property) {
+ assert rNamedElement == property;
+ }
+ return property;
}
protected @NonNull Property getProperty(/*@NonNull*/ Type aClass, /*@NonNull*/ String name) throws CompilerChainException {
assert (aClass != null) && (name != null);
@@ -539,13 +515,13 @@ public class QVTrToQVTc
return ClassUtil.nonNullState(relationalTransformation2tracePackage.get(relationalTransformation));
}
-/* public @NonNull Set<org.eclipse.ocl.pivot.@NonNull Class> getUsedClasses(@NonNull TypedModel rTypedModel) {
+ public @NonNull Set<org.eclipse.ocl.pivot.@NonNull Class> getUsedClasses(@NonNull TypedModel rTypedModel) {
Set<org.eclipse.ocl.pivot.@NonNull Class> usedClasses = new HashSet<org.eclipse.ocl.pivot.@NonNull Class>();
for (org.eclipse.ocl.pivot.@NonNull Package rPackage : ClassUtil.nullFree(rTypedModel.getUsedPackage())) {
usedClasses.addAll(ClassUtil.nullFree(rPackage.getOwnedClasses()));
}
return usedClasses;
- } */
+ }
// Create the top rules, and search the input model for the appropriate types, when possible?
public void prepare() {
@@ -585,6 +561,12 @@ public class QVTrToQVTc
// }
}
+ /*public*/ void putKeyFunction(@NonNull Key rKey, @NonNull Function keyFunction) {
+ Function oldFunction = key2function.put(rKey, keyFunction);
+ assert oldFunction == null;
+// putTrace(traceClass, r);
+ }
+
/*public*/ void putRelationTrace(@NonNull Relation rRelation, org.eclipse.ocl.pivot.@NonNull Class traceClass) {
org.eclipse.ocl.pivot.Class oldTraceClass = relation2traceClass.put(rRelation, traceClass);
assert oldTraceClass == null;
@@ -797,6 +779,8 @@ public class QVTrToQVTc
List<@NonNull Rule> rules = new ArrayList<@NonNull Rule>(ClassUtil.nullFree(relationalTransformation.getRule()));
Collections.sort(rules, NameUtil.NAMEABLE_COMPARATOR);
Transformation coreTransformation = getCoreTransformation(relationalTransformation);
+ List<@NonNull Key> rKeys = new ArrayList<@NonNull Key>(ClassUtil.nullFree(relationalTransformation.getOwnedKey()));
+// Collections.sort(keys, NameUtil.NAMEABLE_COMPARATOR);
List<@NonNull TypedModel> rEnforceableTypdModels = new ArrayList<@NonNull TypedModel>();
for (@NonNull Rule rule : rules) {
if (rule instanceof Relation) {
@@ -810,6 +794,19 @@ public class QVTrToQVTc
}
}
}
+ for (@NonNull TypedModel rTypedModel : rEnforceableTypdModels) {
+ Set<org.eclipse.ocl.pivot.@NonNull Class> usedClasses = getUsedClasses(rTypedModel);
+ for (@NonNull Key rKey : rKeys) {
+ org.eclipse.ocl.pivot.@NonNull Class identifiedClass = ClassUtil.nonNullState(rKey.getIdentifies());
+ if (usedClasses.contains(identifiedClass)) {
+ QVTrToQVTc.SYNTHESIS.println("key " + rKey);
+ KeyToFunctionForIdentification keyToMapping = new KeyToFunctionForIdentification(this, rKey);
+ Function cKeyFunction = keyToMapping.transform();
+ putKeyFunction(rKey, cKeyFunction);
+ coreTransformation.getOwnedOperations().add(cKeyFunction);
+ }
+ }
+ }
for (@NonNull Rule rule : rules) {
if (rule instanceof Relation) {
Relation rRelation = (Relation)rule;
@@ -833,6 +830,7 @@ public class QVTrToQVTc
}
}
}
+ CompilerUtil.normalizeNameables(ClassUtil.nullFree(coreTransformation.getOwnedOperations()));
CompilerUtil.normalizeNameables(ClassUtil.nullFree(coreTransformation.getRule()));
}
/* for (@NonNull Transformation coreTransformation : relationalTransformation2coreTransformation.values()) {
diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvtc/VariablesAnalysis.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvtc/VariablesAnalysis.java
index ccd8b6e6e..785bb387c 100644
--- a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvtc/VariablesAnalysis.java
+++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvtc/VariablesAnalysis.java
@@ -21,24 +21,41 @@ import java.util.Set;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
+import org.eclipse.ocl.pivot.CollectionType;
import org.eclipse.ocl.pivot.Element;
+import org.eclipse.ocl.pivot.OCLExpression;
+import org.eclipse.ocl.pivot.OperationCallExp;
+import org.eclipse.ocl.pivot.Parameter;
+import org.eclipse.ocl.pivot.Property;
import org.eclipse.ocl.pivot.Type;
import org.eclipse.ocl.pivot.Variable;
import org.eclipse.ocl.pivot.VariableDeclaration;
import org.eclipse.ocl.pivot.VariableExp;
import org.eclipse.ocl.pivot.utilities.ClassUtil;
import org.eclipse.qvtd.pivot.qvtbase.Domain;
+import org.eclipse.qvtd.pivot.qvtbase.Function;
+import org.eclipse.qvtd.pivot.qvtbase.Predicate;
+import org.eclipse.qvtd.pivot.qvtbase.Transformation;
+import org.eclipse.qvtd.pivot.qvtbase.utilities.QVTbaseUtil;
import org.eclipse.qvtd.pivot.qvtbase.utilities.TreeIterable;
import org.eclipse.qvtd.pivot.qvtcore.Mapping;
import org.eclipse.qvtd.pivot.qvtcore.utilities.QVTcoreHelper;
import org.eclipse.qvtd.pivot.qvtcore.utilities.QVTcoreUtil;
import org.eclipse.qvtd.pivot.qvtcorebase.Area;
+import org.eclipse.qvtd.pivot.qvtcorebase.Assignment;
import org.eclipse.qvtd.pivot.qvtcorebase.BottomPattern;
import org.eclipse.qvtd.pivot.qvtcorebase.CoreDomain;
import org.eclipse.qvtd.pivot.qvtcorebase.CorePattern;
+import org.eclipse.qvtd.pivot.qvtcorebase.NavigationAssignment;
import org.eclipse.qvtd.pivot.qvtcorebase.RealizedVariable;
+import org.eclipse.qvtd.pivot.qvtcorebase.VariableAssignment;
+import org.eclipse.qvtd.pivot.qvtcorebase.utilities.QVTcoreBaseUtil;
+import org.eclipse.qvtd.pivot.qvtrelation.Key;
import org.eclipse.qvtd.pivot.qvtrelation.Relation;
+import org.eclipse.qvtd.pivot.qvtrelation.RelationalTransformation;
import org.eclipse.qvtd.pivot.qvttemplate.CollectionTemplateExp;
+import org.eclipse.qvtd.pivot.qvttemplate.ObjectTemplateExp;
+import org.eclipse.qvtd.pivot.qvttemplate.PropertyTemplateItem;
import org.eclipse.qvtd.pivot.qvttemplate.TemplateExp;
/**
@@ -49,22 +66,22 @@ import org.eclipse.qvtd.pivot.qvttemplate.TemplateExp;
/**
* Return all variables bound to a single variable within the composition tree of each of asRoots.
*/
- public static void gatherBoundVariables(@NonNull Set<@NonNull Variable> boundVariables, @NonNull Iterable<@NonNull ? extends Element> asRoots) {
+ public static void gatherBoundVariables(@NonNull Map<@NonNull Variable, @Nullable TemplateExp> boundVariables, @NonNull Iterable<@NonNull ? extends Element> asRoots) {
for (Element asRoot : asRoots) {
gatherBoundVariables(boundVariables, asRoot);
}
}
- public static void gatherBoundVariables(@NonNull Set<@NonNull Variable> boundVariables, @NonNull Element asRoot) {
+ public static void gatherBoundVariables(@NonNull Map<@NonNull Variable, @Nullable TemplateExp> boundVariables, @NonNull Element asRoot) {
for (EObject eObject : new TreeIterable(asRoot, true)) {
if (eObject instanceof TemplateExp) {
Variable bindsTo = ((TemplateExp)eObject).getBindsTo(); // ?? CollectionTemplateExp collection is not bound
if (bindsTo != null) {
- boundVariables.add(bindsTo);
+ boundVariables.put(bindsTo, (TemplateExp)eObject);
}
if (eObject instanceof CollectionTemplateExp) { // ?? VariableExp members are bound
Variable rest = ((CollectionTemplateExp)eObject).getRest(); // ?? not bound
if (rest != null) {
- boundVariables.add(rest);
+ boundVariables.put(rest, null);
}
}
}
@@ -130,7 +147,8 @@ import org.eclipse.qvtd.pivot.qvttemplate.TemplateExp;
{
protected final @NonNull Variable rVariable;
protected final @NonNull String name;
-
+ private @Nullable Key rKey = null;
+ private @Nullable TemplateExp rTemplateExp = null;
private boolean isEnforcedBound = false;
private boolean isEnforcedReferred = false;
private @Nullable CoreDomain otherBound = null;
@@ -144,6 +162,55 @@ import org.eclipse.qvtd.pivot.qvttemplate.TemplateExp;
this.rVariable = rVariable;
this.name = getUniqueVariableName(ClassUtil.nonNullState(rVariable.getName()), this);
}
+
+ /**
+ * Add the predicate "cLeftExpression = cRightExpression" to cCorePattern.
+ */
+ protected void addConditionPredicate(@NonNull CorePattern cCorePattern, @NonNull OCLExpression cLeftExpression, @NonNull OCLExpression cRightExpression) {
+ OperationCallExp eTerm = createOperationCallExp(cLeftExpression, "=", cRightExpression);
+ addPredicate(cCorePattern, eTerm);
+ }
+
+ /**
+ * Add the NavigationAssignment "cVariable.cProperty := cExpression" to the cBottomPattern inverting the usage
+ * of a Collection element assignment to "cExpression.cOppositeProperty := cVariable".
+ */
+ public void addNavigationAssignment(@NonNull Property targetProperty, @NonNull OCLExpression cExpression) {
+ Key rKey2 = rKey;
+ if (isKeyed() && (rKey2 != null)) {
+ if (rKey2.getPart().contains(targetProperty)) {
+ return;
+ }
+ if (rKey2.getOppositePart().contains(targetProperty.getOpposite())) {
+ return;
+ }
+ }
+ Variable cVariable2 = getCoreVariable();
+ if (!targetProperty.isIsMany() || (cExpression.getType() instanceof CollectionType)) {
+ VariableExp cSlotVariableExp = createVariableExp(cVariable2);
+ NavigationAssignment cAssignment = createNavigationAssignment(cSlotVariableExp, targetProperty, cExpression);
+ QVTrToQVTc.SYNTHESIS.println("addPropertyAssignment " + cAssignment);
+ assertNewAssignment(cMiddleBottomPattern.getAssignment(), cAssignment);
+ cMiddleBottomPattern.getAssignment().add(cAssignment);
+ return;
+ }
+ Property cOppositeProperty = targetProperty.getOpposite();
+ if ((cOppositeProperty != null) && (cExpression instanceof VariableExp) && (!cOppositeProperty.isIsMany() || (cVariable2.getType() instanceof CollectionType))) {
+ VariableExp cSlotVariableExp = (VariableExp)cExpression;
+ NavigationAssignment cAssignment = createNavigationAssignment(cSlotVariableExp, cOppositeProperty, createVariableExp(cVariable2));
+ QVTrToQVTc.SYNTHESIS.println("addOppositePropertyAssignment " + cAssignment);
+ assertNewAssignment(cMiddleBottomPattern.getAssignment(), cAssignment);
+ cMiddleBottomPattern.getAssignment().add(cAssignment);
+ return;
+ }
+ throw new IllegalStateException("Unsupported collection assign " + cVariable2 + " . " + targetProperty + " := " + cExpression);
+ }
+
+ protected void addPredicate(@NonNull CorePattern cCorePattern, @NonNull OCLExpression cExpression) {
+ QVTrToQVTc.SYNTHESIS.println("addPredicate " + cExpression);
+ Predicate cPredicate = createPredicate(cExpression);
+ cCorePattern.getPredicate().add(cPredicate);
+ }
public @Nullable RealizedVariable basicGetCoreRealizedVariable() {
return (RealizedVariable)cVariable;
@@ -163,24 +230,20 @@ import org.eclipse.qvtd.pivot.qvttemplate.TemplateExp;
assert (cVariable != null) && (cVariable.eContainer() == cPattern);
assert (cVariable instanceof RealizedVariable) == isRealized;
}
-
-// public @NonNull TemplateExp getTemplateExp() {
-// return ClassUtil.nonNullState(rTemplateExp);
-// }
private @NonNull CorePattern getCorePattern() {
Area cArea = null;
boolean isGuard = false;
if (isWhen) {
- isGuard = true;
+// isGuard = true;
assert isEnforcedBound || (otherBound != null);
cArea = isEnforcedBound ? cEnforcedDomain : otherBound;
}
// else if (isWhere) {
// }
else if (isEnforcedBound) {
- isGuard = false;
- cArea = cEnforcedDomain;
+ isGuard = false; //rKey != null;
+ cArea = rKey != null ? cMapping : cEnforcedDomain;
}
else if (otherBound != null) {
isGuard = isRoot;
@@ -195,13 +258,58 @@ import org.eclipse.qvtd.pivot.qvttemplate.TemplateExp;
}
public @NonNull Variable getCoreVariable() {
- return ClassUtil.nonNullState(cVariable);
+ Variable cVariable2 = cVariable;
+ if (cVariable2 == null) {
+ cVariable2 = synthesize();
+ }
+ return cVariable2;
}
public @NonNull Variable getRelationVariable() {
return rVariable;
}
+ private void initializeKeyedVariable(@NonNull Variable cKeyedVariable) {
+ Function function = qvtr2qvtc.getKeyFunction(ClassUtil.nonNull(rKey));
+ Variable thisVariable = QVTbaseUtil.getContextVariable(environmentFactory.getStandardLibrary(), cTransformation);
+ List<@NonNull OCLExpression> asArguments = new ArrayList<@NonNull OCLExpression>();
+ if (rTemplateExp instanceof ObjectTemplateExp) {
+ ObjectTemplateExp objectTemplateExp = (ObjectTemplateExp)rTemplateExp;
+ for (@NonNull Parameter keyParameter : ClassUtil.nullFree(function.getOwnedParameters())) {
+ OCLExpression parameterExp = getTemplateExp(objectTemplateExp, keyParameter);
+ if (parameterExp instanceof TemplateExp) {
+ Variable rVariable = ClassUtil.nonNullState(((TemplateExp)parameterExp).getBindsTo());
+ Variable cVariable = VariablesAnalysis.this.getCoreVariable(rVariable);
+ asArguments.add(createVariableExp(cVariable));
+ }
+ else if (parameterExp instanceof VariableExp) {
+ Variable rVariable = (Variable) ClassUtil.nonNullState(((VariableExp)parameterExp).getReferredVariable());
+ Variable cVariable = VariablesAnalysis.this.getCoreVariable(rVariable);
+ asArguments.add(createVariableExp(cVariable));
+ }
+ else {
+ asArguments.add(createInvalidExpression());
+ }
+ }
+ }
+ OCLExpression asConstructor = createOperationCallExp(createVariableExp(thisVariable), function, asArguments);
+// addConditionPredicate(cMiddleBottomPattern, createVariableExp(cKeyedVariable), asConstructor);
+ @NonNull VariableAssignment cVariableAssignment = createVariableAssignment(cKeyedVariable, asConstructor);
+ cMiddleBottomPattern.getAssignment().add(cVariableAssignment);
+ }
+
+ private boolean isKeyed() {
+ boolean isKeyed = false;
+ if (isWhen) {
+ }
+// else if (isWhere) {
+// }
+ else if (isEnforcedBound) {
+ isKeyed = rKey != null;
+ }
+ return isKeyed;
+ }
+
private boolean isRealized() {
boolean isRealized = false;
if (isWhen) {
@@ -209,15 +317,19 @@ import org.eclipse.qvtd.pivot.qvttemplate.TemplateExp;
// else if (isWhere) {
// }
else if (isEnforcedBound) {
- isRealized = true;
+ isRealized = rKey == null;
}
return isRealized;
}
- public void setIsEnforcedBound() {
+ public void setIsEnforcedBound(@Nullable TemplateExp rTemplateExp, @Nullable Key rKey) {
assert !isEnforcedBound;
assert this.otherBound == null;
+ assert this.rKey == null;
+ assert this.rTemplateExp == null;
this.isEnforcedBound = true;
+ this.rTemplateExp = rTemplateExp;
+ this.rKey = rKey;
}
public void setIsEnforcedReferred() {
@@ -247,20 +359,27 @@ import org.eclipse.qvtd.pivot.qvttemplate.TemplateExp;
}
public @NonNull Variable synthesize() {
- CorePattern cPattern = getCorePattern();
- boolean isRealized = isRealized();
- //
Variable cVariable2 = cVariable;
- assert cVariable2 == null;
- Type type = ClassUtil.nonNullState(rVariable.getType());
- if (isRealized) {
- RealizedVariable cRealizedVariable = createRealizedVariable(name, type);
- ((BottomPattern)cPattern).getRealizedVariable().add(cRealizedVariable);
- cVariable = cVariable2 = cRealizedVariable;
- }
- else {
- cVariable = cVariable2 = createVariable(name, type, rVariable.isIsRequired(), null);
- cPattern.getVariable().add(cVariable2);
+ if (cVariable2 == null) {
+ CorePattern cPattern = getCorePattern();
+ boolean isKeyed = isKeyed();
+ boolean isRealized = isRealized();
+ //
+ Type type = ClassUtil.nonNullState(rVariable.getType());
+ if (isKeyed) {
+ cVariable = cVariable2 = createVariable(name, type, true, null);
+ initializeKeyedVariable(cVariable2);
+ cPattern.getVariable().add(cVariable2);
+ }
+ else if (!isRealized) {
+ cVariable = cVariable2 = createVariable(name, type, rVariable.isIsRequired(), null);
+ cPattern.getVariable().add(cVariable2);
+ }
+ else {
+ RealizedVariable cRealizedVariable = createRealizedVariable(name, type);
+ ((BottomPattern)cPattern).getRealizedVariable().add(cRealizedVariable);
+ cVariable = cVariable2 = cRealizedVariable;
+ }
}
return cVariable2;
}
@@ -278,6 +397,9 @@ import org.eclipse.qvtd.pivot.qvttemplate.TemplateExp;
if (isRoot) {
s.append(" ROOT");
}
+ if (rKey != null) {
+ s.append(" KEYED");
+ }
if (isEnforcedBound) {
s.append(" ENFORCED");
}
@@ -290,12 +412,19 @@ import org.eclipse.qvtd.pivot.qvttemplate.TemplateExp;
else if (isOtherReferred) {
s.append(" other");
}
+ if (rTemplateExp != null) {
+ s.append(" " + rTemplateExp);
+ }
return s.toString();
}
}
- protected final @NonNull CoreDomain cEnforcedDomain; // md: The resultant enforced domain
- protected final @NonNull Mapping cMapping; // m: The resultant mapping
+ protected final @NonNull QVTrToQVTc qvtr2qvtc;
+ protected final @NonNull CoreDomain cEnforcedDomain;
+ protected final @NonNull Mapping cMapping;
+ protected final @NonNull Transformation cTransformation;
+ protected final @NonNull BottomPattern cMiddleBottomPattern;
+ protected final @NonNull RealizedVariable cMiddleRealizedVariable; // tcv: The trace class variable (the middle variable identifying the middle object)
/**
* Map from the each core variable name in use to an originating object, typically the VariableAnalysis of a relation variable,
@@ -308,10 +437,55 @@ import org.eclipse.qvtd.pivot.qvttemplate.TemplateExp;
*/
private final @NonNull Map<@NonNull Variable, @NonNull VariableAnalysis> rVariable2analysis = new HashMap<@NonNull Variable, @NonNull VariableAnalysis>();
- public VariablesAnalysis(@NonNull QVTrToQVTc qvtr2qvtc, @NonNull CoreDomain cEnforcedDomain) {
+ public VariablesAnalysis(@NonNull QVTrToQVTc qvtr2qvtc, @NonNull CoreDomain cEnforcedDomain, @NonNull Type traceClass) {
super(qvtr2qvtc.getEnvironmentFactory());
+ this.qvtr2qvtc = qvtr2qvtc;
this.cEnforcedDomain = cEnforcedDomain;
this.cMapping = ClassUtil.nonNullState(QVTcoreUtil.getContainingMapping(cEnforcedDomain));
+ this.cTransformation = ClassUtil.nonNullState(cMapping.getTransformation());
+ this.cMiddleBottomPattern = ClassUtil.nonNullState(cMapping.getBottomPattern());
+ //
+ String middleRealizedVariableName = getUniqueVariableName("trace", this);
+ this.cMiddleRealizedVariable = createRealizedVariable(middleRealizedVariableName, traceClass);
+ cMiddleBottomPattern.getRealizedVariable().add(cMiddleRealizedVariable);
+ }
+
+ public void addNavigationAssignment(@NonNull Variable rTargetVariable, @NonNull Property targetProperty, @NonNull OCLExpression cExpression) {
+ getVariableAnalysis(rTargetVariable).addNavigationAssignment(targetProperty, cExpression);
+ }
+
+ /**
+ * Add the NavigationAssignment "trace.cProperty := cExpression" to the middle BottomPattern.
+ */
+ public void addTraceNavigationAssignment(@NonNull Property targetProperty, @NonNull OCLExpression cExpression) {
+ assert (!targetProperty.isIsMany() || (cExpression.getType() instanceof CollectionType));
+ VariableExp cSlotVariableExp = createVariableExp(cMiddleRealizedVariable);
+ NavigationAssignment cAssignment = createNavigationAssignment(cSlotVariableExp, targetProperty, cExpression);
+ QVTrToQVTc.SYNTHESIS.println("addPropertyAssignment " + cAssignment);
+ assertNewAssignment(cMiddleBottomPattern.getAssignment(), cAssignment);
+ cMiddleBottomPattern.getAssignment().add(cAssignment);
+ }
+
+ private void assertNewAssignment(@NonNull List<Assignment> oldAssignments, @NonNull NavigationAssignment newAssignment) {
+// if ("tr.action := sm".equals(newAssignment.toString())) {
+// newAssignment.toString();
+// }
+ OCLExpression newSlotExpression = newAssignment.getSlotExpression();
+ if (newSlotExpression instanceof VariableExp) {
+ VariableDeclaration newVariable = ((VariableExp)newSlotExpression).getReferredVariable();
+ Property targetProperty = QVTcoreBaseUtil.getTargetProperty(newAssignment);
+ for (Assignment oldAssignment : oldAssignments) {
+ if (oldAssignment instanceof NavigationAssignment) {
+ if (QVTcoreBaseUtil.getTargetProperty((NavigationAssignment)oldAssignment) == targetProperty) {
+ OCLExpression oldSlotExpression = ((NavigationAssignment)oldAssignment).getSlotExpression();
+ if (oldSlotExpression instanceof VariableExp) {
+ VariableDeclaration oldVariable = ((VariableExp)oldSlotExpression).getReferredVariable();
+ assert oldVariable != newVariable : "Repeated assignment: \"" + oldAssignment + "\", \"" + newAssignment + "\"";
+ }
+ }
+ }
+ }
+ }
}
public void check() {
@@ -336,6 +510,30 @@ import org.eclipse.qvtd.pivot.qvttemplate.TemplateExp;
public @NonNull Variable getCoreVariable(@NonNull Variable rVariable) { // doRVarToMVar
return getVariableAnalysis(rVariable).getCoreVariable();
}
+
+ public @NonNull RealizedVariable getMiddleRealizedVariable() {
+ return cMiddleRealizedVariable;
+ }
+
+ private @Nullable OCLExpression getTemplateExp(@NonNull ObjectTemplateExp objectTemplateExp, @NonNull Parameter keyParameter) {
+ String keyParameterName = keyParameter.getName();
+ for (@NonNull PropertyTemplateItem propertyTemplateItem : ClassUtil.nullFree(objectTemplateExp.getPart())) {
+ Property property = propertyTemplateItem.getReferredProperty();
+ if (ClassUtil.safeEquals(property.getName(), keyParameterName)) {
+ return propertyTemplateItem.getValue();
+ }
+ }
+ EObject eContainer = objectTemplateExp.eContainer();
+ if (eContainer instanceof PropertyTemplateItem) {
+ PropertyTemplateItem continingPropertyTemplateItem = (PropertyTemplateItem)eContainer;
+ Property property = continingPropertyTemplateItem.getReferredProperty();
+ Property oppositeProperty = property != null ? property.getOpposite() : null;
+ if ((oppositeProperty != null) && ClassUtil.safeEquals(oppositeProperty.getName(), keyParameterName)) {
+ return continingPropertyTemplateItem.getValue();
+ }
+ }
+ return null;
+ }
public @NonNull String getUniqueVariableName(@NonNull String name, @NonNull Object originator) {
Object oldOriginator = name2originator.get(name);
@@ -356,6 +554,7 @@ import org.eclipse.qvtd.pivot.qvttemplate.TemplateExp;
protected @NonNull VariableAnalysis getVariableAnalysis(@NonNull Variable relationVariable) {
VariableAnalysis analysis = rVariable2analysis.get(relationVariable);
if (analysis == null) {
+ assert QVTbaseUtil.getContainingTransformation(relationVariable) instanceof RelationalTransformation;
analysis = new VariableAnalysis(relationVariable);
rVariable2analysis.put(relationVariable, analysis);
}
@@ -372,7 +571,10 @@ import org.eclipse.qvtd.pivot.qvttemplate.TemplateExp;
s.append("\n");
}
s.append(name + " => " );
- s.append(name2originator.get(name));
+ Object originator = name2originator.get(name);
+ if (originator != this) {
+ s.append(originator);
+ }
}
return s.toString();
}
diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvts2qvti/BasicRegion2Mapping.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvts2qvti/BasicRegion2Mapping.java
index db66021fb..a5e03b433 100644
--- a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvts2qvti/BasicRegion2Mapping.java
+++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvts2qvti/BasicRegion2Mapping.java
@@ -1309,9 +1309,19 @@ public class BasicRegion2Mapping extends AbstractRegion2Mapping
private void createRealizedVariables() {
for (@NonNull Node node : region.getRealizedVariableNodes()) {
+ OCLExpression constructor = null;
+ for (Edge edge : node.getIncomingEdges()) {
+ if (edge.isResult()) {
+ Node sourceNode = edge.getSource();
+ if (sourceNode.isOperation()) {
+ constructor = ((OperationCallExp)sourceNode.getTypedElements().iterator().next()).accept(expressionCreator);
+ }
+ }
+ }
ClassDatumAnalysis classDatumAnalysis = node.getClassDatumAnalysis();
BottomPattern bottomPattern = getArea(classDatumAnalysis).getBottomPattern();
RealizedVariable realizedVariable = QVTimperativeUtil.createRealizedVariable(getSafeName(node), classDatumAnalysis.getCompleteClass().getPrimaryClass());
+ realizedVariable.setOwnedInit(constructor);
bottomPattern.getRealizedVariable().add(realizedVariable);
Variable oldVariable = node2variable.put(node, realizedVariable);
assert oldVariable == null;
diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/utilities/JavaSourceFileObject.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/utilities/JavaSourceFileObject.java
index 731372160..dedec05fc 100644
--- a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/utilities/JavaSourceFileObject.java
+++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/utilities/JavaSourceFileObject.java
@@ -68,9 +68,13 @@ public final class JavaSourceFileObject extends SimpleJavaFileObject
s.append("\n" + diagnostic);
}
if (s.length() > 0) {
- throw new IOException("Failed to compile " + sourcePath + s.toString());
+// throw new IOException("Failed to compile " + sourcePath + s.toString());
+ // If a previous generation was bad we may get many irrelevant errors.
+ System.err.println("Failed to compile " + sourcePath + s.toString());
+ }
+ else {
+ System.out.println("Compilation of " + sourcePath + " returned false but no diagnostics");
}
- System.out.println("Compilation of " + sourcePath + " returned false but no diagnostics");
}
// System.out.printf("%6.3f close\n", 0.001 * (System.currentTimeMillis()-base));
stdFileManager2.close(); // Close the file manager which re-opens automatically
diff --git a/plugins/org.eclipse.qvtd.cs2as.compiler/src/org/eclipse/qvtd/cs2as/compiler/internal/CS2ASJavaCompilerImpl.java b/plugins/org.eclipse.qvtd.cs2as.compiler/src/org/eclipse/qvtd/cs2as/compiler/internal/CS2ASJavaCompilerImpl.java
index bab9acc61..0d737f498 100644
--- a/plugins/org.eclipse.qvtd.cs2as.compiler/src/org/eclipse/qvtd/cs2as/compiler/internal/CS2ASJavaCompilerImpl.java
+++ b/plugins/org.eclipse.qvtd.cs2as.compiler/src/org/eclipse/qvtd/cs2as/compiler/internal/CS2ASJavaCompilerImpl.java
@@ -247,9 +247,9 @@ public class CS2ASJavaCompilerImpl implements CS2ASJavaCompiler {
@Override
- protected void doConstructorConstants(List<CGMapping> cgMappings) {
+ protected void doMappingConstructorConstants(List<CGMapping> cgMappings) {
- super.doConstructorConstants(cgMappings);
+ super.doMappingConstructorConstants(cgMappings);
CS2ASJavaCompilerParameters params = ((CS2ASJavaCodeGenerator)getCodeGenerator()).getCGParameters();
String lookupSolver = params.getLookupSolverClassName();
diff --git a/plugins/org.eclipse.qvtd.pivot.qvtbase/src/org/eclipse/qvtd/pivot/qvtbase/utilities/QVTbaseHelper.java b/plugins/org.eclipse.qvtd.pivot.qvtbase/src/org/eclipse/qvtd/pivot/qvtbase/utilities/QVTbaseHelper.java
index 324f8d499..bfe4f075d 100644
--- a/plugins/org.eclipse.qvtd.pivot.qvtbase/src/org/eclipse/qvtd/pivot/qvtbase/utilities/QVTbaseHelper.java
+++ b/plugins/org.eclipse.qvtd.pivot.qvtbase/src/org/eclipse/qvtd/pivot/qvtbase/utilities/QVTbaseHelper.java
@@ -39,6 +39,7 @@ import org.eclipse.ocl.pivot.OCLExpression;
import org.eclipse.ocl.pivot.Operation;
import org.eclipse.ocl.pivot.OperationCallExp;
import org.eclipse.ocl.pivot.Package;
+import org.eclipse.ocl.pivot.Parameter;
import org.eclipse.ocl.pivot.PivotFactory;
import org.eclipse.ocl.pivot.Property;
import org.eclipse.ocl.pivot.RealLiteralExp;
@@ -63,6 +64,8 @@ import org.eclipse.ocl.pivot.utilities.FeatureFilter;
import org.eclipse.ocl.pivot.utilities.PivotUtil;
import org.eclipse.ocl.pivot.utilities.TypeUtil;
import org.eclipse.ocl.pivot.values.TemplateParameterSubstitutions;
+import org.eclipse.qvtd.pivot.qvtbase.Function;
+import org.eclipse.qvtd.pivot.qvtbase.FunctionParameter;
import org.eclipse.qvtd.pivot.qvtbase.Predicate;
import org.eclipse.qvtd.pivot.qvtbase.QVTbaseFactory;
@@ -115,6 +118,27 @@ public class QVTbaseHelper // FIXME extends PivotHelper
return collectionRange;
}
+ public @NonNull Function createFunction(@NonNull String name, @NonNull Type returnType, boolean returnIsRequired, @Nullable List<@NonNull FunctionParameter> asParameters) {
+ Function asFunction = QVTbaseFactory.eINSTANCE.createFunction();
+ asFunction.setName(name);
+ asFunction.setType(returnType);
+ asFunction.setIsRequired(returnIsRequired);
+ if (asParameters != null) {
+ asFunction.getOwnedParameters().addAll(asParameters);
+ }
+ return asFunction;
+ }
+
+ public @NonNull FunctionParameter createFunctionParameter(@NonNull TypedElement typedElement) {
+ String name = ClassUtil.nonNullState(typedElement.getName());
+ Type type = ClassUtil.nonNullState(typedElement.getType());
+ FunctionParameter asParameter = QVTbaseFactory.eINSTANCE.createFunctionParameter();
+ asParameter.setName(name);
+ asParameter.setType(type);
+ asParameter.setIsRequired(typedElement.isIsRequired());
+ return asParameter;
+ }
+
public @NonNull IfExp createIfExp(@NonNull OCLExpression asCondition, @NonNull OCLExpression asThen, @NonNull OCLExpression asElse) {
Type commonType = getMetamodelManager().getCommonType(ClassUtil.nonNullState(asThen.getType()), TemplateParameterSubstitutions.EMPTY,
ClassUtil.nonNullState(asElse.getType()), TemplateParameterSubstitutions.EMPTY);
@@ -322,6 +346,13 @@ public class QVTbaseHelper // FIXME extends PivotHelper
return asPackage;
}
+ public @NonNull Parameter createParameter(@NonNull TypedElement typedElement) {
+ String name = ClassUtil.nonNullState(typedElement.getName());
+ Type type = ClassUtil.nonNullState(typedElement.getType());
+ Parameter asParameter = PivotUtil.createParameter(name, type, typedElement.isIsRequired());
+ return asParameter;
+ }
+
public @NonNull Predicate createPredicate(@NonNull OCLExpression asConditionExpression) {
Predicate asPredicate = QVTbaseFactory.eINSTANCE.createPredicate();
asPredicate.setConditionExpression(asConditionExpression);
@@ -405,8 +436,10 @@ public class QVTbaseHelper // FIXME extends PivotHelper
return asVariable;
}
- public @NonNull Variable createVariable(@NonNull TypedElement typedElement) {
- Variable asVariable = PivotUtil.createVariable(typedElement.getName(), typedElement.getType(), typedElement.isIsRequired(), null);
+ public @NonNull Variable createVariable(@NonNull TypedElement typedElement) {
+ String name = ClassUtil.nonNullState(typedElement.getName());
+ Type type = ClassUtil.nonNullState(typedElement.getType());
+ Variable asVariable = PivotUtil.createVariable(name, type, typedElement.isIsRequired(), null);
return asVariable;
}
diff --git a/plugins/org.eclipse.qvtd.pivot.qvtbase/src/org/eclipse/qvtd/pivot/qvtbase/utilities/QVTbaseUtil.java b/plugins/org.eclipse.qvtd.pivot.qvtbase/src/org/eclipse/qvtd/pivot/qvtbase/utilities/QVTbaseUtil.java
index 5e0510742..b64a02c26 100644
--- a/plugins/org.eclipse.qvtd.pivot.qvtbase/src/org/eclipse/qvtd/pivot/qvtbase/utilities/QVTbaseUtil.java
+++ b/plugins/org.eclipse.qvtd.pivot.qvtbase/src/org/eclipse/qvtd/pivot/qvtbase/utilities/QVTbaseUtil.java
@@ -34,6 +34,7 @@ import org.eclipse.ocl.pivot.OCLExpression;
import org.eclipse.ocl.pivot.Operation;
import org.eclipse.ocl.pivot.OperationCallExp;
import org.eclipse.ocl.pivot.PivotFactory;
+import org.eclipse.ocl.pivot.ShadowExp;
import org.eclipse.ocl.pivot.StandardLibrary;
import org.eclipse.ocl.pivot.Type;
import org.eclipse.ocl.pivot.Variable;
@@ -49,6 +50,7 @@ import org.eclipse.ocl.pivot.utilities.NameUtil;
import org.eclipse.ocl.pivot.utilities.PivotUtil;
import org.eclipse.qvtd.pivot.qvtbase.BaseModel;
import org.eclipse.qvtd.pivot.qvtbase.Domain;
+import org.eclipse.qvtd.pivot.qvtbase.Function;
import org.eclipse.qvtd.pivot.qvtbase.Rule;
import org.eclipse.qvtd.pivot.qvtbase.Transformation;
import org.eclipse.qvtd.pivot.qvtbase.TypedModel;
@@ -275,6 +277,19 @@ public class QVTbaseUtil
enforceableTypedModels.removeAll(notEnforceableTypedModels);
return enforceableTypedModels;
}
+
+ /**
+ * Return true if asOperation is an Identification - an operation whose result is a singleton object.
+ */
+ public static boolean isIdentification(Operation asOperation) {
+ if (asOperation instanceof Function) {
+ OCLExpression queryExpression = ((Function)asOperation).getQueryExpression();
+ if (queryExpression instanceof ShadowExp) {
+ return true;
+ }
+ }
+ return false;
+ }
public static @NonNull Transformation loadTransformation(@NonNull Class<? extends Model> modelClass, @NonNull EnvironmentFactory environmentFactory, @NonNull URI transformationURI, boolean keepDebug) throws IOException {
CSResource xtextResource = null;
diff --git a/plugins/org.eclipse.qvtd.pivot.qvtimperative/src/org/eclipse/qvtd/pivot/qvtimperative/evaluation/BasicQVTiExecutor.java b/plugins/org.eclipse.qvtd.pivot.qvtimperative/src/org/eclipse/qvtd/pivot/qvtimperative/evaluation/BasicQVTiExecutor.java
index 2a86b8f61..bef509dab 100644
--- a/plugins/org.eclipse.qvtd.pivot.qvtimperative/src/org/eclipse/qvtd/pivot/qvtimperative/evaluation/BasicQVTiExecutor.java
+++ b/plugins/org.eclipse.qvtd.pivot.qvtimperative/src/org/eclipse/qvtd/pivot/qvtimperative/evaluation/BasicQVTiExecutor.java
@@ -137,7 +137,23 @@ public class BasicQVTiExecutor extends AbstractExecutor implements QVTiExecutor
CoreDomain enforceableDomain = (CoreDomain)domain;
BottomPattern enforceableBottomPattern = enforceableDomain.getBottomPattern();
for (RealizedVariable realizedVariable : enforceableBottomPattern.getRealizedVariable()) {
- realizedVariable.accept(undecoratedVisitor);
+ OCLExpression ownedInit = realizedVariable.getOwnedInit();
+ if (ownedInit != null) {
+ Object initValue = ownedInit.accept(undecoratedVisitor);
+ getEvaluationEnvironment().add(realizedVariable, initValue);
+ replace(realizedVariable, initValue);
+ Area area = ((BottomPattern)realizedVariable.eContainer()).getArea();
+ TypedModel typedModel = QVTcoreBaseUtil.getTypedModel(area);
+ assert typedModel != null;
+ Object ecoreValue = getIdResolver().ecoreValueOf(null, initValue);
+ assert ecoreValue != null;
+ getModelManager().addModelElement(typedModel, ecoreValue);
+ }
+ }
+ for (RealizedVariable realizedVariable : enforceableBottomPattern.getRealizedVariable()) {
+ if (realizedVariable.getOwnedInit() == null) {
+ realizedVariable.accept(undecoratedVisitor);
+ }
}
}
}
@@ -206,13 +222,6 @@ public class BasicQVTiExecutor extends AbstractExecutor implements QVTiExecutor
replace(rVar, initValue);
}
}
- for (@NonNull RealizedVariable rVar : ClassUtil.nullFree(enforceableBottomPattern.getRealizedVariable())) {
- OCLExpression ownedInit = rVar.getOwnedInit();
- if (ownedInit != null) {
- Object initValue = ownedInit.accept(undecoratedVisitor);
- replace(rVar, initValue);
- }
- }
}
}
BottomPattern middleBottomPattern = mapping.getBottomPattern();

Back to the top