001: package dk.brics.soot.intermediate.foonalasys;
002:
003: import java.io.IOException;
004: import java.util.Collection;
005: import java.util.Iterator;
006: import java.util.Map;
007:
008: import dk.brics.soot.intermediate.representation.Method;
009: import dk.brics.soot.intermediate.representation.Statement;
010: import dk.brics.soot.intermediate.translation.JavaTranslator;
011:
012: import soot.Scene;
013: import soot.SootClass;
014: import soot.SootMethod;
015: import soot.ValueBox;
016: import soot.jimple.toolkits.callgraph.CallGraph;
017: import soot.util.dot.DotGraph;
018:
019: /** A <code>Foonalysis</code> object encapsulates a foonalysis performed
020: * on a collection of classes.
021: * The class also contains some convenience methods for loading and traversing
022: * the classes to be analyzed.<p>
023: */
024: public class Foonalasys {
025:
026: private static final boolean DEBUG = false;
027:
028: private JavaTranslator jt;
029: private Map/*<ValueBox,String>*/sourcefile_map;
030: private Map/*<ValueBox,String>*/class_map;
031: private Map/*<ValueBox,String>*/method_map;
032: private Map/*<ValueBox,Integer>*/line_map;
033:
034: // Make sure we get line numbers
035: static {
036: soot.Scene.v().loadBasicClasses();
037: soot.options.Options.v().parse(
038: new String[] { "-keep-line-number" });
039: }
040:
041: /** Performs a foonalysis on the current application classes.
042: * @throws IOException
043: */
044: public Foonalasys() {
045: jt = new JavaTranslator();
046: debug("Translating classes to intermediate form...");
047: Method[] methods = jt.translateApplicationClasses();
048:
049: for (Method m : methods) {
050: System.out.println("Method: " + m.getName() + ":");
051: Collection<Statement> stmts = m.getEntry().getSuccs();
052: printStmts(stmts);
053: System.out.println("------------------------");
054: }
055:
056: debug("Foonalasys done");
057: }
058:
059: private void printStmts(Collection<Statement> stmts) {
060: for (Statement stmt : stmts) {
061: System.out.println("stmt: " + " " + stmt);
062: printStmts(stmt.getSuccs());
063: }
064: }
065:
066: /** Returns the name of the source file containing the given expression.
067: * @param box the expression.
068: * @return the source file name.
069: */
070: public final String getSourceFile(ValueBox box) {
071: return (String) sourcefile_map.get(box);
072: }
073:
074: /** Returns the name of the class containing the given expression.
075: * @param box the expression.
076: * @return the fully qualified class name.
077: */
078: public final String getClassName(ValueBox box) {
079: return (String) class_map.get(box);
080: }
081:
082: /** Returns the name of the method containing the given expression.
083: * @param box the expression.
084: * @return the method name.
085: */
086: public final String getMethodName(ValueBox box) {
087: return (String) method_map.get(box);
088: }
089:
090: /** Returns the source line number of the given expression.
091: * @param box the expression.
092: * @return the line number.
093: */
094: public final int getLineNumber(ValueBox box) {
095: return ((Integer) line_map.get(box)).intValue();
096: }
097:
098: /** Loads the named class into the Soot scene,
099: * marks it as an application class, and generates bodies
100: * for all of its concrete methods.
101: * @param name the fully qualified name of the class to be loaded.
102: */
103: public static void loadClass(String name) {
104: SootClass c = Scene.v().loadClassAndSupport(name);
105: c.setApplicationClass();
106: Iterator mi = c.getMethods().iterator();
107: while (mi.hasNext()) {
108: SootMethod sm = (SootMethod) mi.next();
109: if (sm.isConcrete()) {
110: sm.retrieveActiveBody();
111: }
112: }
113: }
114:
115: private void debug(String s) {
116: if (DEBUG) {
117: System.err.println(s);
118: }
119: }
120:
121: }
|