1 24 25 package org.aspectj.compiler.base; 26 27 import org.aspectj.compiler.base.ast.World; 28 import org.aspectj.compiler.base.ast.AST; 29 import org.aspectj.compiler.base.ast.CompilationUnit; 30 import org.aspectj.compiler.base.ast.ASTObject; 31 import org.aspectj.compiler.base.ast.TypeDec; 32 import org.aspectj.compiler.base.parser.JavaParser; 33 34 35 import java.util.*; 36 import java.util.Stack ; 37 import java.io.*; 38 import java.text.NumberFormat ; 39 import java.lang.reflect.Constructor ; 40 41 public class JavaCompiler { 42 private Options options = new Options(); 44 private TypeManager typeManager; 46 protected World world; 48 protected ErrorHandler errorHandler; 50 protected Class scanner; 52 protected List passes; 54 private Stack parsers = new Stack (); 56 protected List filesToCompile; 58 59 60 61 public final Options getOptions() { return options; } 62 63 public final World getWorld() { return world; } 64 65 public final TypeManager getTypeManager() { return typeManager; } 66 67 68 public boolean willGenerateSourceCode() { 69 return options.usejavac || options.preprocess; 70 } 71 72 public String getVersion() { 73 return Options.version; 74 } 75 76 public long getBuildTime() { 77 return Options.build; 78 } 79 80 public List getFilesToCompile() { 81 if (filesToCompile == null) return new LinkedList(); 82 return filesToCompile; 83 } 84 85 public void addFileToCompile(File f) { 86 if (filesToCompile == null) filesToCompile = new LinkedList(); 87 filesToCompile.add(f); 88 } 89 90 public CompilationUnit newCompilationUnit(File _file) { 91 return new CompilationUnit(this,_file); 92 } 93 94 public JavaCompiler(ErrorHandler errHandler) { 95 this.errorHandler = (errHandler != null) ? errHandler : makeErrorHandler(); 97 this.errorHandler.setCompiler(this); 98 } 99 100 104 protected ErrorHandler makeErrorHandler() { 105 return new ErrorHandler(new OutputStreamWriter(System.err)); 106 } 107 108 109 public JavaParser makeJavaParser() { 110 return new JavaParser(this); 111 } 112 113 public boolean isIncremental() { 114 return options.incremental; 115 } 116 117 public boolean getOptionDumpStack() { 118 return options.dumpstack; 119 } 120 121 public boolean getOptionIgnoreErrors() { 122 return options.ignoreErrors; 123 } 124 125 public boolean getOptionVerbose() { 126 return options.verbose; 127 } 128 129 public void clearState() { 130 world.cleanup(); 131 filesToCompile = null; 132 errorHandler.cleanupErrorWarningCounters(); 133 } 134 135 public void compile(List filenames) { 136 addPasses(); 137 138 if (getOptions().threads != 0) { 139 System.out.println("warning: multi-threaded compilation not supported in this release"); 140 getOptions().threads = 0; 141 } 142 143 try { 144 internalCompile(filenames); 145 } catch (CompilerErrors compilerErrors) { 146 throw compilerErrors; 147 } catch (ExitRequestException exitRequest) { 148 throw exitRequest; 149 } catch (InternalCompilerError internalError) { 150 if (!getOptions().torture) errorHandler.exitOnErrors(); 152 throw internalError; 153 } catch (Throwable throwable) { 154 if (!getOptions().torture) errorHandler.exitOnErrors(); 157 throw new InternalCompilerError(this, throwable, getCurrentNode()); 158 } finally { 159 } 161 } 162 163 164 protected void createWorld(List filenames) { 165 typeManager = new TypeManager(this); 166 world = new World(this); 167 if (!typeManager.checkLoadable("java.lang", "Object")) { 168 warnNoObject(); 169 } 170 if (!typeManager.checkLoadable("org.aspectj.lang", "JoinPoint")) { 171 warnNoRuntime(false); 172 } 173 if (!typeManager.checkLoadable("org.aspectj.runtime.internal", "AroundClosure")) { 174 warnNoRuntime(true); 175 } 176 for(Iterator i=filenames.iterator(); i.hasNext();) { 178 Object o = i.next(); 179 String filename; 180 File file; 181 if (o instanceof String ) { 182 filename = (String )o; 183 file = new File(filename); 184 } else { 185 file = (File)o; 186 filename = file.getPath(); 187 } 188 world.addFile(filename); 189 } 190 } 191 192 private static final String noRuntimeWarning = 193 "Can't find org.aspectj.lang.JoinPoint on your classpath anywhere.\n" + 194 "You need to include aspectjrt.jar on your classpath when compiling or\n" + 195 "running applications with ajc. See README-TOOLS.html in the top directory of\n" + 196 "the distribution for more details on how to configure this correctly."; 197 198 private static final String oldRuntimeWarning = 199 "You appear to have an out-of-date version of aspectjrt.jar on your classpath.\n" + 200 "You need to include the latest verion of aspectjrt.jar on your classpath when\n" + 201 "compiling or running applications with ajc. See README-TOOLS.html in the top\n" + 202 "directory of the distribution for more details on how to configure this\n" + 203 "correctly."; 204 205 208 protected void warnNoRuntime(boolean foundOld) { 209 System.err.println(foundOld ? oldRuntimeWarning : noRuntimeWarning); 210 System.err.println(); 211 System.err.println("I looked in: "); 212 for (Iterator i = getTypeManager().getClassPathStrings().iterator(); i.hasNext(); ) { 213 System.err.print(" "); 214 System.err.println(i.next()); 215 } 216 217 219 throw new ExitRequestException(-1); 220 } 221 222 223 private static final String noObjectWarning = 224 "Serious configuration problem: can't find java.lang.Object"; 225 private static final String modifiedBootpathWarning = 226 "Check your custom bootclasspath for validity: "; 227 private static final String jviewWarning = 228 "You must run 'claspack -auto' to use ajc with MS's jview VM"; 229 230 231 private void warnNoObject() { 232 System.err.println(noObjectWarning); 233 if (options.bootclasspath != null) { 234 System.err.println(modifiedBootpathWarning+options.bootclasspath); 235 } else { 236 String vendor = System.getProperty("java.vm.vendor"); 237 if (vendor != null && vendor.startsWith("Microsoft")) { 238 System.err.println(jviewWarning); 239 } 240 } 241 242 throw new ExitRequestException(-1); 243 } 244 245 protected void addPasses() {} 246 247 248 public synchronized JavaParser allocateParser() { 249 JavaParser parser; 250 if (parsers.empty()) { 251 parser = makeJavaParser(); 252 } else { 253 parser = (JavaParser)parsers.pop(); 254 } 255 return parser; 256 } 257 258 public synchronized void freeParser(JavaParser parser) { 259 parser.cleanup(false); 260 parsers.push(parser); 261 } 262 263 264 265 266 267 private Hashtable timingInformation = new Hashtable(); 268 private ThreadLocal sectionLabel = new ThreadLocal (); 269 private ThreadLocal localNodes = new ThreadLocal (); 270 private long startTime; 271 272 private Stack getNodes() { 273 Object nodes = localNodes.get(); 274 if (nodes == null) { 275 nodes = new Stack (); 276 localNodes.set(nodes); 277 } 278 return (Stack )nodes; 279 } 280 281 public String getCurrentSection() { 282 return (String )sectionLabel.get(); 283 } 284 285 public void setCurrentSection(String label) { 286 sectionLabel.set(label); 287 } 288 289 private String formatTime(long time) { 290 NumberFormat format = NumberFormat.getNumberInstance(); 291 format.setMinimumFractionDigits(2); 292 format.setMaximumFractionDigits(2); 293 String value = format.format(time/1000.0); 294 while (value.length() < 3+2) value = " "+value; 295 return value; 296 } 297 298 protected double totalWorkEstimate = 0.0; 299 protected double percentComplete = 0.0; 300 public double getPercentComplete() { 301 return percentComplete; 302 } 303 304 protected void updateCompileState(String section, String subSection, double pct) { 305 } 307 308 309 public void completedFile(CompilerPass pass, CompilationUnit cu) { 310 exitIfRequested(); 311 312 double pct = (pass.getWorkEstimate()/totalWorkEstimate)* 313 (1.0/getWorld().getCompilationUnits().size()); 314 percentComplete += pct; 315 updateCompileState(pass.getDisplayName(), cu.getSourceCanonicalPath(), 316 percentComplete); 317 } 318 319 protected void initializeWorld(List filenames) { 320 createWorld(filenames); 322 errorHandler.exitOnErrors(); 323 324 Set doneFiles = new HashSet(); 325 for(Iterator i = world.getFiles().iterator(); i.hasNext(); ) { 326 File file = new File((String )i.next()); 327 try { 328 if (doneFiles.contains(file.getCanonicalPath())) { 329 showMessage(this, "ignoring duplicate file: "+file.getPath()); 330 continue; 331 } else { 332 doneFiles.add(file.getCanonicalPath()); 333 } 334 } catch (IOException e) { 335 this.showError(null,e.toString()); 336 continue; 337 } 338 world.addCompilationUnit(newCompilationUnit(file)); 339 } 340 } 341 342 343 private volatile boolean exitRequested = false; 344 private void exitIfRequested() { 345 if (exitRequested) { 346 throw new ExitRequestException(0); 349 } 350 } 351 352 357 public void requestCompileExit() { 358 exitRequested = true; 359 } 360 361 362 protected void internalCompile(List filenames) { 363 exitRequested = false; 364 initializeWorld(filenames); 365 366 for (Iterator i = passes.iterator(); i.hasNext(); ) { 367 CompilerPass pass = (CompilerPass)i.next(); 368 pass.transformWorld(); 369 exitIfRequested(); 370 } 371 errorHandler.exitOnErrors(); 372 finish(); 373 } 374 375 376 public void beginSection(String label) { 377 beginSection(label, true); 378 } 379 380 public void beginSection(String label, boolean show) { 381 if (!getNodes().empty()) { 382 } 384 385 if (show) showMessage(label); 386 if (options.timings && options.threads == 0) { 387 long thisTime = System.currentTimeMillis(); 388 if (sectionLabel.get() != null) { 389 Long t = (Long )timingInformation.get(sectionLabel.get()); 390 if (t == null) { 391 t = new Long (thisTime-startTime); 392 } else { 393 t = new Long (t.longValue()+(thisTime-startTime)); 394 } 395 timingInformation.put(sectionLabel.get(),t); 396 } 397 startTime = thisTime; 398 } 399 setCurrentSection(label); 400 } 401 402 public void finish() { 403 beginSection("compilation complete"); 404 if (options.timings && options.threads == 0) { 405 errorHandler.showMessage("Timing information:"); 406 Map.Entry[] a = (Map.Entry[]) 407 timingInformation.entrySet().toArray(new Map.Entry[0]); 408 Arrays.sort(a, new Comparator() { 409 public int compare(Object x, Object y) { 410 return 411 ((Long ) ((Map.Entry) x).getValue()) 412 .compareTo(((Map.Entry) y).getValue()); 413 } 414 }); 415 long totalTime = 0; 416 for (int i = 0, len = a.length; i < len; i++) { 417 Map.Entry n = a[i]; 418 String sectionLabel = (String )n.getKey(); 419 Long tm = (Long )n.getValue(); 420 long thisTime = tm.longValue(); 421 String msg = " "+formatTime(thisTime)+" seconds in "+sectionLabel; 422 totalTime += thisTime; 423 errorHandler.showMessage(msg); 424 } 425 errorHandler.showMessage("---------------------------------------------"); 426 String msg = " "+formatTime(totalTime)+" total seconds"; 427 errorHandler.showMessage(msg); 428 } 429 } 430 431 public void enterNode(ASTObject where) { 432 getNodes().push(where); 433 } 434 435 public void exitNode(ASTObject where) { 436 if (getNodes().pop() != where) { 437 } 439 } 440 441 public ASTObject getCurrentNode() { 442 return getNodes().empty() ? null : (ASTObject)getNodes().peek(); 443 } 444 445 446 447 public void internalError(Throwable uncaughtException, ASTObject where) { 448 if (!errorHandler.willExitWithErrors()) { 449 errorHandler.internalError(uncaughtException, where); 450 } 451 } 452 453 public void internalError(String message) { 454 internalError(null, message); 455 } 456 457 public void internalError(ASTObject where, String message) { 458 if (!errorHandler.willExitWithErrors()) { 459 errorHandler.showError(where, "INTERNAL: " + message); 460 } 461 } 462 463 public void showError(String message) { 464 this.showError(null, message); 465 } 466 467 public void showError(ASTObject where, String message) { 468 errorHandler.showError(where, message); 469 } 470 471 public void showError(File source, int line, int column, String message) { 472 errorHandler.showError(source, line, column, message); 473 } 474 475 public void showWarning(ASTObject where, String message) { 476 errorHandler.showWarning(where, message); 477 } 478 479 public void showWarning(ASTObject where, ErrorHandler.Message message) { 480 errorHandler.showWarning(where, message); 481 } 482 483 public void showMessage(Object where, String message) { 484 if (where != null && where instanceof ASTObject) { 485 errorHandler.showMessage((ASTObject)where, message); 486 return; 487 } 488 489 if (options.verbose) { 490 errorHandler.showMessage(" "+message); 491 } 492 } 493 494 public void showMessage(String message) { 495 if (options.verbose) { 496 errorHandler.showMessage(message); 497 } 498 } 499 500 public void warnVersion(String oldVersion, ASTObject object, String message) { 501 if (options.porting) { 502 showWarning(object, "Deprecated since "+oldVersion+": "+message); 503 } else { 504 errorVersion(oldVersion, object, message); 505 } 506 } 507 508 public void errorVersion(String oldVersion, ASTObject object, String message) { 509 showError(object, "Removed in "+oldVersion+": "+message); 510 } 511 } 512 | Popular Tags |