001: /*
002: * Bytecode Analysis Framework
003: * Copyright (C) 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 org.apache.bcel.classfile.Method;
023: import org.apache.bcel.generic.CodeExceptionGen;
024: import org.apache.bcel.generic.InstructionHandle;
025: import org.apache.bcel.generic.ObjectType;
026:
027: import edu.umd.cs.findbugs.annotations.CheckForNull;
028:
029: /**
030: * Dataflow analysis to determine the nesting of catch and finally
031: * blocks within a method.
032: *
033: * @see BlockType
034: * @author David Hovemeyer
035: */
036: public class BlockTypeAnalysis extends
037: BasicAbstractDataflowAnalysis<BlockType> {
038: private DepthFirstSearch dfs;
039:
040: /**
041: * Constructor.
042: *
043: * @param dfs a DepthFirstSearch for the method to be analyzed
044: */
045: public BlockTypeAnalysis(DepthFirstSearch dfs) {
046: this .dfs = dfs;
047: }
048:
049: public BlockType createFact() {
050: return new BlockType();
051: }
052:
053: public void copy(BlockType source, BlockType dest) {
054: dest.copyFrom(source);
055: }
056:
057: public void initEntryFact(BlockType result)
058: throws DataflowAnalysisException {
059: result.setNormal();
060: }
061:
062: public void makeFactTop(BlockType fact) {
063: fact.setTop();
064: }
065:
066: public boolean isTop(BlockType fact) {
067: return fact.isTop();
068: }
069:
070: public boolean isForwards() {
071: return true;
072: }
073:
074: public BlockOrder getBlockOrder(CFG cfg) {
075: return new ReversePostOrder(cfg, dfs);
076: }
077:
078: public boolean same(BlockType fact1, BlockType fact2) {
079: return fact1.sameAs(fact2);
080: }
081:
082: public void transfer(BasicBlock basicBlock, @CheckForNull
083: InstructionHandle end, BlockType start, BlockType result)
084: throws DataflowAnalysisException {
085: result.copyFrom(start);
086:
087: if (start.isValid()) {
088: if (basicBlock.isExceptionHandler()) {
089: CodeExceptionGen exceptionGen = basicBlock
090: .getExceptionGen();
091: ObjectType catchType = exceptionGen.getCatchType();
092: if (catchType == null) {
093: // Probably a finally block, or a synchronized block
094: // exception-compensation catch block.
095: result.pushFinally();
096: } else {
097: // Catch type was explicitly specified:
098: // this is probably a programmer-written catch block
099: result.pushCatch();
100: }
101: }
102: }
103: }
104:
105: public void meetInto(BlockType fact, Edge edge, BlockType result)
106: throws DataflowAnalysisException {
107: result.mergeWith(fact);
108: }
109:
110: public static void main(String[] argv) throws Exception {
111: if (argv.length != 1) {
112: System.err.println("Usage: "
113: + BlockTypeAnalysis.class.getName()
114: + " <classfile>");
115: System.exit(1);
116: }
117:
118: DataflowTestDriver<BlockType, BlockTypeAnalysis> driver = new DataflowTestDriver<BlockType, BlockTypeAnalysis>() {
119: /* (non-Javadoc)
120: * @see edu.umd.cs.findbugs.ba.DataflowTestDriver#createDataflow(edu.umd.cs.findbugs.ba.ClassContext, org.apache.bcel.classfile.Method)
121: */
122: @Override
123: public Dataflow<BlockType, BlockTypeAnalysis> createDataflow(
124: ClassContext classContext, Method method)
125: throws CFGBuilderException,
126: DataflowAnalysisException {
127: return classContext.getBlockTypeDataflow(method);
128: }
129: };
130:
131: driver.execute(argv[0]);
132: }
133: }
134:
135: // vim:ts=4
|