Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEd Willink2020-02-23 10:03:57 +0000
committerEd Willink2020-02-25 12:35:13 +0000
commit34098865e729dd0ed0ea6526de9ff2cf2c866d97 (patch)
tree7aa00a6082301523bd3648b22f17c92c49eb31e3
parent7bcb9c8424ef3ebddda9140dba5ad9aa67566751 (diff)
downloadorg.eclipse.qvtd-34098865e729dd0ed0ea6526de9ff2cf2c866d97.tar.gz
org.eclipse.qvtd-34098865e729dd0ed0ea6526de9ff2cf2c866d97.tar.xz
org.eclipse.qvtd-34098865e729dd0ed0ea6526de9ff2cf2c866d97.zip
[560427] detect incompatible root/head usage
-rw-r--r--plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtb2qvts/HeadAnalysis.java2
-rw-r--r--plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtb2qvts/HeadNodeGroup.java13
-rw-r--r--plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtb2qvts/RuleHeadAnalysis.java21
-rw-r--r--plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtb2qvts/trace/TracedHeadAnalysis.java15
-rw-r--r--plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtb2qvts/trace/TracedHeadNodeGroup.java14
-rw-r--r--plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvts/trace/Relation2TraceClass.java23
-rw-r--r--plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvts/trace/Relation2TraceGroup.java4
7 files changed, 63 insertions, 29 deletions
diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtb2qvts/HeadAnalysis.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtb2qvts/HeadAnalysis.java
index 222b40ae4..83c32ba91 100644
--- a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtb2qvts/HeadAnalysis.java
+++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtb2qvts/HeadAnalysis.java
@@ -176,6 +176,8 @@ public abstract class HeadAnalysis
this.mappingRegion = mappingRegion;;
}
+ protected abstract boolean canBeSameGroup(@NonNull Edge source2targetEdge);
+
protected @NonNull List<@NonNull HeadNodeGroup> computeHeadNodeGroups(@NonNull Map<@NonNull Node, @NonNull Set<@NonNull Node>> targetFromSourcesClosure,
@NonNull Map<@NonNull Node, @NonNull Set<@NonNull Node>> sourceToTargetsClosure,
@Nullable List<@NonNull Node> preferredHeadNodes) {
diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtb2qvts/HeadNodeGroup.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtb2qvts/HeadNodeGroup.java
index 654af8d21..1785367fd 100644
--- a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtb2qvts/HeadNodeGroup.java
+++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtb2qvts/HeadNodeGroup.java
@@ -40,6 +40,8 @@ import com.google.common.collect.Iterables;
*/
public abstract class HeadNodeGroup implements Nameable
{
+ protected final @NonNull HeadAnalysis headAnalysis;
+
/**
* The mutually to-one navigable nodes that define the head group.
*/
@@ -50,8 +52,9 @@ public abstract class HeadNodeGroup implements Nameable
*/
private Set<@NonNull Node> uniqueNodes = null;
- public HeadNodeGroup(@NonNull List<@NonNull Node> headGroupNodes) {
+ public HeadNodeGroup(@NonNull HeadAnalysis headAnalysis, @NonNull List<@NonNull Node> headGroupNodes) {
assert !headGroupNodes.isEmpty();
+ this.headAnalysis = headAnalysis;
this.headGroupNodes = headGroupNodes;
}
@@ -61,7 +64,7 @@ public abstract class HeadNodeGroup implements Nameable
boolean gotOne = false;
for (@NonNull Edge source2targetEdge : QVTscheduleUtil.getOutgoingEdges(sourceNode)) {
Node targetNode = QVTscheduleUtil.getTargetNode(source2targetEdge);
- if (targetNode.isUnconditional() && canBeSameGroup(sourceNode, source2targetEdge) && !uniqueNodes.contains(targetNode)) {
+ if (targetNode.isUnconditional() && headAnalysis.canBeSameGroup(source2targetEdge) && !uniqueNodes.contains(targetNode)) {
if (source2targetEdge.isCast()) { // Can happen when analyzing traced heads
uniqueNodes.add(targetNode);
workList.add(targetNode);
@@ -154,8 +157,6 @@ public abstract class HeadNodeGroup implements Nameable
}
}
- protected abstract boolean canBeSameGroup(@NonNull Node sourceNode, @NonNull Edge source2targetEdge);
-
public @NonNull Iterable<@NonNull Node> getHeadNodes() {
return headGroupNodes;
}
@@ -181,6 +182,10 @@ public abstract class HeadNodeGroup implements Nameable
return toOneSet2;
}
+ public @Nullable Iterable<@NonNull Node> getUniqueNodes() {
+ return uniqueNodes != null ? uniqueNodes : getToOneSet();
+ }
+
/**
* Return true if all of the headNodes of this HeadNodeGroup are reachable as to-one nodess of thatHeadNodeGroup.
*/
diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtb2qvts/RuleHeadAnalysis.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtb2qvts/RuleHeadAnalysis.java
index cf22f60a6..f9901c128 100644
--- a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtb2qvts/RuleHeadAnalysis.java
+++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtb2qvts/RuleHeadAnalysis.java
@@ -30,20 +30,14 @@ import org.eclipse.qvtd.pivot.qvtschedule.utilities.QVTscheduleUtil;
import com.google.common.collect.Sets;
/**
- * RuleHeadAnalysis is a helper class to compute the head nodes of a region.
+ * RuleHeadAnalysis is a helper class to compute the head nodes of a region after synthesisfor a chosen direction.
*/
public class RuleHeadAnalysis extends HeadAnalysis
{
protected static final class RuleHeadNodeGroup extends HeadNodeGroup
{
- protected RuleHeadNodeGroup(@NonNull List<@NonNull Node> headGroupNodes) {
- super(headGroupNodes);
- }
-
- @Override
- protected boolean canBeSameGroup(@NonNull Node sourceNode, @NonNull Edge source2targetEdge) {
- boolean isOldSource = sourceNode.isOld();
- return isOldSource ? source2targetEdge.isOld() : true; //source2targetEdge.isNew(); // nonTopWhen my be REALIZED sourceNode and PREDICATED source2targetEdge
+ protected RuleHeadNodeGroup(@NonNull RuleHeadAnalysis ruleHeadAnalysis, @NonNull List<@NonNull Node> headGroupNodes) {
+ super(ruleHeadAnalysis, headGroupNodes);
}
@Override
@@ -85,6 +79,13 @@ public class RuleHeadAnalysis extends HeadAnalysis
}
}
+ @Override
+ protected boolean canBeSameGroup(@NonNull Edge source2targetEdge) {
+ Node sourceNode = QVTscheduleUtil.getSourceNode(source2targetEdge);
+ boolean isOldSource = sourceNode.isOld();
+ return isOldSource ? source2targetEdge.isOld() : true; //source2targetEdge.isNew(); // nonTopWhen my be REALIZED sourceNode and PREDICATED source2targetEdge
+ }
+
private void checkHeadNodeConsistency(@NonNull Iterable<@NonNull Node> headNodes) {
Set<@NonNull Node> debugHeadNodes = new HashSet<>();
for (@NonNull Node node : QVTscheduleUtil.getOwnedNodes(mappingRegion)) {
@@ -175,7 +176,7 @@ public class RuleHeadAnalysis extends HeadAnalysis
@Override
protected @NonNull HeadNodeGroup createHeadNodeGroup(@NonNull List<@NonNull Node> headNodeGroup) {
- return new RuleHeadNodeGroup(headNodeGroup);
+ return new RuleHeadNodeGroup(this, headNodeGroup);
}
private void setHeadNodes(@NonNull Set<@NonNull Node> reachableNodes, @NonNull List<@NonNull Node> headNodes) {
diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtb2qvts/trace/TracedHeadAnalysis.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtb2qvts/trace/TracedHeadAnalysis.java
index f04de3e46..795693d29 100644
--- a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtb2qvts/trace/TracedHeadAnalysis.java
+++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtb2qvts/trace/TracedHeadAnalysis.java
@@ -99,6 +99,17 @@ public class TracedHeadAnalysis extends HeadAnalysis
super(mappingRegion);
}
+ @Override
+ protected boolean canBeSameGroup(@NonNull Edge source2targetEdge) {
+ Node sourceNode = QVTscheduleUtil.getSourceNode(source2targetEdge);
+ Node targetNode = source2targetEdge.getEdgeTarget();
+ TypedModel sourceTypedModel = QVTscheduleUtil.getReferredTypedModel(QVTscheduleUtil.getClassDatum(sourceNode));
+ // assert (typedModel == sourceTypedModel) || sourceTypedModel.isIsPrimitive();
+ TypedModel targetTypedModel = QVTscheduleUtil.getReferredTypedModel(QVTscheduleUtil.getClassDatum(targetNode));
+ // return (typedModel == targetTypedModel) || targetTypedModel.isIsPrimitive();
+ return sourceTypedModel.isIsPrimitive() || targetTypedModel.isIsPrimitive() || (sourceTypedModel== targetTypedModel);
+ }
+
private @NonNull Map<@NonNull Node, @NonNull Set<@NonNull Node>> computeTracedTargetFromSources(@NonNull Set<@NonNull Node> excludedNodes) {
Map<@NonNull Node, @NonNull Set<@NonNull Node>> targetFromSources = new HashMap<>();
for (@NonNull Node targetNode : QVTscheduleUtil.getOwnedNodes(mappingRegion)) {
@@ -113,7 +124,7 @@ public class TracedHeadAnalysis extends HeadAnalysis
}
for (@NonNull Edge edge : QVTscheduleUtil.getIncomingEdges(targetNode)) {
Node sourceNode = edge.getEdgeSource();
- if (!excludedNodes.contains(sourceNode) && !sourceNode.isConditional() && !sourceNode.isConstant()) {
+ if (!excludedNodes.contains(sourceNode) && !sourceNode.isConditional() && !sourceNode.isConstant() && canBeSameGroup(edge)) {
if (edge instanceof NavigationEdge) {
if (!((NavigationEdge)edge).isPartial()) {
sources.add(sourceNode);
@@ -140,6 +151,6 @@ public class TracedHeadAnalysis extends HeadAnalysis
@Override
protected @NonNull HeadNodeGroup createHeadNodeGroup(@NonNull List<@NonNull Node> headNodeGroup) {
- return new TracedHeadNodeGroup(headNodeGroup);
+ return new TracedHeadNodeGroup(this, headNodeGroup);
}
} \ No newline at end of file
diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtb2qvts/trace/TracedHeadNodeGroup.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtb2qvts/trace/TracedHeadNodeGroup.java
index 3a08a6539..ccc56aa3d 100644
--- a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtb2qvts/trace/TracedHeadNodeGroup.java
+++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtb2qvts/trace/TracedHeadNodeGroup.java
@@ -15,7 +15,6 @@ import java.util.List;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.qvtd.compiler.internal.qvtb2qvts.HeadNodeGroup;
import org.eclipse.qvtd.pivot.qvtbase.TypedModel;
-import org.eclipse.qvtd.pivot.qvtschedule.Edge;
import org.eclipse.qvtd.pivot.qvtschedule.Node;
import org.eclipse.qvtd.pivot.qvtschedule.utilities.QVTscheduleUtil;
@@ -28,8 +27,8 @@ public class TracedHeadNodeGroup extends HeadNodeGroup
{
protected final @NonNull TypedModel typedModel;
- public TracedHeadNodeGroup(@NonNull List<@NonNull Node> headGroupNodes) {
- super(headGroupNodes);
+ public TracedHeadNodeGroup(@NonNull TracedHeadAnalysis tracedHeadAnalysis, @NonNull List<@NonNull Node> headGroupNodes) {
+ super(tracedHeadAnalysis, headGroupNodes);
typedModel = QVTscheduleUtil.getReferredTypedModel(QVTscheduleUtil.getClassDatum(headGroupNodes.get(0)));
for (@NonNull Node headGroupNode : headGroupNodes) {
assert typedModel == QVTscheduleUtil.getReferredTypedModel(QVTscheduleUtil.getClassDatum(headGroupNode));
@@ -44,15 +43,6 @@ public class TracedHeadNodeGroup extends HeadNodeGroup
}
@Override
- protected boolean canBeSameGroup(@NonNull Node sourceNode, @NonNull Edge source2targetEdge) {
- Node targetNode = source2targetEdge.getEdgeTarget();
- TypedModel sourceTypedModel = QVTscheduleUtil.getReferredTypedModel(QVTscheduleUtil.getClassDatum(sourceNode));
- assert (typedModel == sourceTypedModel) || sourceTypedModel.isIsPrimitive();
- TypedModel targetTypedModel = QVTscheduleUtil.getReferredTypedModel(QVTscheduleUtil.getClassDatum(targetNode));
- return (typedModel == targetTypedModel) || targetTypedModel.isIsPrimitive();
- }
-
- @Override
public String getName() {
return typedModel.getName();
}
diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvts/trace/Relation2TraceClass.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvts/trace/Relation2TraceClass.java
index fd4f9dc21..6038ebd25 100644
--- a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvts/trace/Relation2TraceClass.java
+++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvts/trace/Relation2TraceClass.java
@@ -127,13 +127,34 @@ public class Relation2TraceClass extends AbstractRelation2MiddleType
} */
protected void analyzePatternNodes(@NonNull List<@NonNull HeadNodeGroup> headNodeGroups, @NonNull RelationAnalysis relationAnalysis) {
- // String name = relation.getName();
+ String name = relation.getName();
+ if ("FtoN2_Daughter2DaughterPlan".equals(name)) {
+ getClass();
+ }
boolean manyTracesPerHead = headNodeGroups.size() > 2;
Set<@NonNull Node> allHeadGroupNodes = new HashSet<>();
for (@NonNull HeadNodeGroup headNodeGroup : headNodeGroups) {
Iterables.addAll(allHeadGroupNodes, headNodeGroup.getHeadNodes());
}
+ boolean compatibleRootVariable = true;
List<@NonNull VariableDeclaration> rootVariables = QVTrelationUtil.getRootVariables(relation);
+ for (@NonNull VariableDeclaration rootVariable : rootVariables) {
+ boolean foundHeadGroup = false;
+ Node rootNode = relationAnalysis.getReferenceNode(rootVariable);
+ for (@NonNull HeadNodeGroup headNodeGroup : headNodeGroups) {
+ if (Iterables.contains(headNodeGroup.getHeadNodes(), rootNode)) {
+ foundHeadGroup = true;
+ }
+ else {
+ Iterable<@NonNull Node> uniqueNodes = headNodeGroup.getUniqueNodes();
+ if ((uniqueNodes != null) && Iterables.contains(uniqueNodes, rootNode)) {
+ foundHeadGroup = true;
+ compatibleRootVariable = false;
+ }
+ }
+ }
+ assert foundHeadGroup;
+ }
for (@NonNull Node node : QVTscheduleUtil.getOwnedNodes(relationAnalysis.getRegion())) {
if (node.isThis()) {
; // Do not trace this
diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvts/trace/Relation2TraceGroup.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvts/trace/Relation2TraceGroup.java
index bbfe76065..fcbccf4cb 100644
--- a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvts/trace/Relation2TraceGroup.java
+++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvts/trace/Relation2TraceGroup.java
@@ -112,6 +112,10 @@ public class Relation2TraceGroup extends Rule2TraceGroup
@Override
public void analyzeTraceElements(@NonNull RuleAnalysis ruleAnalysis, @NonNull Set<@NonNull Node> excludedNodes) throws CompilerChainException {
RelationAnalysis relationAnalysis = (RelationAnalysis)ruleAnalysis;
+ String name = relationAnalysis.getName();
+ if ("ClassToClass_java".equals(name)) {
+ getClass();
+ }
//
// Determine a head node for the minimum number of sub-regions that have a to-one path from the head.
//

Back to the top