1 11 package org.eclipse.jdt.internal.compiler; 12 13 import org.eclipse.jdt.core.compiler.*; 14 import org.eclipse.jdt.internal.compiler.env.*; 15 import org.eclipse.jdt.internal.compiler.impl.*; 16 import org.eclipse.jdt.internal.compiler.ast.*; 17 import org.eclipse.jdt.internal.compiler.lookup.*; 18 import org.eclipse.jdt.internal.compiler.parser.*; 19 import org.eclipse.jdt.internal.compiler.problem.*; 20 import org.eclipse.jdt.internal.compiler.util.*; 21 22 import java.io.*; 23 import java.util.*; 24 25 public class Compiler implements ITypeRequestor, ProblemSeverities { 26 public Parser parser; 27 public ICompilerRequestor requestor; 28 public CompilerOptions options; 29 public ProblemReporter problemReporter; 30 protected PrintWriter out; 32 public CompilationUnitDeclaration[] unitsToProcess; 35 public int totalUnits; 37 public LookupEnvironment lookupEnvironment; 39 40 public static boolean DEBUG = false; 42 public int parseThreshold = -1; 43 44 public AbstractAnnotationProcessorManager annotationProcessorManager; 45 public ReferenceBinding[] referenceBindings; 46 47 49 55 public static IDebugRequestor DebugRequestor = null; 56 57 95 public Compiler( 96 INameEnvironment environment, 97 IErrorHandlingPolicy policy, 98 Map settings, 99 final ICompilerRequestor requestor, 100 IProblemFactory problemFactory) { 101 this(environment, policy, new CompilerOptions(settings), requestor, problemFactory, null); 102 } 103 104 146 public Compiler( 147 INameEnvironment environment, 148 IErrorHandlingPolicy policy, 149 Map settings, 150 final ICompilerRequestor requestor, 151 IProblemFactory problemFactory, 152 boolean parseLiteralExpressionsAsConstants) { 153 this(environment, policy, new CompilerOptions(settings, parseLiteralExpressionsAsConstants), requestor, problemFactory, null); 154 } 155 156 192 public Compiler( 193 INameEnvironment environment, 194 IErrorHandlingPolicy policy, 195 CompilerOptions options, 196 final ICompilerRequestor requestor, 197 IProblemFactory problemFactory) { 198 this(environment, policy, options, requestor, problemFactory, null); 199 } 200 201 237 public Compiler( 238 INameEnvironment environment, 239 IErrorHandlingPolicy policy, 240 CompilerOptions options, 241 final ICompilerRequestor requestor, 242 IProblemFactory problemFactory, 243 PrintWriter out) { 244 245 this.options = options; 246 247 if(DebugRequestor == null) { 249 this.requestor = requestor; 250 } else { 251 this.requestor = new ICompilerRequestor(){ 252 public void acceptResult(CompilationResult result){ 253 if (DebugRequestor.isActive()){ 254 DebugRequestor.acceptDebugResult(result); 255 } 256 requestor.acceptResult(result); 257 } 258 }; 259 } 260 this.problemReporter = new ProblemReporter(policy, this.options, problemFactory); 261 this.lookupEnvironment = new LookupEnvironment(this, this.options, problemReporter, environment); 262 this.out = out == null ? new PrintWriter(System.out, true) : out; 263 initializeParser(); 264 } 265 266 269 public void accept(IBinaryType binaryType, PackageBinding packageBinding, AccessRestriction accessRestriction) { 270 if (this.options.verbose) { 271 this.out.println( 272 Messages.bind(Messages.compilation_loadBinary, new String (binaryType.getName()))); 273 } 276 lookupEnvironment.createBinaryTypeFrom(binaryType, packageBinding, accessRestriction); 277 } 278 279 283 public void accept(ICompilationUnit sourceUnit, AccessRestriction accessRestriction) { 284 CompilationResult unitResult = 286 new CompilationResult(sourceUnit, totalUnits, totalUnits, this.options.maxProblemsPerUnit); 287 try { 288 if (options.verbose) { 289 String count = String.valueOf(totalUnits + 1); 290 this.out.println( 291 Messages.bind(Messages.compilation_request, 292 new String [] { 293 count, 294 count, 295 new String (sourceUnit.getFileName()) 296 })); 297 } 298 CompilationUnitDeclaration parsedUnit; 300 if (totalUnits < parseThreshold) { 301 parsedUnit = parser.parse(sourceUnit, unitResult); 302 } else { 303 parsedUnit = parser.dietParse(sourceUnit, unitResult); 304 } 305 parsedUnit.bits |= ASTNode.IsImplicitUnit; 306 lookupEnvironment.buildTypeBindings(parsedUnit, accessRestriction); 308 this.addCompilationUnit(sourceUnit, parsedUnit); 309 310 lookupEnvironment.completeTypeBindings(parsedUnit); 312 } catch (AbortCompilationUnit e) { 313 if (unitResult.compilationUnit == sourceUnit) { requestor.acceptResult(unitResult.tagAsAccepted()); 317 } else { 318 throw e; } 320 } 321 } 322 323 326 public void accept(ISourceType[] sourceTypes, PackageBinding packageBinding, AccessRestriction accessRestriction) { 327 problemReporter.abortDueToInternalError( 328 Messages.bind(Messages.abort_againstSourceModel, new String [] { String.valueOf(sourceTypes[0].getName()), String.valueOf(sourceTypes[0].getFileName()) })); 329 } 330 331 protected void addCompilationUnit( 332 ICompilationUnit sourceUnit, 333 CompilationUnitDeclaration parsedUnit) { 334 335 int size = unitsToProcess.length; 337 if (totalUnits == size) 338 System.arraycopy( 340 unitsToProcess, 341 0, 342 (unitsToProcess = new CompilationUnitDeclaration[size * 2]), 343 0, 344 totalUnits); 345 unitsToProcess[totalUnits++] = parsedUnit; 346 } 347 348 352 protected void beginToCompile(ICompilationUnit[] sourceUnits) { 353 int maxUnits = sourceUnits.length; 354 this.totalUnits = 0; 355 this.unitsToProcess = new CompilationUnitDeclaration[maxUnits]; 356 357 internalBeginToCompile(sourceUnits, maxUnits); 358 } 359 360 365 public void compile(ICompilationUnit[] sourceUnits) { 366 CompilationUnitDeclaration unit = null; 367 int i = 0; 368 try { 369 371 beginToCompile(sourceUnits); 372 373 if (this.annotationProcessorManager != null) { 374 processAnnotations(); 375 if (!options.generateClassFiles) { 376 return; 378 } 379 } 380 for (; i < this.totalUnits; i++) { 382 unit = unitsToProcess[i]; 383 try { 384 if (options.verbose) 385 this.out.println( 386 Messages.bind(Messages.compilation_process, 387 new String [] { 388 String.valueOf(i + 1), 389 String.valueOf(this.totalUnits), 390 new String (unitsToProcess[i].getFileName()) 391 })); 392 process(unit, i); 393 } finally { 394 unit.cleanUp(); 396 } 397 unitsToProcess[i] = null; requestor.acceptResult(unit.compilationResult.tagAsAccepted()); 399 if (options.verbose) 400 this.out.println( 401 Messages.bind(Messages.compilation_done, 402 new String [] { 403 String.valueOf(i + 1), 404 String.valueOf(this.totalUnits), 405 new String (unit.getFileName()) 406 })); 407 } 408 } catch (AbortCompilation e) { 409 this.handleInternalException(e, unit); 410 } catch (Error e) { 411 this.handleInternalException(e, unit, null); 412 throw e; } catch (RuntimeException e) { 414 this.handleInternalException(e, unit, null); 415 throw e; } finally { 417 this.reset(); 418 } 419 if (options.verbose) { 420 if (this.totalUnits > 1) { 421 this.out.println( 422 Messages.bind(Messages.compilation_units, String.valueOf(this.totalUnits))); 423 } else { 424 this.out.println( 425 Messages.bind(Messages.compilation_unit, String.valueOf(this.totalUnits))); 426 } 427 } 428 } 429 430 public void setBinaryTypes(ReferenceBinding[] binaryTypes) { 431 this.referenceBindings = binaryTypes; 432 } 433 436 protected void handleInternalException( 437 Throwable internalException, 438 CompilationUnitDeclaration unit, 439 CompilationResult result) { 440 441 if ((result == null) && (unit != null)) { 442 result = unit.compilationResult; } 444 if ((result == null) && lookupEnvironment.unitBeingCompleted != null) { 446 result = lookupEnvironment.unitBeingCompleted.compilationResult; 447 } 448 if ((result == null) && lookupEnvironment.unitBeingCompleted != null) { 450 result = lookupEnvironment.unitBeingCompleted.compilationResult; 451 } 452 if ((result == null) && (unitsToProcess != null) && (totalUnits > 0)) 453 result = unitsToProcess[totalUnits - 1].compilationResult; 454 456 boolean needToPrint = true; 457 if (result != null) { 458 459 StringWriter stringWriter = new StringWriter(); 460 PrintWriter writer = new PrintWriter(stringWriter); 461 internalException.printStackTrace(writer); 462 StringBuffer buffer = stringWriter.getBuffer(); 463 464 String [] pbArguments = new String [] { 465 Messages.compilation_internalError 466 + "\n" + buffer.toString()}; 468 469 result 470 .record( 471 problemReporter 472 .createProblem( 473 result.getFileName(), 474 IProblem.Unclassified, 475 pbArguments, 476 pbArguments, 477 Error, 0, 0, 0, 0), unit); 483 484 485 if (!result.hasBeenAccepted) { 486 requestor.acceptResult(result.tagAsAccepted()); 487 needToPrint = false; 488 } 489 } 490 if (needToPrint) { 491 492 internalException.printStackTrace(); 493 } 494 } 495 496 499 protected void handleInternalException( 500 AbortCompilation abortException, 501 CompilationUnitDeclaration unit) { 502 503 504 if (abortException.isSilent) { 505 if (abortException.silentException == null) { 506 return; 507 } 508 throw abortException.silentException; 509 } 510 511 512 514 CompilationResult result = abortException.compilationResult; 516 if ((result == null) && (unit != null)) { 517 result = unit.compilationResult; } 519 if ((result == null) && lookupEnvironment.unitBeingCompleted != null) { 521 result = lookupEnvironment.unitBeingCompleted.compilationResult; 522 } 523 if ((result == null) && (unitsToProcess != null) && (totalUnits > 0)) 524 result = unitsToProcess[totalUnits - 1].compilationResult; 525 if (result != null && !result.hasBeenAccepted) { 527 528 if (abortException.problem != null) { 529 recordDistantProblem: { 530 CategorizedProblem distantProblem = abortException.problem; 531 CategorizedProblem[] knownProblems = result.problems; 532 for (int i = 0; i < result.problemCount; i++) { 533 if (knownProblems[i] == distantProblem) { break recordDistantProblem; 535 } 536 } 537 if (distantProblem instanceof DefaultProblem) { ((DefaultProblem) distantProblem).setOriginatingFileName(result.getFileName()); 539 } 540 result.record(distantProblem, unit); 541 } 542 } else { 543 544 if (abortException.exception != null) { 545 this.handleInternalException(abortException.exception, null, result); 546 return; 547 } 548 } 549 550 if (!result.hasBeenAccepted) { 551 requestor.acceptResult(result.tagAsAccepted()); 552 } 553 } else { 554 abortException.printStackTrace(); 555 } 556 } 557 558 public void initializeParser() { 559 560 this.parser = new Parser(this.problemReporter, this.options.parseLiteralExpressionsAsConstants); 561 } 562 563 567 protected void internalBeginToCompile(ICompilationUnit[] sourceUnits, int maxUnits) { 568 for (int i = 0; i < maxUnits; i++) { 570 CompilationUnitDeclaration parsedUnit; 571 CompilationResult unitResult = 572 new CompilationResult(sourceUnits[i], i, maxUnits, this.options.maxProblemsPerUnit); 573 try { 574 if (options.verbose) { 575 this.out.println( 576 Messages.bind(Messages.compilation_request, 577 new String [] { 578 String.valueOf(i + 1), 579 String.valueOf(maxUnits), 580 new String (sourceUnits[i].getFileName()) 581 })); 582 } 583 if (totalUnits < parseThreshold) { 585 parsedUnit = parser.parse(sourceUnits[i], unitResult); 586 } else { 587 parsedUnit = parser.dietParse(sourceUnits[i], unitResult); 588 } 589 lookupEnvironment.buildTypeBindings(parsedUnit, null ); 591 this.addCompilationUnit(sourceUnits[i], parsedUnit); 592 ImportReference currentPackage = parsedUnit.currentPackage; 593 if (currentPackage != null) { 594 unitResult.recordPackageName(currentPackage.tokens); 595 } 596 } finally { 599 sourceUnits[i] = null; } 601 } 602 lookupEnvironment.completeTypeBindings(); 604 } 605 606 609 public void process(CompilationUnitDeclaration unit, int i) { 610 this.lookupEnvironment.unitBeingCompleted = unit; 611 612 this.parser.getMethodBodies(unit); 613 614 if (unit.scope != null) 616 unit.scope.faultInTypes(); 617 618 if (unit.scope != null) 620 unit.scope.verifyMethods(lookupEnvironment.methodVerifier()); 621 622 unit.resolve(); 624 625 unit.analyseCode(); 627 628 unit.generateCode(); 630 631 if (options.produceReferenceInfo && unit.scope != null) 633 unit.scope.storeDependencyInfo(); 634 635 unit.compilationResult.totalUnitsKnown = totalUnits; 637 638 this.lookupEnvironment.unitBeingCompleted = null; 639 } 640 641 protected void processAnnotations() { 642 int newUnitSize = 0; 643 int newClassFilesSize = 0; 644 int bottom = 0; 645 int top = this.unitsToProcess.length; 646 ReferenceBinding[] binaryTypeBindingsTemp = this.referenceBindings; 647 if (top == 0 && binaryTypeBindingsTemp == null) return; 648 this.referenceBindings = null; 649 do { 650 int length = top - bottom; 652 CompilationUnitDeclaration[] currentUnits = new CompilationUnitDeclaration[length]; 653 int index = 0; 654 for (int i = bottom; i < top; i++) { 655 CompilationUnitDeclaration currentUnit = this.unitsToProcess[i]; 656 if ((currentUnit.bits & ASTNode.IsImplicitUnit) == 0) { 657 currentUnits[index++] = currentUnit; 658 } 659 } 660 if (index != length) { 661 System.arraycopy(currentUnits, 0, (currentUnits = new CompilationUnitDeclaration[index]), 0, index); 662 } 663 this.annotationProcessorManager.processAnnotations(currentUnits, binaryTypeBindingsTemp, false); 664 ICompilationUnit[] newUnits = this.annotationProcessorManager.getNewUnits(); 665 newUnitSize = newUnits.length; 666 ReferenceBinding[] newClassFiles = this.annotationProcessorManager.getNewClassFiles(); 667 binaryTypeBindingsTemp = newClassFiles; 668 newClassFilesSize = newClassFiles.length; 669 if (newUnitSize != 0) { 670 internalBeginToCompile(newUnits, newUnitSize); 672 bottom = top; 673 top = this.totalUnits; } else { 675 bottom = top; 676 } 677 this.annotationProcessorManager.reset(); 678 } while (newUnitSize != 0 || newClassFilesSize != 0); 679 this.annotationProcessorManager.processAnnotations(null, null, true); 683 } 685 686 public void reset() { 687 lookupEnvironment.reset(); 688 parser.scanner.source = null; 689 unitsToProcess = null; 690 if (DebugRequestor != null) DebugRequestor.reset(); 691 this.problemReporter.reset(); 692 } 693 694 697 public CompilationUnitDeclaration resolve( 698 CompilationUnitDeclaration unit, 699 ICompilationUnit sourceUnit, 700 boolean verifyMethods, 701 boolean analyzeCode, 702 boolean generateCode) { 703 704 try { 705 if (unit == null) { 706 parseThreshold = 0; beginToCompile(new ICompilationUnit[] { sourceUnit }); 709 unit = unitsToProcess[0]; 711 } else { 712 lookupEnvironment.buildTypeBindings(unit, null ); 714 715 lookupEnvironment.completeTypeBindings(); 717 } 718 this.lookupEnvironment.unitBeingCompleted = unit; 719 this.parser.getMethodBodies(unit); 720 if (unit.scope != null) { 721 unit.scope.faultInTypes(); 723 if (unit.scope != null && verifyMethods) { 724 unit.scope.verifyMethods(lookupEnvironment.methodVerifier()); 727 } 728 unit.resolve(); 730 731 if (analyzeCode) unit.analyseCode(); 733 734 if (generateCode) unit.generateCode(); 736 } 737 if (unitsToProcess != null) unitsToProcess[0] = null; requestor.acceptResult(unit.compilationResult.tagAsAccepted()); 739 return unit; 740 } catch (AbortCompilation e) { 741 this.handleInternalException(e, unit); 742 return unit == null ? unitsToProcess[0] : unit; 743 } catch (Error e) { 744 this.handleInternalException(e, unit, null); 745 throw e; } catch (RuntimeException e) { 747 this.handleInternalException(e, unit, null); 748 throw e; } finally { 750 753 } 761 } 762 765 public CompilationUnitDeclaration resolve( 766 ICompilationUnit sourceUnit, 767 boolean verifyMethods, 768 boolean analyzeCode, 769 boolean generateCode) { 770 771 return resolve( 772 null, 773 sourceUnit, 774 verifyMethods, 775 analyzeCode, 776 generateCode); 777 } 778 } 779 | Popular Tags |