00001 package edu.ksu.cis.bandera.jjjc;
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.*;
00037 import ca.mcgill.sable.soot.*;
00038 import ca.mcgill.sable.soot.jimple.*;
00039 import edu.ksu.cis.bandera.specification.assertion.*;
00040 import edu.ksu.cis.bandera.specification.predicate.*;
00041 import edu.ksu.cis.bandera.specification.datastructure.*;
00042 import edu.ksu.cis.bandera.jjjc.node.*;
00043 import edu.ksu.cis.bandera.annotation.*;
00044 import edu.ksu.cis.bandera.jjjc.lexer.*;
00045 import edu.ksu.cis.bandera.jjjc.parser.*;
00046 import edu.ksu.cis.bandera.jjjc.doc.*;
00047 import ca.mcgill.sable.laleh.java.astfix.*;
00048 import edu.ksu.cis.bandera.jjjc.exception.*;
00049 import edu.ksu.cis.bandera.jjjc.symboltable.*;
00050 import edu.ksu.cis.bandera.jjjc.codegenerator.*;
00051 import edu.ksu.cis.bandera.jjjc.symboltable.Package;
00052 import edu.ksu.cis.bandera.specification.predicate.datastructure.*;
00053 import edu.ksu.cis.bandera.jjjc.analysis.*;
00054 import edu.ksu.cis.bandera.jjjc.unicodepreprocessor.*;
00055 import edu.ksu.cis.bandera.specification.assertion.datastructure.*;
00056 import edu.ksu.cis.bandera.specification.predicate.datastructure.*;
00057 import edu.ksu.cis.bandera.bofa.*;
00058
00059 public class CompilationManager {
00060 private static Hashtable fileTable;
00061 private static Hashtable symTable;
00062 private static Hashtable compiledClasses = new Hashtable();
00063 private static Hashtable exceptions = new Hashtable();
00064 private static Hashtable compiledFiles;
00065 private static AnnotationManager am;
00066 private static SootClassManager scm;
00067 private static boolean isRecompile;
00068 private static String[] includedPackagesOrTypes;
00069 private static String classpath;
00070 private static String filename;
00071 private static String[] lastIncluded;
00072 private static String lastClasspath;
00073 private static String lastFilename;
00074 private static Hashtable modifiedMethodTable = new Hashtable();
00075 private static Vector quantifiers = new Vector();
00076 private static Hashtable quantifierTable = new Hashtable();
00077 private static Vector syncTransformed = new Vector();
00078 private static Hashtable docComments;
00079 private static String mainClassQualifiedName;
00080 private static java.lang.String mainClassSimpleName;
00081 private static java.util.Hashtable fieldForQuantifiers;
00082 private static Vector docTriples;
00083 private static boolean doBSL = true;
00084
00085
00086
00087 private CompilationManager() {
00088 compiledFiles = new Hashtable();
00089 }
00090
00091
00092
00093
00094 public static void addDocTriple(DocTriple dt) {
00095 docTriples.add(dt);
00096 }
00097
00098
00099
00100
00101 public static void addFieldForQuantifier(SootField sf) {
00102 fieldForQuantifiers.put(sf.getName(), sf);
00103 }
00104
00105
00106
00107
00108
00109 public static SymbolTable buildSymbolTable(Name className) throws CompilerException {
00110 ClassOrInterfaceType classOrInterfaceType = Package.getClassOrInterfaceType(className);
00111
00112 if (!classOrInterfaceType.isLoaded()) {
00113 if (classOrInterfaceType.getPath() == null) {
00114 return new SymbolTable(className);
00115 } else
00116 return buildSymbolTable(classOrInterfaceType.getPath());
00117 }
00118 return classOrInterfaceType.getSymbolTable();
00119 }
00120
00121
00122
00123
00124
00125 public static SymbolTable buildSymbolTable(String filename) throws CompilerException {
00126 try {
00127 filename = new File(filename).getCanonicalPath();
00128 } catch (Exception e) {
00129 }
00130 if (getSymbolTable(filename) != null) {
00131 return getSymbolTable(filename);
00132 }
00133 SymbolTable symbolTable = new SymbolTable(filename);
00134 symTable.put(filename, symbolTable);
00135 return symbolTable;
00136 }
00137
00138
00139
00140 public static void compile() throws CompilerException
00141 {
00142 if (filename == null)
00143 {
00144 throw new CompilerException("Filename must be set first");
00145 } else
00146 if (classpath == null)
00147 {
00148 throw new CompilerException("Classpath must be set first");
00149 } else
00150 if (includedPackagesOrTypes == null)
00151 {
00152 throw new CompilerException("Included packages or types must be set first");
00153 }
00154 System.setProperty("user.dir", edu.ksu.cis.bandera.bui.BUI.originalUserDir);
00155 mainClassQualifiedName = null;
00156 mainClassSimpleName = new File(filename).getName();
00157 mainClassSimpleName = mainClassSimpleName.substring(0, mainClassSimpleName.indexOf("."));
00158 fieldForQuantifiers = new Hashtable();
00159 isRecompile = false;
00160 if (("" + lastFilename).equals("" + filename) && ("" + lastClasspath).equals("" + classpath))
00161 {
00162 if (lastIncluded != null)
00163 {
00164 if (lastIncluded.length == includedPackagesOrTypes.length)
00165 {
00166 boolean f = true;
00167 for (int i = 0; i < includedPackagesOrTypes.length; i++)
00168 {
00169 if (!(lastIncluded[i]).equals(includedPackagesOrTypes[i]))
00170 {
00171 f = false;
00172 break;
00173 }
00174 }
00175 if (f)
00176 isRecompile = true;
00177 }
00178 }
00179 }
00180 if (isRecompile)
00181 {
00182 if (compiledFiles.size() == 0)
00183 isRecompile = false;
00184 for (Enumeration e = compiledFiles.keys(); e.hasMoreElements();)
00185 {
00186 String filename = (String) e.nextElement();
00187 long lastModified = ((Long) compiledFiles.get(filename)).longValue();
00188 long currentLastModified = new File(filename).lastModified();
00189 if (lastModified != currentLastModified)
00190 {
00191 isRecompile = false;
00192 }
00193 }
00194 }
00195 am = new AnnotationManager();
00196 scm = new SootClassManager();
00197 exceptions = new Hashtable();
00198 compiledClasses = new Hashtable();
00199 symTable = new Hashtable();
00200 compiledFiles = new Hashtable();
00201 docTriples = new Vector();
00202 if (!isRecompile)
00203 {
00204 fileTable = new Hashtable();
00205 lastFilename = filename;
00206 lastClasspath = classpath;
00207 lastIncluded = includedPackagesOrTypes;
00208 syncTransformed = new Vector();
00209 docComments = new Hashtable();
00210 }
00211 JIJCCodeGenerator codeGenerator = null;
00212 try
00213 {
00214 Package.setClassPath(classpath);
00215 codeGenerator = compile(filename);
00216 int numClasses = 1;
00217 Object[] temp = scm.getClasses().toArray();
00218 while (numClasses != temp.length)
00219 {
00220 for (int i = 0; i < temp.length; i++)
00221 {
00222 SootClass sc = (SootClass) temp[i];
00223 String className = sc.getName().trim();
00224 Name qName = new Name(className);
00225 if (isCompile(includedPackagesOrTypes, qName) && (compiledClasses.get(className) == null))
00226 {
00227 String filename = null;
00228 ClassOrInterfaceType type = Package.getClassOrInterfaceType(qName);
00229 if (type.getPath() == null)
00230 continue;
00231 for (Enumeration e = type.getContainingPackage().getPaths(); e.hasMoreElements();)
00232 {
00233 try
00234 {
00235 String packagePath = (String) e.nextElement();
00236 if (packagePath.equals(""))
00237 {
00238 filename = qName.getLastIdentifier().toString().trim() + ".java";
00239 } else
00240 {
00241 filename = packagePath + File.separator + qName.getLastIdentifier().toString().trim() + ".java";
00242 }
00243 } catch (Exception ex)
00244 {
00245 }
00246 }
00247 if ((filename != null) && (compiledClasses.get(filename) == null))
00248 {
00249 codeGenerator = compile(filename);
00250 }
00251 }
00252 }
00253 numClasses = temp.length;
00254 temp = scm.getClasses().toArray();
00255 }
00256
00257 if (mainClassQualifiedName == null) {
00258 throw new CompilerException("Cannot find the main class '" + mainClassSimpleName + "'");
00259 }
00260
00261
00262 System.out.println("");
00263 System.out.println("");
00264 System.out.println("Compiled Classes:");
00265 System.out.println("=================");
00266 for (Enumeration e = compiledClasses.elements(); e.hasMoreElements();)
00267 {
00268 SootClass sc = (SootClass) e.nextElement();
00269 System.out.println(sc.getName());
00270 }
00271
00272
00273 if (doBSL) {
00274 AssertionSet.reset();
00275 PredicateSet.reset();
00276 for (Iterator i = docTriples.iterator(); i.hasNext();) {
00277 DocTriple dt = (DocTriple) i.next();
00278 AssertionExtractor.extract(dt.sc, dt.sm, dt.tags);
00279 PredicateExtractor.extract(dt.sc, dt.sm, dt.tags);
00280 }
00281 }
00282
00283
00284
00285 {
00286 try { BOFA.reset(); } catch (Exception e)
00287 { System.out.println("BOFA is already reset."); }
00288 try { BOFA.analyze(); } catch (Exception e)
00289 {
00290 System.out.println("BOFA Failed! "+e.getMessage());
00291 }
00292
00293 }
00294 } catch (CompilerException e)
00295 {
00296 Vector exceptions = (codeGenerator != null) ? codeGenerator.getExceptions() : new Vector();
00297 exceptions.addElement(e);
00298 CompilationManager.exceptions.put(filename, exceptions);
00299 }
00300 }
00301
00302
00303
00304
00305 private static JIJCCodeGenerator compile(String filename) throws CompilerException {
00306 File file = new File(filename);
00307 filename = file.getAbsolutePath();
00308
00309 System.out.println("Compiling: " + filename);
00310
00311 System.out.println("Parsing...");
00312 Start ast = null;
00313 try {
00314 ast = parseFile(filename);
00315 compiledFiles.put(filename, new Long(file.lastModified()));
00316 } catch (Exception e) {
00317 throw new AnalysisException(e.toString());
00318 }
00319
00320 System.out.println("Building symbol table...");
00321 SymbolTable symbolTable = buildSymbolTable(filename);
00322
00323 if (mainClassQualifiedName == null) {
00324 String dotSimpleName = "." + mainClassSimpleName;
00325 for (Enumeration e = symbolTable.getDeclaredTypes(); e.hasMoreElements();) {
00326 ClassOrInterfaceType type = (ClassOrInterfaceType) e.nextElement();
00327 String typeName = type.getFullyQualifiedName();
00328 if (typeName.endsWith(dotSimpleName) || typeName.equals(mainClassSimpleName)) {
00329 mainClassQualifiedName = typeName;
00330 if (!type.getMethods(new Name("main")).hasMoreElements()) {
00331 throw new CompilerException("Main Java file should contain a main method");
00332 }
00333 }
00334 }
00335 }
00336
00337 JIJCCodeGenerator codeGenerator = new JIJCCodeGenerator(symbolTable, scm, am, docComments);
00338 System.out.println("Generating code...");
00339 try {
00340 ast.apply(codeGenerator);
00341 } catch (Exception e) {
00342 e.printStackTrace();
00343 }
00344 System.out.println("------------------------");
00345 System.out.println("Finished\n");
00346 Vector classes = codeGenerator.getCompiledClasses();
00347 for (int i = 0; i < classes.size(); i++) {
00348 compiledClasses.put(classes.elementAt(i), scm.getClass((String) classes.elementAt(i)));
00349 }
00350 if (codeGenerator.getExceptions().elements().hasMoreElements()) {
00351 exceptions.put(filename, codeGenerator.getExceptions());
00352 }
00353 System.gc();
00354 return codeGenerator;
00355 }
00356
00357
00358
00359
00360
00361
00362 public void compile(String filename, String classpath, String[] includedPackagesOrTypes) throws CompilerException {
00363 setFilename(filename);
00364 setClasspath(classpath);
00365 setIncludedPackagesOrTypes(includedPackagesOrTypes);
00366 compile();
00367 }
00368
00369
00370
00371
00372 public static AnnotationManager getAnnotationManager() {
00373 return am;
00374 }
00375
00376
00377
00378
00379
00380 public static Node getAST(String filename) {
00381 return (Node) fileTable.get(filename);
00382 }
00383 public static String getClasspath() {
00384 return classpath;
00385 }
00386
00387
00388
00389
00390 public static Hashtable getCompiledClasses() {
00391 return compiledClasses;
00392 }
00393
00394
00395
00396
00397 public static Hashtable getExceptions() {
00398 return exceptions;
00399 }
00400
00401
00402
00403
00404
00405 public static SootField getFieldForQuantifier(String name) {
00406 return (SootField) fieldForQuantifiers.get(name);
00407 }
00408
00409
00410
00411
00412 public static SootClass getMainSootClass() {
00413 return scm.getClass(mainClassQualifiedName);
00414 }
00415
00416
00417
00418
00419 public static java.util.Hashtable getModifiedMethodTable() {
00420 return modifiedMethodTable;
00421 }
00422
00423
00424
00425
00426
00427 public static QuantifiedVariable getQuantifier(String name) {
00428 return (QuantifiedVariable) quantifierTable.get(name);
00429 }
00430
00431
00432
00433
00434 public static java.util.Vector getQuantifiers() {
00435 return quantifiers;
00436 }
00437
00438
00439
00440
00441 public static SootClassManager getSootClassManager() {
00442 return scm;
00443 }
00444
00445
00446
00447
00448
00449 public static SymbolTable getSymbolTable(String filename) {
00450 return (SymbolTable) symTable.get(filename);
00451 }
00452
00453
00454
00455
00456
00457 private static boolean isCompile(String packageNames[], Name qName) {
00458 boolean compile = false;
00459 if (qName.toString().equals("Bandera")) return false;
00460 if (qName.isSimpleName()) {
00461 compile = true;
00462 } else
00463 if (packageNames != null) {
00464 String name = qName.toString().trim();
00465 String sName = qName.getSuperName().toString().trim();
00466 for (int j = 0; j < packageNames.length; j++) {
00467 String packageName = packageNames[j];
00468 if ((packageName != null) && (name.equals(packageName) || sName.equals(packageName))) {
00469 compile = true;
00470 j = packageNames.length;
00471 }
00472 }
00473 }
00474 return compile;
00475 }
00476
00477
00478
00479
00480 public static boolean isDoBSL() {
00481 return doBSL;
00482 }
00483
00484
00485
00486
00487
00488 public static boolean isSynchTransformed(Node node) {
00489 return syncTransformed.contains(node);
00490 }
00491
00492
00493
00494
00495 public static void main(String args[]) {
00496 String classPath;
00497 String javaFileName;
00498 if (args.length < 2) {
00499 System.out.println("usage:");
00500 System.out.println(" java CompilationManager <classpath> <main java file> [packages]");
00501 return;
00502 }
00503 classPath = args[0];
00504 javaFileName = args[1];
00505
00506 String[] packageNames = new String[args.length - 1];
00507 packageNames[0] = "";
00508
00509 for (int i = 0; i < packageNames.length - 1; i++) {
00510 packageNames[i + 1] = args[i + 2];
00511 }
00512
00513 setClasspath(classPath);
00514 setFilename(javaFileName);
00515 setIncludedPackagesOrTypes(packageNames);
00516 try {
00517 compile();
00518 } catch (Exception e) {
00519 System.out.println(e);
00520 }
00521 for (Enumeration e = compiledClasses.elements(); e.hasMoreElements();) {
00522 SootClass sc = (SootClass) e.nextElement();
00523 try {
00524 sc.printTo(new StoredBody(Jimple.v()), new PrintWriter(new FileWriter(sc.getName() + ".jimple"), true));
00525 } catch (IOException ioe) {
00526 ioe.printStackTrace();
00527 }
00528 }
00529 System.exit(0);
00530 }
00531
00532
00533
00534
00535
00536 public static Start parseFile(String filename) throws Exception {
00537 filename = new File(filename).getCanonicalPath();
00538 if (fileTable.get(filename) != null)
00539 return (Start) fileTable.get(filename);
00540 FileReader fr = new FileReader(filename);
00541 UnicodePreprocessor preprocessor = new UnicodePreprocessor(
00542 new PushbackReader(new BufferedReader(fr, 8192), 1024));
00543 Lexer lexer = new Lexer(new PushbackReader(preprocessor, 1024));
00544 JJCParser parser = new JJCParser(lexer);
00545 Start ast = parser.parse();
00546 fr.close();
00547 Hashtable table = ((AnalysisAdapter) parser.ignoredTokens).getIn();
00548 for (Enumeration e = table.keys(); e.hasMoreElements();) {
00549 Object key = e.nextElement();
00550 Object value = table.get(key);
00551 if (value.toString().indexOf("
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562 public static void reset() {
00563 compiledClasses = new Hashtable();
00564 exceptions = new Hashtable();
00565 CompilationManager.setFilename(null);
00566 CompilationManager.setClasspath(null);
00567 CompilationManager.setIncludedPackagesOrTypes(null);
00568 }
00569
00570
00571
00572
00573 public static void setClasspath(String classpath) {
00574 CompilationManager.classpath = classpath;
00575 }
00576
00577
00578
00579
00580 public static void setDoBSL(boolean newDoBSL) {
00581 doBSL = newDoBSL;
00582 }
00583
00584
00585
00586
00587 public static void setFilename(String filename) {
00588 CompilationManager.filename = filename;
00589 }
00590
00591
00592
00593
00594 public static void setIncludedPackagesOrTypes(String[] includedPackagesOrTypes) {
00595 if (CompilationManager.includedPackagesOrTypes == includedPackagesOrTypes) return;
00596 if ((CompilationManager.includedPackagesOrTypes != null) &&
00597 (includedPackagesOrTypes != null)) {
00598 if (CompilationManager.includedPackagesOrTypes.length == includedPackagesOrTypes.length) {
00599 boolean f = true;
00600 for (int i = 0; i < includedPackagesOrTypes.length; i++) {
00601 if (!("" + CompilationManager.includedPackagesOrTypes[i]).equals("" + includedPackagesOrTypes[i])) {
00602 f = false;
00603 break;
00604 }
00605 }
00606 if (f) return;
00607 }
00608 }
00609 CompilationManager.includedPackagesOrTypes = includedPackagesOrTypes;
00610 isRecompile = false;
00611 }
00612
00613
00614
00615
00616 public static void setModifiedMethodTable(java.util.Hashtable newModifiedMethodTable) {
00617 modifiedMethodTable = newModifiedMethodTable;
00618 }
00619
00620
00621
00622
00623 public static void setQuantifiers(java.util.Vector newQuantifiers) {
00624 quantifiers = newQuantifiers;
00625 quantifierTable = new Hashtable();
00626 for (Iterator i = quantifiers.iterator(); i.hasNext();) {
00627 QuantifiedVariable qv = (QuantifiedVariable) i.next();
00628 quantifierTable.put(qv.getName(), qv);
00629 }
00630 }
00631 }