/*
* Bytecode Analysis Framework
* Copyright (C) 2003,2004 University of Maryland
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package edu.umd.cs.findbugs.ba;
import java.io.PrintStream;
import org.apache.bcel.generic.InstructionHandle;
/**
* CFGPrinter class which prints dataflow values at each basic block and
* instruction.
*/
public class DataflowCFGPrinter<Fact, AnalysisType extends DataflowAnalysis<Fact>> extends CFGPrinter {
private Dataflow<Fact, AnalysisType> dataflow;
/**
* Constructor.
*
* @param dataflow
* the Dataflow object whose values should be used to annotate
* the printed CFG
*/
public DataflowCFGPrinter(Dataflow<Fact, AnalysisType> dataflow) {
super(dataflow.getCFG());
this.dataflow = dataflow;
setIsForwards(dataflow.getAnalysis().isForwards());
}
/*
* (non-Javadoc)
*
* @see
* edu.umd.cs.findbugs.ba.CFGPrinter#edgeAnnotate(edu.umd.cs.findbugs.ba
* .Edge)
*/
@Override
public String edgeAnnotate(Edge edge) {
String edgeAnnotation = "";
try {
edgeAnnotation = " " + dataflow.getAnalysis().factToString(dataflow.getAnalysis().getFactOnEdge(edge));
} catch (Throwable e) {
// ignore
}
return edgeAnnotation;
}
@Override
public String blockStartAnnotate(BasicBlock bb) {
boolean flip = isForwards() != dataflow.getAnalysis().isForwards();
Fact fact = flip ? dataflow.getResultFact(bb) : dataflow.getStartFact(bb);
return " " + dataflow.getAnalysis().factToString(fact);
}
@Override
public String blockAnnotate(BasicBlock bb) {
boolean flip = isForwards() != dataflow.getAnalysis().isForwards();
Fact fact = flip ? dataflow.getStartFact(bb) : dataflow.getResultFact(bb);
return " " + dataflow.getAnalysis().factToString(fact);
}
@Override
public String instructionAnnotate(InstructionHandle handle, BasicBlock bb) {
try {
boolean flip = isForwards() != dataflow.getAnalysis().isForwards();
Location loc = new Location(handle, bb);
Fact fact = flip ? dataflow.getAnalysis().getFactAfterLocation(loc) : dataflow.getAnalysis().getFactAtLocation(loc);
return " " + dataflow.getAnalysis().factToString(fact);
} catch (DataflowAnalysisException e) {
throw new IllegalStateException("Caught exception: " + e.toString());
}
}
/**
* Print CFG annotated with results from given dataflow analysis.
*
* @param <Fact>
* Dataflow fact type
* @param <AnalysisType>
* Dataflow analysis type
* @param dataflow
* dataflow driver
* @param out
* PrintStream to use
*/
public static <Fact, AnalysisType extends BasicAbstractDataflowAnalysis<Fact>> void printCFG(
Dataflow<Fact, AnalysisType> dataflow, PrintStream out) {
DataflowCFGPrinter<Fact, AnalysisType> printer = new DataflowCFGPrinter<Fact, AnalysisType>(dataflow);
printer.print(out);
}
}
// vim:ts=4