001: /*
002: * Bytecode Analysis Framework
003: * Copyright (C) 2003,2004 University of Maryland
004: *
005: * This library is free software; you can redistribute it and/or
006: * modify it under the terms of the GNU Lesser General Public
007: * License as published by the Free Software Foundation; either
008: * version 2.1 of the License, or (at your option) any later version.
009: *
010: * This library is distributed in the hope that it will be useful,
011: * but WITHOUT ANY WARRANTY; without even the implied warranty of
012: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
013: * Lesser General Public License for more details.
014: *
015: * You should have received a copy of the GNU Lesser General Public
016: * License along with this library; if not, write to the Free Software
017: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
018: */
019:
020: package edu.umd.cs.findbugs.ba;
021:
022: import java.io.PrintStream;
023:
024: import org.apache.bcel.generic.InstructionHandle;
025:
026: /**
027: * CFGPrinter class which prints dataflow values at
028: * each basic block and instruction.
029: */
030: public class DataflowCFGPrinter<Fact, AnalysisType extends DataflowAnalysis<Fact>>
031: extends CFGPrinter {
032: private Dataflow<Fact, AnalysisType> dataflow;
033:
034: /**
035: * Constructor.
036: *
037: * @param dataflow the Dataflow object whose values should be used to annotate the printed CFG
038: */
039: public DataflowCFGPrinter(Dataflow<Fact, AnalysisType> dataflow) {
040: super (dataflow.getCFG());
041: this .dataflow = dataflow;
042:
043: setIsForwards(dataflow.getAnalysis().isForwards());
044: }
045:
046: /* (non-Javadoc)
047: * @see edu.umd.cs.findbugs.ba.CFGPrinter#edgeAnnotate(edu.umd.cs.findbugs.ba.Edge)
048: */
049: @Override
050: public String edgeAnnotate(Edge edge) {
051: String edgeAnnotation = "";
052: try {
053: edgeAnnotation = " "
054: + dataflow.getAnalysis().factToString(
055: dataflow.getAnalysis().getFactOnEdge(edge));
056: } catch (Throwable e) {
057: // ignore
058: }
059: return edgeAnnotation;
060: }
061:
062: @Override
063: public String blockStartAnnotate(BasicBlock bb) {
064: boolean flip = isForwards() != dataflow.getAnalysis()
065: .isForwards();
066: Fact fact = flip ? dataflow.getResultFact(bb) : dataflow
067: .getStartFact(bb);
068:
069: return " " + dataflow.getAnalysis().factToString(fact);
070: }
071:
072: @Override
073: public String blockAnnotate(BasicBlock bb) {
074: boolean flip = isForwards() != dataflow.getAnalysis()
075: .isForwards();
076: Fact fact = flip ? dataflow.getStartFact(bb) : dataflow
077: .getResultFact(bb);
078:
079: return " " + dataflow.getAnalysis().factToString(fact);
080: }
081:
082: @Override
083: public String instructionAnnotate(InstructionHandle handle,
084: BasicBlock bb) {
085: try {
086: boolean flip = isForwards() != dataflow.getAnalysis()
087: .isForwards();
088:
089: Location loc = new Location(handle, bb);
090:
091: Fact fact = flip ? dataflow.getAnalysis()
092: .getFactAfterLocation(loc) : dataflow.getAnalysis()
093: .getFactAtLocation(loc);
094: return " " + dataflow.getAnalysis().factToString(fact);
095: } catch (DataflowAnalysisException e) {
096: throw new IllegalStateException("Caught exception: "
097: + e.toString());
098: }
099: }
100:
101: /**
102: * Print CFG annotated with results from given dataflow analysis.
103: *
104: * @param <Fact> Dataflow fact type
105: * @param <AnalysisType> Dataflow analysis type
106: * @param dataflow dataflow driver
107: * @param out PrintStream to use
108: */
109: public static <Fact, AnalysisType extends BasicAbstractDataflowAnalysis<Fact>> void printCFG(
110: Dataflow<Fact, AnalysisType> dataflow, PrintStream out) {
111: DataflowCFGPrinter<Fact, AnalysisType> printer = new DataflowCFGPrinter<Fact, AnalysisType>(
112: dataflow);
113: printer.print(out);
114: }
115:
116: }
117:
118: // vim:ts=4
|