001: /* GraphTalker.java */
002: package org.quilt.cl;
003:
004: import org.apache.bcel.generic.*;
005: import org.quilt.graph.*;
006:
007: /**
008: * Walks through a control flow graph, displaying information about
009: * each vertex and edge. Useful for debugging and as a model
010: * GraphXformer implementation.
011: *
012: * @author <a href="jddixon@users.sourceforge.net">Jim Dixon</a>
013: */
014: public class GraphTalker implements GraphXformer,
015: org.quilt.graph.Visitor {
016:
017: private static String name = null;
018:
019: public GraphTalker() {
020: }
021:
022: // INTERFACE VISITOR ////////////////////////////////////////
023: public void discoverGraph(Directed graph) {
024: ControlFlowGraph g = (ControlFlowGraph) graph;
025: System.out.println("--------------------------------------");
026: if (g.getParent() != null)
027: System.out.print("SUB");
028: System.out.println("GRAPH with " + g.size() + " vertices");
029: }
030:
031: public void finishGraph(Directed graph) {
032: System.out.println("--------------------------------------");
033: }
034:
035: public void discoverVertex(Vertex v) {
036: Connector conn = v.getConnector();
037: // MAKE THIS A STRINGBUFFER
038: StringBuffer sb = new StringBuffer().append("VERTEX ")
039: .append(v);
040: if (v instanceof Entry) {
041: ControlFlowGraph parent = (ControlFlowGraph) v.getGraph()
042: .getParent();
043: sb.append(" graph ").append(v.getGraph().getIndex())
044: .append(" whose parent is graph ");
045: if (parent == null) {
046: sb.append("<null>\n");
047: } else {
048: sb.append(parent.getIndex()).append("\n");
049: }
050: if (conn instanceof ComplexConnector) {
051: int k = conn.size();
052: sb.append(" HANDLERS\n");
053: for (int i = 0; i < k; i++) {
054: sb.append(" -> ").append(
055: ((ComplexConnector) conn).getEdge(i)
056: .getTarget()).append("\n");
057: }
058: }
059: } else if (v instanceof Exit) {
060: sb.append(" EXIT\n");
061: } else {
062: CodeVertex cv = (CodeVertex) v;
063: sb.append("\n instructions:\n");
064: InstructionList ilist = cv.getInstructionList();
065: Instruction[] inst = ilist.getInstructions();
066: if (inst.length == 0)
067: sb.append(" none\n");
068: for (int i = 0; i < inst.length; i++) {
069: sb.append(" ").append(inst[i]).append("\n");
070: }
071: Instruction connInst = cv.getConnInst();
072: if (connInst == null) {
073: sb
074: .append(" NO CONNECTING INSTRUCTION (flows through)\n");
075: } else {
076: sb.append(" CONNECTING INST: ").append(connInst)
077: .append("\n");
078: }
079: }
080: System.out.print(sb.toString());
081: }
082:
083: public void finishVertex(Vertex v) {
084: }
085:
086: public void discoverEdge(Edge e) {
087: System.out.println(" EDGE " + e.getSource() + " -> "
088: + e.getTarget());
089: }
090:
091: public void finishEdge(Edge e) {
092: }
093:
094: // INTERFACE GRAPHXFORMER ///////////////////////////////////
095: public void xform(final ClassGen cg, final MethodGen method,
096: ControlFlowGraph cfg) {
097: Walker walker = new Walker();
098: walker.visit(cfg, this );
099: }
100:
101: public static String getName() {
102: return name;
103: }
104:
105: public static void setName(String s) {
106: name = s;
107: }
108: }
|