From 71c7d41ad5e444c8107e322bcf1ea3c159ff81bd Mon Sep 17 00:00:00 2001 From: Ed Willink Date: Sun, 6 Nov 2016 15:26:52 +0000 Subject: [506806] Resolve isCondition/isRequired interactions --- .../internal/qvtp2qvts/AbstractMappingRegion.java | 119 ++++++++++++++------- .../compiler/internal/qvtp2qvts/NavigableEdge.java | 5 - .../internal/qvtp2qvts/impl/NavigableEdgeImpl.java | 18 ---- 3 files changed, 80 insertions(+), 62 deletions(-) (limited to 'plugins') diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/AbstractMappingRegion.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/AbstractMappingRegion.java index cbe286dae..8438bb6c9 100644 --- a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/AbstractMappingRegion.java +++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/AbstractMappingRegion.java @@ -169,6 +169,32 @@ public abstract class AbstractMappingRegion extends AbstractRegion implements Ma super.addNode(node); } + private boolean canBeStronglyMatched(@NonNull Node node) { + if (node.isExplicitNull()) { + return true; + } + if (node.isPattern()) { + return true; + } + return false; + } + + private boolean canBeUnconditional(@NonNull Node node) { + if (node.isExplicitNull()) { + return true; + } + if (node.isIterator()) { + return false; + } + if (node.isOperation()) { + return true; + } + if (node.isPattern()) { + return true; + } + return false; + } + /** * Any node with an edge to an unconditional node that is not itself unconditional must be conditional. */ @@ -357,25 +383,33 @@ public abstract class AbstractMappingRegion extends AbstractRegion implements Ma return headNodes; } - private void computeStronglyMatchedNodes(@NonNull Node sourceNode, @NonNull Set<@NonNull Node> stronglyMatchedNodes) { - for (@NonNull NavigableEdge edge : sourceNode.getNavigationEdges()) { - Node targetNode = edge.getTarget(); - if (isMatchable(targetNode)) { - boolean targetIsStronglyMatched = edge.isRequired(); - if (targetIsStronglyMatched && stronglyMatchedNodes.add(targetNode)) { - computeStronglyMatchedNodes(targetNode, stronglyMatchedNodes); - } - } - } - } - private @NonNull Set<@NonNull Node> computeStronglyMatchedNodes(@NonNull Iterable<@NonNull Node> headNodes) { Set<@NonNull Node> stronglyMatchedNodes = new HashSet<>(); for (@NonNull Node headNode : headNodes) { - if (!headNode.isDependency() && !headNode.isTrue() && stronglyMatchedNodes.add(headNode)) { - computeStronglyMatchedNodes(headNode, stronglyMatchedNodes); + if (!headNode.isDependency() && !headNode.isTrue()) { + stronglyMatchedNodes.add(headNode); } } + Set<@NonNull Node> moreStronglyMatchedNodes = new HashSet<>(stronglyMatchedNodes); + while (moreStronglyMatchedNodes.size() > 0) { + Set<@NonNull Node> moreMoreNodes = new HashSet<>(); + for (@NonNull Node sourceNode : moreStronglyMatchedNodes) { + for (@NonNull NavigableEdge edge : sourceNode.getNavigationEdges()) { + Node targetNode = edge.getTarget(); + if (canBeStronglyMatched(targetNode)) { + if (targetNode.isExplicitNull() || edge.getProperty().isIsRequired()) { + if (stronglyMatchedNodes.add(targetNode)) { + moreMoreNodes.add(targetNode); + } + } + } + } + } + if (moreMoreNodes.size() <= 0) { + break; + } + moreStronglyMatchedNodes = moreMoreNodes; + } this.stronglyMatchedNodes = new ArrayList<>(stronglyMatchedNodes); Collections.sort(this.stronglyMatchedNodes, NameUtil.NAMEABLE_COMPARATOR); return stronglyMatchedNodes; @@ -384,13 +418,15 @@ public abstract class AbstractMappingRegion extends AbstractRegion implements Ma private @NonNull Set<@NonNull Node> computeUnconditionalNodes(@NonNull Iterable<@NonNull Node> headNodes) { @NonNull Set<@NonNull Node> unconditionalNodes = Sets.newHashSet(headNodes); Iterables.addAll(unconditionalNodes, getNewNodes()); - for (@NonNull Edge edge : getRealizedEdges()) { - Node sourceNode = edge.getSource(); - assert isUnconditionable(sourceNode); - unconditionalNodes.add(sourceNode); - Node targetNode = edge.getTarget(); - assert isUnconditionable(targetNode); - unconditionalNodes.add(targetNode); + for (@NonNull NavigableEdge edge : getRealizedNavigationEdges()) { + if (!edge.isSecondary()) { + Node sourceNode = edge.getSource(); + assert canBeUnconditional(sourceNode); + unconditionalNodes.add(sourceNode); + Node targetNode = edge.getTarget(); + assert canBeUnconditional(targetNode); + unconditionalNodes.add(targetNode); + } } Set<@NonNull Node> moreUnconditionalNodes = new HashSet<>(unconditionalNodes); while (moreUnconditionalNodes.size() > 0) { @@ -398,14 +434,20 @@ public abstract class AbstractMappingRegion extends AbstractRegion implements Ma for (@NonNull Node node : moreUnconditionalNodes) { for (@NonNull Edge incomingEdge : node.getIncomingEdges()) { Node sourceNode = incomingEdge.getSource(); - if (!isUnconditionable(sourceNode)) {} - else if (incomingEdge.isNavigation()) { - if (unconditionalNodes.add(sourceNode)) { - moreMoreNodes.add(sourceNode); + if (!canBeUnconditional(sourceNode)) {} + else if (incomingEdge.isComputation()) { + if (!isConditionalEdge(incomingEdge)) { + if (unconditionalNodes.add(sourceNode)) { + moreMoreNodes.add(sourceNode); + } } + // if is <> + // gather <> visibilities + // gather <> visibilities + // intersection <>/<> is unconditional } - else if (incomingEdge.isComputation()) { - if (!isConditionalEdge(incomingEdge) && unconditionalNodes.add(sourceNode)) { + else if (incomingEdge.isNavigation()) { // Unconditional target has unconditional source + if (unconditionalNodes.add(sourceNode)) { moreMoreNodes.add(sourceNode); } } @@ -415,13 +457,20 @@ public abstract class AbstractMappingRegion extends AbstractRegion implements Ma } for (@NonNull Edge outgoingEdge : node.getOutgoingEdges()) { Node targetNode = outgoingEdge.getTarget(); - if (!isUnconditionable(targetNode)) {} + if (!canBeUnconditional(targetNode)) {} + else if (outgoingEdge.isComputation()) {} else if (outgoingEdge.isNavigation()) { - if (((NavigableEdge)outgoingEdge).isRequired() && unconditionalNodes.add(targetNode)) { - moreMoreNodes.add(targetNode); + if (targetNode.isExplicitNull()) { + if (unconditionalNodes.add(targetNode)) { + moreMoreNodes.add(targetNode); + } + } + else if (node.isRequired() && ((NavigableEdge)outgoingEdge).getProperty().isIsRequired()) { + if (unconditionalNodes.add(targetNode)) { + moreMoreNodes.add(targetNode); + } } } - else if (outgoingEdge.isComputation()) {} else { System.out.println("Unsupported outgoing edge in " + this + " : " + outgoingEdge); } @@ -507,14 +556,6 @@ public abstract class AbstractMappingRegion extends AbstractRegion implements Ma || ExpressionAnalyzer.LOOP_BODY_NAME.equals(edgeName); } - private boolean isMatchable(@NonNull Node node) { - return node.isExplicitNull() || node.isPattern(); - } - - private boolean isUnconditionable(@NonNull Node node) { - return !node.isIterator(); - } - @Override public void resetHead(@NonNull Node headNode) { boolean wasRemoved = getHeadNodes().remove(headNode); 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 ba969ed01..de9aac7bc 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 @@ -44,11 +44,6 @@ public interface NavigableEdge extends Edge, ConnectionEnd */ @NonNull Property getProperty(); - /** - * Return true if this edge has a non-zero target lower bound or if the target node isRequired. - */ - boolean isRequired(); - void removeIncomingConnection(@NonNull EdgeConnection edgeConnection); void removeOutgoingConnection(@NonNull EdgeConnection edgeConnection); } \ No newline at end of file diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/impl/NavigableEdgeImpl.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/impl/NavigableEdgeImpl.java index 93c8c4ae6..49e2488be 100644 --- a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/impl/NavigableEdgeImpl.java +++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/impl/NavigableEdgeImpl.java @@ -194,24 +194,6 @@ public abstract class NavigableEdgeImpl extends EdgeImpl implements NavigableEdg } } - @Override - public boolean isRequired() { - Node targetNode = getTarget(); - Property property = getProperty(); - if (targetNode.isExplicitNull()) { - return true; // ?? a degenerate typedElement.isIsRequired() - } - else if (property.isIsRequired()) { - return true; - } - else if (targetNode.isRequired()) { - return true; - } - else { - return false; - } - } - @Override public boolean isSecondary() { return isSecondary; -- cgit v1.2.3