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

TypeExtractor.java

00001 package edu.ksu.cis.bandera.birc;
00002 
00003 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
00004  * Bandera, a Java(TM) analysis and transformation toolkit           *
00005  * Copyright (C) 1998, 1999   James Corbett (corbett@hawaii.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.Vector;
00037 import java.util.Hashtable;
00038 
00039 import edu.ksu.cis.bandera.bir.TransSystem;
00040 import edu.ksu.cis.bandera.jext.*;
00041 
00042 import ca.mcgill.sable.soot.ArrayType; 
00043 
00044 import ca.mcgill.sable.util.*;
00045 import ca.mcgill.sable.soot.*;
00046 import ca.mcgill.sable.soot.jimple.*;
00047 
00048 /**
00049  * A Jimple type switch for extracting BIR types from Jimple types.
00050  * <p>
00051  * The TransSystem class is a factory for the BIR type classes.
00052  * For Jimple primitive types, the extractor simply calls 
00053  * the appropriate constructor method in the factory.
00054  * For Jimple reference types, the extractor maintains
00055  * a mapping from the Jimple type to the BIR record, array,
00056  * or reference type.
00057  */
00058 
00059 public class TypeExtractor extends BanderaTypeSwitch {
00060 
00061     TransSystem system;
00062     SootClassManager classManager;
00063 
00064     /**
00065      * These tables map Jimple types to BIR types.
00066      * <p>
00067      * Note that a single Jimple type (e.g., a SootClass C) may
00068      * have multiple BIR types (e.g., C_rec and C_ref).
00069      */
00070     Hashtable refTypeTable = new Hashtable();
00071     Hashtable recordTypeTable = new Hashtable();
00072     Hashtable arrayTypeTable = new Hashtable();
00073 
00074     public TypeExtractor(TransSystem system, SootClassManager classManager) {
00075     this.system = system;
00076     this.classManager = classManager;
00077     }
00078     /**
00079      * Add the fields of a class to a BIR record.
00080      */
00081 
00082     void addFields(edu.ksu.cis.bandera.bir.Record rec, SootClass sootClass) {
00083     Iterator fieldIt = sootClass.getFields().iterator();        
00084     while(fieldIt.hasNext()) {
00085         SootField field = (SootField) fieldIt.next();
00086         // For all non-static fields
00087         if (! Modifier.isStatic(field.getModifiers())) {
00088         // If type unknown, ignore field
00089         field.getType().apply(this);
00090         edu.ksu.cis.bandera.bir.Type type = 
00091             (edu.ksu.cis.bandera.bir.Type)getResult();
00092         if (type == null) 
00093             continue;
00094         // If field already named (e.g., in superclass), use that name
00095         String fieldName = system.getNameOf(field);
00096         if (fieldName == null)
00097             fieldName = system.createName(field,field.getName());
00098         edu.ksu.cis.bandera.bir.Field birField = 
00099             rec.addField(fieldName, type);
00100         system.setSource(birField,field);
00101         }
00102     }   
00103     }
00104     /**
00105      * Construct name for array type by appending "_arr" to the base
00106      * type name for each dimension (e.g., int [][] would be int_arr_arr).
00107      */
00108 
00109     public String arrayName(ArrayType sootArrayType) {
00110     Type type = sootArrayType.baseType;
00111     while (type instanceof ArrayType) 
00112         type = ((ArrayType)type).baseType;
00113     String name = type.toString();
00114     for (int i = 0; i < sootArrayType.numDimensions; i++)
00115         name += "_arr";
00116     return name;
00117     }
00118     public void caseArrayType(ArrayType type) {
00119     // By the time this is called, the ref type should have
00120     // already been created from the dynamic map
00121     setResult(refTypeTable.get(type));
00122     }
00123     public void caseBooleanType(BooleanType type) {
00124     setResult(system.booleanType());
00125     }
00126     public void caseByteType(ByteType type) {
00127     setResult(system.rangeType());
00128     }
00129     public void caseIntType(IntType type) {
00130     setResult(system.rangeType());
00131     }
00132     public void caseLongType(LongType type) {
00133     setResult(system.rangeType());
00134     }
00135     public void caseRefType(RefType type) {
00136     SootClass sootClass = classManager.getClass(type.className);
00137     // By the time this is called, the ref type should have
00138     // already been created from the dynamic map
00139     setResult(refTypeTable.get(sootClass));
00140     }
00141     public void caseShortType(ShortType type) {
00142     setResult(system.rangeType());
00143     }
00144     /**
00145      * Declare BIR array type for a Soot array type.
00146      */
00147 
00148     void createArrayType(ArrayType sootArrayType, int arrayLen) {
00149     // Get BIR type for base type
00150     sootArrayType.baseType.apply(this);
00151     edu.ksu.cis.bandera.bir.Type baseType = 
00152         (edu.ksu.cis.bandera.bir.Type) getResult();
00153     edu.ksu.cis.bandera.bir.ConstExpr lenExpr = 
00154         new edu.ksu.cis.bandera.bir.IntLit(arrayLen);
00155     edu.ksu.cis.bandera.bir.Array type = 
00156         system.arrayType(baseType,lenExpr);
00157     String name = arrayName(sootArrayType);
00158     type.setName(system.createName(null,name));
00159     system.define(type.getName(), type);
00160     arrayTypeTable.put(sootArrayType, type);
00161     }
00162     /**
00163      * Create a collection type for a given BIR type and collection size.
00164      */
00165 
00166     edu.ksu.cis.bandera.bir.Collection createCollectionType(edu.ksu.cis.bandera.bir.Type type, int size) {
00167     edu.ksu.cis.bandera.bir.ConstExpr sizeExpr = 
00168         new edu.ksu.cis.bandera.bir.IntLit(size);
00169     return system.collectionType(type,sizeExpr);
00170     }
00171     /**
00172      * Declare a record type for a class C (name it C_rec).
00173      * <p>
00174      * Note: we flatten the implementation inheritance here
00175      * by adding all fields from superclasses of C into C_rec.
00176      * <p>
00177      * It is important that the inherited fields of a subclass 
00178      * appear first and in the same order as they do in the
00179      * superclass.
00180      */
00181 
00182     void createRecordType(SootClass sootClass, boolean isLocked) {
00183     edu.ksu.cis.bandera.bir.Record type = system.recordType();
00184     system.addType(type); // Robbyjo's patch
00185     type.setName(system.createName(null,sootClass.getName() + "_rec"));
00186     system.define(type.getName(), type);
00187     recordTypeTable.put(sootClass, type);
00188     if (isLocked) {
00189            type.addField("BIRLock",system.lockType(true,true));
00190     }
00191     Vector superClasses = getSuperClasses(sootClass);
00192     for (int i = superClasses.size() - 1; i >= 0; i--) {
00193         SootClass supClass = (SootClass) superClasses.elementAt(i);
00194         // Don't include fields of predefined classes
00195         if (supClass.getName().startsWith("java."))
00196             continue;  
00197         addFields(type,supClass);
00198     }
00199     addFields(type,sootClass);
00200     system.setSource(type,sootClass);
00201     }
00202     /**
00203      * Declare a reference type for an array type A (name it A_ref).
00204      */
00205 
00206     void createRefType(ArrayType sootArrayType) {
00207     edu.ksu.cis.bandera.bir.Ref type = system.refType();
00208     String name = arrayName(sootArrayType);
00209     type.setName(system.createName(null,name + "_ref"));
00210     system.define(type.getName(), type);
00211     refTypeTable.put(sootArrayType, type);  
00212     }
00213     /**
00214      * Declare reference type for a class C (name it C_ref).
00215      */
00216 
00217     void createRefType(SootClass sootClass) {
00218     if (refTypeTable.get(sootClass) == null) {
00219         edu.ksu.cis.bandera.bir.Ref type = system.refType();
00220         type.setName(system.createName(null,sootClass.getName() + "_ref"));
00221         system.define(type.getName(), type);
00222         refTypeTable.put(sootClass, type);
00223         // Must create ref types for all super classes and interfaces
00224         if (sootClass.hasSuperClass())
00225         createRefType(sootClass.getSuperClass());
00226         Iterator intIt = sootClass.getInterfaces().iterator();
00227         while (intIt.hasNext()) {
00228         SootClass intClass = (SootClass) intIt.next();
00229         createRefType(intClass);
00230         }
00231     }
00232     }
00233     public void defaultCase(Type type) {
00234     setResult(null);
00235     }
00236     /**
00237      * Get BIR array type for Soot array type.
00238      */
00239 
00240     edu.ksu.cis.bandera.bir.Array getArrayType(ArrayType sootArrayType) {
00241     return (edu.ksu.cis.bandera.bir.Array) 
00242         arrayTypeTable.get(sootArrayType);
00243     }
00244     /**
00245      * Return the set of interfaces implemented by a class.
00246      * <p>
00247      * Note: need to look at all superclasses.
00248      */
00249 
00250     Vector getInterfaceClasses(SootClass sootClass) {
00251     Vector result = new Vector();
00252     Vector supClasses = getSuperClasses(sootClass);
00253     supClasses.addElement(sootClass);
00254     for (int i = 0; i < supClasses.size(); i++) {
00255         SootClass supClass = (SootClass) supClasses.elementAt(i);
00256         Iterator interfaceIt = supClass.getInterfaces().iterator();
00257         while (interfaceIt.hasNext()) {
00258         SootClass interfaceClass = (SootClass) interfaceIt.next();
00259         if (! result.contains(interfaceClass))
00260             result.addElement(interfaceClass);
00261         }
00262     }
00263     return result;
00264     }
00265     /**
00266      * Get BIR record type of class.
00267      */
00268 
00269 // BIRC FIXUP : make this private again after real fix
00270 // Made this public to enable hack in ...bir.Ref
00271 //
00272     public edu.ksu.cis.bandera.bir.Record getRecordType(SootClass sootClass) {
00273     return (edu.ksu.cis.bandera.bir.Record) recordTypeTable.get(sootClass);
00274     }
00275     edu.ksu.cis.bandera.bir.Ref getRefType(ArrayType sootArrayType) {
00276     return (edu.ksu.cis.bandera.bir.Ref) refTypeTable.get(sootArrayType);
00277     }
00278     /**
00279      * Get the reference type for a class or array.
00280      */
00281 
00282     edu.ksu.cis.bandera.bir.Ref getRefType(SootClass sootClass) {
00283     return (edu.ksu.cis.bandera.bir.Ref) refTypeTable.get(sootClass);
00284     }
00285     /**
00286      * Return the set of super classes of a class.
00287      */
00288 
00289     Vector getSuperClasses(SootClass sootClass) {
00290     Vector result = new Vector();
00291     SootClass supClass = sootClass; 
00292     while (supClass.hasSuperClass()) {
00293         supClass = supClass.getSuperClass();        
00294         // Don't include fields of predefined classes
00295         // if (supClass.getName().startsWith("java."))
00296         //  break;  
00297         result.addElement(supClass);
00298     }
00299     return result;
00300     }
00301 }

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