[509858] Use isPartial PropertyAssignment rather thahn includes
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 8e71674..84a5b7c 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
@@ -220,14 +220,16 @@
js.appendValueName(cgMappingCallBinding.getOwnedValue());
}
- protected void appendEcoreSet(@NonNull CGValuedElement cgSlot, @NonNull EStructuralFeature eStructuralFeature, @NonNull CGValuedElement cgInit) {
+ protected void appendEcoreSet(@NonNull CGValuedElement cgSlot, @NonNull EStructuralFeature eStructuralFeature, @NonNull CGValuedElement cgInit, boolean isPartial) {
if (eStructuralFeature.isMany()) {
String getAccessor = genModelHelper.getGetAccessor(eStructuralFeature);
//
js.appendValueName(cgSlot);
js.append(".");
js.append(getAccessor);
- js.append("().addAll(");
+ js.append("().");
+ js.append(isPartial ? "add" : "addAll");
+ js.append("(");
js.appendAtomicReferenceTo(cgInit);
js.append(");\n");
}
@@ -2090,6 +2092,7 @@
// Property pivotProperty = cgPropertyCallExp.getReferredProperty();
// CGTypeId cgTypeId = analyzer.getTypeId(pivotProperty.getOwningType().getTypeId());
// JavaTypeDescriptor requiredTypeDescriptor = context.getJavaTypeDescriptor(cgTypeId, false);
+ SetStatement asSetStatement = QVTiCGUtil.getAST(cgPropertyAssignment);
EStructuralFeature eStructuralFeature = QVTiCGUtil.getEStructuralFeature(cgPropertyAssignment);
CGValuedElement cgSlot = getExpression(QVTiCGUtil.getOwnedSlotValue(cgPropertyAssignment));
CGValuedElement cgInit = getExpression(QVTiCGUtil.getOwnedInitValue(cgPropertyAssignment));
@@ -2103,7 +2106,7 @@
if (!js.appendLocalStatements(cgInit)) {
return false;
}
- appendEcoreSet(cgSlot, eStructuralFeature, cgInit);
+ appendEcoreSet(cgSlot, eStructuralFeature, cgInit, asSetStatement.isIsPartial());
doAssigned(cgPropertyAssignment);
return true;
}
diff --git a/plugins/org.eclipse.qvtd.codegen/src/org/eclipse/qvtd/codegen/utilities/QVTiCGUtil.java b/plugins/org.eclipse.qvtd.codegen/src/org/eclipse/qvtd/codegen/utilities/QVTiCGUtil.java
index e0f0572..65452ba 100644
--- a/plugins/org.eclipse.qvtd.codegen/src/org/eclipse/qvtd/codegen/utilities/QVTiCGUtil.java
+++ b/plugins/org.eclipse.qvtd.codegen/src/org/eclipse/qvtd/codegen/utilities/QVTiCGUtil.java
@@ -44,6 +44,7 @@
import org.eclipse.qvtd.pivot.qvtimperative.SimpleParameter;
import org.eclipse.qvtd.pivot.qvtimperative.utilities.QVTimperativeUtil;
import org.eclipse.qvtd.pivot.qvtimperative.NewStatement;
+import org.eclipse.qvtd.pivot.qvtimperative.SetStatement;
public class QVTiCGUtil extends CGUtil
{
@@ -68,6 +69,10 @@
return ClassUtil.nonNullState((MappingCall)cgMappingCall.getAst());
}
+ public static @NonNull SetStatement getAST(@NonNull CGPropertyAssignment cgPropertyAssignment) {
+ return ClassUtil.nonNullState((SetStatement)cgPropertyAssignment.getAst());
+ }
+
public static @NonNull NewStatement getAST(@NonNull CGRealizedVariable cgRealizedVariable) {
return ClassUtil.nonNullState((NewStatement)cgRealizedVariable.getAst());
}
diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/common/AbstractQVTc2QVTc.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/common/AbstractQVTc2QVTc.java
index 03c20d2..039cee5 100644
--- a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/common/AbstractQVTc2QVTc.java
+++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/common/AbstractQVTc2QVTc.java
@@ -341,6 +341,9 @@
if (paIn.eIsSet(QVTcorePackage.Literals.ASSIGNMENT__IS_DEFAULT)) {
paOut.setIsDefault(paIn.isIsDefault());
}
+ if (paIn.eIsSet(QVTcorePackage.Literals.ASSIGNMENT__IS_PARTIAL)) {
+ paOut.setIsPartial(paIn.isIsPartial());
+ }
paOut.setTargetProperty(paIn.getTargetProperty());
createAll(paIn.getOwnedComments(), paOut.getOwnedComments());
return paOut;
diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/BasicMappingRegion.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/BasicMappingRegion.java
index aa5a529..ac0da8f 100644
--- a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/BasicMappingRegion.java
+++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/BasicMappingRegion.java
@@ -313,7 +313,7 @@
if (!referredProperty.isIsMany()) {
Edge predicateEdge = sourceNode.getPredicateEdge(referredProperty);
if (predicateEdge == null) {
- RegionUtil.createNavigationEdge(sourceNode, referredProperty, targetNode);
+ RegionUtil.createNavigationEdge(sourceNode, referredProperty, targetNode, false);
}
else {
assert predicateEdge.getTarget() == targetNode;
diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/Edge.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/Edge.java
index bd58d68..0970711 100644
--- a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/Edge.java
+++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/Edge.java
@@ -23,7 +23,7 @@
/**
* Create an edgeRole edge from sourceNode to targetNode with the same name as this edge.
*/
- @NonNull Edge createEdge(@NonNull EdgeRole edgeRole, @NonNull Node sourceNode, @NonNull Node targetNode);
+ @NonNull Edge createEdge(@NonNull EdgeRole edgeRole, @NonNull Node sourceNode, @NonNull Node targetNode, @Nullable Boolean isPartial);
void destroy();
@@ -136,6 +136,11 @@
boolean isNavigation();
/**
+ * Return true if this edge is for a partial many-to-one relationship.
+ */
+ boolean isPartial();
+
+ /**
* Return true if this edge is for a predicate.
*/
boolean isPredicate();
diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/ExpressionAnalyzer.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/ExpressionAnalyzer.java
index a0e430a..693154d 100644
--- a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/ExpressionAnalyzer.java
+++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/ExpressionAnalyzer.java
@@ -21,6 +21,7 @@
import org.eclipse.ocl.pivot.CollectionLiteralExp;
import org.eclipse.ocl.pivot.CollectionLiteralPart;
import org.eclipse.ocl.pivot.CollectionRange;
+import org.eclipse.ocl.pivot.CollectionType;
import org.eclipse.ocl.pivot.CompleteClass;
import org.eclipse.ocl.pivot.DataType;
import org.eclipse.ocl.pivot.Element;
@@ -89,11 +90,6 @@
}
@Override
- protected @NonNull NavigableEdge createNavigationEdge(@NonNull Node sourceNode, @NonNull Property source2targetProperty, @NonNull Node targetNode) {
- return RegionUtil.createNavigationEdge(sourceNode, source2targetProperty, targetNode);
- }
-
- @Override
protected @NonNull Node createStepNode(@NonNull String name, @NonNull CallExp callExp, @NonNull Node sourceNode) {
return RegionUtil.createStepNode(name, callExp, sourceNode, false);
}
@@ -216,7 +212,7 @@
String name = operationCallExp.getReferredOperation().getName();
assert name != null;
Node oclContainerNode = createStepNode(name, operationCallExp, sourceNode);
- oclContainerEdge = createNavigationEdge(sourceNode, oclContainerProperty, oclContainerNode);
+ oclContainerEdge = createNavigationEdge(sourceNode, oclContainerProperty, oclContainerNode, false);
return oclContainerNode;
/* String name = operationCallExp.getReferredOperation().getName();
assert name != null;
@@ -328,21 +324,22 @@
}
protected @NonNull NavigableEdge createNavigableNavigationEdge(@NonNull Node sourceNode, @NonNull Property source2targetProperty, @NonNull Node targetNode) {
- return RegionUtil.createNavigationEdge(sourceNode, source2targetProperty, targetNode);
+ return RegionUtil.createNavigationEdge(sourceNode, source2targetProperty, targetNode, false);
}
- protected @NonNull NavigableEdge createNavigationEdge(@NonNull Node sourceNode, @NonNull Property source2targetProperty, @NonNull Node targetNode) {
- return RegionUtil.createNavigationEdge(sourceNode, source2targetProperty, targetNode);
+ protected @NonNull NavigableEdge createNavigationEdge(@NonNull Node sourceNode, @NonNull Property source2targetProperty, @NonNull Node targetNode, @Nullable Boolean isPartial) {
+ return RegionUtil.createNavigationEdge(sourceNode, source2targetProperty, targetNode, isPartial);
}
protected @NonNull NavigableEdge createNavigationOrRealizedEdge(@NonNull Node sourceNode, @NonNull Property source2targetProperty, @NonNull Node targetNode, @Nullable NavigationAssignment navigationAssignment) {
NavigableEdge navigationEdge = sourceNode.getNavigationEdge(source2targetProperty);
assert navigationEdge == null;
+ Boolean isPartial = navigationAssignment != null ? navigationAssignment.isIsPartial() : null;
if ((navigationAssignment != null) || context.isPropertyAssignment(sourceNode, source2targetProperty)) {
- navigationEdge = createRealizedNavigationEdge(sourceNode, source2targetProperty, targetNode);
+ navigationEdge = createRealizedNavigationEdge(sourceNode, source2targetProperty, targetNode, isPartial);
}
else {
- navigationEdge = createNavigationEdge(sourceNode, source2targetProperty, targetNode);
+ navigationEdge = createNavigationEdge(sourceNode, source2targetProperty, targetNode, isPartial);
}
return navigationEdge;
}
@@ -371,8 +368,8 @@
return RegionUtil.createRealizedExpressionEdge(sourceNode, name, targetNode);
}
- protected @NonNull NavigableEdge createRealizedNavigationEdge(@NonNull Node sourceNode, @NonNull Property source2targetProperty, @NonNull Node targetNode) {
- return RegionUtil.createRealizedNavigationEdge(sourceNode, source2targetProperty, targetNode);
+ protected @NonNull NavigableEdge createRealizedNavigationEdge(@NonNull Node sourceNode, @NonNull Property source2targetProperty, @NonNull Node targetNode, @Nullable Boolean isPartial) {
+ return RegionUtil.createRealizedNavigationEdge(sourceNode, source2targetProperty, targetNode, isPartial);
}
protected @NonNull Node createStepNode(@NonNull String name, @NonNull CallExp callExp, @NonNull Node sourceNode) {
@@ -548,7 +545,7 @@
String name = referenceTargetNode.getName();
ClassDatumAnalysis classDatumAnalysis = referenceTargetNode.getClassDatumAnalysis();
Node instantiatedTargetNode = createDependencyNode(name, classDatumAnalysis);
- createNavigationEdge(instantiatedNode, referenceEdge.getProperty(), instantiatedTargetNode);
+ createNavigationEdge(instantiatedNode, referenceEdge.getProperty(), instantiatedTargetNode, false);
instantiate(instantiatedTargetNode, referenceTargetNode);
}
}
@@ -626,7 +623,7 @@
else {
Node varNode = createLetNode(ownedVariable, initNode);
Property castProperty = scheduler.getCastProperty(type);
- createNavigationEdge(initNode, castProperty, varNode);
+ createNavigationEdge(initNode, castProperty, varNode, false);
}
return analyze(letExp.getOwnedIn());
}
@@ -714,7 +711,10 @@
NavigableEdge navigationEdge = getNavigationEdge(slotNode, property, targetNode, asNavigationAssignment);
Node valueNode = navigationEdge.getTarget();
CompleteClass valueCompleteClass = valueNode.getCompleteClass();
- Type propertyType = ClassUtil.nonNullState(property.getType());
+ Type propertyType = PivotUtil.getType(property);
+ if (asNavigationAssignment.isIsPartial()) {
+ propertyType = PivotUtil.getElementType(((CollectionType)propertyType));
+ }
CompleteClass targetCompleteClass = environmentFactory.getCompleteModel().getCompleteClass(propertyType);
if (!valueCompleteClass.conformsTo(targetCompleteClass)) {
// FIXME we could synthesize a cast, but it's easier to do oclAsType() in QVTm/QVTp
diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/NavigableEdge.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/NavigableEdge.java
index de9aac7..6ae09d2 100644
--- a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/NavigableEdge.java
+++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/NavigableEdge.java
@@ -25,7 +25,7 @@
* Create an edgeRole edge from sourceNode to targetNode with the same property as this edge. * @param edgeRole
*/
@Override
- @NonNull NavigableEdge createEdge(@NonNull EdgeRole edgeRole, @NonNull Node sourceNode, @NonNull Node targetNode);
+ @NonNull NavigableEdge createEdge(@NonNull EdgeRole edgeRole, @NonNull Node sourceNode, @NonNull Node targetNode, @Nullable Boolean isPartial);
@Override
@NonNull NavigableEdge getForwardEdge();
diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/OperationRegion.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/OperationRegion.java
index 2fe98cf..4324231 100644
--- a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/OperationRegion.java
+++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/OperationRegion.java
@@ -150,7 +150,7 @@
ClassDatumAnalysis elementClassDatumAnalysis = schedulerConstants.getClassDatumAnalysis((@NonNull Class) elementType, typedModel2);
Node elementNode = RegionUtil.createOperationElementNode(this, name, elementClassDatumAnalysis, dependencyNode2);
//(region, name, typedElement, argNodes)Node(region, name, callExp, sourceNode)Node(this, name, iterateProperty, dependencyNode2);
- RegionUtil.createNavigationEdge(dependencyNode2, iterateProperty, elementNode);
+ RegionUtil.createNavigationEdge(dependencyNode2, iterateProperty, elementNode, false);
dependencyNode2 = elementNode;
}
// assert !dependencyNode2.isMatched();
@@ -161,7 +161,7 @@
else {
nextNode = RegionUtil.createDataTypeNode(dependencyNode2, property);
}
- RegionUtil.createNavigationEdge(dependencyNode2, property, nextNode);
+ RegionUtil.createNavigationEdge(dependencyNode2, property, nextNode, false);
dependencyNode2 = nextNode;
}
}
diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/RegionUtil.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/RegionUtil.java
index b800c4d..e3340f2 100644
--- a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/RegionUtil.java
+++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/RegionUtil.java
@@ -181,10 +181,10 @@
return PatternVariableNodeImpl.create(nodeRole, region, stepVariable, true);
}
- public static @NonNull NavigableEdge createNavigationEdge(@NonNull Node sourceNode, @NonNull Property source2targetProperty, @NonNull Node targetNode) {
+ public static @NonNull NavigableEdge createNavigationEdge(@NonNull Node sourceNode, @NonNull Property source2targetProperty, @NonNull Node targetNode, @Nullable Boolean isPartial) {
EdgeRole.Phase phase = mergeToLessKnownPhase(sourceNode.getNodeRole(), targetNode.getNodeRole()).getPhase();
EdgeRole edgeRole = EdgeRoleImpl.getEdgeRole(phase);
- return NavigationEdgeImpl.createEdge(edgeRole, sourceNode, source2targetProperty, targetNode);
+ return NavigationEdgeImpl.createEdge(edgeRole, sourceNode, source2targetProperty, targetNode, isPartial);
}
public static @NonNull Node createNullNode(@NonNull Region region, boolean isMatched, @Nullable TypedElement typedElement) {
@@ -263,9 +263,9 @@
return ExpressionEdgeImpl.create(edgeRole, sourceNode, name, targetNode);
}
- public static @NonNull NavigableEdge createRealizedNavigationEdge(@NonNull Node sourceNode, @NonNull Property source2targetProperty, @NonNull Node targetNode) {
+ public static @NonNull NavigableEdge createRealizedNavigationEdge(@NonNull Node sourceNode, @NonNull Property source2targetProperty, @NonNull Node targetNode, @Nullable Boolean isPartial) {
EdgeRole edgeRole = EdgeRoleImpl.getEdgeRole(Role.Phase.REALIZED);
- return NavigationEdgeImpl.createEdge(edgeRole, sourceNode, source2targetProperty, targetNode);
+ return NavigationEdgeImpl.createEdge(edgeRole, sourceNode, source2targetProperty, targetNode, isPartial);
}
public static @NonNull VariableNodeImpl createRealizedStepNode(@NonNull Region region, @NonNull Variable stepVariable) {
@@ -533,7 +533,7 @@
return isUnconditional(typedElement);
}
- public static boolean isRealizedIncludes(@NonNull Edge edge) { // FIXME includes should be a pseudo-navigation edge
+ /* public static boolean isRealizedIncludes(@NonNull Edge edge) { // FIXME includes should be a pseudo-navigation edge
if (!edge.isRealized()) {
return false;
}
@@ -541,7 +541,7 @@
return false;
}
return "«includes»".equals(edge.getName()) || "«includesAll»".equals(edge.getName());
- }
+ } */
public static boolean isUnconditional(@NonNull TypedElement typedElement) {
EObject eContainer = typedElement.eContainer();
diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/RootCompositionRegion.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/RootCompositionRegion.java
index ddc46b1..2c6ef29 100644
--- a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/RootCompositionRegion.java
+++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/RootCompositionRegion.java
@@ -114,7 +114,7 @@
if (introducedNode == null) {
introducedNode = RegionUtil.createComposingNode(this, "«" + elementType.getName() + "-null»", childrenClassDatumAnalysis);
property2node.put(null, introducedNode);
- RegionUtil.createNavigationEdge(getNullNode(), parent2childProperty, introducedNode);
+ RegionUtil.createNavigationEdge(getNullNode(), parent2childProperty, introducedNode, false);
}
}
else if (containingClassDatumAnalysis != null) { // Non-root oclContainer ownership
@@ -128,7 +128,7 @@
introducedNode = RegionUtil.createComposingNode(this, "«" + elementType.getName() + "-oclContents»", childrenClassDatumAnalysis);
type2node.put(containingClassDatumAnalysis, introducedNode);
Node containerNode = RegionUtil.createComposingNode(this, "«" + containingClassDatumAnalysis.getCompleteClass().getName() + "-oclContainer»", containingClassDatumAnalysis);
- RegionUtil.createNavigationEdge(containerNode, parent2childProperty, introducedNode);
+ RegionUtil.createNavigationEdge(containerNode, parent2childProperty, introducedNode, false);
}
}
else { // Knonw distinctive containment
@@ -145,7 +145,7 @@
assert owningClass != null;
containingClassDatumAnalysis = scheduler.getClassDatumAnalysis(owningClass, typedModel);
Node containerNode = RegionUtil.createComposingNode(this, "«" + owningClass.getName() + "-" + parent2childProperty.getName() + "»", containingClassDatumAnalysis);
- RegionUtil.createNavigationEdge(containerNode, parent2childProperty, introducedNode);
+ RegionUtil.createNavigationEdge(containerNode, parent2childProperty, introducedNode, false);
}
}
return introducedNode;
diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/impl/CastEdgeImpl.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/impl/CastEdgeImpl.java
index c1e4444..9bfc6b4 100644
--- a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/impl/CastEdgeImpl.java
+++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/impl/CastEdgeImpl.java
@@ -44,7 +44,7 @@
}
@Override
- public @NonNull NavigableEdge createEdge(@NonNull EdgeRole edgeRole, @NonNull Node sourceNode, @NonNull Node targetNode) {
+ public @NonNull NavigableEdge createEdge(@NonNull EdgeRole edgeRole, @NonNull Node sourceNode, @NonNull Node targetNode, @Nullable Boolean isPartial) {
return createEdge(edgeRole, sourceNode, getProperty(), targetNode);
}
diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/impl/EdgeImpl.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/impl/EdgeImpl.java
index 12bb83e..eec0afb 100644
--- a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/impl/EdgeImpl.java
+++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/impl/EdgeImpl.java
@@ -285,6 +285,11 @@
}
@Override
+ public boolean isPartial() {
+ return false;
+ }
+
+ @Override
public boolean isPredicate() {
return false;
}
diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/impl/ExpressionEdgeImpl.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/impl/ExpressionEdgeImpl.java
index 10e6e05..3ad6899 100644
--- a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/impl/ExpressionEdgeImpl.java
+++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/impl/ExpressionEdgeImpl.java
@@ -25,7 +25,7 @@
}
@Override
- public @NonNull Edge createEdge(@NonNull EdgeRole edgeRole, @NonNull Node sourceNode, @NonNull Node targetNode) {
+ public @NonNull Edge createEdge(@NonNull EdgeRole edgeRole, @NonNull Node sourceNode, @NonNull Node targetNode, @Nullable Boolean isPartial) {
return create(edgeRole, sourceNode, getName(), targetNode);
}
diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/impl/IteratedEdgeImpl.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/impl/IteratedEdgeImpl.java
index f861ee4..9cf0b5b 100644
--- a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/impl/IteratedEdgeImpl.java
+++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/impl/IteratedEdgeImpl.java
@@ -25,7 +25,7 @@
}
@Override
- public @NonNull Edge createEdge(@NonNull EdgeRole edgeRole, @NonNull Node sourceNode, @NonNull Node targetNode) {
+ public @NonNull Edge createEdge(@NonNull EdgeRole edgeRole, @NonNull Node sourceNode, @NonNull Node targetNode, @Nullable Boolean isPartial) {
return create(edgeRole, sourceNode, getName(), targetNode);
}
diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/impl/NavigationEdgeImpl.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/impl/NavigationEdgeImpl.java
index cdd97b6..f37fbb6 100644
--- a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/impl/NavigationEdgeImpl.java
+++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/impl/NavigationEdgeImpl.java
@@ -12,19 +12,23 @@
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
+import org.eclipse.ocl.pivot.CollectionType;
+import org.eclipse.ocl.pivot.CompleteClass;
import org.eclipse.ocl.pivot.Property;
+import org.eclipse.ocl.pivot.Type;
+import org.eclipse.ocl.pivot.utilities.PivotUtil;
import org.eclipse.qvtd.compiler.internal.qvtp2qvts.EdgeRole;
import org.eclipse.qvtd.compiler.internal.qvtp2qvts.NavigableEdge;
import org.eclipse.qvtd.compiler.internal.qvtp2qvts.Node;
public class NavigationEdgeImpl extends NavigableEdgeImpl
{
- private static @NonNull NavigationEdgeImpl create(@NonNull EdgeRole edgeRole, @NonNull Node sourceNode, @NonNull Property source2targetProperty, @NonNull Node targetNode) {
- if ("ownedCallExp".equals(source2targetProperty.getName())) {
+ private static @NonNull NavigationEdgeImpl create(@NonNull EdgeRole edgeRole, @NonNull Node sourceNode, @NonNull Property source2targetProperty, @NonNull Node targetNode, @Nullable Boolean isPartial) {
+ if ("outTransition".equals(source2targetProperty.getName())) {
edgeRole.toString();
}
NavigationEdgeImpl edge = new NavigationEdgeImpl();
- edge.initialize(edgeRole, sourceNode, source2targetProperty, targetNode);
+ edge.initialize(edgeRole, sourceNode, source2targetProperty, targetNode, isPartial);
return edge;
}
@@ -33,22 +37,63 @@
* source2targetProperty has an opposite, the opposite edge is also created and installed.
*/
public static @NonNull NavigableEdge createEdge(@NonNull EdgeRole edgeRole,
- @NonNull Node sourceNode, @NonNull Property source2targetProperty, @NonNull Node targetNode) {
- NavigationEdgeImpl forwardEdge = create(edgeRole, sourceNode, source2targetProperty, targetNode);
+ @NonNull Node sourceNode, @NonNull Property source2targetProperty, @NonNull Node targetNode, @Nullable Boolean isPartial) {
+ NavigationEdgeImpl forwardEdge = create(edgeRole, sourceNode, source2targetProperty, targetNode, isPartial);
Property target2sourceProperty = source2targetProperty.getOpposite();
if ((target2sourceProperty != null) && !targetNode.isExplicitNull()) {
- assert (targetNode.getNavigationEdge(target2sourceProperty) == null) || target2sourceProperty.isIsMany();
+ assert (targetNode.getNavigationEdge(target2sourceProperty) == null) || target2sourceProperty.isIsMany() || (isPartial == Boolean.TRUE);
if (!source2targetProperty.isIsMany() && !target2sourceProperty.isIsMany() /*&& target2sourceProperty.isIsRequired()*/) { // FIXME do we need stronger type conformance here ??
- NavigationEdgeImpl reverseEdge = create(edgeRole, targetNode, target2sourceProperty, sourceNode);
+ NavigationEdgeImpl reverseEdge = create(edgeRole, targetNode, target2sourceProperty, sourceNode, isPartial);
forwardEdge.initializeOpposite(reverseEdge);
}
}
return forwardEdge;
}
+ /**
+ * True if this edge is a partial many-to-one relationship.
+ */
+ private boolean isPartial = false;
+
@Override
- public @NonNull NavigableEdge createEdge(@NonNull EdgeRole edgeRole, @NonNull Node sourceNode, @NonNull Node targetNode) {
- return createEdge(edgeRole, sourceNode, getProperty(), targetNode);
+ public @NonNull NavigableEdge createEdge(@NonNull EdgeRole edgeRole, @NonNull Node sourceNode, @NonNull Node targetNode, @Nullable Boolean isPartial) {
+ return createEdge(edgeRole, sourceNode, getProperty(), targetNode, isPartial);
+ }
+
+ @Override
+ public @Nullable String getLabel() {
+ if (isPartial) {
+ return "«includes»\\n" + super.getLabel();
+ }
+ else {
+ return super.getLabel();
+ }
+ }
+
+ public void initialize(@NonNull EdgeRole edgeRole, @NonNull Node sourceNode, @NonNull Property source2targetProperty,
+ @NonNull Node targetNode, @Nullable Boolean isPartial) {
+ super.initialize(edgeRole, sourceNode, source2targetProperty, targetNode);
+ boolean isComputedPartial = false;
+ Type propertyTargetType = PivotUtil.getType(source2targetProperty);
+ CompleteClass targetClass = targetNode.getCompleteClass();
+ if (!targetClass.conformsTo(propertyTargetType)) {
+ if (propertyTargetType instanceof CollectionType) {
+ Type elementType = PivotUtil.getElementType(((CollectionType)propertyTargetType));
+ if (targetClass.conformsTo(elementType)) {
+ isComputedPartial = true;
+ }
+ }
+ }
+ if (isPartial == null) {
+ isPartial = isComputedPartial;
+ }
+ assert isPartial == isComputedPartial;
+ setIsPartial(isPartial);
+ }
+
+ @Override
+ public final boolean isPartial() {
+ return isPartial;
}
@Override
@@ -56,6 +101,10 @@
return true;
}
+ public void setIsPartial(boolean isPartial) {
+ this.isPartial = isPartial;
+ }
+
@Override
public void setSource(@Nullable Node sourceNode) {
assert (sourceNode == null) || !sourceNode.isExplicitNull();
diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/impl/PredicateEdgeImpl.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/impl/PredicateEdgeImpl.java
index 55a542b..91f07db 100644
--- a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/impl/PredicateEdgeImpl.java
+++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/impl/PredicateEdgeImpl.java
@@ -25,7 +25,7 @@
}
@Override
- public @NonNull Edge createEdge(@NonNull EdgeRole edgeRole, @NonNull Node sourceNode, @NonNull Node targetNode) {
+ public @NonNull Edge createEdge(@NonNull EdgeRole edgeRole, @NonNull Node sourceNode, @NonNull Node targetNode, @Nullable Boolean isPartial) {
return create(edgeRole, sourceNode, getName(), targetNode);
}
diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/impl/RecursionEdgeImpl.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/impl/RecursionEdgeImpl.java
index 21d0cf5..bf40c53 100644
--- a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/impl/RecursionEdgeImpl.java
+++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/impl/RecursionEdgeImpl.java
@@ -11,6 +11,7 @@
package org.eclipse.qvtd.compiler.internal.qvtp2qvts.impl;
import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.qvtd.compiler.internal.qvtp2qvts.Edge;
import org.eclipse.qvtd.compiler.internal.qvtp2qvts.EdgeRole;
import org.eclipse.qvtd.compiler.internal.qvtp2qvts.Node;
@@ -28,7 +29,7 @@
private boolean isPrimary = false;
@Override
- public @NonNull Edge createEdge(@NonNull EdgeRole edgeRole, @NonNull Node sourceNode, @NonNull Node targetNode) {
+ public @NonNull Edge createEdge(@NonNull EdgeRole edgeRole, @NonNull Node sourceNode, @NonNull Node targetNode, @Nullable Boolean isPartial) {
return create(edgeRole, sourceNode, targetNode, isPrimary);
}
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 41895ba..00e39ee 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
@@ -46,6 +46,7 @@
import org.eclipse.qvtd.pivot.qvtcore.CorePattern;
import org.eclipse.qvtd.pivot.qvtcore.GuardPattern;
import org.eclipse.qvtd.pivot.qvtcore.Mapping;
+import org.eclipse.qvtd.pivot.qvtcore.NavigationAssignment;
import org.eclipse.qvtd.pivot.qvtcore.RealizedVariable;
import org.eclipse.qvtd.pivot.qvtcore.VariableAssignment;
import org.eclipse.qvtd.pivot.qvtcore.utilities.QVTcoreHelper;
@@ -91,6 +92,7 @@
this.cOtherTypedModel = getCoreTypedModel(rOtherTypedModel);
this.cOtherDomain = createCoreDomain(cOtherTypedModel, false);
cOtherDomain.setIsCheckable(rOtherDomain.isIsCheckable());
+ cOtherDomain.setIsEnforceable(false);
this.cOtherGuardPattern = ClassUtil.nonNullState(cOtherDomain.getGuardPattern());
this.cOtherBottomPattern = ClassUtil.nonNullState(cOtherDomain.getBottomPattern());
@@ -156,7 +158,7 @@
/**
* The predicate for a CollectionTemplateExp without a rest variable is a total comparison.
*
- * ve1:T1{tp = ve2:Collection{a++b}} => ve2 := ve1.tp; ve2 = Collection{a,b};
+ * ve1:T1{tp = ve2:Collection{a,b}} => ve2 := ve1.tp; ve2 = Collection{a,b};
*/
List<@NonNull CollectionLiteralPart> mParts = new ArrayList<>();
for (@NonNull OCLExpression rMember : rMembers) {
@@ -249,7 +251,7 @@
Variable rVariable/*vpte*/ = ClassUtil.nonNullState((Variable) ((VariableExp)propertyTemplateValue).getReferredVariable());
Variable cVariable/*mvpte*/ = variablesAnalysis.getCoreVariable(rVariable);
// BottomPattern cBottomPattern = rSharedVariables.contains(rVariable) ? cMiddleBottomPattern : cEnforcedBottomPattern;
- variablesAnalysis.addNavigationAssignment(rTemplateVariable, partProperty, createVariableExp(cVariable));
+ variablesAnalysis.addNavigationPredicate(cOtherBottomPattern, rTemplateVariable, partProperty, createVariableExp(cVariable));
}
else if (propertyTemplateValue instanceof CollectionTemplateExp) {
/**
@@ -264,7 +266,7 @@
NavigationCallExp pce = createNavigationCallExp(createVariableExp(cTemplateVariable), partProperty);
VariableAssignment a = createVariableAssignment(mvcte, pce);
cMiddleBottomPattern.getAssignment().add(a);
- mapOtherCollectionTemplateExpression(cte);
+ mapOtherTemplateExpression(cte);
}
else if (propertyTemplateValue instanceof ObjectTemplateExp) {
/**
@@ -276,8 +278,8 @@
ObjectTemplateExp pte = (ObjectTemplateExp)propertyTemplateValue;
Variable vpte = ClassUtil.nonNullState(pte.getBindsTo());
Variable mvpte = variablesAnalysis.getCoreVariable(vpte);
- variablesAnalysis.addNavigationAssignment(rTemplateVariable, partProperty, createVariableExp(mvpte));
- mapOtherObjectTemplateExpression(pte);
+ variablesAnalysis.addNavigationPredicate(cOtherBottomPattern, rTemplateVariable, partProperty, createVariableExp(mvpte));
+ mapOtherTemplateExpression(pte);
}
else {
// loop body of RDomainPatternToMDBottomPatternSimpleNonVarExpr
@@ -287,7 +289,7 @@
*
* ve1:T{tp = me} => ve1.tp := me;
*/
- variablesAnalysis.addNavigationAssignment(rTemplateVariable, partProperty, mapExpression(propertyTemplateValue));
+ variablesAnalysis.addNavigationPredicate(cOtherBottomPattern, rTemplateVariable, partProperty, mapExpression(propertyTemplateValue));
}
}
}
@@ -506,12 +508,13 @@
cExpression = mapExpression(rExpression);
}
if ((cTargetVariable != null) && (cExpression != null)) {
- variablesAnalysis.addNavigationAssignment(rTargetVariable, targetProperty, cExpression);
+ variablesAnalysis.addNavigationAssignment(rTargetVariable, targetProperty, cExpression, false);
}
}
private @NonNull CoreDomain createCoreDomain(@NonNull TypedModel cTypedModel, boolean isEnforced) {
CoreDomain coreDomain = qvtr2qvtc.createCoreDomain(cTypedModel);
+ coreDomain.setIsCheckable(false);
coreDomain.setIsEnforceable(isEnforced);
coreDomain.setRule(cMapping);
return coreDomain;
@@ -635,7 +638,7 @@
/**
* The predicate for a CollectionTemplateExp without a rest variable is a total comparison.
*
- * ve1:T1{tp = ve2:Collection{a++b}} => ve2 := ve1.tp; ve2 = Collection{a,b};
+ * ve1:T1{tp = ve2:Collection{a,b}} => ve2 := ve1.tp; ve2 = Collection{a,b};
*/
List<@NonNull CollectionLiteralPart> mParts = new ArrayList<>();
for (@NonNull OCLExpression rMember : rMembers) {
@@ -674,41 +677,39 @@
variablesAnalysis.addConditionPredicate(cMiddleBottomPattern, createVariableExp(mVariable), vElement);
}
} */
- else {
- if (!rRest.isIsImplicit()) {
- /**
- * The assignment for an unordered CollectionTemplateExp rest variable is a cumulative exclusion.
- *
- * ve1:T1{tp = ve2:Collection{a,b++c}} => c := ve2->excluding(a)->excluding(b);
- */
- Variable mRest = variablesAnalysis.getCoreVariable(rRest);
- OCLExpression exclusions = createVariableExp(mvcte);
- for (@NonNull OCLExpression rMember : rMembers) {
- Variable mVariable = ClassUtil.nonNullState(rMember2mVariable.get(rMember));
- exclusions = createOperationCallExp(exclusions, "excluding", createVariableExp(mVariable));
- }
- VariableAssignment aRest = createVariableAssignment(mRest, exclusions);
+ else if (rRest.isIsImplicit()) {
+ PropertyTemplateItem rPropertyTemplateItem = (PropertyTemplateItem) cte.eContainer();
+ ObjectTemplateExp rObjectTemplateExp = rPropertyTemplateItem.getObjContainer();
+ Variable vote = ClassUtil.nonNullState(rObjectTemplateExp.getBindsTo());
+ Variable cvote = variablesAnalysis.getCoreVariable(vote);
+ /**
+ * The assignment for a CollectionTemplateExp variable is a literal for the members and an addition of the rest.
+ *
+ * ve1:T1{tp = ve2:Collection{a,b++_}} => ve1.tp += a; ve1.tp += b;
+ */
+ for (@NonNull OCLExpression rMember : rMembers) {
+ Variable mVariable = ClassUtil.nonNullState(rMember2mVariable.get(rMember));
+ NavigationAssignment aRest = createNavigationAssignment(createVariableExp(cvote), QVTrelationUtil.getReferredProperty(rPropertyTemplateItem), createVariableExp(mVariable), true);
cMiddleBottomPattern.getAssignment().add(aRest);
}
- /**
- * The predicates for each unordered CollectionTemplateExp member variable is an excluded inclusion test.
- *
- * ve1:T1{tp = ve2:Collection{a,b++c}} => ve2->excluding(a)->includes(b);
- */
- for (int i = 0; i < size; i++) {
- @NonNull OCLExpression eTerm = createVariableExp(mvcte);
- for (int j = 0; j < i; j++) {
- OCLExpression rMember = rMembers.get(j);
- Variable mVariable = ClassUtil.nonNullState(rMember2mVariable.get(rMember));
- eTerm = createOperationCallExp(eTerm, "excluding", createVariableExp(mVariable));
- }
- OCLExpression rMember = rMembers.get(i);
- Variable mVariable = ClassUtil.nonNullState(rMember2mVariable.get(rMember));
- eTerm = createOperationCallExp(eTerm, "includes", createVariableExp(mVariable));
- variablesAnalysis.addPredicate(cMiddleBottomPattern, eTerm);
- }
}
- // }
+ else {
+ /**
+ * The assignment for a CollectionTemplateExp variable is a literal for the members and an addition of the rest.
+ *
+ * ve1:T1{tp = ve2:Collection{a,b++c}} => ve2 := Collection{a,b}->includingAll(c);
+ */
+ List<@NonNull CollectionLiteralPart> ownedParts = new ArrayList<>();
+ for (@NonNull OCLExpression rMember : rMembers) {
+ Variable mVariable = ClassUtil.nonNullState(rMember2mVariable.get(rMember));
+ ownedParts.add(createCollectionItem(createVariableExp(mVariable)));
+ }
+ OCLExpression cExpression = createCollectionLiteralExp(collectionType, ownedParts);
+ Variable mRest = variablesAnalysis.getCoreVariable(rRest);
+ cExpression = createOperationCallExp(cExpression, "includingAll", createVariableExp(mRest));
+ VariableAssignment aRest = createVariableAssignment(mvcte, cExpression);
+ cMiddleBottomPattern.getAssignment().add(aRest);
+ }
}
// RDomainToMDBottomForEnforcement (second half)
@@ -727,23 +728,40 @@
// body of RDomainToMDBottomForEnforcementOfIdentityProp
addPropertyAssignmentToMiddleBottomPattern(rTemplateVariable, partProperty, rPartValue);
}
- else if (rPartValue instanceof TemplateExp) {
+ else if (rPartValue instanceof CollectionTemplateExp) {
// body of RDomainToMDBottomForEnforcementOfNonIdentityPropObject
- TemplateExp pte = (TemplateExp)rPartValue;
- Variable pv = ClassUtil.nonNullState(pte.getBindsTo());
+ CollectionTemplateExp cte = (CollectionTemplateExp)rPartValue;
+ /**
+ * Each PropertyTemplateItem whose value is a CollectionTemplateExp
+ * converts to a VariableAssignment and Predicates.
+ *
+ * ve1:T1{tp = ve2:Collection{a++b}} => ve2 := ve1.tp;
+ */
+ /*Realized*/Variable cTemplateVariable = variablesAnalysis.getCoreVariable(rTemplateVariable);
+ Variable vcte = ClassUtil.nonNullState(cte.getBindsTo());
+ Variable mvcte = variablesAnalysis.getCoreVariable(vcte);
+ NavigationCallExp pce = createNavigationCallExp(createVariableExp(cTemplateVariable), partProperty);
+ VariableAssignment a = createVariableAssignment(mvcte, pce);
+ cMiddleBottomPattern.getAssignment().add(a);
+ mapEnforcedTemplateExpression(cte);
+ }
+ else if (rPartValue instanceof ObjectTemplateExp) {
+ // body of RDomainToMDBottomForEnforcementOfNonIdentityPropObject
+ ObjectTemplateExp ote = (ObjectTemplateExp)rPartValue;
+ Variable pv = ClassUtil.nonNullState(ote.getBindsTo());
/*Realized*/Variable cTargetVariable/*mpv*/ = variablesAnalysis.getCoreVariable(pv); //rWhenVariables.contains(pv) ? getCoreVariable(pv) : whenRealizedVariable(cEnforcedBottomPattern, pv);
// Variable cTemplateVariable/*mv*/ = variablesAnalysis.getCoreVariable(rTemplateVariable);
- variablesAnalysis.addNavigationAssignment(rTemplateVariable, partProperty, createVariableExp(cTargetVariable));
- mapEnforcedTemplateExpression(pte);
+ variablesAnalysis.addNavigationAssignment(rTemplateVariable, partProperty, createVariableExp(cTargetVariable), null);
+ mapEnforcedTemplateExpression(ote);
// Property cTargetProperty2 = qvtr2qvtc.getProperty(cMiddleRealizedVariable.getType(), cTargetVariable);
// variablesAnalysis.addNavigationAssignment(rMiddleRealizedVariable, cTargetProperty2, createVariableExp(cTargetVariable));
}
- else {
+ else if (rPartValue instanceof VariableExp) {
// body of RDomainToMDBottomForEnforcementOfNonIdentityPropPrimitive
// Variable cTemplateVariable = variablesAnalysis.getCoreVariable(rTemplateVariable);
//RDomainToMComposedMappingGuardrEnforcedDomain
for (@NonNull TemplateExp rTemplateExpression : rEnforcedRootTemplateExpressions) {
- if ((rPartValue instanceof VariableExp) && (rTemplateExpression instanceof ObjectTemplateExp)) {
+ if (rTemplateExpression instanceof ObjectTemplateExp) {
// check
Variable rReferredVariable = (Variable) ClassUtil.nonNullState(((VariableExp) rPartValue).getReferredVariable());
if (isVarBoundToSomeOtherTemplate((ObjectTemplateExp) rTemplateExpression, rEnforcedObjectTemplateExpression, rReferredVariable)) {
@@ -754,8 +772,14 @@
cEnforcedGuardPattern.getBindsTo().add(cReferredVariable);
}
}
- variablesAnalysis.addNavigationAssignment(rTemplateVariable, partProperty, mapExpression(rPartValue));
}
+ variablesAnalysis.addNavigationAssignment(rTemplateVariable, partProperty, mapExpression(rPartValue), null);
+ }
+ else {
+ // body of RDomainToMDBottomForEnforcementOfNonIdentityPropPrimitive
+ // Variable cTemplateVariable = variablesAnalysis.getCoreVariable(rTemplateVariable);
+ //RDomainToMComposedMappingGuardrEnforcedDomain
+ variablesAnalysis.addNavigationAssignment(rTemplateVariable, partProperty, mapExpression(rPartValue), null);
}
}
}
@@ -909,7 +933,7 @@
Relation rInvokedRelation = QVTrelationUtil.getReferredRelation(rInvocation);
Type invokedTraceClass/*tc*/ = qvtr2qvtc.getTraceClass(rInvokedRelation);
//
- List<@NonNull OCLExpression> rArguments = QVTrelationUtil.getOwnedArguments(rInvocation);
+ List<@NonNull OCLExpression> rArguments = QVTrelationUtil.Internal.getOwnedArgumentsList(rInvocation);
/* StringBuilder s = new StringBuilder();
for (OCLExpression rArgument : rArguments) {
VariableExp a = (VariableExp) rArgument;
diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvtc/AbstractVariableAnalysis.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvtc/AbstractVariableAnalysis.java
index 279a07d..e71e5e9 100644
--- a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvtc/AbstractVariableAnalysis.java
+++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvtc/AbstractVariableAnalysis.java
@@ -43,7 +43,7 @@
}
@Override
- public void addNavigationAssignment(@NonNull Property targetProperty, @NonNull OCLExpression cExpression) {
+ public void addNavigationAssignment(@NonNull Property targetProperty, @NonNull OCLExpression cExpression, @Nullable Boolean isPartial) {
System.out.println("Unexpected " + getClass().getSimpleName() + ".addNavigationAssignment for " + this);
}
diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvtc/RelationVariableAnalysis.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvtc/RelationVariableAnalysis.java
index 7a938d6..20303f6 100644
--- a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvtc/RelationVariableAnalysis.java
+++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvtc/RelationVariableAnalysis.java
@@ -69,7 +69,7 @@
* of a Collection element assignment to "cExpression.cOppositeProperty := cVariable".
*/
@Override
- public void addNavigationAssignment(@NonNull Property targetProperty, @NonNull OCLExpression cExpression) {
+ public void addNavigationAssignment(@NonNull Property targetProperty, @NonNull OCLExpression cExpression, @Nullable Boolean isPartial) {
Key rKey2 = rKey;
if (isKeyed() && (rKey2 != null)) {
if (rKey2.getPart().contains(targetProperty)) {
@@ -81,24 +81,27 @@
}
Variable cVariable2 = getCoreVariable();
List<@NonNull Assignment> cMiddleBottomAssignments = QVTcoreUtil.getOwnedAssignments(variablesAnalysis.getMiddleBottomPattern());
- if (!targetProperty.isIsMany() || (cExpression.getType() instanceof CollectionType)) {
- VariableExp cSlotVariableExp = variablesAnalysis.createVariableExp(cVariable2);
- NavigationAssignment cAssignment = variablesAnalysis.createNavigationAssignment(cSlotVariableExp, targetProperty, cExpression);
- QVTr2QVTc.SYNTHESIS.println(" addPropertyAssignment " + cAssignment);
- variablesAnalysis.assertNewAssignment(cMiddleBottomAssignments, cAssignment);
- cMiddleBottomAssignments.add(cAssignment);
- return;
+ if (isPartial == null) {
+ isPartial = targetProperty.isIsMany() && !(cExpression.getType() instanceof CollectionType);
}
- Property cOppositeProperty = targetProperty.getOpposite();
+ // if (isPartial == isPartial2) {
+ VariableExp cSlotVariableExp = variablesAnalysis.createVariableExp(cVariable2);
+ NavigationAssignment cAssignment = variablesAnalysis.createNavigationAssignment(cSlotVariableExp, targetProperty, cExpression, isPartial);
+ QVTr2QVTc.SYNTHESIS.println(" addPropertyAssignment " + cAssignment);
+ variablesAnalysis.assertNewAssignment(cMiddleBottomAssignments, cAssignment);
+ cMiddleBottomAssignments.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 = variablesAnalysis.createNavigationAssignment(cSlotVariableExp, cOppositeProperty, variablesAnalysis.createVariableExp(cVariable2));
+ NavigationAssignment cAssignment = variablesAnalysis.createNavigationAssignment(cSlotVariableExp, cOppositeProperty, variablesAnalysis.createVariableExp(cVariable2), isPartial);
QVTr2QVTc.SYNTHESIS.println(" addOppositePropertyAssignment " + cAssignment);
variablesAnalysis.assertNewAssignment(cMiddleBottomAssignments, cAssignment);
cMiddleBottomAssignments.add(cAssignment);
return;
- }
- throw new IllegalStateException("Unsupported collection assign " + cVariable2 + " . " + targetProperty + " := " + cExpression);
+ } */
+ // throw new IllegalStateException("Unsupported collection assign " + cVariable2 + " . " + targetProperty + " := " + cExpression);
}
public @Nullable RealizedVariable basicGetCoreRealizedVariable() {
diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvtc/VariableAnalysis.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvtc/VariableAnalysis.java
index 26283a0..0c980d9 100644
--- a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvtc/VariableAnalysis.java
+++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvtc/VariableAnalysis.java
@@ -32,7 +32,7 @@
* Add the NavigationAssignment "cVariable.cProperty := cExpression" to the cBottomPattern inverting the usage
* of a Collection element assignment to "cExpression.cOppositeProperty := cVariable".
*/
- void addNavigationAssignment(@NonNull Property targetProperty, @NonNull OCLExpression cExpression);
+ void addNavigationAssignment(@NonNull Property targetProperty, @NonNull OCLExpression cExpression, @Nullable Boolean isPartial);
/**
* Perform diagnostic checks at the end of the analysis.
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 0f75658..f48d59d 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
@@ -23,6 +23,7 @@
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.ocl.pivot.CollectionType;
import org.eclipse.ocl.pivot.Element;
+import org.eclipse.ocl.pivot.NavigationCallExp;
import org.eclipse.ocl.pivot.OCLExpression;
import org.eclipse.ocl.pivot.OperationCallExp;
import org.eclipse.ocl.pivot.Parameter;
@@ -273,8 +274,14 @@
return cVariable;
}
- public void addNavigationAssignment(@NonNull Variable rTargetVariable, @NonNull Property targetProperty, @NonNull OCLExpression cExpression) {
- getVariableAnalysis(rTargetVariable).addNavigationAssignment(targetProperty, cExpression);
+ public void addNavigationAssignment(@NonNull Variable rTargetVariable, @NonNull Property targetProperty, @NonNull OCLExpression cExpression, @Nullable Boolean isPartial) {
+ getVariableAnalysis(rTargetVariable).addNavigationAssignment(targetProperty, cExpression, isPartial);
+ }
+
+ public void addNavigationPredicate(@NonNull CorePattern cCorePattern, @NonNull Variable rTargetVariable, @NonNull Property targetProperty, @NonNull OCLExpression cExpression) {
+ Variable cTargetVariable = getCoreVariable(rTargetVariable);
+ NavigationCallExp cNavigationExp = createNavigationCallExp(createVariableExp(cTargetVariable), targetProperty);
+ addConditionPredicate(cCorePattern, cNavigationExp, cExpression);
}
protected void addPredicate(@NonNull CorePattern cExpectedCorePattern, @NonNull OCLExpression cExpression) {
@@ -333,7 +340,7 @@
assert (!cTargetProperty.isIsMany() || (cVariable.getType() instanceof CollectionType));
VariableExp cSlotVariableExp = createVariableExp(cMiddleRealizedVariable);
OCLExpression cExpression = createVariableExp(cVariable);
- NavigationAssignment cAssignment = createNavigationAssignment(cSlotVariableExp, cTargetProperty, cExpression);
+ NavigationAssignment cAssignment = createNavigationAssignment(cSlotVariableExp, cTargetProperty, cExpression, false);
QVTr2QVTc.SYNTHESIS.println(" addPropertyAssignment " + cAssignment);
assertNewAssignment(QVTcoreUtil.getOwnedAssignments(cMiddleBottomPattern), cAssignment);
cMiddleBottomPattern.getAssignment().add(cAssignment);
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 e8744ae..8d23031 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
@@ -71,7 +71,6 @@
import org.eclipse.qvtd.compiler.internal.qvtp2qvts.Node;
import org.eclipse.qvtd.compiler.internal.qvtp2qvts.NodeConnection;
import org.eclipse.qvtd.compiler.internal.qvtp2qvts.Region;
-import org.eclipse.qvtd.compiler.internal.qvtp2qvts.RegionUtil;
import org.eclipse.qvtd.compiler.internal.qvtp2qvts.SchedulerConstants;
import org.eclipse.qvtd.compiler.internal.qvtp2qvts.analysis.ClassDatumAnalysis;
import org.eclipse.qvtd.pivot.qvtbase.Function;
@@ -798,7 +797,7 @@
Property property = edge.getProperty();
OCLExpression targetVariableExp = createVariableExp(targetNode);
boolean isNotify = isHazardousWrite(edge);
- SetStatement setStatement = QVTimperativeUtil.createSetStatement(slotVariable, property, targetVariableExp, isNotify);
+ SetStatement setStatement = QVTimperativeUtil.createSetStatement(slotVariable, property, targetVariableExp, edge.isPartial(), isNotify);
mapping.getOwnedStatements().add(setStatement);
}
}
@@ -821,7 +820,7 @@
}
} */
for (@NonNull Edge edge : region.getEdges()) {
- if (edge.isPredicate() && !RegionUtil.isRealizedIncludes(edge)) {
+ if (edge.isPredicate()) {
ExpressionCreator expressionCreator = new ExpressionCreator();
ExpressionCreator inlineExpressionCreator = expressionCreator.getInlineExpressionCreator();
Node sourceNode = edge.getSource();
@@ -1004,19 +1003,19 @@
for (@NonNull NavigableEdge traversedEdge : navigationForest.getForestNavigations()) {
Node sourceNode = traversedEdge.getSource();
Node targetNode = traversedEdge.getTarget();
- Boolean isJustRealizedIncludes = null;
- for (@NonNull Edge outgoingEdge : targetNode.getOutgoingEdges()) {
- if (!RegionUtil.isRealizedIncludes(outgoingEdge)) {
- isJustRealizedIncludes = false;
- break;
- }
- else {
- isJustRealizedIncludes = true;
- }
- }
- if (isJustRealizedIncludes == Boolean.TRUE) {
- continue;
- }
+ // Boolean isJustRealizedIncludes = null;
+ // for (@NonNull Edge outgoingEdge : targetNode.getOutgoingEdges()) {
+ // if (!RegionUtil.isRealizedIncludes(outgoingEdge)) {
+ // isJustRealizedIncludes = false;
+ // break;
+ // }
+ // else {
+ // isJustRealizedIncludes = true;
+ // }
+ // }
+ // if (isJustRealizedIncludes == Boolean.TRUE) {
+ // continue;
+ // }
Property property = traversedEdge.getProperty();
OCLExpression sourceExp = createVariableExp(sourceNode);
OCLExpression source2targetExp = createCallExp(sourceExp, property);
@@ -1199,7 +1198,7 @@
}
if (valueExp != null) {
boolean isNotify = isHazardousWrite(edge);
- SetStatement setStatement = QVTimperativeUtil.createSetStatement(asVariable, property, valueExp, isNotify);
+ SetStatement setStatement = QVTimperativeUtil.createSetStatement(asVariable, property, valueExp, edge.isPartial(), isNotify);
// addObservedProperties(setStatement);
mapping.getOwnedStatements().add(setStatement);
}
@@ -1233,12 +1232,12 @@
List<@NonNull Edge> realizedIncludesEdges = null;
// ImperativeBottomPattern bottomPattern = (ImperativeBottomPattern) mapping.getBottomPattern();
for (@NonNull Edge edge : region.getRealizedEdges()) {
- if (RegionUtil.isRealizedIncludes(edge)) {
- if (realizedIncludesEdges == null) {
- realizedIncludesEdges = new ArrayList<>();
- }
- realizedIncludesEdges.add(edge);
- }
+ // if (RegionUtil.isRealizedIncludes(edge)) {
+ // if (realizedIncludesEdges == null) {
+ // realizedIncludesEdges = new ArrayList<>();
+ // }
+ // realizedIncludesEdges.add(edge);
+ // }
}
if (realizedIncludesEdges != null) {
if (realizedIncludesEdges.size() > 1) {
diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvts2qvts/merger/EdgeMerger.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvts2qvts/merger/EdgeMerger.java
index a6e738c..49e8882 100644
--- a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvts2qvts/merger/EdgeMerger.java
+++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvts2qvts/merger/EdgeMerger.java
@@ -60,7 +60,7 @@
Edge newEdge2 = newEdge;
assert newEdge2 == null;
for (@NonNull Edge oldEdge : oldEdges) {
- newEdge2 = newEdge = oldEdge.createEdge(edgeRole, sourceNodeMerger, targetNodeMerger);
+ newEdge2 = newEdge = oldEdge.createEdge(edgeRole, sourceNodeMerger, targetNodeMerger, oldEdge.isPartial());
break;
}
if (newEdge2 == null) {
diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvts2qvts/partitioner/Partitioner.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvts2qvts/partitioner/Partitioner.java
index c9d24b8..5fef65d 100644
--- a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvts2qvts/partitioner/Partitioner.java
+++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvts2qvts/partitioner/Partitioner.java
@@ -30,7 +30,6 @@
import org.eclipse.qvtd.compiler.internal.qvtp2qvts.Node;
import org.eclipse.qvtd.compiler.internal.qvtp2qvts.QVTp2QVTs;
import org.eclipse.qvtd.compiler.internal.qvtp2qvts.Region;
-import org.eclipse.qvtd.compiler.internal.qvtp2qvts.RegionUtil;
import org.eclipse.qvtd.compiler.internal.utilities.CompilerUtil;
import com.google.common.collect.Iterables;
@@ -217,7 +216,7 @@
}
}
}
- else if (RegionUtil.isRealizedIncludes(edge)) {
+ /* else if (RegionUtil.isRealizedIncludes(edge)) {
realizedEdges.add(edge);
Node sourceNode = edge.getSource();
if (!realizedMiddleNodes.contains(sourceNode) && (sourceNode.isPredicated() || sourceNode.isRealized())) {
@@ -229,7 +228,7 @@
if (edge.getTarget().isLoaded() && edge.getSource().getClassDatumAnalysis().getDomainUsage().isMiddle()) {
// navigableEdges.add(navigationEdge);
}
- }
+ } */
}
}
for (@NonNull NavigableEdge edge : region.getNavigationEdges()) {
diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvts2qvts/partitioner/PartitioningVisitor.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvts2qvts/partitioner/PartitioningVisitor.java
index 121dcc0..239553d 100644
--- a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvts2qvts/partitioner/PartitioningVisitor.java
+++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvts2qvts/partitioner/PartitioningVisitor.java
@@ -100,7 +100,7 @@
if (edgeRole == null) {
return null;
}
- return edge.createEdge(edgeRole, partialSourceNode, partialTargetNode);
+ return edge.createEdge(edgeRole, partialSourceNode, partialTargetNode, edge.isPartial());
}
@Override
@@ -142,7 +142,7 @@
if (edgeRole == null) {
return null;
}
- return navigableEdge.createEdge(edgeRole, partialSourceNode, partialTargetNode);
+ return navigableEdge.createEdge(edgeRole, partialSourceNode, partialTargetNode, navigableEdge.isPartial());
}
@Override
diff --git a/plugins/org.eclipse.qvtd.pivot.qvtcore/emf-gen/org/eclipse/qvtd/pivot/qvtcore/impl/PropertyAssignmentImpl.java b/plugins/org.eclipse.qvtd.pivot.qvtcore/emf-gen/org/eclipse/qvtd/pivot/qvtcore/impl/PropertyAssignmentImpl.java
index 8175b09..c104323 100644
--- a/plugins/org.eclipse.qvtd.pivot.qvtcore/emf-gen/org/eclipse/qvtd/pivot/qvtcore/impl/PropertyAssignmentImpl.java
+++ b/plugins/org.eclipse.qvtd.pivot.qvtcore/emf-gen/org/eclipse/qvtd/pivot/qvtcore/impl/PropertyAssignmentImpl.java
@@ -338,7 +338,7 @@
else {
/*@Caught*/ @NonNull Object CAUGHT_result;
try {
- final /*@NonInvalid*/ boolean isPartial = this.isIsPartial();
+ final /*@NonInvalid*/ java.lang.@Nullable Boolean isPartial = this.isIsPartial();
final /*@NonInvalid*/ java.lang.@Nullable Boolean not = BooleanNotOperation.INSTANCE.evaluate(isPartial);
if (not == null) {
throw new InvalidValueException("Null if condition");
@@ -448,7 +448,7 @@
else {
@SuppressWarnings("null")
final /*@NonInvalid*/ org.eclipse.ocl.pivot.@NonNull Property targetProperty = this.getTargetProperty();
- final /*@NonInvalid*/ boolean isImplicit = targetProperty.isIsImplicit();
+ final /*@NonInvalid*/ java.lang.@Nullable Boolean isImplicit = targetProperty.isIsImplicit();
final /*@NonInvalid*/ java.lang.@Nullable Boolean result = BooleanNotOperation.INSTANCE.evaluate(isImplicit);
final /*@NonInvalid*/ boolean logDiagnostic = CGStringLogDiagnosticOperation.INSTANCE.evaluate(executor, TypeId.BOOLEAN, QVTcoreTables.STR_PropertyAssignment_c_c_PropertyIsNotImplicit, this, (Object)null, diagnostics, context, (Object)null, severity_0, result, QVTcoreTables.INT_0).booleanValue();
symbol_0 = logDiagnostic;
diff --git a/plugins/org.eclipse.qvtd.pivot.qvtcore/src/org/eclipse/qvtd/pivot/qvtcore/utilities/QVTcoreHelper.java b/plugins/org.eclipse.qvtd.pivot.qvtcore/src/org/eclipse/qvtd/pivot/qvtcore/utilities/QVTcoreHelper.java
index 2bfebe6..34ee7ec 100644
--- a/plugins/org.eclipse.qvtd.pivot.qvtcore/src/org/eclipse/qvtd/pivot/qvtcore/utilities/QVTcoreHelper.java
+++ b/plugins/org.eclipse.qvtd.pivot.qvtcore/src/org/eclipse/qvtd/pivot/qvtcore/utilities/QVTcoreHelper.java
@@ -67,7 +67,7 @@
return coreMapping;
}
- public @NonNull NavigationAssignment createNavigationAssignment(@NonNull OCLExpression asSlotExpression, @NonNull Property asProperty, @NonNull OCLExpression asValueExpression) {
+ public @NonNull NavigationAssignment createNavigationAssignment(@NonNull OCLExpression asSlotExpression, @NonNull Property asProperty, @NonNull OCLExpression asValueExpression, boolean isPartial) {
NavigationAssignment asNavigationAssignment;
if (asProperty.isIsImplicit()) {
OppositePropertyAssignment asPropertyAssignment = QVTcoreFactory.eINSTANCE.createOppositePropertyAssignment();
@@ -81,6 +81,8 @@
}
asNavigationAssignment.setSlotExpression(asSlotExpression);
asNavigationAssignment.setValue(asValueExpression);
+ asNavigationAssignment.setIsDefault(false);
+ asNavigationAssignment.setIsPartial(isPartial);
return asNavigationAssignment;
}
@@ -96,6 +98,8 @@
VariableAssignment asVariableAssignment = QVTcoreFactory.eINSTANCE.createVariableAssignment();
asVariableAssignment.setTargetVariable(asVariable);
asVariableAssignment.setValue(asValueExpression);
+ asVariableAssignment.setIsDefault(false);
+ asVariableAssignment.setIsPartial(false);
return asVariableAssignment;
}
}
\ No newline at end of file
diff --git a/plugins/org.eclipse.qvtd.pivot.qvtcore/src/org/eclipse/qvtd/pivot/qvtcore/utilities/QVTcoreToStringVisitor.java b/plugins/org.eclipse.qvtd.pivot.qvtcore/src/org/eclipse/qvtd/pivot/qvtcore/utilities/QVTcoreToStringVisitor.java
index 4fab8fe..4cb3d19 100644
--- a/plugins/org.eclipse.qvtd.pivot.qvtcore/src/org/eclipse/qvtd/pivot/qvtcore/utilities/QVTcoreToStringVisitor.java
+++ b/plugins/org.eclipse.qvtd.pivot.qvtcore/src/org/eclipse/qvtd/pivot/qvtcore/utilities/QVTcoreToStringVisitor.java
@@ -133,7 +133,7 @@
safeVisit(asNavigationAssignment.getSlotExpression());
append(".");
appendName(QVTcoreUtil.getTargetProperty(asNavigationAssignment));
- append(" := ");
+ append(asNavigationAssignment.isIsPartial() ? " += " : " := ");
safeVisit(asNavigationAssignment.getValue());
return null;
}
diff --git a/plugins/org.eclipse.qvtd.pivot.qvtimperative/src/org/eclipse/qvtd/pivot/qvtimperative/utilities/QVTimperativeUtil.java b/plugins/org.eclipse.qvtd.pivot.qvtimperative/src/org/eclipse/qvtd/pivot/qvtimperative/utilities/QVTimperativeUtil.java
index 3d4769c..eae6352 100644
--- a/plugins/org.eclipse.qvtd.pivot.qvtimperative/src/org/eclipse/qvtd/pivot/qvtimperative/utilities/QVTimperativeUtil.java
+++ b/plugins/org.eclipse.qvtd.pivot.qvtimperative/src/org/eclipse/qvtd/pivot/qvtimperative/utilities/QVTimperativeUtil.java
@@ -200,7 +200,7 @@
return newStatement;
}
- public static @NonNull SetStatement createSetStatement(@NonNull VariableDeclaration asVariable, @NonNull Property asProperty, @NonNull OCLExpression asValueExpression, boolean isNotify) {
+ public static @NonNull SetStatement createSetStatement(@NonNull VariableDeclaration asVariable, @NonNull Property asProperty, @NonNull OCLExpression asValueExpression, boolean isPartial, boolean isNotify) {
SetStatement asSetAssignment = QVTimperativeFactory.eINSTANCE.createSetStatement();
if (asProperty.isIsImplicit()) {
asSetAssignment.setTargetProperty(asProperty.getOpposite());
@@ -212,7 +212,9 @@
}
asSetAssignment.setTargetVariable(asVariable);
asSetAssignment.setOwnedExpression(asValueExpression);
+ asSetAssignment.setIsPartial(isPartial);
asSetAssignment.setIsNotify(isNotify);
+ assert isPartial == ((asSetAssignment.getTargetProperty().getType() instanceof CollectionType) && !(asValueExpression.getType() instanceof CollectionType)); // FIXME inadequate for nested types but good for initial debugging
return asSetAssignment;
}
diff --git a/plugins/org.eclipse.qvtd.pivot.qvtrelation/src/org/eclipse/qvtd/pivot/qvtrelation/utilities/QVTrelationUtil.java b/plugins/org.eclipse.qvtd.pivot.qvtrelation/src/org/eclipse/qvtd/pivot/qvtrelation/utilities/QVTrelationUtil.java
index f0a125c..d36b0f7 100644
--- a/plugins/org.eclipse.qvtd.pivot.qvtrelation/src/org/eclipse/qvtd/pivot/qvtrelation/utilities/QVTrelationUtil.java
+++ b/plugins/org.eclipse.qvtd.pivot.qvtrelation/src/org/eclipse/qvtd/pivot/qvtrelation/utilities/QVTrelationUtil.java
@@ -20,6 +20,7 @@
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.ocl.pivot.OCLExpression;
+import org.eclipse.ocl.pivot.Property;
import org.eclipse.ocl.pivot.Variable;
import org.eclipse.ocl.pivot.utilities.ClassUtil;
import org.eclipse.qvtd.pivot.qvtbase.Domain;
@@ -34,12 +35,23 @@
import org.eclipse.qvtd.pivot.qvtrelation.RelationDomain;
import org.eclipse.qvtd.pivot.qvtrelation.RelationModel;
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;
import com.google.common.collect.Iterables;
public class QVTrelationUtil extends QVTbaseUtil
{
+
+ public static class Internal extends QVTbaseUtil.Internal
+ {
+ public static List<@NonNull OCLExpression> getOwnedArgumentsList(@NonNull RelationCallExp rInvocation) {
+ return ClassUtil.nullFree(rInvocation.getArgument());
+ }
+ }
+
public static final @NonNull String DUMMY_VARIABLE_NAME = "_";
public static @Nullable Relation getContainingRelation(@Nullable EObject eObject) {
@@ -55,7 +67,7 @@
return ClassUtil.nonNullState(rKey.getIdentifies());
}
- public static @NonNull List<@NonNull OCLExpression> getOwnedArguments(@NonNull RelationCallExp rInvocation) {
+ public static @NonNull Iterable<@NonNull OCLExpression> getOwnedArguments(@NonNull RelationCallExp rInvocation) {
return ClassUtil.nullFree(rInvocation.getArgument());
}
@@ -67,6 +79,14 @@
return ClassUtil.nullFree(rTransformation.getOwnedKey());
}
+ public static @NonNull Iterable<@NonNull OCLExpression> getOwnedMembers(@NonNull CollectionTemplateExp rCollectionTemplateExp) {
+ return ClassUtil.nullFree(rCollectionTemplateExp.getMember());
+ }
+
+ public static @NonNull Iterable<@NonNull PropertyTemplateItem> getOwnedParts(@NonNull ObjectTemplateExp eObject) {
+ return ClassUtil.nullFree(eObject.getPart());
+ }
+
public static @NonNull Iterable<@NonNull DomainPattern> getOwnedPatterns(@NonNull RelationDomain rRelationDomain) {
return ClassUtil.nullFree(rRelationDomain.getPattern());
}
@@ -75,6 +95,18 @@
return Iterables.filter(ClassUtil.nullFree(rTransformation.getRule()), Relation.class);
}
+ public static @NonNull OCLExpression getOwnedValue(@NonNull PropertyTemplateItem rPropertyTemplateItem) {
+ return ClassUtil.nonNullState(rPropertyTemplateItem.getValue());
+ }
+
+ public static @NonNull Iterable<@NonNull Variable> getOwnedVariable(@NonNull Relation rRelation) {
+ return ClassUtil.nullFree(rRelation.getVariable());
+ }
+
+ public static @NonNull Property getReferredProperty(@NonNull PropertyTemplateItem rPropertyTemplateItem) {
+ return ClassUtil.nonNullState(rPropertyTemplateItem.getReferredProperty());
+ }
+
public static @NonNull Relation getReferredRelation(@NonNull RelationCallExp rInvocation) {
return ClassUtil.nonNullState(rInvocation.getReferredRelation());
}
diff --git a/plugins/org.eclipse.qvtd.xtext.qvtcore/src/org/eclipse/qvtd/xtext/qvtcore/as2cs/QVTcoreDeclarationVisitor.java b/plugins/org.eclipse.qvtd.xtext.qvtcore/src/org/eclipse/qvtd/xtext/qvtcore/as2cs/QVTcoreDeclarationVisitor.java
index 7d1604f..d8c7429 100644
--- a/plugins/org.eclipse.qvtd.xtext.qvtcore/src/org/eclipse/qvtd/xtext/qvtcore/as2cs/QVTcoreDeclarationVisitor.java
+++ b/plugins/org.eclipse.qvtd.xtext.qvtcore/src/org/eclipse/qvtd/xtext/qvtcore/as2cs/QVTcoreDeclarationVisitor.java
@@ -325,7 +325,7 @@
public ElementCS visitBottomPattern(@NonNull BottomPattern asBottomPattern) {
BottomPatternCS csBottomPattern = context.refreshElement(BottomPatternCS.class, QVTcoreCSPackage.Literals.BOTTOM_PATTERN_CS, asBottomPattern);
csBottomPattern.setPivot(asBottomPattern);
- List<Element> asConstraints = new ArrayList<Element>(asBottomPattern.getAssignment());
+ List<Element> asConstraints = new ArrayList<>(asBottomPattern.getAssignment());
asConstraints.addAll(asBottomPattern.getPredicate());
context.refreshList(csBottomPattern.getOwnedConstraints(), context.visitDeclarations(PredicateOrAssignmentCS.class, asConstraints, null));
context.refreshList(csBottomPattern.getOwnedRealizedVariables(), context.visitDeclarations(RealizedVariableCS.class, asBottomPattern.getRealizedVariable(), null));
@@ -361,13 +361,13 @@
List<Mapping> asMappings = null;
List<Function> asQueries = null;
- List<Transformation> asTransformations = new ArrayList<Transformation>();
+ List<Transformation> asTransformations = new ArrayList<>();
gatherTransformations(asTransformations, asModel.getOwnedPackages());
for (Transformation asTransformation : asTransformations) {
for (Rule asRule : asTransformation.getRule()) {
if (asRule instanceof Mapping) {
if (asMappings == null) {
- asMappings = new ArrayList<Mapping>();
+ asMappings = new ArrayList<>();
}
asMappings.add((Mapping) asRule);
}
@@ -375,7 +375,7 @@
for (Operation asOperation : asTransformation.getOwnedOperations()) {
if (asOperation instanceof Function) {
if (asQueries == null) {
- asQueries = new ArrayList<Function>();
+ asQueries = new ArrayList<>();
}
asQueries.add((Function) asOperation);
}
diff --git a/tests/org.eclipse.qvtd.xtext.qvtrelation.tests/src/org/eclipse/qvtd/xtext/qvtrelation/tests/pn2sc/PetriNet2StateChart.qvtr b/tests/org.eclipse.qvtd.xtext.qvtrelation.tests/src/org/eclipse/qvtd/xtext/qvtrelation/tests/pn2sc/PetriNet2StateChart.qvtr
index 34cea4d..af8e2ad 100644
--- a/tests/org.eclipse.qvtd.xtext.qvtrelation.tests/src/org/eclipse/qvtd/xtext/qvtrelation/tests/pn2sc/PetriNet2StateChart.qvtr
+++ b/tests/org.eclipse.qvtd.xtext.qvtrelation.tests/src/org/eclipse/qvtd/xtext/qvtrelation/tests/pn2sc/PetriNet2StateChart.qvtr
@@ -68,22 +68,25 @@
}
} */
- top relation Transition2HyperEdge { -- no need to do both bidirectionals
- postps: OrderedSet(pnMM::Place);
- rnexts: OrderedSet(scMM::Basic);
+ top relation Transition2HyperEdge {
domain pn t : Transition {
- name = transitionName : String{},
--- prep = preps:OrderedSet(Place){prep:Place{} ++ _},
- postp = postps:OrderedSet(Place){postp:Place{} ++ _}
+ name = transitionName : String{}
};
enforce domain sc e : HyperEdge {
- name = transitionName,
--- next = nexts:OrderedSet(State){next:State{} ++ _},
- rnext = rnexts:OrderedSet(State){rnext:State{} ++ _}
+ name = transitionName
+ };
+ }
+
+ top relation Transition2HyperEdge_Content { -- no need to do both bidirectionals
+ domain pn postp:Place {
+ pret = t:Transition{}
+ };
+ enforce domain sc rnext:State {
+ rnext = e:HyperEdge{}
};
when {
--- Place2Basic(prep, next);
Place2Basic(postp, rnext);
+ Transition2HyperEdge(t, e);
}
}