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.IOException;
023: import java.util.Iterator;
024:
025: import org.apache.bcel.classfile.ClassParser;
026: import org.apache.bcel.classfile.JavaClass;
027: import org.apache.bcel.classfile.Method;
028: import org.apache.bcel.generic.InstructionHandle;
029: import org.apache.bcel.generic.MethodGen;
030:
031: import edu.umd.cs.findbugs.annotations.CheckForNull;
032:
033: public abstract class ResourceValueAnalysisTestDriver<Resource, ResourceTrackerType extends ResourceTracker<Resource>> {
034:
035: public abstract ResourceTrackerType createResourceTracker(
036: ClassContext classContext, Method method)
037: throws CFGBuilderException, DataflowAnalysisException;
038:
039: public void execute(String classFile, String methodName, int offset)
040: throws IOException, CFGBuilderException,
041: DataflowAnalysisException {
042:
043: final RepositoryLookupFailureCallback lookupFailureCallback = new DebugRepositoryLookupFailureCallback();
044:
045: // Set the lookup failure callback in the Analysis Context
046: AnalysisContext analysisContext = AnalysisContext
047: .create(lookupFailureCallback);
048:
049: JavaClass jclass = new ClassParser(classFile).parse();
050: ClassContext classContext = analysisContext
051: .getClassContext(jclass);
052:
053: Method[] methodList = jclass.getMethods();
054: for (Method method : methodList) {
055: if (!method.getName().equals(methodName))
056: continue;
057:
058: CFG cfg = classContext.getCFG(method);
059:
060: BasicBlock creationBlock = null;
061: InstructionHandle creationInstruction = null;
062:
063: blockLoop: for (Iterator<BasicBlock> ii = cfg
064: .blockIterator(); ii.hasNext();) {
065: BasicBlock basicBlock = ii.next();
066: for (Iterator<InstructionHandle> j = basicBlock
067: .instructionIterator(); j.hasNext();) {
068: InstructionHandle handle = j.next();
069: if (handle.getPosition() == offset) {
070: creationBlock = basicBlock;
071: creationInstruction = handle;
072: break blockLoop;
073: }
074: }
075: }
076:
077: if (creationInstruction == null || creationBlock == null)
078: throw new IllegalArgumentException(
079: "No bytecode with offset " + offset);
080:
081: final ResourceTrackerType resourceTracker = createResourceTracker(
082: classContext, method);
083: final Resource resource = resourceTracker
084: .isResourceCreation(creationBlock,
085: creationInstruction, classContext
086: .getConstantPoolGen());
087:
088: if (resource == null)
089: throw new IllegalArgumentException("offset " + offset
090: + " is not a resource creation");
091:
092: DataflowTestDriver<ResourceValueFrame, ResourceValueAnalysis<Resource>> driver = new DataflowTestDriver<ResourceValueFrame, ResourceValueAnalysis<Resource>>() {
093: @Override
094: @CheckForNull
095: public Dataflow<ResourceValueFrame, ResourceValueAnalysis<Resource>> createDataflow(
096: ClassContext classContext, Method method)
097: throws CFGBuilderException,
098: DataflowAnalysisException {
099: MethodGen methodGen = classContext
100: .getMethodGen(method);
101: if (methodGen == null)
102: return null;
103: CFG cfg = classContext.getCFG(method);
104: DepthFirstSearch dfs = classContext
105: .getDepthFirstSearch(method);
106:
107: ResourceValueAnalysis<Resource> analysis = new ResourceValueAnalysis<Resource>(
108: methodGen, cfg, dfs, resourceTracker,
109: resource);
110: Dataflow<ResourceValueFrame, ResourceValueAnalysis<Resource>> dataflow = new Dataflow<ResourceValueFrame, ResourceValueAnalysis<Resource>>(
111: cfg, analysis);
112: dataflow.execute();
113:
114: return dataflow;
115: }
116: };
117:
118: driver.execute(classContext, method);
119: break;
120: }
121: }
122: }
123:
124: // vim:ts=4
|