00001 package edu.ksu.cis.bandera.birc;
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
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
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059 public class TypeExtractor extends BanderaTypeSwitch {
00060
00061 TransSystem system;
00062 SootClassManager classManager;
00063
00064
00065
00066
00067
00068
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
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
00087 if (! Modifier.isStatic(field.getModifiers())) {
00088
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
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
00106
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
00120
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
00138
00139 setResult(refTypeTable.get(sootClass));
00140 }
00141 public void caseShortType(ShortType type) {
00142 setResult(system.rangeType());
00143 }
00144
00145
00146
00147
00148 void createArrayType(ArrayType sootArrayType, int arrayLen) {
00149
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
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
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182 void createRecordType(SootClass sootClass, boolean isLocked) {
00183 edu.ksu.cis.bandera.bir.Record type = system.recordType();
00184 system.addType(type);
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
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
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
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
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
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
00246
00247
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
00267
00268
00269
00270
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
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
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
00295
00296
00297 result.addElement(supClass);
00298 }
00299 return result;
00300 }
00301 }