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

SootClass.java

00001 package ca.mcgill.sable.soot;
00002 
00003 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
00004  * Soot, a Java(TM) classfile optimization framework.                *
00005  * Copyright (C) 1997, 1998 Raja Vallee-Rai (kor@sable.mcgill.ca)    *
00006  * All rights reserved.                                              *
00007  *                                                                   *
00008  * Modifications by Vijay Sundaresan (vijay@sable.mcgill.ca) are     *
00009  * Copyright (C) 1999 Vijay Sundaresan.  All rights reserved.        *
00010  *                                                                   *
00011  * This work was done as a project of the Sable Research Group,      *
00012  * School of Computer Science, McGill University, Canada             *
00013  * (http://www.sable.mcgill.ca/).  It is understood that any         *
00014  * modification not identified as such is not covered by the         *
00015  * preceding statement.                                              *
00016  *                                                                   *
00017  * This work is free software; you can redistribute it and/or        *
00018  * modify it under the terms of the GNU Library General Public       *
00019  * License as published by the Free Software Foundation; either      *
00020  * version 2 of the License, or (at your option) any later version.  *
00021  *                                                                   *
00022  * This work is distributed in the hope that it will be useful,      *
00023  * but WITHOUT ANY WARRANTY; without even the implied warranty of    *
00024  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU *
00025  * Library General Public License for more details.                  *
00026  *                                                                   *
00027  * You should have received a copy of the GNU Library General Public *
00028  * License along with this library; if not, write to the             *
00029  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,      *
00030  * Boston, MA  02111-1307, USA.                                      *
00031  *                                                                   *
00032  * Java is a trademark of Sun Microsystems, Inc.                     *
00033  *                                                                   *
00034  * To submit a bug report, send a comment, or get the latest news on *
00035  * this project and other Sable Research Group projects, please      *
00036  * visit the web site: http://www.sable.mcgill.ca/                   *
00037  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
00038 
00039 /*
00040  Reference Version
00041  -----------------
00042  This is the latest official version on which this file is based.
00043  The reference version is: $SootVersion: 1.beta.4 $
00044 
00045  Change History
00046  --------------
00047  A) Notes:
00048 
00049  Please use the following template.  Most recent changes should
00050  appear at the top of the list.
00051 
00052  - Modified on [date (March 1, 1900)] by [name]. [(*) if appropriate]
00053    [description of modification].
00054 
00055  Any Modification flagged with "(*)" was done as a project of the
00056  Sable Research Group, School of Computer Science,
00057  McGill University, Canada (http://www.sable.mcgill.ca/).
00058 
00059  You should add your copyright, using the following template, at
00060  the top of this file, along with other copyrights.
00061 
00062  *                                                                   *
00063  * Modifications by [name] are                                       *
00064  * Copyright (C) [year(s)] [your name (or company)].  All rights     *
00065  * reserved.                                                         *
00066  *                                                                   *
00067 
00068  B) Changes:
00069 
00070  - Modified on March 2, 1999 by Patrick Lam (plam@sable.mcgill.ca)
00071    Added a toString method.
00072    
00073  - Modified on January 26, 1998 by Vijay Sundaresan (vija@sable.mcgill.ca) (*)
00074    Made the write() method name the output jasmin files according to the classfile
00075    being output.
00076    
00077  - Modified on November 21, 1998 by Raja Vallee-Rai (kor@sable.mcgill.ca) (*)
00078    Changed the default resolution state of new classes.
00079 
00080  - Modified on November 2, 1998 by Raja Vallee-Rai (kor@sable.mcgill.ca) (*)
00081    Repackaged all source files and performed extensive modifications.
00082    First initial release of Soot.
00083 
00084  - Modified on 15-Jun-1998 by Raja Vallee-Rai (kor@sable.mcgill.ca). (*)
00085    First internal release (Version 0.1).
00086 */
00087 
00088 import ca.mcgill.sable.util.*;
00089 import java.io.*;
00090 
00091 /*
00092  * Incomplete and inefficient implementation.
00093  *
00094  * Implementation notes:
00095  *
00096  * 1. The getFieldOf() method is slow because it traverses the list of fields, comparing the names,
00097  * one by one.  If you establish a Dictionary of Name->Field, you will need to add a
00098  * notifyOfNameChange() method, and register fields which belong to classes, because the hashtable
00099  * will need to be updated.  I will do this later. - kor  16-Sep-97
00100  */
00101 /**
00102     Instances of this class represent Java classes.  They are usually created by a SootClassManager,
00103     but can also be constructed manually through the given constructors.
00104 
00105 */
00106 
00107 public class SootClass
00108 {
00109     String name;
00110     int modifiers;
00111     List fields = new ArrayList();
00112     List methods = new ArrayList();
00113     List interfaces = new ArrayList();
00114 
00115     SootClassManager manager;
00116     boolean isManaged;
00117 
00118     SootClass superClass;
00119     boolean isResolved;
00120 
00121     /**
00122         Constructs an empty SootClass with the given name and no modifiers.
00123     */
00124 
00125     public SootClass(String name)
00126     {
00127         this.name = name;
00128         this.modifiers = 0;
00129         isResolved = true;
00130     }
00131     /**
00132         Constructs an empty SootClass with the given name and modifiers.
00133     */
00134 
00135     public SootClass(String name, int modifiers)
00136     {
00137         this.name = name;
00138         this.modifiers = modifiers;
00139         isResolved = true;
00140 
00141     }
00142     /*
00143     public void setFields(Field[] fields)
00144     {
00145         this.fields = new ArraySet(fields);
00146     }
00147     */
00148 
00149     /**
00150         Adds the given field to this class.
00151     */
00152 
00153     public void addField(SootField f) throws AlreadyDeclaredException 
00154     {
00155         resolveIfNecessary();
00156 
00157         if(f.isDeclared())
00158             throw new AlreadyDeclaredException(f.getName());
00159 
00160             /*
00161         if(declaresField(f.getName()))
00162             throw new DuplicateNameException(f.getName());
00163  */
00164  
00165         fields.add(f);
00166 
00167         f.isDeclared = true;
00168         f.declaringClass = this;
00169     }
00170     /**
00171         Add the given class to the list of interfaces which are directly implemented by this class.
00172     */
00173 
00174     public void addInterface(SootClass interfaceClass) throws DuplicateNameException
00175     {
00176         resolveIfNecessary();
00177         if(implementsInterface(interfaceClass.getName()))
00178             throw new DuplicateNameException(interfaceClass.getName());
00179 
00180         interfaces.add(interfaceClass);
00181     }
00182     /*
00183     public void setMethods(Method[] method)
00184     {
00185         methods = new ArraySet(method);
00186     }
00187     */
00188 
00189     /**
00190         Adds the given method to this class.
00191     */
00192 
00193     public void addMethod(SootMethod m) throws AlreadyDeclaredException
00194     {
00195         resolveIfNecessary();
00196 
00197         if(m.isDeclared())
00198             throw new AlreadyDeclaredException(m.getName());
00199 
00200         /*
00201         if(declaresMethod(m.getName(), m.getParameterTypes()))
00202             throw new DuplicateNameException("duplicate signature for: " + m.getName());
00203         */
00204         
00205         methods.add(m);
00206         m.isDeclared = true;
00207         m.declaringClass = this;
00208     }
00209     /**
00210         Does this class declare a field with the given name?
00211     */
00212 
00213     public boolean declaresField(String name)
00214     {
00215         resolveIfNecessary();
00216 
00217         Iterator fieldIt = getFields().iterator();
00218 
00219         while(fieldIt.hasNext())
00220         {
00221             SootField field = (SootField) fieldIt.next();
00222 
00223             if(field.name.equals(name))
00224                 return true;
00225         }
00226 
00227         return false;
00228     }
00229     /**
00230         Does this class declare a field with the given name and type.
00231     */
00232 
00233     public boolean declaresField(String name, Type type)
00234     {
00235         resolveIfNecessary();
00236 
00237         Iterator fieldIt = getFields().iterator();
00238 
00239         while(fieldIt.hasNext())
00240         {
00241             SootField field = (SootField) fieldIt.next();
00242 
00243             if(field.name.equals(name) &&
00244                 field.type.equals(type))
00245                 return true;
00246         }
00247 
00248         return false;
00249     }
00250     /**
00251         Does this class declare a method with the given name?
00252     */
00253 
00254     public boolean declaresMethod(String name)
00255     {
00256         resolveIfNecessary();
00257         // inefficient
00258 
00259         Iterator methodIt = getMethods().iterator();
00260 
00261         while(methodIt.hasNext())
00262         {
00263             SootMethod method = (SootMethod) methodIt.next();
00264 
00265             if(method.getName().equals(name))
00266                 return true;
00267         }
00268         
00269         return false;
00270     }
00271     /**
00272         Does this class declare a method with the given name and parameter types?
00273     */
00274 
00275     public boolean declaresMethod(String name, List parameterTypes)
00276     {
00277         resolveIfNecessary();
00278         // inefficient
00279 
00280         Iterator methodIt = getMethods().iterator();
00281 
00282         while(methodIt.hasNext())
00283         {
00284             SootMethod method = (SootMethod) methodIt.next();
00285 
00286             if(method.getName().equals(name) &&
00287                 method.getParameterTypes().equals(parameterTypes))
00288                 return true;
00289         }
00290         
00291         return false;
00292     }
00293     /**
00294         Does this class declare a method with the given name, parameter types, and return type?
00295     */
00296 
00297     public boolean declaresMethod(String name, List parameterTypes, Type returnType)
00298     {
00299         resolveIfNecessary();
00300         // inefficient
00301 
00302         Iterator methodIt = getMethods().iterator();
00303 
00304         while(methodIt.hasNext())
00305         {
00306             SootMethod method = (SootMethod) methodIt.next();
00307 
00308             if(method.getName().equals(name) &&
00309                 method.getParameterTypes().equals(parameterTypes) &&
00310                 method.getReturnType().equals(returnType))
00311                 
00312                 return true;
00313         }
00314         
00315         return false;
00316     }
00317     /**
00318         Returns the field of this class with the given name.  May throw an AmbiguousFieldException if there
00319         are more than one.
00320     */
00321 
00322     public SootField getField(String name) throws ca.mcgill.sable.soot.NoSuchFieldException, ca.mcgill.sable.soot.AmbiguousFieldException
00323     {
00324         boolean found = false;
00325         SootField foundField = null;
00326         resolveIfNecessary();
00327 
00328         Iterator fieldIt = getFields().iterator();
00329 
00330         while(fieldIt.hasNext())
00331         {
00332             SootField field = (SootField) fieldIt.next();
00333 
00334             if(field.name.equals(name))
00335             {
00336                 if(found)
00337                     throw new AmbiguousFieldException();
00338                 else {
00339                     found = true;
00340                     foundField = field;
00341                 }
00342             }
00343         }
00344 
00345         if(found)
00346             return foundField;
00347         else
00348             throw new ca.mcgill.sable.soot.NoSuchFieldException("No field " + name + " in class " + getName());
00349     }
00350     /**
00351         Returns the field of this class with the given name and type. 
00352     */
00353 
00354     public SootField getField(String name, Type type) throws ca.mcgill.sable.soot.NoSuchFieldException
00355     {
00356         resolveIfNecessary();
00357 
00358         Iterator fieldIt = getFields().iterator();
00359 
00360         while(fieldIt.hasNext())
00361         {
00362             SootField field = (SootField) fieldIt.next();
00363 
00364             if(field.name.equals(name) && field.type.equals(type))
00365                 return field;
00366         }
00367 
00368         throw new ca.mcgill.sable.soot.NoSuchFieldException("No field " + name + " in class " + getName());
00369     }
00370     /**
00371         Returns the number of fields in this class.
00372     */
00373 
00374     public int getFieldCount()
00375     {
00376         return fields.size();
00377     }
00378     /**
00379      * Returns a backed list of fields.
00380      */
00381 
00382     public List getFields()
00383     {
00384         resolveIfNecessary();
00385 
00386         return fields;
00387     }
00388     /**
00389         Returns the number of interfaces being directly implemented by this class.  Note that direct
00390         implementation corresponds to an "implements" keyword in the Java class file and that this class may
00391         still be implementing additional interfaces in the usual sense by being a subclass of a class
00392         which directly implements some interfaces.
00393     */
00394 
00395     public int getInterfaceCount()
00396     {
00397         return interfaces.size();
00398     }
00399     /**
00400      * Returns a backed list of the  interfaces that are direclty implemented by this class. (see getInterfaceCount())
00401      */
00402 
00403     public List getInterfaces()
00404     {
00405         resolveIfNecessary();
00406 
00407         return interfaces;
00408     }
00409     /**
00410         Returns the SootClassManager of this class.
00411     */
00412 
00413     public SootClassManager getManager() throws NotManagedException
00414     {
00415         return manager;
00416     }
00417      /**
00418         Attempts to retrieve the method with the given name.  This method
00419         may throw an AmbiguousMethodException if there are more than one method with the
00420         given name.
00421     */
00422 
00423     public SootMethod getMethod(String name) throws
00424         ca.mcgill.sable.soot.NoSuchMethodException, ca.mcgill.sable.soot.AmbiguousMethodException
00425     {
00426         boolean found = false;
00427         SootMethod foundMethod = null;
00428         
00429         resolveIfNecessary();
00430         // inefficient
00431 
00432         Iterator methodIt = getMethods().iterator();
00433 
00434         while(methodIt.hasNext())
00435         {
00436             SootMethod method = (SootMethod) methodIt.next();
00437 
00438             if(method.getName().equals(name))
00439             {
00440                 if(found)
00441                     throw new ca.mcgill.sable.soot.AmbiguousMethodException();
00442                 else {                    
00443                     found = true;
00444                     foundMethod = method;
00445                 }
00446             }
00447         }
00448 
00449         if(found)
00450             return foundMethod;
00451         else
00452             throw new ca.mcgill.sable.soot.NoSuchMethodException();
00453     }
00454     /**
00455         Attempts to retrieve the method with the given name and parameters.  This method
00456         may throw an AmbiguousMethodException if there are more than one method with the
00457         given name and parameter.
00458     */
00459 
00460     public SootMethod getMethod(String name, List parameterTypes) throws
00461         ca.mcgill.sable.soot.NoSuchMethodException, ca.mcgill.sable.soot.AmbiguousMethodException
00462     {
00463         boolean found = false;
00464         SootMethod foundMethod = null;
00465         
00466         resolveIfNecessary();
00467         // inefficient
00468 
00469         Iterator methodIt = getMethods().iterator();
00470 
00471         while(methodIt.hasNext())
00472         {
00473             SootMethod method = (SootMethod) methodIt.next();
00474 
00475             if(method.getName().equals(name) &&
00476                 parameterTypes.equals(method.getParameterTypes()))
00477             {
00478                 if(found)
00479                     throw new ca.mcgill.sable.soot.AmbiguousMethodException();
00480                 else {                    
00481                     found = true;
00482                     foundMethod = method;
00483                 }
00484             }
00485         }
00486 
00487         if(found)
00488             return foundMethod;
00489         else
00490             throw new ca.mcgill.sable.soot.NoSuchMethodException();
00491     }
00492     /**
00493         Attempts to retrieve the method with the given name, parameters and return type.  
00494         
00495     */
00496 
00497     public SootMethod getMethod(String name, List parameterTypes, Type returnType) throws
00498         ca.mcgill.sable.soot.NoSuchMethodException
00499     {
00500         resolveIfNecessary();
00501         // inefficient
00502 
00503         Iterator methodIt = getMethods().iterator();
00504 
00505         while(methodIt.hasNext())
00506         {
00507             SootMethod method = (SootMethod) methodIt.next();
00508 
00509             if(method.getName().equals(name) &&
00510                 parameterTypes.equals(method.getParameterTypes()) &&
00511                 returnType.equals(method.getReturnType()))
00512             {
00513                 return method;
00514             }
00515         }
00516 
00517         throw new ca.mcgill.sable.soot.NoSuchMethodException(getName() + "." + name + "(" + 
00518             parameterTypes + ")" + " : " + returnType);
00519     }
00520     /**
00521         Returns the number of methods in this class.
00522     */
00523 
00524     public int getMethodCount()
00525     {
00526         return methods.size();
00527     }
00528     /**
00529      * Returns a backed list of methods.
00530      */
00531 
00532     public List getMethods()
00533     {
00534         resolveIfNecessary();
00535 
00536         return methods;
00537     }
00538     /**
00539         Returns the modifiers of this class.
00540     */
00541 
00542     public int getModifiers()
00543     {
00544         resolveIfNecessary();
00545         return modifiers;
00546     }
00547     /**
00548         Returns the name of this class.
00549     */
00550 
00551     public String getName()
00552     {
00553         return name;
00554     }
00555     /**
00556         Returns the superclass of this class. (see hasSuperClass())
00557     */
00558 
00559     public SootClass getSuperClass() throws NoSuperClassException
00560     {
00561         resolveIfNecessary();
00562         if(superClass == null)
00563             throw new NoSuperClassException();
00564         else
00565             return superClass;
00566     }
00567     /*
00568     public void setInterfaces(SootClass[] interfaces)
00569     {
00570         this.interfaces = new ArraySet(interfaces);
00571     }
00572     */
00573 
00574     /**
00575         Does this class have a superclass? False implies that this is the java.lang.Object class.  Note that interfaces are subclasses
00576         of the java.lang.Object class.
00577     */
00578 
00579 
00580     public boolean hasSuperClass()
00581     {
00582         resolveIfNecessary();
00583 
00584         return superClass != null;
00585     }
00586     /**
00587         Does this class directly implement the given interface? (see getInterfaceCount())
00588     */
00589 
00590     public boolean implementsInterface(String name)
00591     {
00592         resolveIfNecessary();
00593 
00594         Iterator interfaceIt = getInterfaces().iterator();
00595 
00596         while(interfaceIt.hasNext())
00597         {
00598             SootClass SootClass = (SootClass) interfaceIt.next();
00599 
00600             if(SootClass.getName().equals(name))
00601                 return true;
00602         }
00603 
00604         return false;
00605     }
00606     /**
00607         Is this class being managed by a SootClassManager? A class may be unmanaged  while it is being constructed.
00608     */
00609 
00610     public boolean isManaged()
00611     {
00612         return isManaged;
00613     }
00614     /*
00615     public void jimplifyMethods()
00616     {
00617         resolveIfNecessary();
00618 
00619         Iterator methodIt = getMethods().iterator();
00620 
00621         while(methodIt.hasNext())
00622         {
00623             SootMethod m = (SootMethod) methodIt.next();
00624 
00625             if(!m.isJimplified())
00626                 m.jimplify();
00627         }
00628     }
00629     */
00630 
00631     /**
00632         Have the methods and fields for this class been loaded? False indicates that the class has been referred
00633         to but is not resolved in this sense.
00634     */
00635 
00636     public boolean isResolved()
00637     {
00638         return isResolved;
00639     }
00640     public void printTo(BodyExpr bodyExpr, PrintWriter out)
00641     {
00642         printTo(bodyExpr, out, 0);
00643     }
00644     public void printTo(BodyExpr bodyExpr, PrintWriter out, int printBodyOptions)
00645     {
00646         // Print class name + modifiers
00647         {
00648             String classPrefix = "";
00649 
00650             classPrefix = classPrefix + " " + Modifier.toString(this.getModifiers());
00651             classPrefix = classPrefix.trim();
00652 
00653             if(!Modifier.isInterface(this.getModifiers()))
00654             {
00655                 classPrefix = classPrefix + " class";
00656                 classPrefix = classPrefix.trim();
00657             }
00658 
00659             out.print(classPrefix + " " + this.getName());
00660         }
00661 
00662         // Print extension
00663         {
00664             if(this.hasSuperClass())
00665                 out.print(" extends " + this.getSuperClass().getName());
00666         }
00667 
00668         // Print interfaces
00669         {
00670             Iterator interfaceIt = this.getInterfaces().iterator();
00671 
00672             if(interfaceIt.hasNext())
00673             {
00674                 out.print(" implements ");
00675 
00676                 out.print(((SootClass) interfaceIt.next()).getName());
00677 
00678                 while(interfaceIt.hasNext())
00679                 {
00680                     out.print(",");
00681                     out.print(" " + ((SootClass) interfaceIt.next()).getName());
00682                 }
00683             }
00684         }
00685 
00686         out.println();
00687         out.println("{");
00688 
00689         // Print fields
00690         {
00691             Iterator fieldIt = this.getFields().iterator();
00692 
00693             if(fieldIt.hasNext())
00694             {
00695                 while(fieldIt.hasNext())
00696                     out.println("    " + ((SootField) fieldIt.next()).getDeclaration() + ";");
00697             }
00698         }
00699 
00700         // Print methods
00701         {
00702             Iterator methodIt = this.getMethods().iterator();
00703 
00704             if(methodIt.hasNext())
00705             {
00706                 if(this.getMethods().size() != 0)
00707                     out.println();
00708 
00709                 while(methodIt.hasNext())
00710                 {
00711                     SootMethod method = (SootMethod) methodIt.next();
00712 
00713                     if(!Modifier.isAbstract(method.getModifiers()) &&
00714                         !Modifier.isNative(method.getModifiers()))
00715                     {
00716                         bodyExpr.resolveFor(method).printTo(out, printBodyOptions);
00717 
00718                         if(methodIt.hasNext())
00719                             out.println();
00720                     }
00721                     else {
00722                         out.print("    ");
00723                         out.print(method.getDeclaration());
00724                         out.println(";");
00725 
00726                         if(methodIt.hasNext())
00727                             out.println();
00728                     }
00729                 }
00730             }
00731         }
00732         out.println("}");
00733 
00734     }
00735     /**
00736         Removes the given field from this class.
00737     */
00738 
00739     public void removeField(SootField f) throws IncorrectDeclarerException
00740     {
00741         resolveIfNecessary();
00742 
00743         if(!f.isDeclared() || f.getDeclaringClass() != this)
00744             throw new IncorrectDeclarerException(f.getName());
00745 
00746         fields.remove(f);
00747         f.isDeclared = false;
00748     }
00749     /**
00750         Removes the given class from the list of interfaces which are direclty implemented by this class.
00751     */
00752 
00753     public void removeInterface(SootClass interfaceClass) throws NoSuchInterfaceException
00754     {
00755         if(!implementsInterface(interfaceClass.getName()))
00756             throw new NoSuchInterfaceException(interfaceClass.getName());
00757 
00758         interfaces.remove(interfaceClass);
00759     }
00760     /**
00761         Removes the given method from this class.
00762     */
00763 
00764     public void removeMethod(SootMethod m) throws IncorrectDeclarerException
00765     {
00766         resolveIfNecessary();
00767 
00768         if(!m.isDeclared() || m.getDeclaringClass() != this)
00769             throw new IncorrectDeclarerException(m.getName());
00770 
00771         methods.remove(m);
00772         m.isDeclared = false;
00773     }
00774     /**
00775         Resolves the class by loading the fields and methods from the original class file.  This creates SootFields and SootMethods.
00776     */
00777 
00778     public void resolve()
00779     {
00780         if(isResolved)
00781             throw new RuntimeException("SootClass " + getName() + " already resolved!");
00782 
00783         isResolved = true;
00784 
00785         /*
00786         if(Main.isProfilingOptimization)
00787             Main.resolveTimer.start();
00788           */
00789 
00790         ca.mcgill.sable.soot.coffi.Util.resolveClass(this);
00791 
00792         /*
00793         if(Main.isProfilingOptimization)
00794             Main.resolveTimer.end(); */
00795     }
00796     /**
00797         Resolves the class if it has not been resolved yet.
00798     */
00799 
00800     public void resolveIfNecessary()
00801     {
00802         if(!isResolved)
00803             resolve();
00804     }
00805     /**
00806         Sets the modifiers for this class.
00807     */
00808 
00809     public void setModifiers(int modifiers)
00810     {
00811         resolveIfNecessary();
00812         this.modifiers = modifiers;
00813     }
00814     /**
00815         Sets the name of this class.
00816     */
00817 
00818     public void setName(String name) throws DuplicateNameException
00819     {
00820         this.name = name;
00821     }
00822     /**
00823         Establishes the resolution state of the class (see isResolved()).  This is useful when
00824         constructing the class such as with Coffi.
00825     */
00826 
00827     public void setResolved(boolean flag)
00828     {
00829         isResolved = flag;
00830     }
00831     /**
00832         Sets the superclass of this class.  Note that passing a null will cause the class to have no superclass.
00833     */
00834 
00835     public void setSuperClass(SootClass c)
00836     {
00837         resolveIfNecessary();
00838         superClass = c;
00839     }
00840     public String toString()
00841     {
00842         return getName();
00843     }
00844     /**
00845         Writes the class out to a file.
00846      */
00847 
00848     public void write(BodyExpr bodyExpr)
00849     {
00850         try {
00851             //File tempFile = new File("jimpleClass.jasmin");
00852             File tempFile = new File(this.getName() + ".jasmin");
00853  
00854             FileOutputStream streamOut = new FileOutputStream(tempFile);
00855             PrintWriter writerOut = new PrintWriter(streamOut);
00856 
00857             new ca.mcgill.sable.soot.jimple.JasminClass(this, bodyExpr).print(writerOut);
00858 
00859             writerOut.close();
00860 
00861             Runtime.getRuntime().exec("jasmin " + this.getName() + ".jasmin");
00862             tempFile.delete();
00863         } catch(IOException e)
00864         {
00865             throw new RuntimeException("Could not produce new classfile! (" + e + ")");
00866         }
00867 
00868     }
00869 }

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