/** * Verify that some non-looping paths from {@code a} to {@code b} pass through at least one node * where {@code nodePredicate} is true. */ private boolean checkSomePathsWithoutBackEdges(DiGraphNode<N, E> a, DiGraphNode<N, E> b) { if (nodePredicate.apply(a.getValue()) && (inclusive || (a != start && a != end))) { return true; } if (a == b) { return false; } for (DiGraphEdge<N, E> e : a.getOutEdges()) { // Once we visited that edge once, we no longer need to // re-visit it again. if (e.getAnnotation() == VISITED_EDGE) { continue; } e.setAnnotation(VISITED_EDGE); if (ignoreEdge(e)) { continue; } if (e.getAnnotation() == BACK_EDGE) { continue; } DiGraphNode<N, E> next = e.getDestination(); if (checkSomePathsWithoutBackEdges(next, b)) { return true; } } return false; }
/** * Assert that there exists no control flow edge of the given type * from some node with the first token to the return node. */ private static void assertNoReturnEdge(ControlFlowGraph<Node> cfg, int startToken) { List<DiGraphEdge<Node, Branch>> edges = getAllEdges(cfg); for (DiGraphEdge<Node, Branch> edge : edges) { Node source = edge.getSource().getValue(); DiGraphNode<Node, Branch> dest = edge.getDestination(); if (source.getType() == startToken) { assertFalse("Token " + startToken + " should not have an out going" + " edge to the implicit return", cfg.isImplicitReturn(dest)); return; } } }
/** * Assert that there exists a control flow edge of the given type * from some node with the first token to the return node. */ private static void assertReturnEdge(ControlFlowGraph<Node> cfg, int startToken) { List<DiGraphEdge<Node, Branch>> edges = getAllEdges(cfg); for (DiGraphEdge<Node, Branch> edge : edges) { Node source = edge.getSource().getValue(); DiGraphNode<Node, Branch> dest = edge.getDestination(); if (source.getType() == startToken && cfg.isImplicitReturn(dest)) { return; } } fail("No return edge found"); }
private void discoverBackEdges(DiGraphNode<N, E> u) { u.setAnnotation(GRAY); for (DiGraphEdge<N, E> e : u.getOutEdges()) { if (ignoreEdge(e)) { continue; } DiGraphNode<N, E> v = e.getDestination(); if (v.getAnnotation() == WHITE) { discoverBackEdges(v); } else if (v.getAnnotation() == GRAY) { e.setAnnotation(BACK_EDGE); } } u.setAnnotation(BLACK); }
/** * Gets all the control flow edges from some node with the first token to * some node with the second token. */ private static List<DiGraphEdge<Node, Branch>> getAllEdges( ControlFlowGraph<Node> cfg, int startToken, int endToken) { List<DiGraphEdge<Node, Branch>> edges = getAllEdges(cfg); Iterator<DiGraphEdge<Node, Branch>> it = edges.iterator(); while (it.hasNext()) { DiGraphEdge<Node, Branch> edge = it.next(); Node startNode = edge.getSource().getValue(); Node endNode = edge.getDestination().getValue(); if (startNode == null || endNode == null || startNode.getType() != startToken || endNode.getType() != endToken) { it.remove(); } } return edges; }
/** * Gets all the control flow edges of the given type from some node with * the first token to some node with the second token. * This edge must flow from a parent to one of its descendants. */ private static List<DiGraphEdge<Node, Branch>> getAllDownEdges( ControlFlowGraph<Node> cfg, int startToken, int endToken, Branch type) { List<DiGraphEdge<Node, Branch>> edges = getAllEdges(cfg, startToken, endToken, type); Iterator<DiGraphEdge<Node, Branch>> it = edges.iterator(); while (it.hasNext()) { DiGraphEdge<Node, Branch> edge = it.next(); Node source = edge.getSource().getValue(); Node dest = edge.getDestination().getValue(); if (!isAncestor(source, dest)) { it.remove(); } } return edges; }