Main Page   Packages   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members  

IdentifyRunnableClasses.java

00001 package edu.ksu.cis.bandera.prog;
00002 
00003 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
00004  * Bandera, a Java(TM) analysis and transformation toolkit           *
00005  * Copyright (C) 1998-2001 SAnToS Laboratories (santos@cis.ksu.edu)  *
00006 
00007  * All rights reserved.                                              *
00008  *                                                                   *
00009  * This work was done as a project in the SAnToS Laboratory,         *
00010  * Department of Computing and Information Sciences, Kansas State    *
00011  * University, USA (http://www.cis.ksu.edu/santos).                  *
00012  * It is understood that any modification not identified as such is  *
00013  * not covered by the preceding statement.                           *
00014  *                                                                   *
00015  * This work is free software; you can redistribute it and/or        *
00016  * modify it under the terms of the GNU Library General Public       *
00017  * License as published by the Free Software Foundation; either      *
00018  * version 2 of the License, or (at your option) any later version.  *
00019  *                                                                   *
00020  * This work is distributed in the hope that it will be useful,      *
00021  * but WITHOUT ANY WARRANTY; without even the implied warranty of    *
00022  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU *
00023  * Library General Public License for more details.                  *
00024  *                                                                   *
00025  * You should have received a copy of the GNU Library General Public *
00026  * License along with this toolkit; if not, write to the             *
00027  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,      *
00028  * Boston, MA  02111-1307, USA.                                      *
00029  *                                                                   *
00030  * Java is a trademark of Sun Microsystems, Inc.                     *
00031  *                                                                   *
00032  * To submit a bug report, send a comment, or get the latest news on *
00033  * this project and other SAnToS projects, please visit the web-site *
00034  *                http://www.cis.ksu.edu/santos                      *
00035  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
00036 import java.util.Vector;
00037 import java.util.Hashtable;
00038 import java.util.HashSet;
00039 import java.util.Enumeration;
00040 import java.io.*;
00041 
00042 import ca.mcgill.sable.soot.*;
00043 import ca.mcgill.sable.soot.jimple.*;
00044 import ca.mcgill.sable.util.*;
00045 
00046 import edu.ksu.cis.bandera.jjjc.*;
00047 
00048 public class IdentifyRunnableClasses {
00049     private static SootMethod theRun;
00050 
00051 private static boolean FindRun(SootClass theClass) {
00052     // Check to see if this class implements Runnable
00053         if (theClass.implementsInterface("java.lang.Runnable")) {
00054       // return run method
00055           theRun = theClass.getMethod("run", new ArrayList(), VoidType.v());
00056           return true; 
00057         }
00058 
00059         // Check to see if this class extends Thread
00060         //   check to see if it implements a run method
00061         if (theClass.hasSuperClass() &&
00062             theClass.getSuperClass().getName().equals("java.lang.Thread")) {
00063           // if there is no run method generate an empty one
00064           if (!theClass.declaresMethod("run", new ArrayList(), VoidType.v())) {
00065         theRun = new SootMethod("run", new ArrayList(), VoidType.v());
00066         JimpleBody body = (JimpleBody) Jimple.v().newBody(theRun);
00067         theClass.addMethod(theRun);
00068           } else {
00069             theRun = theClass.getMethod("run", new ArrayList(), VoidType.v());
00070           }
00071           return true; 
00072         }
00073 
00074         // search up
00075         if (theClass.hasSuperClass() &&
00076             FindRun(theClass.getSuperClass())) {
00077       // if there is a local "run" method then reset theRun
00078           if (theClass.declaresMethod("run", new ArrayList(), VoidType.v())) {
00079             theRun = theClass.getMethod("run", new ArrayList(), VoidType.v());
00080           }
00081         } 
00082 
00083     return false;
00084 }
00085 public static java.util.HashSet identify(Enumeration scIter) {
00086     java.util.HashSet tmpClasses = new java.util.HashSet();
00087 
00088         while (scIter.hasMoreElements()) {
00089           SootClass theClass = (SootClass) scIter.nextElement();
00090 
00091       // Check to see if this class has a "main" method
00092       ca.mcgill.sable.util.LinkedList args = new ca.mcgill.sable.util.LinkedList();
00093       args.add(ca.mcgill.sable.soot.ArrayType.v(RefType.v("java.lang.String"), 1));
00094           if (theClass.declaresMethod("main", args, VoidType.v())) {
00095             tmpClasses.add(theClass);
00096             continue;
00097           }
00098 
00099       // Check to see if this class implements Runnable
00100           if (theClass.implementsInterface("java.lang.Runnable")) {
00101             tmpClasses.add(theClass);
00102             continue;
00103           }
00104 
00105           // Check to see if this class extends Thread
00106           //   check to see if it implements a run method
00107           if (theClass.hasSuperClass() &&
00108               theClass.getSuperClass().getName().equals("java.lang.Thread")) {
00109         // if there is no run method generate an empty one
00110         if (!theClass.declaresMethod("run", new ArrayList(), VoidType.v())) {
00111           SootMethod newRun = new SootMethod("run", new ArrayList(), VoidType.v());
00112           JimpleBody body = (JimpleBody) Jimple.v().newBody(newRun);
00113           theClass.addMethod(newRun);
00114         }
00115             tmpClasses.add(theClass);
00116             continue;
00117           }
00118 
00119       // If neither of the above then search up the type hierarchy
00120           // to see if a supertype extends Thread
00121           //   recurse up the hierarchy searching
00122           //   if found then pick up the lowest "run" method coming down
00123           //
00124           // Also check to see if a supertype implements Runnable
00125           // directly or indirectly  
00126           //   recurse up the hierarchy searching
00127           //   if found then pick up the lowest "run" method coming down
00128           {
00129             theRun = null;
00130             if (theClass.hasSuperClass() && FindRun(theClass.getSuperClass())) {
00131           SootMethod newRun = new SootMethod("run", new ArrayList(), VoidType.v());
00132           JimpleBody body = (JimpleBody) Jimple.v().newBody(newRun);
00133           body.getStmtList().addAll(((JimpleBody) theRun.getBody(Jimple.v())).getStmtList());
00134           body.getLocals().addAll(((JimpleBody) theRun.getBody(Jimple.v())).getLocals());
00135           body.getTraps().addAll(((JimpleBody) theRun.getBody(Jimple.v())).getTraps());
00136           newRun.storeBody(Jimple.v(), body);
00137           theClass.addMethod(newRun);
00138               tmpClasses.add(theClass);
00139               continue;
00140             }
00141           }
00142     }
00143 
00144     return tmpClasses;
00145 }
00146 public static void main(String args[]) {
00147     SootClassManager classManager = new SootClassManager();
00148     CompilationManager.reset();
00149     CompilationManager.setFilename(args[0]);
00150     CompilationManager.setClasspath(".");
00151     CompilationManager.setIncludedPackagesOrTypes(new String[0]);
00152 
00153     //Compile 
00154     try { CompilationManager.compile(); } 
00155         catch (Exception e) { 
00156       System.out.println(e);
00157       System.out.println("Compilation failed");
00158     }
00159 
00160     Hashtable storedClasses = CompilationManager.getCompiledClasses();
00161 
00162     Enumeration scIter = storedClasses.elements();
00163     while (scIter.hasMoreElements()) {
00164       ((SootClass) scIter.nextElement()).resolveIfNecessary();
00165     }
00166 
00167     java.util.HashSet rClasses = IdentifyRunnableClasses.identify(storedClasses.elements());
00168 
00169     for (java.util.Iterator cIt = rClasses.iterator(); cIt.hasNext(); ) {
00170       ((SootClass)cIt.next()).printTo(new StoredBody(Jimple.v()), new PrintWriter(System.out, true));
00171     }
00172 }
00173 }

Generated at Thu Feb 7 06:46:20 2002 for Bandera by doxygen1.2.10 written by Dimitri van Heesch, © 1997-2001