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

DecompilerInfo.java

00001 package edu.ksu.cis.bandera.jjjc.decompiler;
00002 
00003 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
00004  * Bandera, a Java(TM) analysis and transformation toolkit           *
00005  * Copyright (C) 2000 Roby Joehanes (robbyjo@cis.ksu.edu)            *
00006  * All rights reserved.                                              *
00007  *                                                                   *
00008  * This work was done as a project in the SAnToS Laboratory,         *
00009  * Department of Computing and Information Sciences, Kansas State    *
00010  * University, USA (http://www.cis.ksu.edu/santos).                  *
00011  * It is understood that any modification not identified as such is  *
00012  * not covered by the preceding statement.                           *
00013  *                                                                   *
00014  * This work is free software; you can redistribute it and/or        *
00015  * modify it under the terms of the GNU Library General Public       *
00016  * License as published by the Free Software Foundation; either      *
00017  * version 2 of the License, or (at your option) any later version.  *
00018  *                                                                   *
00019  * This work is distributed in the hope that it will be useful,      *
00020  * but WITHOUT ANY WARRANTY; without even the implied warranty of    *
00021  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU *
00022  * Library General Public License for more details.                  *
00023  *                                                                   *
00024  * You should have received a copy of the GNU Library General Public *
00025  * License along with this toolkit; if not, write to the             *
00026  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,      *
00027  * Boston, MA  02111-1307, USA.                                      *
00028  *                                                                   *
00029  * Java is a trademark of Sun Microsystems, Inc.                     *
00030  *                                                                   *
00031  * To submit a bug report, send a comment, or get the latest news on *
00032  * this project and other SAnToS projects, please visit the web-site *
00033  *                http://www.cis.ksu.edu/santos                      *
00034  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
00035 /**
00036  * DecompilerInfo basically holds all the information the decompiler need.
00037  * Used in conjunction to DecompilerField.
00038  * The methods and fields are self-explanatory.
00039  * @author <a href="mailto:robbyjo@cis.ksu.edu">Roby Joehanes</a>
00040  * @version 0.4.21
00041 **/
00042 import ca.mcgill.sable.soot.*;
00043 import ca.mcgill.sable.soot.jimple.*;
00044 import java.util.*;
00045 public class DecompilerInfo {
00046     private static SootClass sc;
00047     private static SootMethod sm;
00048     private static int noOfParam;
00049     private static Hashtable fieldTable;
00050     private static boolean synchro;
00051     private static String[] paramType;
00052     private static String[] paramName;
00053     private static Vector boolTemp = new Vector();
00054     private static Vector boolVar = new Vector();
00055     private static LinkedList qvDefined = new LinkedList();
00056 public static void decipherParam(Stmt[] stmt)
00057 {
00058     int max = stmt.length;
00059     String errorMsg = "Error in parameter at "+getClassName()+ ":"+ getMethodName();
00060 
00061     for (int i=0; i<max; i++)
00062     {
00063         if (stmt[i] instanceof IdentityStmt)
00064         {
00065             String name = ((IdentityStmt) stmt[i]).getLeftOp().toString();
00066             String paramID = ((IdentityStmt) stmt[i]).getRightOp().toString();
00067             if (paramID.startsWith("@parameter"))
00068             {
00069                 try {
00070                     int id = Integer.parseInt(paramID.substring(10));
00071                     paramName[id] = name;
00072                 } catch (NumberFormatException ex)
00073                 {
00074                     System.out.println(errorMsg+", non-integer parameterID, seemed to be JJJC error!");
00075                 }
00076             }
00077         } else
00078         {
00079             System.out.println(errorMsg);
00080         }
00081     }
00082 }
00083 public static String getClassDeclaration()
00084 {
00085     // Get class modifier
00086     String modifier = Modifier.toString(sc.getModifiers());
00087     StringBuffer buf = new StringBuffer();
00088 
00089     if (modifier.length() > 0) buf.append(modifier + " ");
00090     buf.append("class " + getClassName() + " ");
00091 
00092     // Is there any super class ?
00093     try
00094     {
00095         if (sc.hasSuperClass())
00096         {
00097             String superName = sc.getSuperClass().getName().trim();
00098             if (!superName.equals("java.lang.Object"))
00099                 buf.append("extends " + DecompilerUtil.stripImports(superName) + " ");
00100         }
00101     } catch (Exception exc)
00102     {
00103         System.out.println("No super class error! This shouldn't happen!\n");
00104     }
00105     return buf.toString();
00106 }
00107 public static String getClassName() { return sc.getName().trim(); }
00108 public static Vector getFieldDeclaration()
00109 {
00110     Vector buf = new Vector();
00111     for (Enumeration key = fieldTable.keys(); key.hasMoreElements();)
00112     {
00113         DecompilerField sf = (DecompilerField) fieldTable.get((String) key.nextElement());
00114         String modi = sf.getModifier();
00115         StringBuffer st = new StringBuffer();
00116         if (modi.length()>0) st.append(sf.getModifier()+" ");
00117         String temp = sf.getType();
00118 //      if (temp.equals("boolean")) temp = "int";
00119         st.append(temp+" "+sf.getName());
00120         
00121         String s = sf.getDefaultValue();
00122         if (s.length()>0) st.append(" = "+s);
00123         buf.add(st.toString()+";");
00124     }
00125     return buf;
00126 }
00127 public static String getMethodDeclaration()
00128 {
00129     String name = getMethodName();
00130     if (name.equals("<initHelper>") || name.equals("<clinit>")) return "";
00131 
00132     StringBuffer s = new StringBuffer();
00133     String modifier = Modifier.toString(sm.getModifiers()).trim();
00134     
00135     if (modifier.length()>0) s.append(modifier+" ");
00136     if (synchro) s.append("synchronized ");
00137 
00138     if (name.equals("<init>"))
00139     {
00140         s.append(getClassName()+"("); 
00141     } else
00142     {
00143         s.append(getMethodRetType()+" "+name+" (");
00144     }
00145 
00146     for (int i = 0; i<noOfParam; i++)
00147     {
00148         String st = paramType[i];
00149 //      if (st.equals("boolean")) st = "int";
00150     String pname = paramName[i];
00151     if (pname == null) pname = "param"+i;
00152         s.append(st+" "+pname);
00153         if (i!=noOfParam-1) s.append(", ");
00154     }
00155     s.append(")");
00156     
00157     return s.toString();
00158 }
00159 public static String getMethodName() { return sm.getName().trim(); }
00160 public static String getMethodRetType()
00161 {
00162     String s = sm.getReturnType().toString().trim();
00163 //  if (s.equals("boolean")) s = "int";
00164     return s;
00165 }
00166 public static int getNoOfParam() { return noOfParam; }
00167 private static String getParamType(String name)
00168 {
00169     if (isParam(name))
00170     {
00171         for (int i=0; i<noOfParam; i++)
00172         {
00173             if (paramName[i].equals(name)) return paramType[i];
00174         }
00175     }
00176     return "";
00177 }
00178 public static boolean hasField()
00179 {
00180     return !fieldTable.isEmpty();
00181 }
00182 public static boolean isAbstract() { return Modifier.isAbstract(sm.getModifiers()); }
00183 // The only thing left unchecked is local variables
00184 public static boolean isBool(Value v)
00185 {
00186     if (isJimpleTemp(v)) return boolTemp.contains(v);
00187     if (v instanceof Local)
00188     {
00189         String st = v.toString().trim();
00190 
00191         // Is it a parameter or not
00192         if (getParamType(st).equals("boolean")) return true;
00193         if (boolVar.contains(st)) return true;
00194     } else
00195     {
00196         if (v instanceof FieldRef)
00197         {
00198             return ((FieldRef) v).getField().getType().toString().trim().equals("boolean");
00199         } else
00200         {
00201             if (v instanceof InvokeExpr)
00202             {
00203                 return ((InvokeExpr) v).getMethod().getReturnType().toString().trim().equals("boolean");
00204             }
00205         }
00206     }
00207     return false;
00208 }
00209 public static boolean isField(String x)
00210 {
00211     return fieldTable.containsKey(stripThis(x));
00212 }
00213 public static boolean isInitializer()
00214 {
00215     String name = getMethodName();
00216     return name.equals("<init>") || name.equals("<clinit>") || name.equals("<initHelper>");
00217 }
00218 public static boolean isInterface() { return Modifier.isInterface(sc.getModifiers()); }
00219 public static boolean isJimpleInitializer()
00220 {
00221     String name = getMethodName();
00222     return name.equals("<clinit>") || name.equals("<initHelper>");
00223 }
00224 public static boolean isJimpleTemp(Value v)
00225 {
00226     String s = v.toString().trim();
00227     return (v instanceof Local) && (DecompilerUtil.isJimpleID(s));
00228 }
00229 public static boolean isParam(String name)
00230 {
00231     if (name==null) return false;
00232     if (paramName == null) return false;
00233 
00234     for (int i=0; i<noOfParam; i++)
00235     {
00236         if ((paramName[i]!=null) && (paramName[i].equals(name)))
00237         {
00238             return true;
00239         }
00240     }
00241     return false;
00242 }
00243 public static boolean isStaticMethod() { return Modifier.isStatic(sm.getModifiers()); }
00244 public static void putVarInfo(Value lhs, Value rhs)
00245 {
00246     if ((isJimpleTemp(lhs)) && (rhs.getType().toString().trim().equals("boolean")))
00247     {
00248         boolTemp.add(lhs);
00249     }
00250 }
00251 public static void putVarInfo(String var)
00252 {
00253     boolVar.add(var);
00254 }
00255 public static int qvDef(Value v)
00256 {
00257     String name = v.toString();
00258     // Is a local, a quantified variable tag, and contains no dot (i.e. no complex name)
00259     if (!(v instanceof Local && name.indexOf("qtvars") != -1 && name.indexOf(".") == -1)) return -1;
00260 
00261     if (qvDefined.contains(name)) return 1;
00262     qvDefined.add(name);
00263     return 0;
00264 }
00265 public static void reset()
00266 {
00267     sc = null; sm = null;
00268     fieldTable = new Hashtable();
00269     noOfParam = -1;
00270 }
00271 public static void setClass(SootClass sootc)
00272 {
00273     sc = sootc;
00274     fieldTable = new Hashtable();
00275     ca.mcgill.sable.util.Iterator i;
00276 
00277     for (i=sc.getFields().iterator(); i.hasNext();)
00278     {
00279         SootField sf = (SootField) i.next();
00280         String name = sf.getName();
00281         String modifier = Modifier.toString(sf.getModifiers()).trim();
00282         String type = sf.getType().toString().trim();
00283         fieldTable.put(name, new DecompilerField(name,type,modifier));
00284     }
00285 }
00286 public static void setFieldDefaultValue(String fieldName, char i)
00287 {
00288     DecompilerField sf = (DecompilerField) fieldTable.get(stripThis(fieldName));
00289     sf.setDefaultValue(String.valueOf(i));
00290 }
00291 public static void setFieldDefaultValue(String fieldName, double i)
00292 {
00293     DecompilerField sf = (DecompilerField) fieldTable.get(stripThis(fieldName));
00294     sf.setDefaultValue(String.valueOf(i));
00295 }
00296 public static void setFieldDefaultValue(String fieldName, float i)
00297 {
00298     DecompilerField sf = (DecompilerField) fieldTable.get(stripThis(fieldName));
00299     sf.setDefaultValue(String.valueOf(i));
00300 }
00301 public static void setFieldDefaultValue(String fieldName, int i)
00302 {
00303     DecompilerField sf = (DecompilerField) fieldTable.get(stripThis(fieldName));
00304     sf.setDefaultValue(String.valueOf(i));
00305 }
00306 public static void setFieldDefaultValue(String fieldName, long i)
00307 {
00308     DecompilerField sf = (DecompilerField) fieldTable.get(stripThis(fieldName));
00309     sf.setDefaultValue(String.valueOf(i));
00310 }
00311 public static void setFieldDefaultValue(String fieldName, String i)
00312 {
00313     DecompilerField sf = (DecompilerField) fieldTable.get(stripThis(fieldName));
00314     sf.setDefaultValue(i);
00315 }
00316 public static void setFieldDefaultValue(String fieldName, boolean i)
00317 {
00318     DecompilerField sf = (DecompilerField) fieldTable.get(stripThis(fieldName));
00319     sf.setDefaultValue(String.valueOf(i));
00320 }
00321 public static void setMethod(SootMethod sootm)
00322 {
00323     sm = sootm;
00324     noOfParam = sm.getParameterCount();
00325     paramType = new String[noOfParam];
00326     paramName = new String[noOfParam];
00327 
00328     for (int i = 0; i<noOfParam; i++)
00329     {
00330         String st = sm.getParameterType(i).toString();
00331         paramType[i] = st;
00332     }
00333     synchro = false;
00334     boolTemp = new Vector();
00335     boolVar = new Vector();
00336 }
00337 public static void setSynchro(boolean s) { synchro = s; }
00338 private static String stripThis(String x)
00339 {
00340     if (x.startsWith("this.")) return x.substring(5);
00341     if (x.startsWith("this().")) return x.substring(7);
00342     return x;
00343 }
00344 }

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