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

GrimpBody.java

00001 package ca.mcgill.sable.soot.grimp;
00002 
00003 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
00004  * Grimp, an aggregated-expression Java(TM) bytecode representation. *
00005  * Copyright (C) 1998 Patrick Lam (plam@sable.mcgill.ca)             *
00006  * All rights reserved.                                              *
00007  *                                                                   *
00008  * Portions by Raja Vallee-Rai (rvalleerai@sable.mcgill.ca) are      *
00009  * Copyright (C) 1998 Raja Vallee-Rai (rvalleerai@sable.mcgill.ca).  *
00010  * All rights reserved.                                              *
00011  *                                                                   *
00012  * Portions by Etienne Gagnon (gagnon@sable.mcgill.ca) are           *
00013  * Copyright (C) 1998 Etienne Gagnon (gagnon@sable.mcgill.ca).  All  *
00014  * rights reserved.                                                  *
00015  *                                                                   *
00016  * This work was done as a project of the Sable Research Group,      *
00017  * School of Computer Science, McGill University, Canada             *
00018  * (http://www.sable.mcgill.ca/).  It is understood that any         *
00019  * modification not identified as such is not covered by the         *
00020  * preceding statement.                                              *
00021  *                                                                   *
00022  * This work is free software; you can redistribute it and/or        *
00023  * modify it under the terms of the GNU Library General Public       *
00024  * License as published by the Free Software Foundation; either      *
00025  * version 2 of the License, or (at your option) any later version.  *
00026  *                                                                   *
00027  * This work is distributed in the hope that it will be useful,      *
00028  * but WITHOUT ANY WARRANTY; without even the implied warranty of    *
00029  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU *
00030  * Library General Public License for more details.                  *
00031  *                                                                   *
00032  * You should have received a copy of the GNU Library General Public *
00033  * License along with this library; if not, write to the             *
00034  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,      *
00035  * Boston, MA  02111-1307, USA.                                      *
00036  *                                                                   *
00037  * Java is a trademark of Sun Microsystems, Inc.                     *
00038  *                                                                   *
00039  * To submit a bug report, send a comment, or get the latest news on *
00040  * this project and other Sable Research Group projects, please      *
00041  * visit the web site: http://www.sable.mcgill.ca/                   *
00042  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
00043 
00044 /*
00045  Reference Version
00046  -----------------
00047  This is the latest official version on which this file is based.
00048  The reference version is: $SootVersion: 1.beta.4 $
00049 
00050  Change History
00051  --------------
00052  A) Notes:
00053 
00054  Please use the following template.  Most recent changes should
00055  appear at the top of the list.
00056 
00057  - Modified on [date (March 1, 1900)] by [name]. [(*) if appropriate]
00058    [description of modification].
00059 
00060  Any Modification flagged with "(*)" was done as a project of the
00061  Sable Research Group, School of Computer Science,
00062  McGill University, Canada (http://www.sable.mcgill.ca/).
00063 
00064  You should add your copyright, using the following template, at
00065  the top of this file, along with other copyrights.
00066 
00067  *                                                                   *
00068  * Modifications by [name] are                                       *
00069  * Copyright (C) [year(s)] [your name (or company)].  All rights     *
00070  * reserved.                                                         *
00071  *                                                                   *
00072 
00073  B) Changes:
00074 
00075  - Modified on February 3, 1999 by Patrick Lam (plam@sable.mcgill.ca). (*)
00076    First release of Grimp.
00077 */
00078 
00079 import ca.mcgill.sable.soot.*;
00080 import ca.mcgill.sable.soot.jimple.*;
00081 import ca.mcgill.sable.util.*;
00082 import ca.mcgill.sable.soot.baf.*;
00083 import java.io.*;
00084 
00085 public class GrimpBody implements StmtBody
00086 {
00087     List locals = new ArrayList();
00088     SootMethod method;
00089 
00090     StmtList stmtList;
00091     List traps = new ArrayList();
00092 
00093     /**
00094         Construct an empty GrimpBody 
00095      **/
00096      
00097     GrimpBody(SootMethod m)
00098     {
00099         this.method = m;
00100         stmtList = new StmtList(this);   
00101     }
00102     /**
00103         Constructs a GrimpBody from the given Body.
00104      */
00105 
00106     GrimpBody(SootMethod m, Body body, int buildOptions)
00107     {
00108 
00109     JimpleBody jBody = null;
00110 
00111         if(body instanceof ClassFileBody)
00112         {
00113         /* we need to resolve conflicts between */
00114         /* Jimple & Grimp buildOptions! */
00115         jBody = new JimpleBody(m, body, buildOptions);
00116         }
00117     else if (body instanceof JimpleBody)
00118         {
00119         jBody = (JimpleBody)body;
00120         }
00121     else
00122             throw new RuntimeException("Can only construct GrimpBody's from ClassFileBody's or JimpleBody's (for now)");
00123 
00124         this.method = jBody.getMethod();
00125     this.locals = new LinkedList();
00126     Iterator it = jBody.getLocals().iterator();
00127     while (it.hasNext())
00128         this.locals.add(((Local)(it.next())));
00129         //      this.locals.add(((Local)(it.next())).clone());
00130 
00131         stmtList = new StmtList(this);
00132     it = jBody.getStmtList().iterator();
00133 
00134     final HashMap oldToNew = new HashMap(stmtList.size() * 2 + 1, 0.7f);
00135     LinkedList updates = new LinkedList();
00136 
00137     /* we should Grimpify the Stmt's here... */
00138     while (it.hasNext())
00139     {
00140         Stmt oldStmt = (Stmt)(it.next());
00141         final StmtBox newStmtBox = new StmtBox(null);
00142         final StmtBox updateStmtBox = new StmtBox(null);
00143 
00144         /* we can't have a general StmtSwapper on Grimp.v() */
00145         /* because we need to collect a list of updates */
00146         oldStmt.apply(new AbstractStmtSwitch()
00147         {
00148         public void caseAssignStmt(AssignStmt s)
00149         {
00150             newStmtBox.setUnit(Grimp.v().newAssignStmt(s));
00151         }
00152         public void caseIdentityStmt(IdentityStmt s)
00153             {
00154             newStmtBox.setUnit(Grimp.v().newIdentityStmt(s));
00155         }
00156         public void caseBreakpointStmt(BreakpointStmt s)
00157         {
00158             newStmtBox.setUnit(Grimp.v().newBreakpointStmt(s));
00159         }
00160         public void caseInvokeStmt(InvokeStmt s)
00161         {
00162             newStmtBox.setUnit(Grimp.v().newInvokeStmt(s));
00163         }
00164         public void defaultCase(Stmt s)
00165             {
00166             throw new RuntimeException("invalid jimple stmt: "+s);
00167         }
00168         public void caseEnterMonitorStmt(EnterMonitorStmt s)
00169         {
00170             newStmtBox.setUnit(Grimp.v().newEnterMonitorStmt(s));
00171         }
00172         public void caseExitMonitorStmt(ExitMonitorStmt s)
00173         {
00174             newStmtBox.setUnit(Grimp.v().newExitMonitorStmt(s));
00175         }
00176         public void caseGotoStmt(GotoStmt s)
00177         {
00178             newStmtBox.setUnit(Grimp.v().newGotoStmt(s));
00179             updateStmtBox.setUnit(s);
00180         }
00181         public void caseIfStmt(IfStmt s)
00182         {
00183             newStmtBox.setUnit(Grimp.v().newIfStmt(s));
00184             updateStmtBox.setUnit(s);
00185         }
00186         public void caseLookupSwitchStmt(LookupSwitchStmt s)
00187         {
00188             newStmtBox.setUnit(Grimp.v().newLookupSwitchStmt(s));
00189             updateStmtBox.setUnit(s);
00190         }
00191         public void caseNopStmt(NopStmt s)
00192         {
00193             newStmtBox.setUnit(Grimp.v().newNopStmt(s));
00194         }
00195         public void caseRetStmt(RetStmt s)
00196         {
00197             newStmtBox.setUnit(Grimp.v().newRetStmt(s));
00198         }
00199         public void caseReturnStmt(ReturnStmt s)
00200         {
00201             newStmtBox.setUnit(Grimp.v().newReturnStmt(s));
00202         }
00203         public void caseReturnVoidStmt(ReturnVoidStmt s)
00204         {
00205             newStmtBox.setUnit(Grimp.v().newReturnVoidStmt(s));
00206         }
00207         public void caseTableSwitchStmt(TableSwitchStmt s)
00208         {
00209             newStmtBox.setUnit(Grimp.v().newTableSwitchStmt(s));
00210             updateStmtBox.setUnit(s);
00211         }
00212         public void caseThrowStmt(ThrowStmt s)
00213         {
00214             newStmtBox.setUnit(Grimp.v().newThrowStmt(s));
00215         }
00216         });
00217 
00218         /* map old Expr's to new Expr's. */
00219         Stmt newStmt = (Stmt)(newStmtBox.getUnit());
00220         Iterator useBoxesIt = (Iterator)
00221         newStmt.getUseAndDefBoxes().iterator();
00222         while(useBoxesIt.hasNext())
00223         {
00224             ValueBox b = (ValueBox) (useBoxesIt.next());
00225             b.setValue(Grimp.v().newExpr(b.getValue()));
00226         }
00227 
00228         stmtList.add(newStmt);
00229         oldToNew.put(oldStmt, newStmt);
00230         if (updateStmtBox.getUnit() != null)
00231         updates.add(updateStmtBox.getUnit());
00232     }
00233 
00234     /* fixup stmt's which have had moved targets */
00235     it = updates.iterator();
00236     while (it.hasNext())
00237     {
00238         Stmt stmt = (Stmt)(it.next());
00239 
00240         stmt.apply(new AbstractStmtSwitch()
00241         {
00242         public void defaultCase(Stmt s)
00243             {
00244             throw new RuntimeException("Internal error: "+s);
00245         }
00246         public void caseGotoStmt(GotoStmt s)
00247         {
00248             GotoStmt newStmt = (GotoStmt)(oldToNew.get(s));
00249             newStmt.setTarget((Stmt)oldToNew.get(newStmt.getTarget()));
00250         }
00251         public void caseIfStmt(IfStmt s)
00252         {
00253             IfStmt newStmt = (IfStmt)(oldToNew.get(s));
00254             newStmt.setTarget((Stmt)oldToNew.get(newStmt.getTarget()));
00255         }
00256         public void caseLookupSwitchStmt(LookupSwitchStmt s)
00257         {
00258             LookupSwitchStmt newStmt = 
00259             (LookupSwitchStmt)(oldToNew.get(s));
00260             newStmt.setDefaultTarget
00261             ((Unit)(oldToNew.get(newStmt.getDefaultTarget())));
00262             Unit[] newTargList = new Unit[newStmt.getTargetCount()];
00263             for (int i = 0; i < newStmt.getTargetCount(); i++)
00264             newTargList[i] = (Unit)(oldToNew.get
00265                         (newStmt.getTarget(i)));
00266             newStmt.setTargets(newTargList);
00267         }
00268         public void caseTableSwitchStmt(TableSwitchStmt s)
00269         {
00270             TableSwitchStmt newStmt = 
00271             (TableSwitchStmt)(oldToNew.get(s));
00272             newStmt.setDefaultTarget
00273             ((Unit)(oldToNew.get(newStmt.getDefaultTarget())));
00274             int tc = newStmt.getHighIndex() - newStmt.getLowIndex()+1;
00275             LinkedList newTargList = new LinkedList();
00276             for (int i = 0; i < tc; i++)
00277             newTargList.add(oldToNew.get
00278                     (newStmt.getTarget(i)));
00279             newStmt.setTargets(newTargList);
00280         }
00281         });
00282     }
00283 
00284     this.traps = new ArrayList();
00285     it = jBody.getTraps().iterator();
00286     while (it.hasNext())
00287     {
00288         Trap oldTrap = (Trap)(it.next());
00289         this.traps.add(Grimp.v().newTrap
00290                (oldTrap.getException(),
00291                 (Unit)(oldToNew.get(oldTrap.getBeginUnit())),
00292                 (Unit)(oldToNew.get(oldTrap.getEndUnit())),
00293                 (Unit)(oldToNew.get(oldTrap.getHandlerUnit()))));
00294     }
00295 
00296     if (Main.isProfilingOptimization)
00297       Main.aggregationTimer.start();
00298     
00299     if (!BuildGrimpBodyOption.noAggregating(buildOptions))
00300     {
00301         GrimpTransformations.foldConstructors(this);
00302         Transformations.aggregate(this);
00303         Transformations.removeUnusedLocals(this);
00304     }
00305     
00306     if (Main.isProfilingOptimization)
00307       Main.aggregationTimer.end();
00308     }
00309     public void addLocal(Local l) throws AlreadyDeclaredException
00310     {
00311         locals.add(l);
00312     }
00313     public void addTrap(Trap t)
00314     {
00315         traps.add(t);
00316     }
00317     public boolean declaresLocal(String localName)
00318     {
00319         Iterator localIt = getLocals().iterator();
00320 
00321         while(localIt.hasNext())
00322         {
00323             Local local = (Local) localIt.next();
00324 
00325             if(local.getName().equals(localName))
00326                 return true;
00327         }
00328 
00329         return false;
00330     }
00331     public void eliminateBackPointersTo(Stmt oldLocation)
00332     {
00333         Iterator boxIt = oldLocation.getUnitBoxes().iterator();
00334 
00335         while(boxIt.hasNext())
00336         {
00337             StmtBox box = (StmtBox) boxIt.next();
00338             Stmt stmt = (Stmt) box.getUnit();
00339 
00340             stmt.getBoxesPointingToThis().remove(oldLocation);
00341         }
00342     }
00343     public Local getLocal(String name) throws ca.mcgill.sable.soot.jimple.NoSuchLocalException
00344     {
00345         Iterator localIt = getLocals().iterator();
00346 
00347         while(localIt.hasNext())
00348         {
00349             Local local = (Local) localIt.next();
00350 
00351             if(local.getName().equals(name))
00352                 return local;
00353         }
00354 
00355         throw new ca.mcgill.sable.soot.jimple.NoSuchLocalException();
00356     }
00357     public int getLocalCount()
00358     {
00359         return locals.size();
00360     }
00361     /**
00362      * Returns a backed list of locals.
00363      */
00364 
00365     public List getLocals()
00366     {
00367         return locals;
00368     }
00369     public SootMethod getMethod()
00370     {
00371         return method;
00372     }
00373     public StmtList getStmtList()
00374     {
00375         return stmtList;
00376     }
00377     public List getTraps()
00378     {
00379         return traps;
00380     }
00381     public List getUnitBoxes()
00382     {
00383         List stmtBoxes = new ArrayList();
00384 
00385         // Put in all statement boxes from the statements
00386             Iterator stmtIt = stmtList.iterator();
00387 
00388             while(stmtIt.hasNext())
00389             {
00390                 Stmt stmt = (Stmt) stmtIt.next();
00391 
00392                 Iterator boxIt = stmt.getUnitBoxes().iterator();
00393 
00394                 while(boxIt.hasNext())
00395                     stmtBoxes.add(boxIt.next());
00396             }
00397 
00398         // Put in all statement boxes from the trap table
00399         {
00400             Iterator trapIt = traps.iterator();
00401 
00402             while(trapIt.hasNext())
00403             {
00404                 Trap trap = (Trap) trapIt.next();
00405                 stmtBoxes.addAll(trap.getUnitBoxes());
00406             }
00407         }
00408 
00409         return stmtBoxes;
00410     }
00411     void print_debug(java.io.PrintWriter out)
00412     {
00413         StmtList stmtList = this.getStmtList();
00414 
00415         
00416         Map stmtToName = new HashMap(stmtList.size() * 2 + 1, 0.7f);
00417 /*
00418         StmtGraph stmtGraph = new BriefStmtGraph(stmtList);
00419 */
00420         /*
00421         System.out.println("Constructing LocalDefs of " + this.getMethod().getName() + "...");
00422 
00423         LocalDefs localDefs = new LocalDefs(graphBody);
00424 
00425         System.out.println("Constructing LocalUses of " + getName() + "...");
00426 
00427         LocalUses localUses = new LocalUses(stmtGraph, localDefs);
00428 
00429         LocalCopies localCopies = new LocalCopies(stmtGraph);
00430 
00431         System.out.println("Constructing LiveLocals of " + this.getMethod().getName() + " ...");
00432         LiveLocals liveLocals = new LiveLocals(stmtGraph);
00433         */
00434 
00435         // Create statement name table
00436         {
00437            int labelCount = 0;
00438 
00439             Iterator stmtIt = stmtList.iterator();
00440 
00441             while(stmtIt.hasNext())
00442             {
00443                 Stmt s = (Stmt) stmtIt.next();
00444 
00445                 stmtToName.put(s, new Integer(labelCount++).toString());
00446             }
00447         }
00448 
00449         for(int j = 0; j < stmtList.size(); j++)
00450         {
00451             Stmt s = ((Stmt) stmtList.get(j));
00452 
00453             out.print("    " + stmtToName.get(s) + ": ");
00454 
00455             out.print(s.toString(stmtToName, "        "));
00456             out.print(";");
00457         /*
00458 
00459             // Print info about live locals
00460             {
00461                 Iterator localIt = liveLocals.getLiveLocalsAfter(s).iterator();
00462 
00463                 out.print("   [");
00464 
00465                 while(localIt.hasNext())
00466                 {
00467                     out.print(localIt.next());
00468 
00469                     if(localIt.hasNext())
00470                         out.print(", ");
00471 
00472                 }
00473 
00474                 out.print("]");
00475             }
00476         */
00477 
00478 
00479              /*
00480              // Print info about uses
00481                 if(s instanceof DefinitionStmt)
00482                 {
00483                     Iterator useIt = localUses.getUsesOf((DefinitionStmt) s).iterator();
00484 
00485                     out.print("   (");
00486 
00487                     while(useIt.hasNext())
00488                     {
00489                         if(k != 0)
00490                             out.print(", ");
00491 
00492                         out.print(stmtToName.get(useIt.next()));
00493                     }
00494 
00495                     out.print(")");
00496                 }
00497             */
00498 
00499 /*
00500             // Print info about defs
00501             {
00502                 Iterator boxIt = s.getUseBoxes().iterator();
00503 
00504                 while(boxIt.hasNext())
00505                 {
00506                     ValueBox useBox = (ValueBox) boxIt.next();
00507 
00508                     if(useBox.getValue() instanceof Local)
00509                     {
00510                         Iterator defIt = localDefs.getDefsOfAt((Local) useBox.getValue(), s).iterator();
00511 
00512                         out.print("  " + useBox.getValue() + " = {");
00513 
00514                         while(defIt.hasNext())
00515                         {
00516                             out.print(stmtToName.get((Stmt) defIt.next()));
00517 
00518                             if(defIt.hasNext())
00519                                 out.print(", ");
00520                         }
00521 
00522                         out.print("}");
00523                     }
00524                 }
00525             } */
00526             /*
00527             // Print info about successors
00528             {
00529                 Iterator succIt = stmtGraph.getSuccsOf(s).iterator();
00530 
00531                 out.print("    [");
00532 
00533                 if(succIt.hasNext())
00534                 {
00535                     out.print(stmtToName.get(succIt.next()));
00536 
00537                     while(succIt.hasNext())
00538                     {
00539                         Stmt stmt = (Stmt) succIt.next();
00540 
00541                         out.print(", " + stmtToName.get(stmt));
00542                     }
00543                 }
00544 
00545                 out.print("]");
00546             }
00547                 */
00548             /*
00549             // Print info about predecessors
00550             {
00551                 Stmt[] preds = stmtGraph.getPredsOf(s);
00552 
00553                 out.print("    {");
00554 
00555                 for(int k = 0; k < preds.length; k++)
00556                 {
00557                     if(k != 0)
00558                         out.print(", ");
00559 
00560                     out.print(stmtToName.get(preds[k]));
00561                 }
00562 
00563                 out.print("}");
00564             }
00565             */
00566             out.println();
00567         }
00568 
00569         // Print out exceptions
00570         {
00571             Iterator trapIt = this.getTraps().iterator();
00572 
00573             while(trapIt.hasNext())
00574             {
00575                 Trap trap = (Trap) trapIt.next();
00576 
00577                 out.println(".catch " + trap.getException().getName() + " from " +
00578                     stmtToName.get(trap.getBeginUnit()) + " to " + stmtToName.get(trap.getEndUnit()) +
00579                     " with " + stmtToName.get(trap.getHandlerUnit()));
00580             }
00581         }
00582     }
00583     void printStatementsInBody(java.io.PrintWriter out, boolean isPrecise)
00584     {
00585         StmtList stmtList = this.getStmtList();
00586 
00587         Map stmtToName = new HashMap(stmtList.size() * 2 + 1, 0.7f);
00588         StmtGraph stmtGraph = new BriefStmtGraph(stmtList);
00589 
00590         // Create statement name table
00591         {
00592             Iterator boxIt = this.getUnitBoxes().iterator();
00593 
00594             Set labelStmts = new HashSet();
00595 
00596             // Build labelStmts
00597             {
00598                 while(boxIt.hasNext())
00599                 {
00600                     StmtBox box = (StmtBox) boxIt.next();
00601                     Stmt stmt = (Stmt) box.getUnit();
00602 
00603                     labelStmts.add(stmt);
00604                 }
00605             }
00606 
00607             // Traverse the stmts and assign a label if necessary
00608             {
00609                 int labelCount = 0;
00610 
00611                 Iterator stmtIt = stmtList.iterator();
00612 
00613                 while(stmtIt.hasNext())
00614                 {
00615                     Stmt s = (Stmt) stmtIt.next();
00616 
00617                     if(labelStmts.contains(s))
00618                         stmtToName.put(s, "label" + (labelCount++));
00619                 }
00620             }
00621         }
00622 
00623         for(int j = 0; j < stmtList.size(); j++)
00624         {
00625             Stmt s = ((Stmt) stmtList.get(j));
00626 
00627             // Put an empty line if the previous node was a branch node, the current node is a join node
00628             //   or the previous statement does not have this statement as a successor, or if
00629             //   this statement has a label on it
00630             {
00631                 if(j != 0)
00632                 {
00633                     Stmt previousStmt = (Stmt) stmtList.get(j - 1);
00634 
00635                     if(stmtGraph.getSuccsOf(previousStmt).size() != 1 ||
00636                         stmtGraph.getPredsOf(s).size() != 1 ||
00637                         stmtToName.containsKey(s))
00638                         out.println();
00639                     else {
00640                         // Or if the previous node does not have this statement as a successor.
00641 
00642                         List succs = stmtGraph.getSuccsOf(previousStmt);
00643 
00644                         if(succs.get(0) != s)
00645                             out.println();
00646 
00647                     }
00648                 }
00649             }
00650 
00651             if(stmtToName.containsKey(s))
00652                 out.println("     " + stmtToName.get(s) + ":");
00653 
00654             if(isPrecise)
00655                 out.print(s.toString(stmtToName, "        "));
00656             else
00657                 out.print(s.toBriefString(stmtToName, "        "));
00658 
00659             out.print(";");
00660             out.println();
00661         }
00662 
00663         // Print out exceptions
00664         {
00665             Iterator trapIt = this.getTraps().iterator();
00666 
00667             if(trapIt.hasNext())
00668                 out.println();
00669 
00670             while(trapIt.hasNext())
00671             {
00672                 Trap trap = (Trap) trapIt.next();
00673 
00674                 out.println("        .catch " + trap.getException().getName() + " from " +
00675                     stmtToName.get(trap.getBeginUnit()) + " to " + stmtToName.get(trap.getEndUnit()) +
00676                     " with " + stmtToName.get(trap.getHandlerUnit()));
00677             }
00678         }
00679     }
00680     public void printTo(java.io.PrintWriter out)
00681     {
00682         printTo(out, 0);
00683     }
00684     public void printTo(PrintWriter out, int printBodyOptions)
00685     {
00686         boolean isPrecise = !PrintJimpleBodyOption.useAbbreviations(printBodyOptions);
00687 
00688         if(PrintJimpleBodyOption.debugMode(printBodyOptions))
00689         {
00690             print_debug(out);
00691             return;
00692         }
00693         
00694         //System.out.println("Constructing the graph of " + getName() + "...");
00695 
00696         StmtList stmtList = this.getStmtList();
00697 
00698         Map stmtToName = new HashMap(stmtList.size() * 2 + 1, 0.7f);
00699 
00700         // Print out method name plus parameters
00701         {
00702             StringBuffer buffer = new StringBuffer();
00703 
00704             buffer.append(Modifier.toString(method.getModifiers()));
00705 
00706             if(buffer.length() != 0)
00707                 buffer.append(" ");
00708 
00709             buffer.append(method.getReturnType().toString() + " " + method.getName());
00710             buffer.append("(");
00711 
00712             Iterator typeIt = method.getParameterTypes().iterator();
00713 
00714             if(typeIt.hasNext())
00715             {
00716                 buffer.append(typeIt.next());
00717 
00718                 while(typeIt.hasNext())
00719                 {
00720                     buffer.append(", ");
00721                     buffer.append(typeIt.next());
00722                 }
00723             }
00724 
00725             buffer.append(")");
00726 
00727             out.print("    " + buffer.toString());
00728         }
00729 
00730         out.println();
00731         out.println("    {");
00732 
00733         /*
00734         // Print out local variables
00735         {
00736             Local[] locals = getLocals();
00737 
00738             for(int j = 0; j < locals.length; j++)
00739                 out.println("        " + locals[j].getType().toString() + " " +
00740                     locals[j].getName());
00741         }
00742 
00743         */
00744 
00745         // Print out local variables
00746         {
00747             Map typeToLocalSet = new HashMap(this.getLocalCount() * 2 + 1, 0.7f);
00748 
00749             // Collect locals
00750             {
00751                 Iterator localIt = this.getLocals().iterator();
00752 
00753                 while(localIt.hasNext())
00754                 {
00755                     Local local = (Local) localIt.next();
00756 
00757                     Set localSet;
00758 
00759                     if(typeToLocalSet.containsKey(local.getType().toString()))
00760                         localSet = (Set) typeToLocalSet.get(local.getType().toString());
00761                     else
00762                     {
00763                         localSet = new HashSet();
00764                         typeToLocalSet.put(local.getType().toString(), localSet);
00765                     }
00766 
00767                     localSet.add(local);
00768                 }
00769             }
00770 
00771             // Print locals
00772             {
00773                 Set typeSet = typeToLocalSet.keySet();
00774 
00775                 Object[] types = typeSet.toArray();
00776 
00777                 for(int j = 0; j < types.length; j++)
00778                 {
00779                     String type = (String) types[j];
00780 
00781                     Set localSet = (Set) typeToLocalSet.get(type);
00782                     Object[] locals = localSet.toArray();
00783 
00784                     out.print("        " + type + " ");
00785 
00786                     for(int k = 0; k < locals.length; k++)
00787                     {
00788                         if(k != 0)
00789                             out.print(", ");
00790 
00791                         out.print(((Local) locals[k]).getName());
00792                     }
00793 
00794                     out.println(";");
00795                 }
00796             }
00797 
00798 
00799             if(!typeToLocalSet.isEmpty())
00800                 out.println();
00801         }
00802 
00803         // Print out statements
00804             printStatementsInBody(out, isPrecise);
00805 
00806         out.println("    }");
00807     }
00808     public void redirectJumps(Stmt oldLocation, Stmt newLocation)
00809     {
00810         List boxesPointing = oldLocation.getBoxesPointingToThis();
00811 
00812         Object[] boxes = boxesPointing.toArray();
00813             // important to change this to an array to have a static copy
00814 
00815         for(int i = 0; i < boxes.length; i++)
00816         {
00817             StmtBox box = (StmtBox) boxes[i];
00818 
00819             if(box.getUnit() != oldLocation)
00820                 throw new RuntimeException("Something weird's happening");
00821 
00822             box.setUnit(newLocation);
00823         }
00824 
00825     }
00826     public void removeLocal(Local l) throws IncorrectDeclarerException
00827     {
00828         locals.remove(l);
00829     }
00830     public void removeTrap(Trap t)
00831     {
00832         traps.remove(t);
00833     }
00834 }

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