diff options
author | Ed Willink | 2019-04-26 17:19:17 +0000 |
---|---|---|
committer | Ed Willink | 2019-04-26 17:19:17 +0000 |
commit | 4fa7b38387bd9cfc8ca0e827c2984752ec402932 (patch) | |
tree | 40f7a4f4e68141de3933a2ea07680b9b23b0655f | |
parent | f12b7d232fe1cfc73c0d6562b55f77755ab1595d (diff) | |
download | org.eclipse.qvtd-4fa7b38387bd9cfc8ca0e827c2984752ec402932.tar.gz org.eclipse.qvtd-4fa7b38387bd9cfc8ca0e827c2984752ec402932.tar.xz org.eclipse.qvtd-4fa7b38387bd9cfc8ca0e827c2984752ec402932.zip |
[546596] Eliminate type-based QVTScheduleUtil.conformsTo
13 files changed, 120 insertions, 96 deletions
diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtb2qvts/AbstractScheduleManager.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtb2qvts/AbstractScheduleManager.java index 77f710abf..9e99a3389 100644 --- a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtb2qvts/AbstractScheduleManager.java +++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtb2qvts/AbstractScheduleManager.java @@ -74,6 +74,7 @@ import org.eclipse.qvtd.pivot.qvtbase.utilities.TraceHelper; import org.eclipse.qvtd.pivot.qvtcore.analysis.DomainUsageAnalysis; import org.eclipse.qvtd.pivot.qvtcore.analysis.RootDomainUsageAnalysis; import org.eclipse.qvtd.pivot.qvtschedule.ClassDatum; +import org.eclipse.qvtd.pivot.qvtschedule.CollectionClassDatum; import org.eclipse.qvtd.pivot.qvtschedule.ConnectionRole; import org.eclipse.qvtd.pivot.qvtschedule.Edge; import org.eclipse.qvtd.pivot.qvtschedule.EdgeConnection; @@ -440,6 +441,21 @@ public abstract class AbstractScheduleManager implements ScheduleManager } @Override + public boolean computeIsPartial(@NonNull Node targetNode, @NonNull Property property) { + ClassDatum targetClassDatum = QVTscheduleUtil.getClassDatum(targetNode); + ClassDatum propertyClassDatum = getClassDatum(property); + if (!QVTscheduleUtil.conformsTo(targetClassDatum, propertyClassDatum)) { + if (propertyClassDatum instanceof CollectionClassDatum) { + ClassDatum elementClassDatum = QVTscheduleUtil.getElementalClassDatum((CollectionClassDatum)propertyClassDatum); + if (QVTscheduleUtil.conformsTo(targetClassDatum, elementClassDatum)) { + return true; + } + } + } + return false; + } + + @Override public @NonNull ConnectionManager createConnectionManager(@NonNull ProblemHandler problemHandler, @NonNull LoadingRegionAnalysis loadingRegionAnalysis) { this.connectionManager = new ConnectionManager(problemHandler, this, loadingRegionAnalysis); return connectionManager; diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtb2qvts/ExpressionSynthesizer.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtb2qvts/ExpressionSynthesizer.java index 61181ac1d..8344630e9 100644 --- a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtb2qvts/ExpressionSynthesizer.java +++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtb2qvts/ExpressionSynthesizer.java @@ -288,14 +288,14 @@ public abstract class ExpressionSynthesizer extends AbstractExtendingQVTbaseVisi return context.createNavigationEdge(sourceNode, source2targetProperty, targetNode, false); } - protected @NonNull NavigableEdge createNavigationEdge(@NonNull Node sourceNode, @NonNull Property source2targetProperty, @NonNull Node targetNode, @Nullable Boolean isPartial) { + protected @NonNull NavigableEdge createNavigationEdge(@NonNull Node sourceNode, @NonNull Property source2targetProperty, @NonNull Node targetNode, boolean isPartial) { return context.createNavigationEdge(sourceNode, source2targetProperty, targetNode, isPartial); } protected @NonNull NavigableEdge createNavigationOrRealizedEdge(@NonNull Node sourceNode, @NonNull Property source2targetProperty, @NonNull Node targetNode, @Nullable NavigationAssignment navigationAssignment) { NavigableEdge navigationEdge = sourceNode.getNavigableEdge(source2targetProperty); assert navigationEdge == null; - Boolean isPartial = navigationAssignment != null ? navigationAssignment.isIsPartial() : null; + boolean isPartial = navigationAssignment != null ? navigationAssignment.isIsPartial() : scheduleManager.computeIsPartial(targetNode, source2targetProperty); if ((navigationAssignment != null) || context.isPropertyAssignment(sourceNode, source2targetProperty)) { navigationEdge = createRealizedNavigationEdge(sourceNode, source2targetProperty, targetNode, isPartial); } @@ -352,7 +352,7 @@ public abstract class ExpressionSynthesizer extends AbstractExtendingQVTbaseVisi return context.createRealizedDataTypeNode(sourceNode, source2targetProperty); } - protected @NonNull NavigableEdge createRealizedNavigationEdge(@NonNull Node sourceNode, @NonNull Property source2targetProperty, @NonNull Node targetNode, @Nullable Boolean isPartial) { + protected @NonNull NavigableEdge createRealizedNavigationEdge(@NonNull Node sourceNode, @NonNull Property source2targetProperty, @NonNull Node targetNode, boolean isPartial) { return context.createRealizedNavigationEdge(sourceNode, source2targetProperty, targetNode, isPartial); } @@ -928,23 +928,24 @@ public abstract class ExpressionSynthesizer extends AbstractExtendingQVTbaseVisi // if ((operationCallExp.getOwnedSource() instanceof CallExp) && sourceNode.refineClassDatumAnalysis(scheduler.getClassDatumAnalysis(operationCallExp))) { // return sourceNode; // } - Type castType = QVTbaseUtil.getType(operationCallExp); + ClassDatum castClassDatum = scheduleManager.getClassDatum(operationCallExp); boolean castIsRequired = operationCallExp.isIsRequired(); // ClassDatum requiredClassDatum = environmentFactory.getCompleteModel().getCompleteClass(castType); ClassDatum predicatedClassDatum = QVTscheduleUtil.getClassDatum(sourceNode); boolean sourceIsRequired = sourceNode.isRequired(); - if (QVTscheduleUtil.conformsTo(predicatedClassDatum, castType) && (sourceIsRequired || !castIsRequired)) { + if (QVTscheduleUtil.conformsTo(predicatedClassDatum, castClassDatum) && (sourceIsRequired || !castIsRequired)) { sourceNode.addOriginatingElement(operationCallExp); return sourceNode; // Skip cast if already conformant, typically a redundant cast daisy chain } for (@NonNull NavigableEdge castEdge : sourceNode.getCastEdges()) { Node targetNode = castEdge.getEdgeTarget(); predicatedClassDatum = QVTscheduleUtil.getClassDatum(targetNode); - if (QVTscheduleUtil.conformsTo(predicatedClassDatum, castType)) { + if (QVTscheduleUtil.conformsTo(predicatedClassDatum, castClassDatum)) { targetNode.addOriginatingElement(operationCallExp); return targetNode; // Re-use a pre-existing class } } + Type castType = QVTbaseUtil.getType(operationCallExp); Property castProperty = scheduleManager.getCastProperty(castType); Edge castEdge = sourceNode.getPredicateEdge(castProperty); if (castEdge != null) { @@ -1166,8 +1167,8 @@ public abstract class ExpressionSynthesizer extends AbstractExtendingQVTbaseVisi assert initNode != null; Type type = QVTbaseUtil.getType(ownedVariable); ClassDatum actualClassDatum = QVTscheduleUtil.getClassDatum(initNode); - Type requiredType = QVTbaseUtil.getType(ownedVariable); - if (QVTscheduleUtil.conformsTo(actualClassDatum, requiredType)) { + ClassDatum variableClassDatum = scheduleManager.getClassDatum(ownedVariable); + if (QVTscheduleUtil.conformsTo(actualClassDatum, variableClassDatum)) { context.getRegion().addVariableNode(ownedVariable, initNode); initNode.setOriginatingVariable(ownedVariable); } diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtb2qvts/RegionHelper.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtb2qvts/RegionHelper.java index 6e7a88e78..8cf46b0c0 100644 --- a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtb2qvts/RegionHelper.java +++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtb2qvts/RegionHelper.java @@ -433,12 +433,12 @@ public class RegionHelper<R extends Region> extends QVTscheduleUtil implements N return mergedPartition; } - public @NonNull NavigableEdge createNavigationEdge(@NonNull Node sourceNode, @NonNull Property source2targetProperty, @NonNull Node targetNode, @Nullable Boolean isPartial) { + public @NonNull NavigableEdge createNavigationEdge(@NonNull Node sourceNode, @NonNull Property source2targetProperty, @NonNull Node targetNode, boolean isPartial) { Role phase = mergeToLessKnownPhase(getNodeRole(sourceNode), getNodeRole(targetNode)); return createNavigationEdge(phase, sourceNode, source2targetProperty, targetNode, isPartial); } - public @NonNull NavigableEdge createNavigationEdge(@NonNull Role edgeRole, @NonNull Node sourceNode, @NonNull Property source2targetProperty, @NonNull Node targetNode, @Nullable Boolean isPartial) { + public @NonNull NavigableEdge createNavigationEdge(@NonNull Role edgeRole, @NonNull Node sourceNode, @NonNull Property source2targetProperty, @NonNull Node targetNode, boolean isPartial) { NavigationEdge edge = QVTscheduleFactory.eINSTANCE.createNavigationEdge(); edge.initialize(edgeRole, sourceNode, source2targetProperty.getName(), targetNode); edge.initializeProperty(source2targetProperty, isPartial); @@ -572,13 +572,14 @@ public class RegionHelper<R extends Region> extends QVTscheduleUtil implements N return edge; } - public @NonNull NavigableEdge createPredicatedNavigationEdge(@NonNull Node sourceNode, @NonNull Property source2targetProperty, @NonNull Node targetNode, @Nullable Boolean isPartial) { + /* public @NonNull NavigableEdge createPredicatedNavigationEdge(@NonNull Node sourceNode, @NonNull Property source2targetProperty, @NonNull Node targetNode, @Nullable Boolean isPartial) { Role edgeRole = Role.PREDICATED; NavigationEdge forwardEdge = QVTscheduleFactory.eINSTANCE.createNavigationEdge(); forwardEdge.initialize(edgeRole, sourceNode, source2targetProperty.getName(), targetNode); - forwardEdge.initializeProperty(source2targetProperty, isPartial); + boolean isPartial2 = QVTscheduleUtil.computeIsPartial(QVTscheduleUtil.getClassDatum(QVTscheduleUtil.getTargetNode(forwardEdge)), source2targetProperty, isPartial); + forwardEdge.initializeProperty(source2targetProperty, isPartial2); return forwardEdge; - } + } */ public @NonNull Node createPredicatedNode(@NonNull String name, @NonNull ClassDatum classDatum, boolean isMatched) { PatternTypedNode node = QVTscheduleFactory.eINSTANCE.createPatternTypedNode(); @@ -616,7 +617,7 @@ public class RegionHelper<R extends Region> extends QVTscheduleUtil implements N return edge; } - public @NonNull NavigableEdge createRealizedNavigationEdge(@NonNull Node sourceNode, @NonNull Property source2targetProperty, @NonNull Node targetNode, @Nullable Boolean isPartial) { + public @NonNull NavigableEdge createRealizedNavigationEdge(@NonNull Node sourceNode, @NonNull Property source2targetProperty, @NonNull Node targetNode, boolean isPartial) { Role edgeRole = Role.REALIZED; NavigationEdge forwardEdge = QVTscheduleFactory.eINSTANCE.createNavigationEdge(); forwardEdge.initialize(edgeRole, sourceNode, source2targetProperty.getName(), targetNode); diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtb2qvts/ScheduleManager.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtb2qvts/ScheduleManager.java index 5c3f833dd..e246e986f 100644 --- a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtb2qvts/ScheduleManager.java +++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtb2qvts/ScheduleManager.java @@ -87,6 +87,13 @@ public interface ScheduleManager @Nullable ConnectionManager basicGetConnectionManager(); @Nullable Property basicGetGlobalSuccessProperty(@NonNull Node node); @Nullable Property basicGetLocalSuccessProperty(@NonNull Node node); + + /** + * Return true if targetNode is one rather than all of the elements computed by the property navigation to targetNode. + * + * FIXME Many calls to this are lazy; cannot possibly be partial. + */ + boolean computeIsPartial(@NonNull Node targetNode, @NonNull Property property); @NonNull ConnectionManager createConnectionManager(@NonNull ProblemHandler problemHandler, @NonNull LoadingRegionAnalysis loadingRegionAnalysis); @NonNull ExpressionSynthesizer createExpressionSynthesizer(@NonNull RuleAnalysis ruleAnalysis); @NonNull RuleAnalysis createRuleAnalysis(@NonNull AbstractTransformationAnalysis transformationAnalysis, @NonNull Rule asRule); diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtm2qvts/MappingAnalysis.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtm2qvts/MappingAnalysis.java index 20632183a..528b26716 100644 --- a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtm2qvts/MappingAnalysis.java +++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtm2qvts/MappingAnalysis.java @@ -581,9 +581,10 @@ public class MappingAnalysis extends RuleAnalysis } } */ ClassDatum initClassDatum = QVTscheduleUtil.getClassDatum(bestInitNode); - Type variableType = PivotUtil.getType(variable); - if (!QVTscheduleUtil.conformsTo(initClassDatum, variableType)) { + ClassDatum variableClassDatum = scheduleManager.getClassDatum(variable); + if (!QVTscheduleUtil.conformsTo(initClassDatum, variableClassDatum)) { Node castNode = createOldNode(variable); + Type variableType = PivotUtil.getType(variable); Property castProperty = scheduleManager.getCastProperty(variableType); expressionSynthesizer.createCastEdge(bestInitNode, castProperty, castNode); bestInitNode = castNode; diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvts/AbstractInvocationAnalysis.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvts/AbstractInvocationAnalysis.java index d005da6a4..73c840ccb 100644 --- a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvts/AbstractInvocationAnalysis.java +++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvts/AbstractInvocationAnalysis.java @@ -89,7 +89,8 @@ public abstract class AbstractInvocationAnalysis implements InvocationAnalysis RelationAnalysis2TraceClass invokingRuleAnalysis2TraceClass = invokingRuleAnalysis2TraceGroup.getRuleAnalysis2TraceClass(); Invocation2TraceProperty invokingInvocation2TraceProperty = invokingRuleAnalysis2TraceClass.getInvocation2TraceProperty(this); Property invocationTraceProperty = invokingInvocation2TraceProperty.getTraceProperty(); - invokingRelationAnalysis.createRealizedNavigationEdge(invokingTraceNode, invocationTraceProperty, invokedNode, null); + boolean isPartial = scheduleManager.computeIsPartial(invokedNode, invocationTraceProperty); + invokingRelationAnalysis.createRealizedNavigationEdge(invokingTraceNode, invocationTraceProperty, invokedNode, isPartial); } /** diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvts/AbstractWhenInvocationAnalysis.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvts/AbstractWhenInvocationAnalysis.java index 62f206e0b..95c244f4d 100644 --- a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvts/AbstractWhenInvocationAnalysis.java +++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvts/AbstractWhenInvocationAnalysis.java @@ -41,7 +41,7 @@ public abstract class AbstractWhenInvocationAnalysis extends AbstractInvocationA @Override protected @NonNull NavigableEdge createInputEdge(@NonNull Node invokedNode, @NonNull Property invocationProperty, @NonNull Node argumentNode) { - return invokingRelationAnalysis.createNavigationEdge(Role.PREDICATED, invokedNode, invocationProperty, argumentNode, null); + return invokingRelationAnalysis.createNavigationEdge(Role.PREDICATED, invokedNode, invocationProperty, argumentNode, false); } @Override @@ -56,7 +56,7 @@ public abstract class AbstractWhenInvocationAnalysis extends AbstractInvocationA @Override protected @NonNull NavigableEdge createOutputEdge(@NonNull Node invokedNode, @NonNull Property invocationProperty, @NonNull Node argumentNode) { - return invokingRelationAnalysis.createNavigationEdge(Role.PREDICATED, invokedNode, invocationProperty, argumentNode, null); + return invokingRelationAnalysis.createNavigationEdge(Role.PREDICATED, invokedNode, invocationProperty, argumentNode, false); } @Override diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvts/NonTopWhereBeforeWhenInvocationAnalysis.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvts/NonTopWhereBeforeWhenInvocationAnalysis.java index 536b59a5d..eca88e40c 100644 --- a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvts/NonTopWhereBeforeWhenInvocationAnalysis.java +++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvts/NonTopWhereBeforeWhenInvocationAnalysis.java @@ -30,7 +30,7 @@ public class NonTopWhereBeforeWhenInvocationAnalysis extends AbstractInvocationA @Override protected @NonNull NavigableEdge createInputEdge(@NonNull Node invokedNode, @NonNull Property invocationProperty, @NonNull Node argumentNode) { - return invokingRelationAnalysis.createNavigationEdge(Role.REALIZED, invokedNode, invocationProperty, argumentNode, null); + return invokingRelationAnalysis.createNavigationEdge(Role.REALIZED, invokedNode, invocationProperty, argumentNode, false); } @Override @@ -44,7 +44,7 @@ public class NonTopWhereBeforeWhenInvocationAnalysis extends AbstractInvocationA @Override protected @NonNull NavigableEdge createOutputEdge(@NonNull Node invokedNode, @NonNull Property invocationProperty, @NonNull Node argumentNode) { - return invokingRelationAnalysis.createNavigationEdge(Role.REALIZED, invokedNode, invocationProperty, argumentNode, null); + return invokingRelationAnalysis.createNavigationEdge(Role.REALIZED, invokedNode, invocationProperty, argumentNode, false); } /* @Override diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvts/NonTopWhereOnlyInvocationAnalysis.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvts/NonTopWhereOnlyInvocationAnalysis.java index 88085f13d..eb5663dfa 100644 --- a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvts/NonTopWhereOnlyInvocationAnalysis.java +++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvts/NonTopWhereOnlyInvocationAnalysis.java @@ -30,7 +30,7 @@ public class NonTopWhereOnlyInvocationAnalysis extends AbstractInvocationAnalysi @Override protected @NonNull NavigableEdge createInputEdge(@NonNull Node invokedNode, @NonNull Property invocationProperty, @NonNull Node argumentNode) { - return invokingRelationAnalysis.createNavigationEdge(Role.REALIZED, invokedNode, invocationProperty, argumentNode, null); + return invokingRelationAnalysis.createNavigationEdge(Role.REALIZED, invokedNode, invocationProperty, argumentNode, false); } @Override @@ -44,7 +44,7 @@ public class NonTopWhereOnlyInvocationAnalysis extends AbstractInvocationAnalysi @Override protected @NonNull NavigableEdge createOutputEdge(@NonNull Node invokedNode, @NonNull Property invocationProperty, @NonNull Node argumentNode) { - return invokingRelationAnalysis.createNavigationEdge(Role.REALIZED, invokedNode, invocationProperty, argumentNode, null); + return invokingRelationAnalysis.createNavigationEdge(Role.REALIZED, invokedNode, invocationProperty, argumentNode, false); } /* @Override diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvts/RelationAnalysis.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvts/RelationAnalysis.java index c93f6cb4d..edaa14efd 100644 --- a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvts/RelationAnalysis.java +++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvts/RelationAnalysis.java @@ -24,7 +24,6 @@ import org.eclipse.ocl.pivot.OCLExpression; 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.Variable; import org.eclipse.ocl.pivot.VariableDeclaration; import org.eclipse.ocl.pivot.VariableExp; @@ -160,7 +159,8 @@ public class RelationAnalysis extends RuleAnalysis Property traceClassProperty = variableDeclaration2traceClassProperty.getTraceProperty(); // Property traceInterfaceProperty = variableDeclaration2traceInterfaceProperty.getTraceProperty(); Node targetNode = createOldNode(variable); - createNavigationEdge(traceNode, traceClassProperty, targetNode, null); + boolean isPartial = scheduleManager.computeIsPartial(targetNode, traceClassProperty); + createNavigationEdge(traceNode, traceClassProperty, targetNode, isPartial); if (isTopLevel) { region.getHeadNodes().add(targetNode); targetNode.setHead(); @@ -1363,21 +1363,23 @@ public class RelationAnalysis extends RuleAnalysis Variable targetVariable = QVTrelationUtil.getBindsTo((CollectionTemplateExp) targetExpression); Node targetNode = region.getNode(targetVariable); if (targetNode != null) { + boolean isPartial = scheduleManager.computeIsPartial(targetNode, source2targetProperty); if (scheduleManager.getDomainUsage(sourceVariable).isOutput() /*&& !propertyTemplateItem.isCheckOnly()*/) { - createRealizedNavigationEdge(sourceNode, source2targetProperty, targetNode, null); + createRealizedNavigationEdge(sourceNode, source2targetProperty, targetNode, isPartial); } else { - createNavigationEdge(sourceNode, source2targetProperty, targetNode, null); + createNavigationEdge(sourceNode, source2targetProperty, targetNode, isPartial); } } } else { Node targetNode = expressionSynthesizer.synthesize(targetExpression); + boolean isPartial = scheduleManager.computeIsPartial(targetNode, source2targetProperty); if (scheduleManager.getDomainUsage(sourceVariable).isOutput() /*&& !propertyTemplateItem.isCheckOnly()*/) { - createRealizedNavigationEdge(sourceNode, source2targetProperty, targetNode, null); + createRealizedNavigationEdge(sourceNode, source2targetProperty, targetNode, isPartial); } else { - createNavigationEdge(sourceNode, source2targetProperty, targetNode, null); + createNavigationEdge(sourceNode, source2targetProperty, targetNode, isPartial); } } return targetExpression; @@ -1470,7 +1472,8 @@ public class RelationAnalysis extends RuleAnalysis Node rootVariableNode = getReferenceNode(rootVariable); VariableDeclaration overridingRootVariable = QVTrelationUtil.getOverriddenVariable(overridingRelation, rootVariable); Property invocationProperty = overridingRelationAnalysis2TraceInterface.getTraceProperty(overridingRootVariable); - createNavigationEdge(guardNode, invocationProperty, rootVariableNode, null); + boolean isPartial = scheduleManager.computeIsPartial(rootVariableNode, invocationProperty); + createNavigationEdge(guardNode, invocationProperty, rootVariableNode, isPartial); } } } @@ -1668,11 +1671,12 @@ public class RelationAnalysis extends RuleAnalysis // VariableDeclaration tracedVariable = overridingVariableDeclaration2traceProperty.getOverridingVariable(); Node targetNode = region.getNode(rootVariable); assert targetNode != null; + boolean isPartial = scheduleManager.computeIsPartial(dispatchNode, traceProperty); if (isInput) { - createNavigationEdge(dispatchNode, traceProperty, targetNode, null); + createNavigationEdge(dispatchNode, traceProperty, targetNode, isPartial); } else { - createRealizedNavigationEdge(dispatchNode, traceProperty, targetNode, null); + createRealizedNavigationEdge(dispatchNode, traceProperty, targetNode, isPartial); } } } @@ -1686,7 +1690,8 @@ public class RelationAnalysis extends RuleAnalysis Node targetNode = region.getNode(tracedVariable); assert targetNode != null; if (!rootVariables.contains(tracedVariable)) { - createRealizedNavigationEdge(traceNode, traceProperty, targetNode, null); + boolean isPartial = scheduleManager.computeIsPartial(targetNode, traceProperty); + createRealizedNavigationEdge(traceNode, traceProperty, targetNode, isPartial); } } } @@ -1699,11 +1704,12 @@ public class RelationAnalysis extends RuleAnalysis VariableDeclaration tracedVariable = variableDeclaration2traceProperty.getOverridingVariable(); Node targetNode = region.getNode(tracedVariable); assert targetNode != null; + boolean isPartial = scheduleManager.computeIsPartial(traceNode, traceProperty); if (hasPredicatedTrace && rootVariables.contains(tracedVariable)) { - createNavigationEdge(traceNode, traceProperty, targetNode, null); + createNavigationEdge(traceNode, traceProperty, targetNode, isPartial); } else { - createRealizedNavigationEdge(traceNode, traceProperty, targetNode, null); + createRealizedNavigationEdge(traceNode, traceProperty, targetNode, isPartial); } } } diff --git a/plugins/org.eclipse.qvtd.pivot.qvtschedule/emf-gen/org/eclipse/qvtd/pivot/qvtschedule/NavigationEdge.java b/plugins/org.eclipse.qvtd.pivot.qvtschedule/emf-gen/org/eclipse/qvtd/pivot/qvtschedule/NavigationEdge.java index 42f1e4950..739eb3edd 100644 --- a/plugins/org.eclipse.qvtd.pivot.qvtschedule/emf-gen/org/eclipse/qvtd/pivot/qvtschedule/NavigationEdge.java +++ b/plugins/org.eclipse.qvtd.pivot.qvtschedule/emf-gen/org/eclipse/qvtd/pivot/qvtschedule/NavigationEdge.java @@ -15,7 +15,6 @@ package org.eclipse.qvtd.pivot.qvtschedule; import org.eclipse.jdt.annotation.NonNull; -import org.eclipse.jdt.annotation.Nullable; import org.eclipse.ocl.pivot.Property; /** @@ -91,5 +90,5 @@ public interface NavigationEdge extends NavigableEdge { */ void setReferredProperty(Property value); - void initializeProperty(@NonNull Property property, @Nullable Boolean isPartial); + void initializeProperty(@NonNull Property property, boolean isPartial); } // NavigationEdge diff --git a/plugins/org.eclipse.qvtd.pivot.qvtschedule/emf-gen/org/eclipse/qvtd/pivot/qvtschedule/impl/NavigationEdgeImpl.java b/plugins/org.eclipse.qvtd.pivot.qvtschedule/emf-gen/org/eclipse/qvtd/pivot/qvtschedule/impl/NavigationEdgeImpl.java index 79d0253bc..57bdb9c33 100644 --- a/plugins/org.eclipse.qvtd.pivot.qvtschedule/emf-gen/org/eclipse/qvtd/pivot/qvtschedule/impl/NavigationEdgeImpl.java +++ b/plugins/org.eclipse.qvtd.pivot.qvtschedule/emf-gen/org/eclipse/qvtd/pivot/qvtschedule/impl/NavigationEdgeImpl.java @@ -14,6 +14,8 @@ */ package org.eclipse.qvtd.pivot.qvtschedule.impl; +import java.util.List; + import org.eclipse.emf.common.notify.Notification; import org.eclipse.emf.ecore.EClass; @@ -22,6 +24,7 @@ import org.eclipse.emf.ecore.impl.ENotificationImpl; 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.internal.ElementImpl; @@ -132,6 +135,7 @@ public class NavigationEdgeImpl extends NavigableEdgeImpl implements NavigationE */ @Override public void setPartial(boolean newPartial) { + checkIsPartial(newPartial); boolean oldPartial = partial; partial = newPartial; if (eNotificationRequired()) @@ -262,6 +266,43 @@ public class NavigationEdgeImpl extends NavigableEdgeImpl implements NavigationE return (R) ((QVTscheduleVisitor<?>)visitor).visitNavigationEdge(this); } + private void checkIsPartial(boolean isPartial) { + Node targetNode = QVTscheduleUtil.getTargetNode(this); + ClassDatum targetClassDatum = QVTscheduleUtil.getClassDatum(targetNode); + Property property = QVTscheduleUtil.getProperty(this); + boolean isComputedPartial = false; + Type propertyTargetType = PivotUtil.getType(property); + if (!conformsTo(targetClassDatum, propertyTargetType)) { + if (propertyTargetType instanceof CollectionType) { + Type elementType = PivotUtil.getElementType(((CollectionType)propertyTargetType)); + if (conformsTo(targetClassDatum, elementType)) { + isComputedPartial = true; + } + } + } + assert isPartial == isComputedPartial; + } + + /** + * Return true if thisClassDatum conforms to, i.e can be used as, thatType. + * + * If the ClassDatum is a multi-CompleteClass it is sufficient that any one of thisClassDatum's CompleteClasses conforms to thatType. + * + * This provate version of QVTscheduleUtil.comformsTo worksound the lack of access to a scheduleManager tyo create the property's CompleteClass. + */ + private boolean conformsTo(@NonNull ClassDatum thisClassDatum, @NonNull Type thatType) { + List<@NonNull CompleteClass> theseCompleteClasses = thisClassDatum.basicGetCompleteClasses(); + if (theseCompleteClasses == null) { + return false; + } + for (@NonNull CompleteClass thisCompleteClass : theseCompleteClasses) { + if (thisCompleteClass.conformsTo(thatType)) { + return true; + } + } + return false; + } + @Override public @NonNull NavigableEdge createEdge(@NonNull Role edgeRole, @NonNull Node sourceNode, @NonNull Node targetNode) { NavigationEdge edge = (NavigationEdge)super.createEdge(edgeRole, sourceNode, targetNode); @@ -284,28 +325,8 @@ public class NavigationEdgeImpl extends NavigableEdgeImpl implements NavigationE return getReferredProperty(); } - private void initializeIsPartial(@Nullable Boolean isPartial) { - boolean isComputedPartial = false; - Type propertyTargetType = PivotUtil.getType(QVTscheduleUtil.getProperty(this)); - Node targetNode = QVTscheduleUtil.getTargetNode(this); - ClassDatum targetClassDatum = QVTscheduleUtil.getClassDatum(targetNode); - if (!QVTscheduleUtil.conformsTo(targetClassDatum, propertyTargetType)) { - if (propertyTargetType instanceof CollectionType) { - Type elementType = PivotUtil.getElementType(((CollectionType)propertyTargetType)); - if (QVTscheduleUtil.conformsTo(targetClassDatum, elementType)) { - isComputedPartial = true; - } - } - } - if (isPartial == null) { - isPartial = isComputedPartial; - } - assert isPartial == isComputedPartial; - setPartial(isPartial); - } - @Override - public void initializeProperty(@NonNull Property property, @Nullable Boolean isPartial) { + public void initializeProperty(@NonNull Property property, boolean isPartial) { setReferredProperty(property); Property target2sourceProperty = property.getOpposite(); if (target2sourceProperty != null) { @@ -322,12 +343,12 @@ public class NavigationEdgeImpl extends NavigableEdgeImpl implements NavigationE NavigationEdge reverseEdge = QVTscheduleFactory.eINSTANCE.createNavigationEdge(); reverseEdge.initialize(edgeRole2, targetNode2, target2sourceProperty.getName(), sourceNode2); reverseEdge.setReferredProperty(target2sourceProperty); - ((NavigationEdgeImpl)reverseEdge).initializeIsPartial(isPartial()); + reverseEdge.setPartial(isPartial()); initializeOpposite(reverseEdge); } } } - initializeIsPartial(isPartial); + setPartial(isPartial); } @Override diff --git a/plugins/org.eclipse.qvtd.pivot.qvtschedule/src/org/eclipse/qvtd/pivot/qvtschedule/utilities/QVTscheduleUtil.java b/plugins/org.eclipse.qvtd.pivot.qvtschedule/src/org/eclipse/qvtd/pivot/qvtschedule/utilities/QVTscheduleUtil.java index 097b9ea9e..06d35e3b0 100644 --- a/plugins/org.eclipse.qvtd.pivot.qvtschedule/src/org/eclipse/qvtd/pivot/qvtschedule/utilities/QVTscheduleUtil.java +++ b/plugins/org.eclipse.qvtd.pivot.qvtschedule/src/org/eclipse/qvtd/pivot/qvtschedule/utilities/QVTscheduleUtil.java @@ -20,10 +20,8 @@ import java.util.function.BinaryOperator; import org.eclipse.emf.ecore.EObject; import org.eclipse.jdt.annotation.NonNull; import org.eclipse.jdt.annotation.Nullable; -import org.eclipse.ocl.pivot.Class; import org.eclipse.ocl.pivot.CollectionType; import org.eclipse.ocl.pivot.CompleteClass; -import org.eclipse.ocl.pivot.DataType; import org.eclipse.ocl.pivot.Element; import org.eclipse.ocl.pivot.IfExp; import org.eclipse.ocl.pivot.LoopExp; @@ -44,6 +42,7 @@ import org.eclipse.qvtd.pivot.qvtbase.utilities.QVTbaseUtil; import org.eclipse.qvtd.pivot.qvtschedule.RuleRegion; import org.eclipse.qvtd.pivot.qvtschedule.BasicPartition; import org.eclipse.qvtd.pivot.qvtschedule.ClassDatum; +import org.eclipse.qvtd.pivot.qvtschedule.CollectionClassDatum; import org.eclipse.qvtd.pivot.qvtschedule.CompositePartition; import org.eclipse.qvtd.pivot.qvtschedule.Connection; import org.eclipse.qvtd.pivot.qvtschedule.ConnectionEnd; @@ -454,24 +453,6 @@ public class QVTscheduleUtil extends QVTscheduleConstants return false; } - /** - * Return true if thisClassDatum conforms to, i.e can be used as, thatType. - * - * If the ClassDatum is a multi-CompleteClass it is sufficient that any one of thisClassDatum's CompleteClasses conforms to thatType. - */ - public static boolean conformsTo(@NonNull ClassDatum thisClassDatum, @NonNull Type thatType) { - List<@NonNull CompleteClass> theseCompleteClasses = thisClassDatum.basicGetCompleteClasses(); - if (theseCompleteClasses == null) { - return false; - } - for (@NonNull CompleteClass thisCompleteClass : theseCompleteClasses) { - if (thisCompleteClass.conformsTo(thatType)) { - return true; - } - } - return false; - } - public static boolean conformsTo(@NonNull CompleteClass thisCompleteClass, @NonNull ClassDatum thatClassDatum) { List<@NonNull CompleteClass> thoseCompleteClasses = thatClassDatum.basicGetCompleteClasses(); if (thoseCompleteClasses == null) { @@ -485,20 +466,6 @@ public class QVTscheduleUtil extends QVTscheduleConstants return true; } - public static boolean conformsToClassOrBehavioralClass(@NonNull ClassDatum thisClassDatum, @NonNull Type thatType) { - if (conformsTo(thisClassDatum, thatType)) { - return true; - } - if (!(thatType instanceof DataType)) { - return false; - } - Class behavioralClass = ((DataType)thatType).getBehavioralClass(); - if (behavioralClass == null) { - return false; - } - return conformsTo(thisClassDatum, behavioralClass); - } - public static boolean conformsToClassOrBehavioralClass(@NonNull CompleteClass thisCompleteClass, @NonNull CompleteClass thatCompleteClass) { return thisCompleteClass.conformsTo(thatCompleteClass) || thisCompleteClass.conformsTo(thatCompleteClass.getBehavioralClass()); } @@ -689,6 +656,10 @@ public class QVTscheduleUtil extends QVTscheduleConstants return ClassUtil.nonNullState(edge.getEdgeRole()); } + public static @NonNull ClassDatum getElementalClassDatum(@NonNull CollectionClassDatum collectionClassDatum) { + return ClassUtil.nonNullState(collectionClassDatum.getElementalClassDatum()); + } + public static @NonNull Iterable<? extends @NonNull Partition> getExplicitPredecessors(@NonNull BasicPartition partition) { return ClassUtil.nullFree(partition.getExplicitPredecessors()); } @@ -1103,8 +1074,8 @@ public class QVTscheduleUtil extends QVTscheduleConstants public static boolean isConformantTarget(@NonNull NavigableEdge thatEdge, @NonNull NavigableEdge thisEdge) { Node thatTarget = getCastTarget(thatEdge.getEdgeTarget()); Node thisTarget = getCastTarget(thisEdge.getEdgeTarget()); - ClassDatum thatType = thatTarget.getClassDatum(); - ClassDatum thisType = thisTarget.getClassDatum(); + ClassDatum thatType = getClassDatum(thatTarget); + ClassDatum thisType = getClassDatum(thisTarget); if (conformsToClassOrBehavioralClass(thatType, thisType)) { return true; } |