00001 package edu.ksu.cis.bandera.jjjc.decompiler;
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
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
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
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
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
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
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
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
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
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 }