Loading EDG/src/main/java/edg/constraint/EdgeConstraint.java +1 −0 Original line number Diff line number Diff line Loading @@ -65,6 +65,7 @@ public abstract class EdgeConstraint extends Constraint } protected Constraints push(Phase phase, Constraints constraints) { // STACK IS FULL AND EXCEPTION IS RAISED if (phase.isInstanceof(Phase.Slicing) && constraints.sizeEdgeConstraints() == Config.MAX_STACK_SIZE) throw new StackOverflowError(); //if (phase.isInstanceof(Phase.SummaryGeneration) && constraints.sizeEdgeConstraints() == this.config.maxStackSize) Loading EDG/src/main/java/edg/graph/Edge.java +6 −1 Original line number Diff line number Diff line package edg.graph; import edg.constraint.AsteriskConstraint; import edg.constraint.Constraint; import edg.constraint.EdgeConstraint; import edg.constraint.EmptyConstraint; Loading @@ -22,6 +23,7 @@ public class Edge private boolean mark; private final Type type; private final EdgeConstraint constraint; private EdgeConstraint visibleConstraint; protected boolean traversable = true; private final int hash; Loading @@ -36,6 +38,7 @@ public class Edge Objects.requireNonNull(constraint, "Constraint can't be null, use 'EmptyConstraint#getConstraint()'"); this.type = type; this.constraint = constraint; this.visibleConstraint = constraint; this.hash = new Random().nextInt(); } Loading @@ -54,10 +57,12 @@ public class Edge return type; } public void resetVisibleConstraint() { this.visibleConstraint = this.constraint; } public EdgeConstraint getConstraint() { return constraint; return visibleConstraint; } public void setVisibleConstraint(EdgeConstraint constraint) { visibleConstraint = constraint;} public boolean isStructuralEdge() { Loading EDG/src/main/java/edg/slicing/AdaptedTwoPassStandardAlgorithm.java 0 → 100644 +112 −0 Original line number Diff line number Diff line package edg.slicing; import edg.graph.EDG; import edg.graph.Edge; import edg.graph.LAST; import edg.graph.Node; import java.util.*; public class AdaptedTwoPassStandardAlgorithm extends StandardAlgorithm{ public AdaptedTwoPassStandardAlgorithm(EDG edg) { super(edg); } public Set<Node> slice(Node slicingCriterion) { final Set<Node> slice = new HashSet<>(); if (slicingCriterion == null) return slice; slice.add(slicingCriterion); this.traverse(slicingCriterion, slice, Edge.Type.Output); this.traverse(slicingCriterion, slice, Edge.Type.Input); return slice; } protected void traverse(Node slicingCriterion, Set<Node> slice, Edge.Type... ignoreEdgeTypes) { final Deque<SliceState> pendingNodes = new LinkedList<>(); for (Node n : slice) pendingNodes.add(new SliceState(n,null)); final Set<Edge.Type> ignoreEdgeTypesSet = new HashSet<>(Arrays.asList(ignoreEdgeTypes)); while (!pendingNodes.isEmpty()) { final SliceState pendingNode = pendingNodes.removeFirst(); final Set<Edge> nextEdges = edg.getEdges(pendingNode.getNode(), sliceDirection); nextEdges.removeIf(e -> ignoreEdgeTypesSet.contains(e.getType())); nextEdges.removeIf(Edge::isControlFlowEdge); nextEdges.removeIf(e -> !e.isTraversable()); if (pendingNode.getLastEdgeType() != null && pendingNode.getLastEdgeType() == Edge.Type.Structural) nextEdges.removeIf(e -> e.getType() != Edge.Type.Structural); for (Edge nextEdge : nextEdges) { final Node nextNode = sliceDirection == LAST.Direction.Backwards ? edg.getEdgeSource(nextEdge): edg.getEdgeTarget(nextEdge); if (!slice.contains(nextNode)) { Node outerStructureNode = this.getOuterCompositeNode(nextNode); if (outerStructureNode != null) { List<Node> nextNodes = edg.getDescendants(outerStructureNode); nextNodes.add(outerStructureNode); if (nextNodes.contains(slicingCriterion)) nextNodes.removeIf(n -> n.getType() == Node.Type.Result); nextNodes.add(edg.getResFromNode(nextNode)); for (Node next : nextNodes) { pendingNodes.addLast(new SliceState(next,nextEdge.getType())); slice.add(next); } } else { pendingNodes.addLast(new SliceState(nextNode,nextEdge.getType())); slice.add(nextNode); } } } } } public Node getOuterCompositeNode(Node node) { Node lastDataContainerParent = null; Node nextParent = edg.getParent(node); while (nextParent != null && isPossibleDataContainer(nextParent)){ if (nextParent.getType() == Node.Type.List || nextParent.getType() == Node.Type.DataConstructor) lastDataContainerParent = nextParent; nextParent = edg.getParent(nextParent); } return lastDataContainerParent; } public boolean isPossibleDataContainer(Node parent) { switch (parent.getType()){ case Equality: case Arguments: case Call: case Operation: case List: case DataConstructor: return true; default: return false; } } private class SliceState{ private Node node; private Edge.Type lastEdgeType; public SliceState(Node n, Edge.Type type){ node = n; lastEdgeType = type; } public Node getNode() { return node; } public Edge.Type getLastEdgeType() { return lastEdgeType; } } } EDG/src/main/java/edg/slicing/OnePassConstrainedAlgorithm.java 0 → 100644 +180 −0 Original line number Diff line number Diff line package edg.slicing; import edg.constraint.*; import edg.graph.EDG; import edg.graph.Edge; import edg.graph.LAST.Direction; import edg.graph.Node; import edg.work.EdgeWork; import edg.work.NodeWork; import edg.work.Work; import edg.work.WorkList; import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.util.Set; public class OnePassConstrainedAlgorithm implements SlicingAlgorithm { protected final EDG edg; public OnePassConstrainedAlgorithm(EDG edg) { this.edg = edg; } public Set<Node> slice(Node node) { final Set<Node> slice = new HashSet<>(); if (node == null) return slice; final WorkList workList = new WorkList(); workList.pend(new NodeWork(node, node, new Constraints())); this.traverse(Phase.OnePhase, workList); slice.addAll(workList.getDoneNodes()); // Reset constraints to their original form after slicing the graph edg.edgeSet().stream() .filter(e -> e.getType() == Edge.Type.Flow || e.getType() == Edge.Type.Value) .forEach(Edge::resetVisibleConstraint); return slice; } private void traverse(Phase phase, WorkList workList) { while (workList.hasMore()) { final Work pendingWork = workList.next(); final List<Work> newWorks = this.processWork(phase, pendingWork); workList.done(pendingWork); workList.pendAll(newWorks); } } public List<Work> processWork(Phase phase, Work work) { if (work instanceof NodeWork) return this.processWork(phase, (NodeWork) work); if (work instanceof EdgeWork) return this.processWork(phase, (EdgeWork) work); throw new RuntimeException("Work type not contemplated"); } protected List<Work> processWork(Phase phase, NodeWork work) { final List<Work> newWorks = new LinkedList<>(); final Node initialNode = work.getInitialNode(); final Node currentNode = work.getCurrentNode(); final Constraints constraints = work.getConstraints(); final List<Edge> traversedEdges = work.getTraversedEdges(); final Set<NodeConstraint> nodeConstraints = constraints.getNodeConstraints(); final Set<Edge> edges = edg.getEdges(currentNode, sliceDirection); edges.removeIf(Edge::isControlFlowEdge); if(phase == Phase.SummaryGeneration) { edges.removeIf(edge -> edge.getType() == Edge.Type.Exception); edges.removeIf(edge -> edge.getType() == Edge.Type.Input || edge.getType() == Edge.Type.Output || edge.getType() == Edge.Type.Call); } // TRAVERSAL RESTRICTION TODO: Change this restriction to construction time removing structural arcs // GENERATOR NODES CONTAIN VALUE EDGES THAT MUST BE TRAVERSED ONLY IF THE GENERATOR NODE IS INCLUDED BY CONTROL if (currentNode.getType() == Node.Type.Generator && work.getPreviousEdgeType() != Edge.Type.Control) edges.removeIf(edge -> edge.getType() == Edge.Type.Value); if (work.getPreviousEdgeType() == Edge.Type.Structural) edges.removeIf(edge -> edge.getType() != Edge.Type.Structural); for (NodeConstraint nodeConstraint : nodeConstraints) nodeConstraint.resolve(phase, edges); final Constraints constraintsClone = (Constraints) constraints.clone(); constraintsClone.clearNodeConstraints(); for (Edge edge : edges){ newWorks.add(new EdgeWork(edg, initialNode, edge, traversedEdges, constraintsClone)); } return newWorks; } private List<Work> processWork(Phase phase, EdgeWork work) { final List<Work> newWorks = new LinkedList<>(); final Node initialNode = work.getInitialNode(); final Edge currentEdge = work.getCurrentEdge(); final List<Edge> traversedEdges = work.getTraversedEdges(); final Node nextNode = sliceDirection == Direction.Backwards ? edg.getEdgeSource(currentEdge) : edg.getEdgeTarget(currentEdge); // NECESSARY TO CONTROL THE OUTPUT EDGES WITH LET_THROUGH_CONSTRAINTS final Edge.Type edgeType = currentEdge.getType(); if (phase == Phase.Input && edgeType == Edge.Type.Output) return newWorks; if (phase == Phase.Output && edgeType == Edge.Type.Input) return newWorks; if (phase == Phase.SummaryGeneration && (edgeType == Edge.Type.Input || edgeType == Edge.Type.Output)) return newWorks; // Do not traverse non-traversable edges if (!currentEdge.isTraversable()) return newWorks; int idTo = edg.getEdgeTarget(currentEdge).getId(); int idFrom = edg.getEdgeSource(currentEdge).getId(); try { final Constraints constraints = work.getConstraints(); final Constraints constraintsClone = (Constraints) constraints.clone(); final EdgeConstraint constraint = currentEdge.getConstraint(); final EdgeConstraint topConstraint = constraintsClone.isEdgeConstraintsEmpty() ? null : constraintsClone.peekEdgeConstraint(); // THIS STATEMENT MAY LAUNCH A StackOverflowError EMPTYING THE STACK (k-limiting 20 elements => Config.MAX_STACK_SIZE = 20;) final List<Constraints> newConstraintsList = constraint.resolve(phase, edg, currentEdge, constraintsClone, topConstraint, 0); for (Constraints newConstraints : newConstraintsList){ List<Edge> traversedParam = new LinkedList<>(); if (traversedEdges.contains(currentEdge)){ // IF WE TRAVERSE THE SAME EDGE TWICE WHILE TRAVERSING FLOW AND VALUE EDGES... List<Edge> loopEdges = work.getTraversedLoop(currentEdge); // 1) WE EXTRACT THE EDGES OF THE LOOP boolean isIncreasingLoop = true; // 2) TODO: WE CALL THE PDA TO EVALUATE THE LOOP // 2.B WE CAN OPTIONALLY SAVE THE LOOP OR MODIFY IT TO OPTIMISE FUTURE TRAVERSALS if (isIncreasingLoop) { // 3) IF THE LOOP IS INCREASING... // ALTERNATIVE 1: REMOVE STACK (ASTERISK CONSTRAINT) AND CONTINUE TRAVERSAL ADDING THE EDGE TO traversedEdges currentEdge.setVisibleConstraint(AsteriskConstraint.getConstraint()); traversedParam.add(currentEdge); newWorks.add(new NodeWork(initialNode, nextNode, traversedParam, new Constraints(), edgeType)); } else { // 4) IF THE LOOP IS NOT INCREASING } } else { switch (currentEdge.getType()) { case Flow: // SUMMARY EDGES MAY GENERATE IT TOO, BUT WE ARE INTRAPROCEDURAL NOW case Value: if (constraint instanceof AccessConstraint || !traversedEdges.isEmpty()) { traversedParam.addAll(traversedEdges); traversedParam.add(currentEdge); } break; default: break; } newWorks.add(new NodeWork(initialNode, nextNode, traversedParam, newConstraints, edgeType)); } } return newWorks; } catch (StackOverflowError e) { if (!phase.isInstanceof(Phase.Slicing)) throw new RuntimeException("Constraint situation not contemplated"); // STACK FULL => EMPTY CONSTRAINT LIST (*) newWorks.add(new NodeWork(initialNode, nextNode, new Constraints(), edgeType)); } return newWorks; } } EDG/src/main/java/edg/work/EdgeWork.java +10 −2 Original line number Diff line number Diff line Loading @@ -23,18 +23,26 @@ import edg.graph.EDG; import edg.graph.Edge; import edg.graph.Node; import java.util.LinkedList; import java.util.List; public class EdgeWork extends Work { private final Edge currentEdge; public EdgeWork(EDG edg, Node initialNode, Edge currentEdge, Constraints constraints) public EdgeWork(EDG edg, Node initialNode, Edge currentEdge, List<Edge> traversed, Constraints constraints) { super(initialNode, constraints); super(initialNode, constraints, traversed); this.id = edg.getEdgeSource(currentEdge).getId() + "->" + edg.getEdgeTarget(currentEdge).getId(); this.currentEdge = currentEdge; } public EdgeWork(EDG edg, Node initialNode, Edge currentEdge, Constraints constraints) { this(edg, initialNode, currentEdge, new LinkedList<>(), constraints); } public Edge getCurrentEdge() { return this.currentEdge; Loading Loading
EDG/src/main/java/edg/constraint/EdgeConstraint.java +1 −0 Original line number Diff line number Diff line Loading @@ -65,6 +65,7 @@ public abstract class EdgeConstraint extends Constraint } protected Constraints push(Phase phase, Constraints constraints) { // STACK IS FULL AND EXCEPTION IS RAISED if (phase.isInstanceof(Phase.Slicing) && constraints.sizeEdgeConstraints() == Config.MAX_STACK_SIZE) throw new StackOverflowError(); //if (phase.isInstanceof(Phase.SummaryGeneration) && constraints.sizeEdgeConstraints() == this.config.maxStackSize) Loading
EDG/src/main/java/edg/graph/Edge.java +6 −1 Original line number Diff line number Diff line package edg.graph; import edg.constraint.AsteriskConstraint; import edg.constraint.Constraint; import edg.constraint.EdgeConstraint; import edg.constraint.EmptyConstraint; Loading @@ -22,6 +23,7 @@ public class Edge private boolean mark; private final Type type; private final EdgeConstraint constraint; private EdgeConstraint visibleConstraint; protected boolean traversable = true; private final int hash; Loading @@ -36,6 +38,7 @@ public class Edge Objects.requireNonNull(constraint, "Constraint can't be null, use 'EmptyConstraint#getConstraint()'"); this.type = type; this.constraint = constraint; this.visibleConstraint = constraint; this.hash = new Random().nextInt(); } Loading @@ -54,10 +57,12 @@ public class Edge return type; } public void resetVisibleConstraint() { this.visibleConstraint = this.constraint; } public EdgeConstraint getConstraint() { return constraint; return visibleConstraint; } public void setVisibleConstraint(EdgeConstraint constraint) { visibleConstraint = constraint;} public boolean isStructuralEdge() { Loading
EDG/src/main/java/edg/slicing/AdaptedTwoPassStandardAlgorithm.java 0 → 100644 +112 −0 Original line number Diff line number Diff line package edg.slicing; import edg.graph.EDG; import edg.graph.Edge; import edg.graph.LAST; import edg.graph.Node; import java.util.*; public class AdaptedTwoPassStandardAlgorithm extends StandardAlgorithm{ public AdaptedTwoPassStandardAlgorithm(EDG edg) { super(edg); } public Set<Node> slice(Node slicingCriterion) { final Set<Node> slice = new HashSet<>(); if (slicingCriterion == null) return slice; slice.add(slicingCriterion); this.traverse(slicingCriterion, slice, Edge.Type.Output); this.traverse(slicingCriterion, slice, Edge.Type.Input); return slice; } protected void traverse(Node slicingCriterion, Set<Node> slice, Edge.Type... ignoreEdgeTypes) { final Deque<SliceState> pendingNodes = new LinkedList<>(); for (Node n : slice) pendingNodes.add(new SliceState(n,null)); final Set<Edge.Type> ignoreEdgeTypesSet = new HashSet<>(Arrays.asList(ignoreEdgeTypes)); while (!pendingNodes.isEmpty()) { final SliceState pendingNode = pendingNodes.removeFirst(); final Set<Edge> nextEdges = edg.getEdges(pendingNode.getNode(), sliceDirection); nextEdges.removeIf(e -> ignoreEdgeTypesSet.contains(e.getType())); nextEdges.removeIf(Edge::isControlFlowEdge); nextEdges.removeIf(e -> !e.isTraversable()); if (pendingNode.getLastEdgeType() != null && pendingNode.getLastEdgeType() == Edge.Type.Structural) nextEdges.removeIf(e -> e.getType() != Edge.Type.Structural); for (Edge nextEdge : nextEdges) { final Node nextNode = sliceDirection == LAST.Direction.Backwards ? edg.getEdgeSource(nextEdge): edg.getEdgeTarget(nextEdge); if (!slice.contains(nextNode)) { Node outerStructureNode = this.getOuterCompositeNode(nextNode); if (outerStructureNode != null) { List<Node> nextNodes = edg.getDescendants(outerStructureNode); nextNodes.add(outerStructureNode); if (nextNodes.contains(slicingCriterion)) nextNodes.removeIf(n -> n.getType() == Node.Type.Result); nextNodes.add(edg.getResFromNode(nextNode)); for (Node next : nextNodes) { pendingNodes.addLast(new SliceState(next,nextEdge.getType())); slice.add(next); } } else { pendingNodes.addLast(new SliceState(nextNode,nextEdge.getType())); slice.add(nextNode); } } } } } public Node getOuterCompositeNode(Node node) { Node lastDataContainerParent = null; Node nextParent = edg.getParent(node); while (nextParent != null && isPossibleDataContainer(nextParent)){ if (nextParent.getType() == Node.Type.List || nextParent.getType() == Node.Type.DataConstructor) lastDataContainerParent = nextParent; nextParent = edg.getParent(nextParent); } return lastDataContainerParent; } public boolean isPossibleDataContainer(Node parent) { switch (parent.getType()){ case Equality: case Arguments: case Call: case Operation: case List: case DataConstructor: return true; default: return false; } } private class SliceState{ private Node node; private Edge.Type lastEdgeType; public SliceState(Node n, Edge.Type type){ node = n; lastEdgeType = type; } public Node getNode() { return node; } public Edge.Type getLastEdgeType() { return lastEdgeType; } } }
EDG/src/main/java/edg/slicing/OnePassConstrainedAlgorithm.java 0 → 100644 +180 −0 Original line number Diff line number Diff line package edg.slicing; import edg.constraint.*; import edg.graph.EDG; import edg.graph.Edge; import edg.graph.LAST.Direction; import edg.graph.Node; import edg.work.EdgeWork; import edg.work.NodeWork; import edg.work.Work; import edg.work.WorkList; import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.util.Set; public class OnePassConstrainedAlgorithm implements SlicingAlgorithm { protected final EDG edg; public OnePassConstrainedAlgorithm(EDG edg) { this.edg = edg; } public Set<Node> slice(Node node) { final Set<Node> slice = new HashSet<>(); if (node == null) return slice; final WorkList workList = new WorkList(); workList.pend(new NodeWork(node, node, new Constraints())); this.traverse(Phase.OnePhase, workList); slice.addAll(workList.getDoneNodes()); // Reset constraints to their original form after slicing the graph edg.edgeSet().stream() .filter(e -> e.getType() == Edge.Type.Flow || e.getType() == Edge.Type.Value) .forEach(Edge::resetVisibleConstraint); return slice; } private void traverse(Phase phase, WorkList workList) { while (workList.hasMore()) { final Work pendingWork = workList.next(); final List<Work> newWorks = this.processWork(phase, pendingWork); workList.done(pendingWork); workList.pendAll(newWorks); } } public List<Work> processWork(Phase phase, Work work) { if (work instanceof NodeWork) return this.processWork(phase, (NodeWork) work); if (work instanceof EdgeWork) return this.processWork(phase, (EdgeWork) work); throw new RuntimeException("Work type not contemplated"); } protected List<Work> processWork(Phase phase, NodeWork work) { final List<Work> newWorks = new LinkedList<>(); final Node initialNode = work.getInitialNode(); final Node currentNode = work.getCurrentNode(); final Constraints constraints = work.getConstraints(); final List<Edge> traversedEdges = work.getTraversedEdges(); final Set<NodeConstraint> nodeConstraints = constraints.getNodeConstraints(); final Set<Edge> edges = edg.getEdges(currentNode, sliceDirection); edges.removeIf(Edge::isControlFlowEdge); if(phase == Phase.SummaryGeneration) { edges.removeIf(edge -> edge.getType() == Edge.Type.Exception); edges.removeIf(edge -> edge.getType() == Edge.Type.Input || edge.getType() == Edge.Type.Output || edge.getType() == Edge.Type.Call); } // TRAVERSAL RESTRICTION TODO: Change this restriction to construction time removing structural arcs // GENERATOR NODES CONTAIN VALUE EDGES THAT MUST BE TRAVERSED ONLY IF THE GENERATOR NODE IS INCLUDED BY CONTROL if (currentNode.getType() == Node.Type.Generator && work.getPreviousEdgeType() != Edge.Type.Control) edges.removeIf(edge -> edge.getType() == Edge.Type.Value); if (work.getPreviousEdgeType() == Edge.Type.Structural) edges.removeIf(edge -> edge.getType() != Edge.Type.Structural); for (NodeConstraint nodeConstraint : nodeConstraints) nodeConstraint.resolve(phase, edges); final Constraints constraintsClone = (Constraints) constraints.clone(); constraintsClone.clearNodeConstraints(); for (Edge edge : edges){ newWorks.add(new EdgeWork(edg, initialNode, edge, traversedEdges, constraintsClone)); } return newWorks; } private List<Work> processWork(Phase phase, EdgeWork work) { final List<Work> newWorks = new LinkedList<>(); final Node initialNode = work.getInitialNode(); final Edge currentEdge = work.getCurrentEdge(); final List<Edge> traversedEdges = work.getTraversedEdges(); final Node nextNode = sliceDirection == Direction.Backwards ? edg.getEdgeSource(currentEdge) : edg.getEdgeTarget(currentEdge); // NECESSARY TO CONTROL THE OUTPUT EDGES WITH LET_THROUGH_CONSTRAINTS final Edge.Type edgeType = currentEdge.getType(); if (phase == Phase.Input && edgeType == Edge.Type.Output) return newWorks; if (phase == Phase.Output && edgeType == Edge.Type.Input) return newWorks; if (phase == Phase.SummaryGeneration && (edgeType == Edge.Type.Input || edgeType == Edge.Type.Output)) return newWorks; // Do not traverse non-traversable edges if (!currentEdge.isTraversable()) return newWorks; int idTo = edg.getEdgeTarget(currentEdge).getId(); int idFrom = edg.getEdgeSource(currentEdge).getId(); try { final Constraints constraints = work.getConstraints(); final Constraints constraintsClone = (Constraints) constraints.clone(); final EdgeConstraint constraint = currentEdge.getConstraint(); final EdgeConstraint topConstraint = constraintsClone.isEdgeConstraintsEmpty() ? null : constraintsClone.peekEdgeConstraint(); // THIS STATEMENT MAY LAUNCH A StackOverflowError EMPTYING THE STACK (k-limiting 20 elements => Config.MAX_STACK_SIZE = 20;) final List<Constraints> newConstraintsList = constraint.resolve(phase, edg, currentEdge, constraintsClone, topConstraint, 0); for (Constraints newConstraints : newConstraintsList){ List<Edge> traversedParam = new LinkedList<>(); if (traversedEdges.contains(currentEdge)){ // IF WE TRAVERSE THE SAME EDGE TWICE WHILE TRAVERSING FLOW AND VALUE EDGES... List<Edge> loopEdges = work.getTraversedLoop(currentEdge); // 1) WE EXTRACT THE EDGES OF THE LOOP boolean isIncreasingLoop = true; // 2) TODO: WE CALL THE PDA TO EVALUATE THE LOOP // 2.B WE CAN OPTIONALLY SAVE THE LOOP OR MODIFY IT TO OPTIMISE FUTURE TRAVERSALS if (isIncreasingLoop) { // 3) IF THE LOOP IS INCREASING... // ALTERNATIVE 1: REMOVE STACK (ASTERISK CONSTRAINT) AND CONTINUE TRAVERSAL ADDING THE EDGE TO traversedEdges currentEdge.setVisibleConstraint(AsteriskConstraint.getConstraint()); traversedParam.add(currentEdge); newWorks.add(new NodeWork(initialNode, nextNode, traversedParam, new Constraints(), edgeType)); } else { // 4) IF THE LOOP IS NOT INCREASING } } else { switch (currentEdge.getType()) { case Flow: // SUMMARY EDGES MAY GENERATE IT TOO, BUT WE ARE INTRAPROCEDURAL NOW case Value: if (constraint instanceof AccessConstraint || !traversedEdges.isEmpty()) { traversedParam.addAll(traversedEdges); traversedParam.add(currentEdge); } break; default: break; } newWorks.add(new NodeWork(initialNode, nextNode, traversedParam, newConstraints, edgeType)); } } return newWorks; } catch (StackOverflowError e) { if (!phase.isInstanceof(Phase.Slicing)) throw new RuntimeException("Constraint situation not contemplated"); // STACK FULL => EMPTY CONSTRAINT LIST (*) newWorks.add(new NodeWork(initialNode, nextNode, new Constraints(), edgeType)); } return newWorks; } }
EDG/src/main/java/edg/work/EdgeWork.java +10 −2 Original line number Diff line number Diff line Loading @@ -23,18 +23,26 @@ import edg.graph.EDG; import edg.graph.Edge; import edg.graph.Node; import java.util.LinkedList; import java.util.List; public class EdgeWork extends Work { private final Edge currentEdge; public EdgeWork(EDG edg, Node initialNode, Edge currentEdge, Constraints constraints) public EdgeWork(EDG edg, Node initialNode, Edge currentEdge, List<Edge> traversed, Constraints constraints) { super(initialNode, constraints); super(initialNode, constraints, traversed); this.id = edg.getEdgeSource(currentEdge).getId() + "->" + edg.getEdgeTarget(currentEdge).getId(); this.currentEdge = currentEdge; } public EdgeWork(EDG edg, Node initialNode, Edge currentEdge, Constraints constraints) { this(edg, initialNode, currentEdge, new LinkedList<>(), constraints); } public Edge getCurrentEdge() { return this.currentEdge; Loading