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

DecompilerValueSwitch.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 import ca.mcgill.sable.soot.*;
00036 import ca.mcgill.sable.soot.jimple.*;
00037 import ca.mcgill.sable.util.*;
00038 import java.util.*;
00039 import edu.ksu.cis.bandera.jjjc.*;
00040 import ca.mcgill.sable.util.Iterator;
00041 import ca.mcgill.sable.util.LinkedList;
00042 import edu.ksu.cis.bandera.jext.*;
00043 import edu.ksu.cis.bandera.abstraction.*;
00044 import edu.ksu.cis.bandera.abstraction.util.*;
00045 
00046 /**
00047  * DecompilerValueSwitch is a recursive analyzer for values.
00048  * The methods are basically each case possible for values.
00049  * See DecompilerSwitch for details.
00050  * @author <a href="mailto:robbyjo@cis.ksu.edu">Roby Joehanes</a>
00051  * @version 0.4.21
00052 **/
00053 public class DecompilerValueSwitch extends AbstractBanderaValueSwitch {
00054     private static DecompilerValueSwitch walker = new DecompilerValueSwitch();
00055     private Vector res = new Vector();
00056     private static boolean ifstmt = false;
00057 public DecompilerValueSwitch()
00058 {
00059 }
00060 public void caseAddExpr(AddExpr v)
00061 {
00062     res.add("(");
00063     evaluate(v.getOp1());
00064     res.add(" ");
00065     res.add("+");
00066     res.add(" ");
00067     evaluate(v.getOp2());
00068     res.add(")");
00069 }
00070 public void caseAndExpr(AndExpr v)
00071 {
00072     res.add("(");
00073     evaluate(v.getOp1());
00074     res.add(" ");
00075     res.add("&");
00076     res.add(" ");
00077     evaluate(v.getOp2());
00078     res.add(")");
00079 }
00080 public void caseArrayRef(ArrayRef v)
00081 {
00082     evaluate(v.getBase());
00083     res.add("[");
00084     evaluate(v.getIndex());
00085     res.add("]");
00086 }
00087 public void caseCastExpr(CastExpr v)
00088 {
00089     res.add("((");
00090     res.add(v.getType().toString());
00091     res.add(")");
00092     res.add(" ");
00093     evaluate(v.getOp());
00094     res.add(")");
00095 }
00096 public void caseCaughtExceptionRef(CaughtExceptionRef v)
00097 {
00098     res.add(v.toString());
00099 }
00100 /**
00101  * This method was created in VisualAge.
00102  */
00103 public void caseChooseExpr(ChooseExpr v) {
00104 /*  SootClass sc = CompilationManager.getSootClassManager().getClass("edu.ksu.cis.bandera.abstraction.Abstraction");
00105     SootMethod sm = sc.getMethod("choose", new ca.mcgill.sable.util.LinkedList());
00106     
00107     ca.mcgill.sable.util.List args = v.getChoices();
00108 
00109     setResult(Jimple.v().newStaticInvokeExpr(sm, args).toString());
00110 */
00111     // This is a very nasty hack
00112     res.add("Bandera.choose() ? 0 : 1");
00113 }
00114 public void caseCmpExpr(CmpExpr v)
00115 {
00116     res.add("/* CMP was added */");
00117 }
00118 public void caseCmpgExpr(CmpgExpr v)
00119 {
00120     res.add("/* CMPG was added */");
00121 }
00122 public void caseCmplExpr(CmplExpr v)
00123 {
00124     res.add("/* CMPL was added */");
00125 }
00126 public void caseDivExpr(DivExpr v)
00127 {
00128     res.add("(");
00129     evaluate(v.getOp1());
00130     res.add(" ");
00131     res.add("/");
00132     res.add(" ");
00133     evaluate(v.getOp2());
00134     res.add(")");
00135 }
00136 public void caseDoubleConstant(DoubleConstant v)
00137 {
00138     res.add(v.toString());
00139 }
00140 public void caseEqExpr(EqExpr v)
00141 {
00142     String sign = "==";
00143     Value leftOp = v.getOp1();
00144     Value rightOp = v.getOp2();
00145     String rightValue = rightOp.toString().trim();
00146 
00147     if (ifstmt) { sign = "!="; ifstmt = false; }
00148     if (rightValue.equals("0"))
00149     {
00150         if (DecompilerInfo.isBool(leftOp))
00151         {
00152             if (sign.equals("=="))
00153             {
00154                 res.add("!");
00155             }
00156             evaluate(leftOp);
00157             return;
00158         }
00159     }
00160     evaluate(leftOp);
00161     res.add(" ");
00162     res.add(sign);
00163     res.add(" ");
00164     evaluate(rightOp);
00165 }
00166 public void caseFloatConstant(FloatConstant v)
00167 {
00168     res.add(v.toString());
00169 }
00170 public void caseGeExpr(GeExpr v)
00171 {
00172     String sign = ">=";
00173     if (ifstmt) { ifstmt = false; sign = "<"; }
00174     evaluate(v.getOp1());
00175     res.add(" ");
00176     res.add(sign);
00177     res.add(" ");
00178     evaluate(v.getOp2());
00179 }
00180 public void caseGtExpr(GtExpr v)
00181 {
00182     String sign = ">";
00183     if (ifstmt) { ifstmt = false; sign = "<="; }
00184     evaluate(v.getOp1());
00185     res.add(" ");
00186     res.add(sign);
00187     res.add(" ");
00188     evaluate(v.getOp2());
00189 }
00190 public void caseInstanceFieldRef(InstanceFieldRef v)
00191 {
00192     evaluate(v.getBase());
00193     res.add(".");
00194     res.add(v.getField().getName());
00195 }
00196 public void caseInstanceOfExpr(InstanceOfExpr v)
00197 {
00198     evaluate(v.getOp());
00199     res.add(" ");
00200     res.add("instanceof");
00201     res.add(" ");
00202     res.add(v.getType().toString());
00203 }
00204 public void caseIntConstant(IntConstant v)
00205 {
00206     if (Decompiler.typeTable != null)
00207     {
00208         Abstraction lt = Decompiler.typeTable.get(v);
00209         // Is this abstracted?
00210         if (DecompilerUtil.isAbstracted(lt))
00211         {
00212             String tokName = AbstractionClassLoader.getTokenName(lt,v.value);
00213             String fullName = lt.getClass().getName();
00214             int lastDot = fullName.lastIndexOf(".");
00215             String pkgName = fullName.substring(0,lastDot);
00216             Decompiler.addImports(pkgName+".*");
00217             res.add(tokName);
00218         } else res.add(v.toString());
00219     } else res.add(v.toString());
00220 }
00221 public void caseInterfaceInvokeExpr(InterfaceInvokeExpr v)
00222 {
00223     caseNonStaticInvokeExpr(v);
00224 }
00225 private void caseInvokeExpr(InvokeExpr v)
00226 {
00227     int param = v.getArgCount();
00228 
00229     SootMethod sm = v.getMethod();
00230     String methodName = sm.getName().trim();
00231 
00232     if ((methodName.length()>0) && (!methodName.equals("<init>")))
00233     {
00234         res.add(".");
00235         res.add(methodName);
00236     }
00237     res.add("(");
00238 
00239     for (int i=0; i<param; i++)
00240     {
00241         Value theParam = v.getArg(i);
00242         String paramType = sm.getParameterType(i).toString().trim();
00243 
00244         // We don't want integer values passed as booleans
00245         if ((theParam instanceof IntConstant) && (paramType.equals("boolean")))
00246         {
00247             String val = theParam.toString().trim();
00248             if (val.equals("0")) res.add("false");
00249                 else if (val.equals("1")) res.add("true");
00250                     else    res.add("true /* Bug in JJJC. boolval = "+val+" */");
00251         } else
00252         {
00253             evaluate(theParam);
00254         }
00255         if (i!=param-1) res.add(",");
00256     }
00257 
00258     // Close parentheses
00259     res.add(")");
00260 }
00261 public void caseLeExpr(LeExpr v)
00262 {
00263     String sign = "<=";
00264     if (ifstmt) { ifstmt = false; sign = ">"; }
00265     evaluate(v.getOp1());
00266     res.add(" ");
00267     res.add(sign);
00268     res.add(" ");
00269     evaluate(v.getOp2());
00270 }
00271 public void caseLengthExpr(LengthExpr v)
00272 {
00273     evaluate(v.getOp());
00274     res.add(".");
00275     res.add("length");
00276 }
00277 public void caseLocal(Local v)
00278 {
00279     res.add(v.getName().trim());
00280 }
00281 public void caseLongConstant(LongConstant v)
00282 {
00283     res.add(v.toString());
00284 }
00285 public void caseLtExpr(LtExpr v)
00286 {
00287     String sign = "<";
00288     if (ifstmt) { ifstmt = false; sign = ">="; }
00289     evaluate(v.getOp1());
00290     res.add(" ");
00291     res.add(sign);
00292     res.add(" ");
00293     evaluate(v.getOp2());
00294 }
00295 public void caseMulExpr(MulExpr v)
00296 {
00297     res.add("(");
00298     evaluate(v.getOp1());
00299     res.add(" ");
00300     res.add("*");
00301     res.add(" ");
00302     evaluate(v.getOp2());
00303     res.add(")");
00304 }
00305 public void caseNeExpr(NeExpr v)
00306 {
00307     String sign = "!=";
00308     Value leftOp = v.getOp1();
00309     Value rightOp = v.getOp2();
00310     String rightValue = rightOp.toString().trim();
00311 
00312     if (ifstmt) { sign = "=="; ifstmt = false; }
00313     if (rightValue.equals("0"))
00314     {
00315         if (DecompilerInfo.isBool(leftOp))
00316         {
00317             if (sign.equals("=="))
00318             {
00319                 res.add("!");
00320             }
00321             evaluate(leftOp);
00322             return;
00323         }
00324     }
00325     evaluate(leftOp);
00326     res.add(" ");
00327     res.add(sign);
00328     res.add(" ");
00329     evaluate(rightOp);
00330 }
00331 public void caseNegExpr(NegExpr v)
00332 {
00333     res.add("-");
00334     res.add(" ");
00335     evaluate(v.getOp());
00336 }
00337 public void caseNewArrayExpr(NewArrayExpr v)
00338 {
00339     res.add("new");
00340     res.add(" ");
00341     String baseType = v.getType().toString();
00342     while (baseType.endsWith("[]"))
00343         baseType = baseType.substring(0,baseType.length()-2);
00344     res.add(baseType);
00345     res.add("[");
00346     evaluate(v.getSize());
00347     res.add("]");
00348 }
00349 public void caseNewExpr(NewExpr v)
00350 {
00351     res.add("new");
00352     res.add(" ");
00353     res.add(v.getType().toString());
00354 }
00355 public void caseNewInvokeExpr(NewInvokeExpr v)
00356 {
00357     res.add("new");
00358     res.add(" ");
00359     res.add(v.getBaseType().toString());
00360     caseInvokeExpr(v);
00361 }
00362 public void caseNewMultiArrayExpr(NewMultiArrayExpr v)
00363 {
00364     int max = v.getSizeCount();
00365     
00366     res.add("new");
00367     res.add(" ");
00368     res.add(v.getBaseType().toString());
00369 
00370     // Get all sizes of the array
00371     for (int i=0; i<max; i++)
00372     {
00373         res.add("[");
00374         evaluate(v.getSize(i));
00375         res.add("]");
00376     }
00377 }
00378 private void caseNonStaticInvokeExpr(NonStaticInvokeExpr v)
00379 {
00380     evaluate(v.getBase());
00381     caseInvokeExpr(v);
00382 }
00383 public void caseNullConstant(NullConstant v)
00384 {
00385     //res.add(v.toString()); // i.e. null
00386     res.add("null");
00387 }
00388 public void caseOrExpr(OrExpr v)
00389 {
00390     res.add("(");
00391     evaluate(v.getOp1());
00392     res.add(" ");
00393     res.add("|");
00394     res.add(" ");
00395     evaluate(v.getOp2());
00396     res.add(")");
00397 }
00398 public void caseParameterRef(ParameterRef v)
00399 {
00400     res.add(v.toString());
00401 }
00402 public void caseRemExpr(RemExpr v)
00403 {
00404     res.add("(");
00405     evaluate(v.getOp1());
00406     res.add(" ");
00407     res.add("%");
00408     res.add(" ");
00409     evaluate(v.getOp2());
00410     res.add(")");
00411 }
00412 public void caseShlExpr(ShlExpr v)
00413 {
00414     res.add("(");
00415     evaluate(v.getOp1());
00416     res.add(" ");
00417     res.add("<<");
00418     res.add(" ");
00419     evaluate(v.getOp2());
00420     res.add(")");
00421 }
00422 public void caseShrExpr(ShrExpr v)
00423 {
00424     res.add("(");
00425     evaluate(v.getOp1());
00426     res.add(" ");
00427     res.add(">>");
00428     res.add(" ");
00429     evaluate(v.getOp2());
00430     res.add(")");
00431 }
00432 public void caseSpecialInvokeExpr(SpecialInvokeExpr v)
00433 {
00434     caseNonStaticInvokeExpr(v);
00435 }
00436 public void caseStaticFieldRef(StaticFieldRef v)
00437 {
00438     SootField sf = v.getField();
00439     String clsName = sf.getDeclaringClass().getName().trim();
00440     String fieldname = v.getField().getName().trim();
00441     if (!clsName.equals(DecompilerInfo.getClassName()))
00442     {
00443         res.add(clsName);
00444         res.add(".");
00445     }
00446     res.add(fieldname);
00447 }
00448 public void caseStaticInvokeExpr(StaticInvokeExpr v)
00449 {
00450     res.add(v.getMethod().getDeclaringClass().getName());
00451     caseInvokeExpr(v);
00452 }
00453 public void caseStringConstant(StringConstant v)
00454 {
00455     res.add(v.toString());
00456 }
00457 public void caseSubExpr(SubExpr v)
00458 {
00459     res.add("(");
00460     evaluate(v.getOp1());
00461     res.add(" ");
00462     res.add("-");
00463     res.add(" ");
00464     evaluate(v.getOp2());
00465     res.add(")");
00466 }
00467 public void caseThisRef(ThisRef v)
00468 {
00469     res.add("this");
00470 }
00471 public void caseUshrExpr(UshrExpr v)
00472 {
00473     res.add("(");
00474     evaluate(v.getOp1());
00475     res.add(" ");
00476     res.add(">>>");
00477     res.add(" ");
00478     evaluate(v.getOp2());
00479     res.add(")");
00480 }
00481 public void caseVirtualInvokeExpr(VirtualInvokeExpr v)
00482 {
00483     caseNonStaticInvokeExpr(v);
00484 }
00485 public void caseXorExpr(XorExpr v)
00486 {
00487     res.add("(");
00488     evaluate(v.getOp1());
00489     res.add(" ");
00490     res.add("^");
00491     res.add(" ");
00492     evaluate(v.getOp2());
00493     res.add(")");
00494 }
00495 public void defaultCase(Object v)
00496 {
00497     // Nothing... probably some error
00498     res.add("/* Default case: Probably some error! */");
00499 }
00500 public static Vector evaluate(Value v)
00501 {
00502     if (v==null) return new Vector();
00503     v.apply(walker);
00504     return walker.getRes();
00505 }
00506 private Vector getRes()
00507 {
00508     return res;
00509 }
00510 public static void isAnIfStmt(boolean b) { ifstmt = b; }
00511 public static void reset()
00512 {
00513     walker.res = new Vector();
00514 }
00515 }

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