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

OptionsSaverLoader.java

00001 package edu.ksu.cis.bandera.abstraction.options;
00002 
00003 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
00004  * Bandera, a Java(TM) analysis and transformation toolkit           *
00005  * Copyright (C) 2000   Robby (robby@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 java.io.*;
00036 import java.util.*;
00037 import java.lang.reflect.Method;
00038 import ca.mcgill.sable.soot.*;
00039 import ca.mcgill.sable.soot.jimple.*;
00040 import edu.ksu.cis.bandera.abstraction.util.*;
00041 import edu.ksu.cis.bandera.abstraction.options.node.*;
00042 import edu.ksu.cis.bandera.abstraction.options.lexer.*;
00043 import edu.ksu.cis.bandera.abstraction.options.parser.*;
00044 import edu.ksu.cis.bandera.abstraction.options.analysis.*;
00045 public class OptionsSaverLoader {
00046     private static final Jimple jimple = Jimple.v();
00047     private Hashtable localMethodNamesTable;
00048     private SootClassManager scm;
00049     private SootClass sc;
00050     private SootMethod sm;
00051     private ca.mcgill.sable.util.List params;
00052     private JimpleBody body;
00053     private Hashtable result;
00054     private Vector warnings;
00055     private class Walker extends DepthFirstAdapter {
00056         public void caseAClassOption(AClassOption node) {
00057             sc = scm.getClass(Util.deleteChars(node.getName().toString(), " "));
00058             if (result.get(sc) != null) {
00059                 String msg = "*** WARNING: Redefinition of options for class '" + sc + "'. Discarding the previous one. ****";
00060                 warnings.add(msg);
00061                 //System.out.println(msg);
00062             }
00063             result.put(sc, new HashSet());
00064             {
00065                 Object temp[] = node.getFieldOption().toArray();
00066                 for (int i = 0; i < temp.length; i++) {
00067                     ((PFieldOption) temp[i]).apply(this);
00068                 }
00069             }
00070             {
00071                 Object temp[] = node.getMethodOption().toArray();
00072                 for (int i = 0; i < temp.length; i++) {
00073                     ((PMethodOption) temp[i]).apply(this);
00074                 }
00075             }
00076         }
00077         public void caseAFieldOption(AFieldOption node) {
00078             String fieldName = node.getId().toString().trim();
00079             if (sc.declaresField(fieldName)) {
00080                 String typeName = Util.deleteChars(node.getName().toString(), " ");
00081                 try {
00082                     SootField sf = sc.getField(fieldName);
00083                     result.put(sf, AbstractionClassLoader.getClass(typeName).getMethod("v", new Class[0]).invoke(null, new Object[0]));
00084                     ((HashSet) result.get(sc)).add(sf);
00085                 } catch (Exception e) {
00086                     String msg = "*** WARNING: Couldn't find abstraction '" + typeName + "'. The '" + sc.getName() + "." + fieldName + "' field's option is ignored. ***";
00087                     warnings.add(msg);
00088                     //System.out.println(msg);
00089                 }
00090             } else {
00091                 String msg = "*** WARNING: Couldn't find field '" + sc.getName() + "." + fieldName + "'. The field's option is ignored. ***";
00092                 warnings.add(msg);
00093                 //System.out.println(msg);
00094             }
00095         }
00096         public void caseALocalOption(ALocalOption node) {
00097             String localName = node.getId().toString().trim();
00098             if (body.declaresLocal(localName)) {
00099                 LocalMethod lm = new LocalMethod(sm, body.getLocal(localName));
00100                 String typeName = Util.deleteChars(node.getName().toString(), " ");
00101                 try {
00102                     result.put(lm, AbstractionClassLoader.getClass(typeName).getMethod("v", new Class[0]).invoke(null, new Object[0]));
00103                     ((HashSet) result.get(sm)).add(lm.getLocal());
00104                 } catch (Exception e) {
00105                     String msg = "*** WARNING: Couldn't find abstraction '" + typeName + "'. The '" + lm + "' local's option is ignored. ***";
00106                     warnings.add(msg);
00107                     //System.out.println(msg);
00108                 }
00109             } else {
00110                 String msg = "*** WARNING: Couldn't find local '" + localName + "' in method '" + sm + "'. The local's option is ignored. ***";
00111                 warnings.add(msg);
00112                 //System.out.println(msg);
00113             }
00114         }
00115         public void caseAMethodOption(AMethodOption node) {
00116             params = new ca.mcgill.sable.util.LinkedList();
00117             if (node.getParams() != null) {
00118                 node.getParams().apply(this);
00119             }
00120             String mName = node.getId().toString().trim();
00121             String cName = sc.getName();
00122             int idx = cName.lastIndexOf(".");
00123             if (idx >= 0) {
00124                 cName = cName.substring(idx + 1);
00125             }
00126             if (mName.equals(cName)) mName = "<init>";
00127             try {
00128                 sm = sc.getMethod(mName, params);
00129                 ((HashSet) result.get(sc)).add(sm);
00130                 if (!sm.isBodyStored(jimple)) {
00131                     new BuildAndStoreBody(jimple, new StoredBody(ClassFile.v()), 0).resolveFor(sm);
00132                 }
00133                 body = (JimpleBody) sm.getBody(jimple);
00134                 result.put(sm, new HashSet());
00135                 {
00136                     Object temp[] = node.getLocalOption().toArray();
00137                     for (int i = 0; i < temp.length; i++) {
00138                         ((PLocalOption) temp[i]).apply(this);
00139                     }
00140                 }
00141             } catch (Exception e) {
00142                 String params = OptionsSaverLoader.this.params.toString();
00143                 params = params.substring(1, params.length() - 1);
00144                 String msg = "*** WARNING: Couldn't find method '" + sc.getName() + "." + mName + "(" + params + ")'. The method's options are ignored. ***";
00145                 warnings.add(msg);
00146                 //System.out.println(msg);
00147             }
00148         }
00149         public void caseAParamParams(AParamParams node) {
00150             Type t = Util.getType(Util.deleteChars(node.getName().toString(), " "));
00151             int dimensions = node.getDim().size();
00152             if (dimensions > 0) {
00153                 t = ArrayType.v((BaseType) t, dimensions);
00154             }
00155             params.add(t);
00156         }
00157         public void caseAParamsParams(AParamsParams node) {
00158             node.getParams().apply(this);
00159             Type t = Util.getType(Util.deleteChars(node.getName().toString(), " "));
00160             int dimensions = node.getDim().size();
00161             if (dimensions > 0) {
00162                 t = ArrayType.v((BaseType) t, dimensions);
00163             }
00164             params.add(t);
00165         }
00166     }
00167     private Walker walker;
00168 /**
00169  * 
00170  */
00171 private OptionsSaverLoader() {
00172     walker = new Walker();
00173 }
00174 /**
00175  * 
00176  * @return java.util.Hashtable
00177  *   The Hashtable is of type:
00178  *     SootClass * HashSet&lt;SootField U SootMethod&gt;, that maps class to its to-be-abstracted members
00179  *     U SootField * String, that maps a field to its abstraction
00180  *     U SootMethod * HashSet&lt;Local&gt;, that maps a method to its to-be-abtracted parameters/locals
00181  *     U LocalMethod * String, that maps a (method, local) pair to its abstraction
00182  *     U String * Vector&lt;String&gt;, that maps the string "WARNINGS" to a vector containing warning messages
00183  * @param scm ca.mcgill.sable.soot.SootClassManager
00184  * @param reader java.io.Reader
00185  */
00186 public static Hashtable load(SootClassManager scm, Reader reader) throws Exception {
00187     OptionsSaverLoader osl = new OptionsSaverLoader();
00188     osl.scm = scm;
00189 
00190     osl.result = new Hashtable();
00191     osl.warnings = new Vector();
00192 
00193     new Parser(new Lexer(new PushbackReader(reader))).parse().apply(osl.walker);
00194 
00195     osl.result.put("WARNINGS", osl.warnings);
00196 
00197     return osl.result;
00198 }
00199 /**
00200  * 
00201  * @param PrintWriter java.io.PrintWriter
00202  * @param table java.util.Hashtable
00203  *   The Hashtable is of type:
00204  *     SootClass * HashSet&lt;SootField U SootMethod&gt;, that maps class to its to-be-abstracted members
00205  *     U SootField * String, that maps a field to its abstraction
00206  *     U SootMethod * HashSet&lt;Local&gt;, that maps a method to its to-be-abtracted parameters/locals
00207  *     U LocalMethod * String, that maps a (method, local) pair to its abstraction
00208  */
00209 public static void save(PrintWriter writer, Hashtable table) {
00210     for (Enumeration e = table.keys(); e.hasMoreElements();) {
00211         Object key = e.nextElement();
00212         if (key instanceof SootClass) {
00213             SootClass sc = (SootClass) key;
00214             writer.println("class " + sc.getName() + " {");
00215             for (Iterator i = ((HashSet) table.get(sc)).iterator(); i.hasNext();) {
00216                 Object o = i.next();
00217                 if (o instanceof SootField) {
00218                     SootField sf = (SootField) o;
00219                     writer.println("  " + sf.getName() + " " + table.get(sf).getClass().getName() + ";");
00220                 }
00221             }
00222             for (Iterator i = ((HashSet) table.get(sc)).iterator(); i.hasNext();) {
00223                 Object o = i.next();
00224                 if (o instanceof SootMethod) {
00225                     SootMethod sm = (SootMethod) o;
00226                     String mName = sm.getName(); 
00227                     if ("<clinit>".equals(mName)) continue;
00228                     if ("<init>".equals(mName)) {
00229                         mName = sm.getDeclaringClass().getName();
00230                         int idx = mName.lastIndexOf(".");
00231                         if (idx >= 0) {
00232                             mName = mName.substring(idx + 1);
00233                         }
00234                     }
00235                     String params = sm.getParameterTypes().toString();
00236                     writer.println("  " + mName + "(" + params.substring(1, params.length() - 1) + ") { ");
00237                     for (Iterator j = ((HashSet) table.get(sm)).iterator(); j.hasNext();) {
00238                         Local lcl = (Local) j.next();
00239                         writer.println("    " + lcl.getName() + " " + table.get(new LocalMethod(sm, lcl)).getClass().getName() + ";");
00240                     }
00241                     writer.println("  }");
00242                 }
00243             }
00244             writer.println("}");
00245             writer.println();
00246         }
00247     }
00248 }
00249 }

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