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

DecompilerSwitch.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 
00039 import edu.ksu.cis.bandera.abstraction.*;
00040 import edu.ksu.cis.bandera.abstraction.util.*;
00041 import edu.ksu.cis.bandera.annotation.*;
00042 import edu.ksu.cis.bandera.jjjc.node.*;
00043 
00044 import java.io.*;
00045 import java.util.*;
00046 
00047 /**
00048  * DecompilerSwitch is a recursive analyzer for annotations.
00049  * The methods are basically each case possible for annotations.
00050  * Inside annotations, we have statements, which is recursively
00051  * handled by DecompilerStmtSwitch. Inside each statement, we can have
00052  * several value chunks, which is recursively handled by
00053  * DecompilerValueSwitch.
00054  * @author <a href="mailto:robbyjo@cis.ksu.edu">Roby Joehanes</a>
00055  * @version 0.4.21
00056 **/
00057 public class DecompilerSwitch extends AnnotationSwitch {
00058     private static DecompilerSwitch walker = new DecompilerSwitch();
00059     private Vector result = new Vector();
00060     private Hashtable lineToAnnotation = new Hashtable();
00061     private static int tempCounter = 0;
00062 public DecompilerSwitch()
00063 {
00064     result = new Vector();
00065 }
00066 private void caseBlock(BlockStmtAnnotation a)
00067 {
00068     for (Enumeration i=a.getContainedAnnotations().elements(); i.hasMoreElements(); )
00069     {
00070         Annotation annot = (Annotation) i.nextElement();
00071         evaluate(annot);
00072     }
00073 }
00074 /**
00075  * caseBlockStmtAnnotation method comment.
00076  */
00077 public void caseBlockStmtAnnotation(BlockStmtAnnotation a)
00078 {
00079     lineToAnnotation.put(new DecompilerPair(result.size()),a);
00080     caseBlock(a);
00081 }
00082 /**
00083  * caseBreakStmtAnnotation method comment.
00084  */
00085 public void caseBreakStmtAnnotation(BreakStmtAnnotation a) {
00086     lineToAnnotation.put(new DecompilerPair(result.size()),a);
00087     result.add("break;");
00088 }
00089 /**
00090  * caseCatchAnnotation method comment.
00091  */
00092 public void caseCatchAnnotation(CatchAnnotation a) {
00093     StringBuffer s = new StringBuffer();
00094     Stmt[] stmts = a.getStatements();
00095     int max = stmts.length;
00096 
00097     lineToAnnotation.put(new DecompilerPair(result.size()),a);
00098     s.append("catch (");
00099     for (int i=0; i<max; i++)
00100     {
00101         if (stmts[i] instanceof IdentityStmt)
00102         {
00103             IdentityStmt ids = (IdentityStmt) stmts[i];
00104             Value lhs  = ids.getLeftOp();
00105             String left = DecompilerUtil.flattenToString(DecompilerValueSwitch.evaluate(lhs));
00106             DecompilerValueSwitch.reset();
00107             String right= DecompilerUtil.flattenToString(DecompilerValueSwitch.evaluate(ids.getRightOp()));
00108             DecompilerValueSwitch.reset();
00109             if (right.equals("@caughtexception"))
00110             {
00111                 s.append(lhs.getType().toString()+" "+left);
00112             }
00113         }
00114     }
00115     s.append(") {");
00116     result.add(s.toString());
00117     caseBlock(a);
00118     result.add("}");
00119 }
00120 /**
00121  * caseClassDeclarationAnnotation method comment.
00122  */
00123 public void caseClassDeclarationAnnotation(ClassDeclarationAnnotation a) {
00124     lineToAnnotation.put(new DecompilerPair(result.size()),a);
00125     // Neglected
00126 }
00127 /**
00128  * caseConstructorDeclarationAnnotation method comment.
00129  */
00130 public void caseConstructorDeclarationAnnotation(ConstructorDeclarationAnnotation a) {
00131     Enumeration i=a.getContainedAnnotations().elements();
00132 
00133     Annotation an;
00134 
00135     lineToAnnotation.put(new DecompilerPair(result.size()),a);
00136     if ((!DecompilerInfo.isStaticMethod()) && (i.hasMoreElements()))
00137     {
00138         an = (Annotation) i.nextElement();
00139         evaluate(an);
00140     }
00141 
00142     if ((DecompilerInfo.getNoOfParam()>0) && (i.hasMoreElements()))
00143     {
00144         an = (Annotation) i.nextElement();
00145         DecompilerInfo.decipherParam(an.getStatements());
00146     }
00147 
00148     if (!DecompilerInfo.hasField()) DecompilerUtil.setAllowField(false);
00149     // Is there init helper?
00150     SootMethod sm = null;
00151     try {
00152         sm = a.getSootMethod().getDeclaringClass().getMethod("<initHelper>");
00153     } catch (Exception e)
00154     {
00155         sm = null;
00156     }
00157     if ((sm==null) && (i.hasMoreElements()) && (DecompilerInfo.hasField()))
00158     {
00159         // If there is no init helper, the next annotation has to be field-initialization.
00160         //DecompilerUtil.setAllowField(true);
00161         an = (Annotation) i.nextElement();
00162         evaluate(an);
00163         DecompilerUtil.setAllowField(false);
00164     }
00165 
00166     // Process the rest.
00167     while (i.hasMoreElements())
00168     {
00169         an = (Annotation) i.nextElement();
00170         evaluate(an);
00171     }
00172 
00173     if (result.size()==0)
00174     {
00175         Hashtable assgVar = DecompilerUtil.getAssignedVarTable();
00176     }
00177 }
00178 /**
00179  * caseContinueStmtAnnotation method comment.
00180  */
00181 public void caseContinueStmtAnnotation(ContinueStmtAnnotation a)
00182 {
00183     // Still murky... dunno about this one
00184     // result.add(a.toString().trim()+";");
00185     lineToAnnotation.put(new DecompilerPair(result.size()),a);
00186     result.add("continue;");
00187 }
00188 /**
00189  * caseDoWhileStmtAnnotation method comment.
00190  */
00191 public void caseDoWhileStmtAnnotation(DoWhileStmtAnnotation a)
00192 {
00193     StringBuffer s = new StringBuffer();
00194     Stmt[] testStmts = a.getTestStatements();
00195 
00196     result.addAll(DecompilerUtil.dumpStmt(testStmts));
00197     
00198     lineToAnnotation.put(new DecompilerPair(result.size()),a);
00199     result.add("do {");
00200     evaluate(a.getBlockAnnotation());
00201     s.append("} while ");
00202     s.append(DecompilerUtil.analyzeCondition(testStmts,2));
00203     s.append(";");
00204     result.add(s.toString());
00205 }
00206 /**
00207  * caseEmptyStmtAnnotation method comment.
00208  */
00209 public void caseEmptyStmtAnnotation(EmptyStmtAnnotation a) {
00210     // An empty statement, do nothing
00211     lineToAnnotation.put(new DecompilerPair(result.size()),a);
00212 }
00213 /**
00214  * caseExpStmtAnnotation method comment.
00215  */
00216 public void caseExpStmtAnnotation(ExpStmtAnnotation a) {
00217     lineToAnnotation.put(new DecompilerPair(result.size()),a);
00218     caseSequential(a);
00219 }
00220 /**
00221  * caseFieldDeclarationAnnotation method comment.
00222  */
00223 public void caseFieldDeclarationAnnotation(FieldDeclarationAnnotation a)
00224 {
00225     // Already processed in decompiling classes,
00226     // no need to further process this one
00227     lineToAnnotation.put(new DecompilerPair(result.size()),a);
00228 }
00229 /**
00230  * caseForStmtAnnotation method comment.
00231  */
00232 public void caseForStmtAnnotation(ForStmtAnnotation a)
00233 {
00234     Annotation initAn = a.getInitAnnotation();
00235     Stmt[] initStmts = null;
00236     if (initAn != null)
00237         initStmts = initAn.getStatements();
00238     Stmt[] testStmts = a.getTestStatements();
00239     Stmt[] updateStmts = a.getUpdateAnnotation().getStatements();
00240 
00241     if (DecompilerUtil.isDebugInfo())
00242     {
00243         result.add("// Init statements");
00244         result.addAll(DecompilerUtil.dumpStmt(initStmts));
00245         result.add("// Test statements");
00246         result.addAll(DecompilerUtil.dumpStmt(testStmts));
00247         result.add("// Update statements");
00248         result.addAll(DecompilerUtil.dumpStmt(updateStmts));
00249     }
00250 
00251     // Annotate this
00252     lineToAnnotation.put(new DecompilerPair(result.size()),a);
00253     DecompilerUtil.resetAssignedVar();
00254     Vector temp = DecompilerUtil.flattenStmts(initStmts);
00255     Hashtable assgVar = DecompilerUtil.getAssignedVarTable();
00256     Hashtable localDecl = a.getDeclaredLocals();
00257     StringBuffer initBuf = new StringBuffer();
00258     initBuf.append("for (");
00259     // If no declared locals, then we simply iterate through the init statements
00260     if (initStmts != null)
00261     {
00262         if (localDecl.size() == 0)
00263         {
00264             for (Enumeration e = assgVar.keys(); e.hasMoreElements();)
00265             {
00266                 String loc = (String) e.nextElement();
00267                 String val = (String) assgVar.get(loc);
00268                 initBuf.append(loc + " = " + val);
00269                 if (e.hasMoreElements())
00270                     initBuf.append(", ");
00271             }
00272         } else
00273         {
00274             boolean first = true;
00275             for (Enumeration e = localDecl.keys(); e.hasMoreElements();)
00276             {
00277                 String locName = (String) e.nextElement();
00278                 String locType = ((Local) localDecl.get(locName)).getType().toString();
00279                 String locVal = (String) assgVar.get(locName);
00280                 if ((locVal == null) || (locVal.length() == 0))
00281                 {
00282                     System.out.println("Error in For: " + locType + " " + locName + " doesn't have value");
00283                 }
00284                 if (first)
00285                 {
00286                     initBuf.append(locType + " ");
00287                     first = false;
00288                 }
00289                 initBuf.append(locName + " = " + locVal);
00290                 if (e.hasMoreElements())
00291                     initBuf.append(", ");
00292             }
00293         }
00294     }
00295     initBuf.append("; ");
00296 
00297     // Test statement
00298     String testLine = DecompilerUtil.analyzeCondition(testStmts,1);
00299     initBuf.append(testLine.substring(1,testLine.length()-1));
00300     initBuf.append("; ");
00301     Vector update = DecompilerUtil.flattenStmts(updateStmts);
00302     for (Enumeration e = update.elements(); e.hasMoreElements();)
00303     {
00304         String st = ((String) e.nextElement()).trim();
00305         initBuf.append(st.substring(0,st.lastIndexOf(";")));
00306         if (e.hasMoreElements())
00307             initBuf.append(", ");
00308     }
00309     initBuf.append(")");
00310     result.add(initBuf.toString());
00311     result.add("{");
00312     evaluate(a.getBlockAnnotation());
00313     result.add("}");
00314 }
00315 /**
00316  * caseIfStmtAnnotation method comment.
00317  */
00318 public void caseIfStmtAnnotation(IfStmtAnnotation a)
00319 {
00320     Stmt[] testStmt = a.getTestStatements();
00321     result.addAll(DecompilerUtil.dumpStmt(testStmt));
00322 
00323     // Not sure yet for the outcome
00324     lineToAnnotation.put(new DecompilerPair(result.size()),a);
00325 
00326     // Slicer may degenerate the if statement into a bunch of assignments...
00327     boolean hasIfStmt = false;
00328     for (int i = 0; i < testStmt.length; i++)
00329     {
00330         if (testStmt[i] instanceof IfStmt)
00331         {
00332             hasIfStmt = true; break;
00333         }
00334     }
00335     if (hasIfStmt)
00336     {
00337         String cond = DecompilerUtil.analyzeCondition(testStmt,1);
00338         String orig = a.toString();
00339 
00340         result.add("if " + cond);
00341         result.add("{");
00342         evaluate(a.getThenAnnotation());
00343 
00344         // Has an else?
00345         Annotation an = a.getElseAnnotation();
00346         if (!DecompilerUtil.isEmptyAnnotation(an))
00347         {
00348             result.add("} else");
00349             result.add("{");
00350             evaluate(an);
00351         }
00352         result.add("}");
00353     } else
00354     {
00355         result.addAll(DecompilerUtil.flattenStmts(testStmt));
00356     }
00357 }
00358 /**
00359  * caseInstanceInitializerAnnotation method comment.
00360  */
00361 public void caseInstanceInitializerAnnotation(InstanceInitializerAnnotation a)
00362 {
00363     lineToAnnotation.put(new DecompilerPair(result.size()),a);
00364     caseBlock(a);
00365 }
00366 /**
00367  * caseLabeledStmtAnnotation method comment.
00368  */
00369 public void caseLabeledStmtAnnotation(LabeledStmtAnnotation a)
00370 {
00371     lineToAnnotation.put(new DecompilerPair(result.size()),a);
00372     caseSequential(a);
00373 }
00374 /**
00375  * caseLocalDeclarationStmtAnnotation method comment.
00376  */
00377 public void caseLocalDeclarationStmtAnnotation(LocalDeclarationStmtAnnotation a)
00378 {
00379     StringBuffer s = new StringBuffer();
00380     String modi = Modifier.toString(a.getModifiers());
00381     String varType = a.getType().toString().trim();
00382     Hashtable locDecl = a.getDeclaredLocals();
00383     if (locDecl.isEmpty()) return; // Probably some bugs in slicing, try to cover up here.
00384     Hashtable abstractedVars = new Hashtable();
00385 
00386     // Something's get abstracted
00387     if (Decompiler.typeTable != null)
00388     {
00389         for (Enumeration locVar = locDecl.elements(); locVar.hasMoreElements(); )
00390         {
00391             Object key = locVar.nextElement();
00392             Abstraction lt = Decompiler.typeTable.get(key);
00393             if (((lt instanceof IntegralAbstraction) && !(lt instanceof ConcreteIntegralAbstraction)) ||
00394                 ((lt instanceof RealAbstraction) && !(lt instanceof ConcreteRealAbstraction)))
00395             {
00396                 abstractedVars.put(key, locDecl.get(key));
00397                 locDecl.remove(key);
00398             }
00399         }
00400     }
00401 
00402     lineToAnnotation.put(new DecompilerPair(result.size()),a);
00403     DecompilerUtil.resetAssignedVar();
00404     Vector temp = DecompilerUtil.flattenStmts(a.getStatements());
00405     Hashtable assgVar = DecompilerUtil.getAssignedVarTable();
00406 
00407     while (abstractedVars != null)
00408     {
00409         if (modi.length()>0) s.append(modi+" ");
00410     //   if (varType.equals("boolean")) varType = "int";
00411         s.append(varType + " ");
00412 
00413         for (Enumeration e = locDecl.keys(); e.hasMoreElements();)
00414         {
00415             String locName = (String) e.nextElement();
00416             String locVal  = (String) assgVar.get(locName);
00417 
00418             s.append(locName);
00419 
00420             // We have a default value here
00421             if ((locVal!=null) && (locVal.length()>0))
00422             {
00423                 s.append(" = ");
00424                 locVal = locVal.trim();
00425                 if (varType.equals("boolean"))
00426                 {
00427                     if (locVal.equals("0")) locVal="false";
00428                         else if (locVal.equals("1")) locVal="true";
00429                             else if (locVal.endsWith("? 1 : 0"))
00430                                 {
00431                                     locVal = locVal.substring(0,locVal.length()-8).trim();
00432                                 }
00433                 }
00434                 s.append(locVal);
00435             }
00436 
00437             if (varType.equals("boolean"))
00438             {
00439                 // Tell the decompiler that we have a boolean variable here
00440                 DecompilerInfo.putVarInfo(locName);
00441             }
00442 
00443             if (e.hasMoreElements())
00444                 s.append(", ");
00445         }
00446         s.append(";");
00447         result.add(s.toString());
00448         if (abstractedVars.isEmpty()) abstractedVars = null;
00449         else
00450         {
00451             locDecl = abstractedVars;
00452             varType = "int";
00453             abstractedVars = null;
00454         }
00455     }
00456     for (Enumeration ei = temp.elements(); ei.hasMoreElements(); )
00457     {
00458         String st = (String) ei.nextElement();
00459         if (st.indexOf("quantification") != -1 || st.indexOf("Bandera.choose") != -1)
00460         {
00461             result.add(st);
00462         }
00463     }
00464 }
00465 /**
00466  * caseMethodDeclarationAnnotation method comment.
00467  */
00468 public void caseMethodDeclarationAnnotation(MethodDeclarationAnnotation a)
00469 {
00470     lineToAnnotation.put(new DecompilerPair(result.size()),a);
00471     Enumeration i = a.getContainedAnnotations().elements();
00472     Annotation annot;
00473 
00474     // If it is not a static method, then JJJCTEMP$0 = this;
00475     if (!DecompilerInfo.isStaticMethod())
00476     {
00477         annot = (Annotation) i.nextElement();
00478         result.addAll(DecompilerUtil.flattenStmts(annot.getStatements()));
00479     }
00480 
00481     // If there are parameters, the next method would be parameters
00482     if (DecompilerInfo.getNoOfParam()>0)
00483     {
00484         annot = (Annotation) i.nextElement();
00485         DecompilerInfo.decipherParam(annot.getStatements());
00486     }
00487 
00488     // The rest are method bodies
00489     while (i.hasMoreElements())
00490     {
00491         annot = (Annotation) i.nextElement();
00492         evaluate(annot);
00493     }
00494 }
00495 /**
00496  * caseReturnStmtAnnotation method comment.
00497  */
00498 public void caseReturnStmtAnnotation(ReturnStmtAnnotation a) {
00499     //String result = "return";
00500 
00501     // Get statements
00502     lineToAnnotation.put(new DecompilerPair(result.size()),a);
00503 
00504     caseSequential(a);
00505 }
00506 private void caseSequential(SequentialAnnotation a)
00507 {
00508     result.addAll(DecompilerUtil.flattenStmts(a.getStatements()));
00509 }
00510 /**
00511  * caseSequentialAnnotation method comment.
00512  */
00513 public void caseSequentialAnnotation(SequentialAnnotation a)
00514 {
00515     lineToAnnotation.put(new DecompilerPair(result.size()),a);
00516     caseSequential(a);
00517 }
00518 /**
00519  * caseStaticInitializerAnnotation method comment.
00520  */
00521 public void caseStaticInitializerAnnotation(StaticInitializerAnnotation a)
00522 {
00523     lineToAnnotation.put(new DecompilerPair(result.size()),a);
00524     caseBlock(a);
00525 }
00526 /**
00527  * caseSuperConstructorInvocationStmtAnnotation method comment.
00528  */
00529 public void caseSuperConstructorInvocationStmtAnnotation(SuperConstructorInvocationStmtAnnotation a)
00530 {
00531     lineToAnnotation.put(new DecompilerPair(result.size()),a);
00532     caseSequential(a);
00533 }
00534 /**
00535  * caseSwitchStmtAnnotation method comment.
00536  */
00537 public void caseSwitchStmtAnnotation(SwitchStmtAnnotation a)
00538 {
00539     Stmt[] testStmt = a.getTestStatements();
00540     Hashtable switchTbl = a.getSwitchCases();
00541     LookupSwitchStmt ls = null;
00542     Abstraction lt = null;
00543     boolean found = false;
00544     boolean isAbstracted = false;
00545 
00546     lineToAnnotation.put(new DecompilerPair(result.size()), a);
00547     for (int i = 0; i < testStmt.length; i++)
00548     {
00549         if (testStmt[i] instanceof LookupSwitchStmt)
00550         {
00551             ls = (LookupSwitchStmt) testStmt[i];
00552             Value v = ls.getKey();
00553             if (v != null)
00554             {
00555                 lt = Decompiler.typeTable.get(v);
00556                 isAbstracted = DecompilerUtil.isAbstracted(lt);
00557                 if (isAbstracted)
00558                 {
00559                     tempCounter++;
00560                     result.add("int abs_temp$"+tempCounter+";");
00561                 }
00562             }
00563             break;
00564         }
00565     }
00566 
00567     Vector res = DecompilerUtil.flattenStmts(testStmt);
00568     Hashtable definedVars = DecompilerUtil.getAssignedVarTable();
00569     for (Enumeration e = res.elements(); e.hasMoreElements();)
00570     {
00571         String st = (String) e.nextElement();
00572         if (st.startsWith("switch "))
00573         {
00574             result.add(st); found = true; break;
00575         }
00576     }
00577     if (!found)
00578     {
00579         result.add("// Error: Switch statement not found!");
00580         result.add("switch ()");
00581     }
00582     result.add("{");
00583 
00584     if (isAbstracted)
00585     {
00586         // Make a silly exception on abstracted code.... please don't complain....
00587         Hashtable annToResult = new Hashtable();
00588         Hashtable annToValue = new Hashtable();
00589         Hashtable valueToAnn = new Hashtable();
00590         Vector tempRes = result;
00591         Vector caseValues = new Vector();
00592         // Put the each case annotation with its result in a table
00593         for (Enumeration e = a.getValues().elements(); e.hasMoreElements();)
00594         {
00595             result = new Vector();
00596             Value v = (Value) e.nextElement();
00597             Annotation caseAnn = (Annotation) switchTbl.get(v);
00598             evaluate(caseAnn);
00599             annToResult.put(caseAnn,result);
00600             annToValue.put(caseAnn,v.toString());
00601             valueToAnn.put(v.toString(),caseAnn);
00602             if (v instanceof IntConstant) caseValues.add(new Integer(((IntConstant) v).value));
00603         }
00604         result = tempRes;
00605         // Determine the constant for default
00606         int defaultInt = 0;
00607         while (true)
00608         {
00609             if (caseValues.contains(new Integer(defaultInt)))
00610             {
00611                 defaultInt++; // If the constant clashes, increment one by one
00612             } else
00613             {
00614                 // We found one!!
00615                 tempRes = result;
00616                 result = new Vector();
00617                 Annotation defAnn = (Annotation) a.getDefaultAnnotation();
00618                 evaluate(defAnn);
00619                 annToResult.put(defAnn,result);
00620                 annToValue.put(defAnn,String.valueOf(defaultInt));
00621                 valueToAnn.put(String.valueOf(defaultInt),defAnn);
00622                 result = tempRes;
00623                 break;
00624             }
00625         }
00626 
00627         // Look into the abstracted cases
00628         int max = ls.getLookupValues().size();
00629         for(int i = 0; i < max; i++)
00630         {
00631             String tokName = AbstractionClassLoader.getTokenName(lt,ls.getLookupValue(i));
00632             String fullName = lt.getClass().getName();
00633             int lastDot = fullName.lastIndexOf(".");
00634             String pkgName = fullName.substring(0,lastDot);
00635             Decompiler.addImports(pkgName+".*");
00636             result.add("case "+tokName+":");
00637 
00638             // Find the position of target in the test statements
00639             int fromPos = DecompilerUtil.stmtIndex((Stmt) ls.getTarget(i),testStmt);
00640             int toPos = i == (max-1) ? testStmt.length : DecompilerUtil.stmtIndex((Stmt) ls.getTarget(i+1),testStmt);
00641 
00642             if (fromPos >= 0 && toPos >= 0)
00643             {
00644                 switchPartialDecompilation(fromPos,toPos,testStmt,annToValue,definedVars);
00645             }
00646         }
00647         // Default target is neglected by default
00648 
00649         result.add("}");
00650         // Add the second switch
00651         result.add("switch (abs_temp$"+tempCounter+")");
00652         result.add("{");
00653         for (Enumeration e = valueToAnn.keys(); e.hasMoreElements(); )
00654         {
00655             String theVal = (String) e.nextElement();
00656             Annotation theAnn = (Annotation) valueToAnn.get(theVal);
00657             Vector currentResult = (Vector) annToResult.get(theAnn);
00658             result.add("case "+theVal+":");
00659             result.addAll(currentResult);
00660         }
00661     } else
00662     {
00663         for (Enumeration e = a.getValues().elements(); e.hasMoreElements();)
00664         {
00665             Value v = (Value) e.nextElement();
00666             result.add("case " + v.toString() + ":");
00667             evaluate((Annotation) switchTbl.get(v));
00668         }
00669         Annotation def = a.getDefaultAnnotation();
00670         if (def != null)
00671         {
00672             result.add("default:");
00673             evaluate(def);
00674         }
00675     }
00676     result.add("}");
00677 }
00678 /**
00679  * caseSynchronizedStmtAnnotation method comment.
00680  */
00681 public void caseSynchronizedStmtAnnotation(SynchronizedStmtAnnotation a)
00682 {
00683     Stmt[] lockStmt = a.getLockStatements();
00684     boolean found = false;
00685 
00686     lineToAnnotation.put(new DecompilerPair(result.size()),a);
00687     Vector res = DecompilerUtil.flattenStmts(lockStmt);
00688     for (Enumeration e = res.elements(); e.hasMoreElements(); )
00689     {
00690         String st = ((String) e.nextElement()).trim();
00691         if (st.startsWith("synchronized "))
00692         {
00693             result.add(st.substring(0,st.lastIndexOf(";")).trim()); found = true;
00694             break;
00695         }
00696     }
00697     if (!found)
00698     {
00699         result.add("// Error: Synchronized statement not found!");
00700         result.add("synchronized (this)");
00701     }
00702     result.add("{");
00703     evaluate(a.getBlockAnnotation());
00704     result.add("}");
00705 }
00706 /**
00707  * caseThisConstructorInvocationStmtAnnotation method comment.
00708  */
00709 public void caseThisConstructorInvocationStmtAnnotation(ThisConstructorInvocationStmtAnnotation a)
00710 {
00711     lineToAnnotation.put(new DecompilerPair(result.size()),a);
00712     caseSequential(a);
00713 }
00714 /**
00715  * caseThrowStmtAnnotation method comment.
00716  */
00717 public void caseThrowStmtAnnotation(ThrowStmtAnnotation a)
00718 {
00719     lineToAnnotation.put(new DecompilerPair(result.size()),a);
00720     caseSequential(a);
00721 }
00722 /**
00723  * caseTryFinallyStmtAnnotation method comment.
00724  */
00725 public void caseTryFinallyStmtAnnotation(TryFinallyStmtAnnotation a) {
00726 
00727     //  Dunno about getFinallyExceptionAnnotation
00728     lineToAnnotation.put(new DecompilerPair(result.size()),a);
00729     caseTryStmtAnnotation(a);
00730     result.add("finally {");
00731     evaluate(a.getFinallyAnnotation());
00732     result.add("}");
00733 }
00734 /**
00735  * caseTryStmtAnnotation method comment.
00736  */
00737 public void caseTryStmtAnnotation(TryStmtAnnotation a)
00738 {
00739     Stmt[] cstmts = ((Annotation) a.getCatchClauses().firstElement()).getStatements();
00740     // Are they got sliced away?
00741     if (cstmts.length == 0) return;
00742     lineToAnnotation.put(new DecompilerPair(result.size()),a);
00743     if ("JJJCTEMP$E".equals(((IdentityStmt) cstmts[0]).getLeftOp().toString().trim())) {
00744         evaluate(a.getBlockAnnotation());
00745         // add synchronized to method modifier
00746     }
00747     else
00748     {
00749         result.add("try {");
00750         evaluate(a.getBlockAnnotation());
00751         result.add("}");
00752         for (Enumeration e = a.getCatchClauses().elements(); e.hasMoreElements();)
00753         {
00754             Annotation clause = (Annotation) e.nextElement();
00755             evaluate(clause);
00756         }
00757     }
00758 }
00759 public void caseUnimplemented(Annotation a)
00760 {
00761     result.add(a.toString() + "; // Unimplemented yet!");
00762 }
00763 /**
00764  * caseWhileStmtAnnotation method comment.
00765  */
00766 public void caseWhileStmtAnnotation(WhileStmtAnnotation a) {
00767     StringBuffer s = new StringBuffer();
00768     Stmt[] testStmts = a.getTestStatements();
00769 
00770     result.addAll(DecompilerUtil.dumpStmt(testStmts));
00771     lineToAnnotation.put(new DecompilerPair(result.size()),a);
00772     s.append("while ");
00773     s.append(DecompilerUtil.analyzeCondition(testStmts,0));
00774     result.add(s.toString());
00775     result.add("{");
00776     evaluate(a.getBlockAnnotation());
00777     result.add("}");
00778 }
00779 public static Vector evaluate(Annotation a){
00780     if (a==null) return new Vector();
00781     a.apply(walker);
00782     return walker.getResult();
00783 }
00784 public static Hashtable getLineToAnnotation() { return walker.getTable(); }
00785 private Vector getResult()
00786 {
00787     return result;
00788 }
00789 private Hashtable getTable() { return lineToAnnotation; }
00790 public static void reset()
00791 {
00792     walker.result = new Vector();
00793     walker.lineToAnnotation = new Hashtable();
00794 }
00795 private void switchPartialDecompilation(int fromPos, int toPos, Stmt[] testStmt, Hashtable annToValue, Hashtable definedVars)
00796 {
00797     boolean prevIf = false;
00798     for (int j = fromPos; j < toPos; j++)
00799     {
00800         if (testStmt[j] instanceof GotoStmt)
00801         {
00802             Stmt target = (Stmt) ((GotoStmt) testStmt[j]).getTarget();
00803             try
00804             {
00805                 Annotation an = Decompiler.annot.getContainingAnnotation(target);
00806                 String annval = (String) annToValue.get(an);
00807                 String tempstr = "abs_temp$" + tempCounter + " = " + annval + ";";
00808                 if (prevIf)
00809                     result.add("else " + tempstr);
00810                 else
00811                     result.add(tempstr);
00812                 result.add("break;");
00813                 prevIf = false;
00814             } catch (Exception e)
00815             {
00816                 System.out.println("Warning: Cannot find containing annotation in abstracted switch!");
00817             }
00818         } else
00819         {
00820             if (testStmt[j] instanceof IfStmt)
00821             {
00822                 IfStmt ifs = (IfStmt) testStmt[j];
00823                 Value cond = ifs.getCondition();
00824                 if (cond instanceof EqExpr)
00825                 {
00826                     System.out.println("Warning: Slabs choose condition is not equality expression!");
00827                 } else cond = ((EqExpr) cond).getOp1();
00828                 String condstr = (String) definedVars.get(cond);
00829                 try
00830                 {
00831                     if (condstr == null) throw new Exception();
00832                     Stmt target = (Stmt) ifs.getTarget();
00833                     Annotation an = Decompiler.annot.getContainingAnnotation(target);
00834                     String annval = (String) annToValue.get(an);
00835                     condstr = "if (" + condstr + ") abs_temp$" + tempCounter + " = " + annval + ";";
00836                     if (prevIf)
00837                         result.add("else " + condstr);
00838                     else
00839                         result.add(condstr);
00840                     prevIf = true;
00841                 } catch (Exception e)
00842                 {
00843                     System.out.println("Warning: Abstracted if in lookup switch has bugs!");
00844                 }
00845             }
00846         }
00847     }
00848 }
00849 }

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