1 /*******************************************************************************
 
   2  * Copyright (c) 2000, 2003 IBM Corporation and others.
 
   3  * All rights reserved. This program and the accompanying materials 
 
   4  * are made available under the terms of the Common Public License v1.0
 
   5  * which accompanies this distribution, and is available at
 
   6  * http://www.eclipse.org/legal/cpl-v10.html
 
   9  *     IBM Corporation - initial API and implementation
 
  10  *******************************************************************************/
 
  11 package net.sourceforge.phpdt.internal.compiler;
 
  13 import java.io.PrintWriter;
 
  14 import java.io.StringWriter;
 
  17 import net.sourceforge.phpdt.core.compiler.IProblem;
 
  18 import net.sourceforge.phpdt.internal.compiler.ast.CompilationUnitDeclaration;
 
  19 import net.sourceforge.phpdt.internal.compiler.ast.TypeDeclaration;
 
  20 import net.sourceforge.phpdt.internal.compiler.env.IBinaryType;
 
  21 import net.sourceforge.phpdt.internal.compiler.env.ICompilationUnit;
 
  22 import net.sourceforge.phpdt.internal.compiler.env.INameEnvironment;
 
  23 import net.sourceforge.phpdt.internal.compiler.env.ISourceType;
 
  24 import net.sourceforge.phpdt.internal.compiler.impl.CompilerOptions;
 
  25 import net.sourceforge.phpdt.internal.compiler.impl.ITypeRequestor;
 
  26 import net.sourceforge.phpdt.internal.compiler.lookup.LookupEnvironment;
 
  27 import net.sourceforge.phpdt.internal.compiler.lookup.PackageBinding;
 
  28 import net.sourceforge.phpdt.internal.compiler.parser.UnitParser;
 
  29 import net.sourceforge.phpdt.internal.compiler.problem.AbortCompilation;
 
  30 import net.sourceforge.phpdt.internal.compiler.problem.AbortCompilationUnit;
 
  31 import net.sourceforge.phpdt.internal.compiler.problem.ProblemReporter;
 
  32 import net.sourceforge.phpdt.internal.compiler.problem.ProblemSeverities;
 
  33 import net.sourceforge.phpdt.internal.compiler.util.Util;
 
  35 public class Compiler implements ITypeRequestor, ProblemSeverities {
 
  36         public UnitParser parser;
 
  38         public ICompilerRequestor requestor;
 
  40         public CompilerOptions options;
 
  42         public ProblemReporter problemReporter;
 
  44         // management of unit to be processed
 
  45         // public CompilationUnitResult currentCompilationUnitResult;
 
  46         public CompilationUnitDeclaration[] unitsToProcess;
 
  48         public int totalUnits; // (totalUnits-1) gives the last unit in
 
  52         public LookupEnvironment lookupEnvironment;
 
  54         // ONCE STABILIZED, THESE SHOULD RETURN TO A FINAL FIELD
 
  55         public static boolean DEBUG = false;
 
  57         public int parseThreshold = -1;
 
  59         // number of initial units parsed at once (-1: none)
 
  61          * Static requestor reserved to listening compilation results in debug mode,
 
  62          * so as for example to monitor compiler activity independantly from a
 
  63          * particular builder implementation. It is reset at the end of compilation,
 
  64          * and should not persist any information after having been reset.
 
  66         // public static IDebugRequestor DebugRequestor = null;
 
  68          * Answer a new compiler using the given name environment and compiler
 
  69          * options. The environment and options will be in effect for the lifetime
 
  70          * of the compiler. When the compiler is run, compilation results are sent
 
  71          * to the given requestor.
 
  74          *            org.eclipse.jdt.internal.compiler.api.env.INameEnvironment
 
  75          *            Environment used by the compiler in order to resolve type and
 
  76          *            package names. The name environment implements the actual
 
  77          *            connection of the compiler to the outside world (e.g. in batch
 
  78          *            mode the name environment is performing pure file accesses,
 
  79          *            reuse previous build state or connection to repositories).
 
  80          *            Note: the name environment is responsible for implementing the
 
  81          *            actual classpath rules.
 
  84          *            org.eclipse.jdt.internal.compiler.api.problem.IErrorHandlingPolicy
 
  85          *            Configurable part for problem handling, allowing the compiler
 
  86          *            client to specify the rules for handling problems (stop on
 
  87          *            first error or accumulate them all) and at the same time
 
  88          *            perform some actions such as opening a dialog in UI when
 
  89          *            compiling interactively.
 
  90          * @see org.eclipse.jdt.internal.compiler.DefaultErrorHandlingPolicies
 
  93          *            org.eclipse.jdt.internal.compiler.api.ICompilerRequestor
 
  94          *            Component which will receive and persist all compilation
 
  95          *            results and is intended to consume them as they are produced.
 
  96          *            Typically, in a batch compiler, it is responsible for writing
 
  97          *            out the actual .class files to the file system.
 
  98          * @see org.eclipse.jdt.internal.compiler.CompilationResult
 
 100          * @param problemFactory
 
 101          *            org.eclipse.jdt.internal.compiler.api.problem.IProblemFactory
 
 102          *            Factory used inside the compiler to create problem
 
 103          *            descriptors. It allows the compiler client to supply its own
 
 104          *            representation of compilation problems in order to avoid
 
 105          *            object conversions. Note that the factory is not supposed to
 
 106          *            accumulate the created problems, the compiler will gather them
 
 107          *            all and hand them back as part of the compilation unit result.
 
 109         public Compiler(INameEnvironment environment, IErrorHandlingPolicy policy,
 
 110                         Map settings, final ICompilerRequestor requestor,
 
 111                         IProblemFactory problemFactory) {
 
 112                 // create a problem handler given a handling policy
 
 113                 this.options = new CompilerOptions(settings);
 
 114                 // wrap requestor in DebugRequestor if one is specified
 
 115                 // if(DebugRequestor == null) {
 
 116                 this.requestor = requestor;
 
 118                 // this.requestor = new ICompilerRequestor(){
 
 119                 // public void acceptResult(CompilationResult result){
 
 120                 // if (DebugRequestor.isActive()){
 
 121                 // DebugRequestor.acceptDebugResult(result);
 
 123                 // requestor.acceptResult(result);
 
 127                 this.problemReporter = new ProblemReporter(policy, this.options,
 
 129                 this.lookupEnvironment = new LookupEnvironment(this, problemReporter,
 
 130                                 environment); // options, problemReporter, environment);
 
 131                 this.parser = new UnitParser(problemReporter);
 
 132                 // this.options.parseLiteralExpressionsAsConstants,
 
 133                 // options.sourceLevel >= CompilerOptions.JDK1_4);
 
 137          * Answer a new compiler using the given name environment and compiler
 
 138          * options. The environment and options will be in effect for the lifetime
 
 139          * of the compiler. When the compiler is run, compilation results are sent
 
 140          * to the given requestor.
 
 143          *            org.eclipse.jdt.internal.compiler.api.env.INameEnvironment
 
 144          *            Environment used by the compiler in order to resolve type and
 
 145          *            package names. The name environment implements the actual
 
 146          *            connection of the compiler to the outside world (e.g. in batch
 
 147          *            mode the name environment is performing pure file accesses,
 
 148          *            reuse previous build state or connection to repositories).
 
 149          *            Note: the name environment is responsible for implementing the
 
 150          *            actual classpath rules.
 
 153          *            org.eclipse.jdt.internal.compiler.api.problem.IErrorHandlingPolicy
 
 154          *            Configurable part for problem handling, allowing the compiler
 
 155          *            client to specify the rules for handling problems (stop on
 
 156          *            first error or accumulate them all) and at the same time
 
 157          *            perform some actions such as opening a dialog in UI when
 
 158          *            compiling interactively.
 
 159          * @see org.eclipse.jdt.internal.compiler.DefaultErrorHandlingPolicies
 
 162          *            org.eclipse.jdt.internal.compiler.api.ICompilerRequestor
 
 163          *            Component which will receive and persist all compilation
 
 164          *            results and is intended to consume them as they are produced.
 
 165          *            Typically, in a batch compiler, it is responsible for writing
 
 166          *            out the actual .class files to the file system.
 
 167          * @see org.eclipse.jdt.internal.compiler.CompilationResult
 
 169          * @param problemFactory
 
 170          *            org.eclipse.jdt.internal.compiler.api.problem.IProblemFactory
 
 171          *            Factory used inside the compiler to create problem
 
 172          *            descriptors. It allows the compiler client to supply its own
 
 173          *            representation of compilation problems in order to avoid
 
 174          *            object conversions. Note that the factory is not supposed to
 
 175          *            accumulate the created problems, the compiler will gather them
 
 176          *            all and hand them back as part of the compilation unit result.
 
 177          * @param parseLiteralExpressionsAsConstants
 
 178          *            <code>boolean</code> This parameter is used to optimize the
 
 179          *            literals or leave them as they are in the source. If you put
 
 180          *            true, "Hello" . " world" will be converted to "Hello world".
 
 182         public Compiler(INameEnvironment environment, IErrorHandlingPolicy policy,
 
 183                         Map settings, final ICompilerRequestor requestor,
 
 184                         IProblemFactory problemFactory,
 
 185                         boolean parseLiteralExpressionsAsConstants) {
 
 186                 // create a problem handler given a handling policy
 
 187                 this.options = new CompilerOptions(settings);
 
 188                 // wrap requestor in DebugRequestor if one is specified
 
 189                 // if(DebugRequestor == null) {
 
 190                 this.requestor = requestor;
 
 192                 // this.requestor = new ICompilerRequestor(){
 
 193                 // public void acceptResult(CompilationResult result){
 
 194                 // if (DebugRequestor.isActive()){
 
 195                 // DebugRequestor.acceptDebugResult(result);
 
 197                 // requestor.acceptResult(result);
 
 201                 this.problemReporter = new ProblemReporter(policy, this.options,
 
 203                 this.lookupEnvironment = new LookupEnvironment(this, problemReporter,
 
 204                                 environment);// options, problemReporter, environment);
 
 205                 this.parser = new UnitParser(problemReporter);
 
 206                 // parseLiteralExpressionsAsConstants,
 
 207                 // this.options.sourceLevel >= CompilerOptions.JDK1_4);
 
 211          * Add an additional binary type
 
 213         public void accept(IBinaryType binaryType, PackageBinding packageBinding) {
 
 214                 lookupEnvironment.createBinaryTypeFrom(binaryType, packageBinding);
 
 218          * Add an additional compilation unit into the loop -> build compilation
 
 219          * unit declarations, their bindings and record their results.
 
 221         public void accept(ICompilationUnit sourceUnit) {
 
 222                 // Switch the current policy and compilation result for this unit to the
 
 224                 CompilationResult unitResult = new CompilationResult(sourceUnit,
 
 225                                 totalUnits, totalUnits, this.options.maxProblemsPerUnit);
 
 227                         // diet parsing for large collection of unit
 
 228                         CompilationUnitDeclaration parsedUnit;
 
 229                         if (totalUnits < parseThreshold) {
 
 230                                 parsedUnit = parser.parse(sourceUnit, unitResult, false);
 
 232                                 parsedUnit = parser.dietParse(sourceUnit, unitResult);
 
 234                         if (options.verbose) {
 
 235                                 String count = String.valueOf(totalUnits + 1);
 
 236                                 System.out.println(Util.bind("compilation.request", //$NON-NLS-1$
 
 237                                                 new String[] { count, count,
 
 238                                                                 new String(sourceUnit.getFileName()) }));
 
 240                         // initial type binding creation
 
 241                         lookupEnvironment.buildTypeBindings(parsedUnit);
 
 242                         this.addCompilationUnit(sourceUnit, parsedUnit);
 
 243                         // binding resolution
 
 244                         lookupEnvironment.completeTypeBindings(parsedUnit);
 
 245                 } catch (AbortCompilationUnit e) {
 
 246                         // at this point, currentCompilationUnitResult may not be
 
 249                         // one requested further along to resolve sourceUnit.
 
 250                         if (unitResult.compilationUnit == sourceUnit) { // only report once
 
 251                                 requestor.acceptResult(unitResult.tagAsAccepted());
 
 253                                 throw e; // want to abort enclosing request to compile
 
 259          * Add additional source types
 
 261         public void accept(ISourceType[] sourceTypes, PackageBinding packageBinding) {
 
 262                 problemReporter.abortDueToInternalError(Util.bind(
 
 263                                 "abort.againstSourceModel ", //$NON-NLS-1$
 
 264                                 String.valueOf(sourceTypes[0].getName()), String
 
 265                                                 .valueOf(sourceTypes[0].getFileName())));
 
 268         protected void addCompilationUnit(ICompilationUnit sourceUnit,
 
 269                         CompilationUnitDeclaration parsedUnit) {
 
 270                 // append the unit to the list of ones to process later on
 
 271                 int size = unitsToProcess.length;
 
 272                 if (totalUnits == size)
 
 273                         // when growing reposition units starting at position 0
 
 278                                                         (unitsToProcess = new CompilationUnitDeclaration[size * 2]),
 
 280                 unitsToProcess[totalUnits++] = parsedUnit;
 
 284          * Add the initial set of compilation units into the loop -> build
 
 285          * compilation unit declarations, their bindings and record their results.
 
 287         protected void beginToCompile(ICompilationUnit[] sourceUnits) {
 
 288                 int maxUnits = sourceUnits.length;
 
 290                 unitsToProcess = new CompilationUnitDeclaration[maxUnits];
 
 291                 // Switch the current policy and compilation result for this unit to the
 
 293                 for (int i = 0; i < maxUnits; i++) {
 
 294                         CompilationUnitDeclaration parsedUnit;
 
 295                         CompilationResult unitResult = new CompilationResult(
 
 296                                         sourceUnits[i], i, maxUnits,
 
 297                                         this.options.maxProblemsPerUnit);
 
 299                                 // diet parsing for large collection of units
 
 300                                 if (totalUnits < parseThreshold) {
 
 302                                                         .parse(sourceUnits[i], unitResult, false);
 
 304                                         parsedUnit = parser.dietParse(sourceUnits[i], unitResult);
 
 306                                 if (options.verbose) {
 
 308                                                         .println(Util.bind("compilation.request", //$NON-NLS-1$
 
 310                                                                                         String.valueOf(i + 1),
 
 311                                                                                         String.valueOf(maxUnits),
 
 312                                                                                         new String(sourceUnits[i]
 
 315                                 // initial type binding creation
 
 316                                 // lookupEnvironment.buildTypeBindings(parsedUnit);
 
 317                                 this.addCompilationUnit(sourceUnits[i], parsedUnit);
 
 318                                 // } catch (AbortCompilationUnit e) {
 
 319                                 // requestor.acceptResult(unitResult.tagAsAccepted());
 
 321                                 sourceUnits[i] = null; // no longer hold onto the unit
 
 324                 // binding resolution
 
 325                 lookupEnvironment.completeTypeBindings();
 
 329          * General API -> compile each of supplied files -> recompile any required
 
 330          * types for which we have an incomplete principle structure
 
 332         public void compile(ICompilationUnit[] sourceUnits) {
 
 333                 CompilationUnitDeclaration unit = null;
 
 336                         // build and record parsed units
 
 337                         beginToCompile(sourceUnits);
 
 338                         // process all units (some more could be injected in the loop by the
 
 339                         // lookup environment)
 
 340                         for (; i < totalUnits; i++) {
 
 341                                 unit = unitsToProcess[i];
 
 344                                                 System.out.println(Util.bind("compilation.process", //$NON-NLS-1$
 
 346                                                                                 String.valueOf(i + 1),
 
 347                                                                                 String.valueOf(totalUnits),
 
 348                                                                                 new String(unitsToProcess[i]
 
 352                                         // cleanup compilation unit result
 
 355                                                 System.out.println(Util.bind("compilation.done", //$NON-NLS-1$
 
 357                                                                                 String.valueOf(i + 1),
 
 358                                                                                 String.valueOf(totalUnits),
 
 359                                                                                 new String(unitsToProcess[i]
 
 362                                 unitsToProcess[i] = null; // release reference to processed
 
 365                                 requestor.acceptResult(unit.compilationResult.tagAsAccepted());
 
 367                 } catch (AbortCompilation e) {
 
 368                         this.handleInternalException(e, unit);
 
 370                         this.handleInternalException(e, unit, null);
 
 372                 } catch (RuntimeException e) {
 
 373                         this.handleInternalException(e, unit, null);
 
 378                 // if (options.verbose) {
 
 379                 // if (totalUnits > 1) {
 
 380                 // System.out.println(
 
 381                 // ProjectPrefUtil.bind("compilation.units" ,
 
 382                 // String.valueOf(totalUnits)));
 
 385                 // System.out.println(
 
 386                 // ProjectPrefUtil.bind("compilation.unit" ,
 
 387                 // String.valueOf(totalUnits)));
 
 393         protected void getMethodBodies(CompilationUnitDeclaration unit, int place) {
 
 394                 // fill the methods bodies in order for the code to be generated
 
 395                 if (unit.ignoreMethodBodies) {
 
 396                         unit.ignoreFurtherInvestigation = true;
 
 398                         // if initial diet parse did not work, no need to dig into method
 
 401                 if (place < parseThreshold)
 
 402                         return; // work already done ...
 
 403                 // real parse of the method....
 
 404                 parser.scanner.setSource(unit.compilationResult.compilationUnit
 
 406                 if (unit.types != null) {
 
 407                         for (int i = unit.types.size(); --i >= 0;)
 
 408                                 if (unit.types.get(i) instanceof TypeDeclaration) {
 
 409                                         ((TypeDeclaration) unit.types.get(i)).parseMethod(parser,
 
 416          * Compiler crash recovery in case of unexpected runtime exceptions
 
 418         protected void handleInternalException(Throwable internalException,
 
 419                         CompilationUnitDeclaration unit, CompilationResult result) {
 
 420                 /* dump a stack trace to the console */
 
 421                 internalException.printStackTrace();
 
 422                 /* find a compilation result */
 
 423                 if ((unit != null)) // basing result upon the current unit if available
 
 424                         result = unit.compilationResult; // current unit being processed
 
 426                 if ((result == null) && (unitsToProcess != null) && (totalUnits > 0))
 
 427                         result = unitsToProcess[totalUnits - 1].compilationResult;
 
 428                 // last unit in beginToCompile ?
 
 429                 if (result != null) {
 
 430                         /* create and record a compilation problem */
 
 431                         StringWriter stringWriter = new StringWriter();
 
 432                         PrintWriter writer = new PrintWriter(stringWriter);
 
 433                         internalException.printStackTrace(writer);
 
 434                         StringBuffer buffer = stringWriter.getBuffer();
 
 435                         String[] pbArguments = new String[] { Util
 
 436                                         .bind("compilation.internalError")
 
 439                                         + buffer.toString() };
 
 440                         result.record(problemReporter.createProblem(result.getFileName(),
 
 441                                         IProblem.Unclassified, pbArguments, pbArguments, Error, // severity
 
 445                                         unit, result), unit);
 
 446                         /* hand back the compilation result */
 
 447                         if (!result.hasBeenAccepted) {
 
 448                                 requestor.acceptResult(result.tagAsAccepted());
 
 454          * Compiler recovery in case of internal AbortCompilation event
 
 456         protected void handleInternalException(AbortCompilation abortException,
 
 457                         CompilationUnitDeclaration unit) {
 
 459                  * special treatment for SilentAbort: silently cancelling the
 
 460                  * compilation process
 
 462                 if (abortException.isSilent) {
 
 463                         if (abortException.silentException == null) {
 
 466                                 throw abortException.silentException;
 
 469                 /* uncomment following line to see where the abort came from */
 
 470                 // abortException.printStackTrace();
 
 471                 // Exception may tell which compilation result it is related, and which
 
 473                 CompilationResult result = abortException.compilationResult;
 
 474                 if ((result == null) && (unit != null))
 
 475                         result = unit.compilationResult; // current unit being processed
 
 477                 if ((result == null) && (unitsToProcess != null) && (totalUnits > 0))
 
 478                         result = unitsToProcess[totalUnits - 1].compilationResult;
 
 479                 // last unit in beginToCompile ?
 
 480                 if (result != null && !result.hasBeenAccepted) {
 
 481                         /* distant problem which could not be reported back there */
 
 482                         if (abortException.problemId != 0) {
 
 483                                 result.record(problemReporter.createProblem(result
 
 484                                                 .getFileName(), abortException.problemId,
 
 485                                                 abortException.problemArguments,
 
 486                                                 abortException.messageArguments, Error, // severity
 
 490                                                 unit, result), unit);
 
 493                                  * distant internal exception which could not be reported back
 
 496                                 if (abortException.exception != null) {
 
 497                                         this.handleInternalException(abortException.exception,
 
 502                         /* hand back the compilation result */
 
 503                         if (!result.hasBeenAccepted) {
 
 504                                 requestor.acceptResult(result.tagAsAccepted());
 
 508                          * if (abortException.problemId != 0){ IProblem problem =
 
 509                          * problemReporter.createProblem( "???".toCharArray(),
 
 510                          * abortException.problemId, abortException.problemArguments, Error, //
 
 511                          * severity 0, // source start 0, // source end 0); // line number
 
 512                          * System.out.println(problem.getMessage()); }
 
 514                         abortException.printStackTrace();
 
 519          * Process a compilation unit already parsed and build.
 
 521         public void process(CompilationUnitDeclaration unit, int i) {
 
 522                 getMethodBodies(unit, i);
 
 523                 // fault in fields & methods
 
 524                 if (unit.scope != null)
 
 525                         unit.scope.faultInTypes();
 
 526                 // verify inherited methods
 
 527                 // if (unit.scope != null)
 
 528                 // unit.scope.verifyMethods(lookupEnvironment.methodVerifier());
 
 534                 // unit.generateCode();
 
 536                 // if (options.produceReferenceInfo && unit.scope != null)
 
 537                 // unit.scope.storeDependencyInfo();
 
 538                 // refresh the total number of units known at this stage
 
 539                 unit.compilationResult.totalUnitsKnown = totalUnits;
 
 542         public void reset() {
 
 543                 lookupEnvironment.reset();
 
 544                 parser.scanner.source = null;
 
 545                 unitsToProcess = null;
 
 546                 // if (DebugRequestor != null) DebugRequestor.reset();
 
 550          * Internal API used to resolve a given compilation unit. Can run a subset
 
 551          * of the compilation process
 
 553         public CompilationUnitDeclaration resolve(CompilationUnitDeclaration unit,
 
 554                         ICompilationUnit sourceUnit, boolean verifyMethods,
 
 555                         boolean analyzeCode) {
 
 559                                 // build and record parsed units
 
 560                                 parseThreshold = 0; // will request a full parse
 
 561                                 beginToCompile(new ICompilationUnit[] { sourceUnit });
 
 562                                 // process all units (some more could be injected in the loop by
 
 563                                 // the lookup environment)
 
 564                                 unit = unitsToProcess[0];
 
 566                                 // initial type binding creation
 
 567                                 lookupEnvironment.buildTypeBindings(unit);
 
 569                                 // binding resolution
 
 570                                 lookupEnvironment.completeTypeBindings();
 
 572                         // TODO : jsurfer check this
 
 573                         // this.parser.getMethodBodies(unit);
 
 574                         getMethodBodies(unit, 0);
 
 576                         if (unit.scope != null) {
 
 577                                 // fault in fields & methods
 
 578                                 unit.scope.faultInTypes();
 
 579                                 if (unit.scope != null && verifyMethods) {
 
 580                                         // http://dev.eclipse.org/bugs/show_bug.cgi?id=23117
 
 581                                         // verify inherited methods
 
 583                                                         .verifyMethods(lookupEnvironment.methodVerifier());
 
 589                                 // if (analyzeCode) unit.analyseCode();
 
 592                                 // if (generateCode) unit.generateCode();
 
 594                         if (unitsToProcess != null)
 
 595                                 unitsToProcess[0] = null; // release reference to processed
 
 597                         requestor.acceptResult(unit.compilationResult.tagAsAccepted());
 
 599                 } catch (AbortCompilation e) {
 
 600                         this.handleInternalException(e, unit);
 
 601                         return unit == null ? unitsToProcess[0] : unit;
 
 603                         this.handleInternalException(e, unit, null);
 
 605                 } catch (RuntimeException e) {
 
 606                         this.handleInternalException(e, unit, null);
 
 609                         // No reset is performed there anymore since,
 
 610                         // within the CodeAssist (or related tools),
 
 611                         // the compiler may be called *after* a call
 
 612                         // to this resolve(...) method. And such a call
 
 613                         // needs to have a compiler with a non-empty
 
 620          * Internal API used to resolve a given compilation unit. Can run a subset
 
 621          * of the compilation process
 
 623         public CompilationUnitDeclaration resolve(ICompilationUnit sourceUnit,
 
 624                         boolean verifyMethods, boolean analyzeCode) {
 
 625                 // boolean generateCode) {
 
 626                 CompilationUnitDeclaration unit = null;
 
 628                         // build and record parsed units
 
 629                         parseThreshold = 0; // will request a full parse
 
 630                         beginToCompile(new ICompilationUnit[] { sourceUnit });
 
 631                         // process all units (some more could be injected in the loop by the
 
 632                         // lookup environment)
 
 633                         unit = unitsToProcess[0];
 
 634                         getMethodBodies(unit, 0);
 
 635                         if (unit.scope != null) {
 
 636                                 // // fault in fields & methods
 
 637                                 // unit.scope.faultInTypes();
 
 638                                 // if (unit.scope != null && verifyMethods) {
 
 639                                 // // http://dev.eclipse.org/bugs/show_bug.cgi?id=23117
 
 640                                 // // verify inherited methods
 
 641                                 // unit.scope.verifyMethods(lookupEnvironment.methodVerifier());
 
 646                                 // if (analyzeCode) unit.analyseCode();
 
 648                                 // if (generateCode) unit.generateCode();
 
 650                         unitsToProcess[0] = null; // release reference to processed unit
 
 652                         requestor.acceptResult(unit.compilationResult.tagAsAccepted());
 
 654                 } catch (AbortCompilation e) {
 
 655                         this.handleInternalException(e, unit);
 
 656                         return unit == null ? unitsToProcess[0] : unit;
 
 658                         this.handleInternalException(e, unit, null);
 
 660                 } catch (RuntimeException e) {
 
 661                         this.handleInternalException(e, unit, null);
 
 664                         // No reset is performed there anymore since,
 
 665                         // within the CodeAssist (or related tools),
 
 666                         // the compiler may be called *after* a call
 
 667                         // to this resolve(...) method. And such a call
 
 668                         // needs to have a compiler with a non-empty