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

CompilationManager.java

00001 package edu.ksu.cis.bandera.jjjc;
00002 
00003 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
00004  * Bandera, a Java(TM) analysis and transformation toolkit           *
00005  * Copyright (C) 1999, 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 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  * @param dt edu.ksu.cis.bandera.jjjc.javadoc.DocTriple
00093  */
00094 public static void addDocTriple(DocTriple dt) {
00095     docTriples.add(dt);
00096 }
00097 /**
00098  * 
00099  * @param sf ca.mcgill.sable.soot.SootField
00100  */
00101 public static void addFieldForQuantifier(SootField sf) {
00102     fieldForQuantifiers.put(sf.getName(), sf);
00103 }
00104 /**
00105  * 
00106  * @return edu.ksu.cis.bandera.jjjc.symboltable.SymbolTable
00107  * @param className edu.ksu.cis.bandera.jjjc.symboltable.Name
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  * @return edu.ksu.cis.bandera.jjjc.symboltable.SymbolTable
00123  * @param filename java.lang.String
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         // print all the classes
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         // invoke bsl
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         // invoke BOFA patch (robbyjo)
00284         //if (isRecompile) (robby)
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 * @return edu.ksu.cis.bandera.jjjc.JIJCCodeGenerator
00303 * @param filename java.lang.String
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  * @param filename java.lang.String
00359  * @param classpath java.lang.String
00360  * @param includedPackagesOrTypes java.lang.String[]
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  * @return edu.ksu.cis.bandera.annotation.AnnotationManager
00371  */
00372 public static AnnotationManager getAnnotationManager() {
00373     return am;
00374 }
00375 /**
00376  * 
00377  * @return edu.ksu.cis.bandera.jjjc.node.Node
00378  * @param filename java.lang.String
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  * @return java.util.Hashtable
00389  */
00390 public static Hashtable getCompiledClasses() {
00391     return compiledClasses;
00392 }
00393 /**
00394  * 
00395  * @return java.util.Hashtable
00396  */
00397 public static Hashtable getExceptions() {
00398     return exceptions;
00399 }
00400 /**
00401  * 
00402  * @return ca.mcgill.sable.soot.SootField
00403  * @param name java.lang.String
00404  */
00405 public static SootField getFieldForQuantifier(String name) {
00406     return (SootField) fieldForQuantifiers.get(name);
00407 }
00408 /**
00409  * 
00410  * @return ca.mcgill.sable.soot.SootClass
00411  */
00412 public static SootClass getMainSootClass() {
00413     return scm.getClass(mainClassQualifiedName);
00414 }
00415 /**
00416  * 
00417  * @return java.util.Hashtable
00418  */
00419 public static java.util.Hashtable getModifiedMethodTable() {
00420     return modifiedMethodTable;
00421 }
00422 /**
00423  * 
00424  * @return edu.ksu.cis.bandera.specification.datastructure.QuantifiedVariable
00425  * @param name java.lang.String
00426  */
00427 public static QuantifiedVariable getQuantifier(String name) {
00428     return (QuantifiedVariable) quantifierTable.get(name);
00429 }
00430 /**
00431  * 
00432  * @return java.util.Vector
00433  */
00434 public static java.util.Vector getQuantifiers() {
00435     return quantifiers;
00436 }
00437 /**
00438  * 
00439  * @return ca.mcgill.sable.soot.SootClassManager
00440  */
00441 public static SootClassManager getSootClassManager() {
00442     return scm;
00443 }
00444 /**
00445  * 
00446  * @return edu.ksu.cis.bandera.jjjc.symboltable.SymbolTable
00447  * @param filename java.lang.String
00448  */
00449 public static SymbolTable getSymbolTable(String filename) {
00450     return (SymbolTable) symTable.get(filename);
00451 }
00452 /**
00453 * 
00454 * @return boolean
00455 * @param name java.lang.String
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  * @return boolean
00479  */
00480 public static boolean isDoBSL() {
00481     return doBSL;
00482 }
00483 /**
00484  * 
00485  * @return boolean
00486  * @param node edu.ksu.cis.bandera.jjjc.node.Node
00487  */
00488 public static boolean isSynchTransformed(Node node) {
00489     return syncTransformed.contains(node);
00490 }
00491 /**
00492 * 
00493 * @param args java.lang.String[]
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  * @return edu.ksu.cis.bandera.jjjc.node.Start
00534  * @param filename java.lang.String
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("/**") >= 0) {
00552             docComments.put(key, value);
00553         }
00554     }
00555     fileTable.put(filename, ast);
00556     ast.apply(new edu.ksu.cis.bandera.jjjc.ast.SynchronizedMethodTransformer(syncTransformed, docComments));
00557     return ast;
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  * @param classpath java.lang.String
00572  */
00573 public static void setClasspath(String classpath) {
00574     CompilationManager.classpath = classpath;
00575 }
00576 /**
00577  * 
00578  * @param newDoBSL boolean
00579  */
00580 public static void setDoBSL(boolean newDoBSL) {
00581     doBSL = newDoBSL;
00582 }
00583 /**
00584  * 
00585  * @param filename java.lang.String
00586  */
00587 public static void setFilename(String filename) {
00588     CompilationManager.filename = filename;
00589 }
00590 /**
00591  * 
00592  * @param includedPackagesOrTypes java.lang.String[]
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  * @param newModifiedMethodTable java.util.Hashtable
00615  */
00616 public static void setModifiedMethodTable(java.util.Hashtable newModifiedMethodTable) {
00617     modifiedMethodTable = newModifiedMethodTable;
00618 }
00619 /**
00620  * 
00621  * @param newQuantifiers java.util.Vector
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 }

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