package de.gaalop.cfg; /** * This class models a control flow node that has one and only one successor. * * @author Sebastian Hartte * @author Christian Schwinn * @version 1.0 * @since 1.0 */ public abstract class SequentialNode extends Node { private Node successor; /** * Constructs a new sequential node. * * @param graph The control flow graph this node should belong to. */ public SequentialNode(ControlFlowGraph graph) { super(graph); } /** * Returns the node that will gain control once this sequential statement has been executed. * * @return The successor node for this sequential node. */ public Node getSuccessor() { return successor; } /** * Overrides the successor node with the given one. * * @param successor successor node to be replaced */ void setSuccessor(Node successor) { this.successor = successor; } /** * Inserts a node after this sequential node and its successor. This method will rewire the nodes to keep the graph * consistent. It will do the following: * <ol> * <li>Remove the connection between this node and its successor.</li> * <li>Add a bi-directional connection between this node and the new node.</li> * <li>Add a bi-directional connection between the new node and this nodes old successor.</li> * </ol> * * @param newNode The new node that should be inserted in the control flow after this one. */ public void insertAfter(SequentialNode newNode) { Node oldSuccessor = successor; successor = newNode; newNode.addPredecessor(this); if (oldSuccessor != null) { newNode.successor = oldSuccessor; oldSuccessor.removePredecessor(this); oldSuccessor.addPredecessor(newNode); } } @Override public void replaceSuccessor(Node oldSuccessor, Node newSuccessor) { if (successor == oldSuccessor) { successor = null; oldSuccessor.removePredecessor(this); newSuccessor.removePredecessor(oldSuccessor); newSuccessor.addPredecessor(this); successor = newSuccessor; } } /** * Must be implemented to copy properties of subtypes. * * @return a copy of this node */ public abstract SequentialNode copyElements(); /** * Makes a deep copy of this node using the same predecessors and successor as the original. Depending on the * subtype, more properties are copied according to the {@link #copyElements()} method. * * @return a copy of this node with same predecessors and successors */ public SequentialNode copy() { SequentialNode copy = copyElements(); copy.setSuccessor(successor); for (Node p : getPredecessors()) { copy.addPredecessor(p); } return copy; } }