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;
 
  12 import java.io.PrintWriter;
 
  13 import java.io.StringWriter;
 
  16 import net.sourceforge.phpdt.core.compiler.IProblem;
 
  17 import net.sourceforge.phpdt.internal.compiler.env.IBinaryType;
 
  18 import net.sourceforge.phpdt.internal.compiler.env.ICompilationUnit;
 
  19 import net.sourceforge.phpdt.internal.compiler.env.INameEnvironment;
 
  20 import net.sourceforge.phpdt.internal.compiler.env.ISourceType;
 
  21 import net.sourceforge.phpdt.internal.compiler.impl.CompilerOptions;
 
  22 import net.sourceforge.phpdt.internal.compiler.impl.ITypeRequestor;
 
  23 import net.sourceforge.phpdt.internal.compiler.lookup.LookupEnvironment;
 
  24 import net.sourceforge.phpdt.internal.compiler.lookup.PackageBinding;
 
  25 import net.sourceforge.phpdt.internal.compiler.parser.UnitParser;
 
  26 import net.sourceforge.phpdt.internal.compiler.problem.AbortCompilation;
 
  27 import net.sourceforge.phpdt.internal.compiler.problem.AbortCompilationUnit;
 
  28 import net.sourceforge.phpdt.internal.compiler.problem.ProblemReporter;
 
  29 import net.sourceforge.phpdt.internal.compiler.problem.ProblemSeverities;
 
  30 import net.sourceforge.phpdt.internal.compiler.util.Util;
 
  31 import net.sourceforge.phpeclipse.internal.compiler.ast.CompilationUnitDeclaration;
 
  32 import net.sourceforge.phpeclipse.internal.compiler.ast.TypeDeclaration;
 
  34 public class Compiler implements ITypeRequestor, ProblemSeverities {
 
  35   public UnitParser parser;
 
  36   public ICompilerRequestor requestor;
 
  37   public CompilerOptions options;
 
  38   public ProblemReporter problemReporter;
 
  39   // management of unit to be processed
 
  40   //public CompilationUnitResult currentCompilationUnitResult;
 
  41   public CompilationUnitDeclaration[] unitsToProcess;
 
  42   public int totalUnits; // (totalUnits-1) gives the last unit in unitToProcess
 
  44   public LookupEnvironment lookupEnvironment;
 
  45   // ONCE STABILIZED, THESE SHOULD RETURN TO A FINAL FIELD
 
  46   public static boolean DEBUG = false;
 
  47   public int parseThreshold = -1;
 
  48   // number of initial units parsed at once (-1: none)
 
  50    * Static requestor reserved to listening compilation results in debug mode,
 
  51    * so as for example to monitor compiler activity independantly from a
 
  52    * particular builder implementation. It is reset at the end of compilation,
 
  53    * and should not persist any information after having been reset.
 
  55   //    public static IDebugRequestor DebugRequestor = null;
 
  57    * Answer a new compiler using the given name environment and compiler
 
  58    * options. The environment and options will be in effect for the lifetime of
 
  59    * the compiler. When the compiler is run, compilation results are sent to
 
  60    * the given requestor.
 
  63    *            org.eclipse.jdt.internal.compiler.api.env.INameEnvironment
 
  64    *            Environment used by the compiler in order to resolve type and
 
  65    *            package names. The name environment implements the actual
 
  66    *            connection of the compiler to the outside world (e.g. in batch
 
  67    *            mode the name environment is performing pure file accesses,
 
  68    *            reuse previous build state or connection to repositories).
 
  69    *            Note: the name environment is responsible for implementing the
 
  70    *            actual classpath rules.
 
  73    *            org.eclipse.jdt.internal.compiler.api.problem.IErrorHandlingPolicy
 
  74    *            Configurable part for problem handling, allowing the compiler
 
  75    *            client to specify the rules for handling problems (stop on
 
  76    *            first error or accumulate them all) and at the same time
 
  77    *            perform some actions such as opening a dialog in UI when
 
  78    *            compiling interactively.
 
  79    * @see org.eclipse.jdt.internal.compiler.DefaultErrorHandlingPolicies
 
  82    *            org.eclipse.jdt.internal.compiler.api.ICompilerRequestor
 
  83    *            Component which will receive and persist all compilation
 
  84    *            results and is intended to consume them as they are produced.
 
  85    *            Typically, in a batch compiler, it is responsible for writing
 
  86    *            out the actual .class files to the file system.
 
  87    * @see org.eclipse.jdt.internal.compiler.CompilationResult
 
  89    * @param problemFactory
 
  90    *            org.eclipse.jdt.internal.compiler.api.problem.IProblemFactory
 
  91    *            Factory used inside the compiler to create problem descriptors.
 
  92    *            It allows the compiler client to supply its own representation
 
  93    *            of compilation problems in order to avoid object conversions.
 
  94    *            Note that the factory is not supposed to accumulate the created
 
  95    *            problems, the compiler will gather them all and hand them back
 
  96    *            as part of the compilation unit result.
 
  98   public Compiler(INameEnvironment environment, IErrorHandlingPolicy policy,
 
  99       Map settings, final ICompilerRequestor requestor,
 
 100       IProblemFactory problemFactory) {
 
 101     // create a problem handler given a handling policy
 
 102     this.options = new CompilerOptions(settings);
 
 103     // wrap requestor in DebugRequestor if one is specified
 
 104     //          if(DebugRequestor == null) {
 
 105     this.requestor = requestor;
 
 107     //                  this.requestor = new ICompilerRequestor(){
 
 108     //                          public void acceptResult(CompilationResult result){
 
 109     //                                  if (DebugRequestor.isActive()){
 
 110     //                                          DebugRequestor.acceptDebugResult(result);
 
 112     //                                  requestor.acceptResult(result);
 
 116     this.problemReporter = new ProblemReporter(policy, this.options,
 
 118     this.lookupEnvironment = new LookupEnvironment(this, problemReporter,
 
 119         environment); //options, problemReporter, environment);
 
 120     this.parser = new UnitParser(problemReporter);
 
 121     //                          this.options.parseLiteralExpressionsAsConstants,
 
 122     //                          options.sourceLevel >= CompilerOptions.JDK1_4);
 
 125    * Answer a new compiler using the given name environment and compiler
 
 126    * options. The environment and options will be in effect for the lifetime of
 
 127    * the compiler. When the compiler is run, compilation results are sent to
 
 128    * the given requestor.
 
 131    *            org.eclipse.jdt.internal.compiler.api.env.INameEnvironment
 
 132    *            Environment used by the compiler in order to resolve type and
 
 133    *            package names. The name environment implements the actual
 
 134    *            connection of the compiler to the outside world (e.g. in batch
 
 135    *            mode the name environment is performing pure file accesses,
 
 136    *            reuse previous build state or connection to repositories).
 
 137    *            Note: the name environment is responsible for implementing the
 
 138    *            actual classpath rules.
 
 141    *            org.eclipse.jdt.internal.compiler.api.problem.IErrorHandlingPolicy
 
 142    *            Configurable part for problem handling, allowing the compiler
 
 143    *            client to specify the rules for handling problems (stop on
 
 144    *            first error or accumulate them all) and at the same time
 
 145    *            perform some actions such as opening a dialog in UI when
 
 146    *            compiling interactively.
 
 147    * @see org.eclipse.jdt.internal.compiler.DefaultErrorHandlingPolicies
 
 150    *            org.eclipse.jdt.internal.compiler.api.ICompilerRequestor
 
 151    *            Component which will receive and persist all compilation
 
 152    *            results and is intended to consume them as they are produced.
 
 153    *            Typically, in a batch compiler, it is responsible for writing
 
 154    *            out the actual .class files to the file system.
 
 155    * @see org.eclipse.jdt.internal.compiler.CompilationResult
 
 157    * @param problemFactory
 
 158    *            org.eclipse.jdt.internal.compiler.api.problem.IProblemFactory
 
 159    *            Factory used inside the compiler to create problem descriptors.
 
 160    *            It allows the compiler client to supply its own representation
 
 161    *            of compilation problems in order to avoid object conversions.
 
 162    *            Note that the factory is not supposed to accumulate the created
 
 163    *            problems, the compiler will gather them all and hand them back
 
 164    *            as part of the compilation unit result.
 
 165    * @param parseLiteralExpressionsAsConstants
 
 166    *            <code>boolean</code> This parameter is used to optimize the
 
 167    *            literals or leave them as they are in the source. If you put
 
 168    *            true, "Hello" . " world" will be converted to "Hello world".
 
 170   public Compiler(INameEnvironment environment, IErrorHandlingPolicy policy,
 
 171       Map settings, final ICompilerRequestor requestor,
 
 172       IProblemFactory problemFactory, boolean parseLiteralExpressionsAsConstants) {
 
 173     // create a problem handler given a handling policy
 
 174     this.options = new CompilerOptions(settings);
 
 175     // wrap requestor in DebugRequestor if one is specified
 
 176     //          if(DebugRequestor == null) {
 
 177     this.requestor = requestor;
 
 179     //                  this.requestor = new ICompilerRequestor(){
 
 180     //                          public void acceptResult(CompilationResult result){
 
 181     //                                  if (DebugRequestor.isActive()){
 
 182     //                                          DebugRequestor.acceptDebugResult(result);
 
 184     //                                  requestor.acceptResult(result);
 
 188     this.problemReporter = new ProblemReporter(policy, this.options,
 
 190     this.lookupEnvironment = new LookupEnvironment(this, problemReporter,
 
 191         environment);//options, problemReporter, environment);
 
 192     this.parser = new UnitParser(problemReporter);
 
 193     //                          parseLiteralExpressionsAsConstants,
 
 194     //                          this.options.sourceLevel >= CompilerOptions.JDK1_4);
 
 197    * Add an additional binary type
 
 199   public void accept(IBinaryType binaryType, PackageBinding packageBinding) {
 
 200     lookupEnvironment.createBinaryTypeFrom(binaryType, packageBinding);
 
 203    * Add an additional compilation unit into the loop -> build compilation unit
 
 204    * declarations, their bindings and record their results.
 
 206   public void accept(ICompilationUnit sourceUnit) {
 
 207     // Switch the current policy and compilation result for this unit to the
 
 209     CompilationResult unitResult = new CompilationResult(sourceUnit,
 
 210         totalUnits, totalUnits, this.options.maxProblemsPerUnit);
 
 212       // diet parsing for large collection of unit
 
 213       CompilationUnitDeclaration parsedUnit;
 
 214       if (totalUnits < parseThreshold) {
 
 215         parsedUnit = parser.parse(sourceUnit, unitResult, false);
 
 217         parsedUnit = parser.dietParse(sourceUnit, unitResult);
 
 219       if (options.verbose) {
 
 220         String count = String.valueOf(totalUnits + 1);
 
 221         System.out.println(Util.bind("compilation.request", //$NON-NLS-1$
 
 222             new String[]{count, count, new String(sourceUnit.getFileName())}));
 
 224       // initial type binding creation
 
 225       lookupEnvironment.buildTypeBindings(parsedUnit);
 
 226       this.addCompilationUnit(sourceUnit, parsedUnit);
 
 227       // binding resolution
 
 228       lookupEnvironment.completeTypeBindings(parsedUnit);
 
 229     } catch (AbortCompilationUnit e) {
 
 230       // at this point, currentCompilationUnitResult may not be sourceUnit, but
 
 232       // one requested further along to resolve sourceUnit.
 
 233       if (unitResult.compilationUnit == sourceUnit) { // only report once
 
 234         requestor.acceptResult(unitResult.tagAsAccepted());
 
 236         throw e; // want to abort enclosing request to compile
 
 241    * Add additional source types
 
 243   public void accept(ISourceType[] sourceTypes, PackageBinding packageBinding) {
 
 244     problemReporter.abortDueToInternalError(Util.bind(
 
 245         "abort.againstSourceModel ", //$NON-NLS-1$
 
 246         String.valueOf(sourceTypes[0].getName()), String.valueOf(sourceTypes[0]
 
 249   protected void addCompilationUnit(ICompilationUnit sourceUnit,
 
 250       CompilationUnitDeclaration parsedUnit) {
 
 251     // append the unit to the list of ones to process later on
 
 252     int size = unitsToProcess.length;
 
 253     if (totalUnits == size)
 
 254       // when growing reposition units starting at position 0
 
 255       System.arraycopy(unitsToProcess, 0,
 
 256           (unitsToProcess = new CompilationUnitDeclaration[size * 2]), 0,
 
 258     unitsToProcess[totalUnits++] = parsedUnit;
 
 261    * Add the initial set of compilation units into the loop -> build
 
 262    * compilation unit declarations, their bindings and record their results.
 
 264   protected void beginToCompile(ICompilationUnit[] sourceUnits) {
 
 265     int maxUnits = sourceUnits.length;
 
 267     unitsToProcess = new CompilationUnitDeclaration[maxUnits];
 
 268     // Switch the current policy and compilation result for this unit to the
 
 270     for (int i = 0; i < maxUnits; i++) {
 
 271       CompilationUnitDeclaration parsedUnit;
 
 272       CompilationResult unitResult = new CompilationResult(sourceUnits[i], i,
 
 273           maxUnits, this.options.maxProblemsPerUnit);
 
 275         // diet parsing for large collection of units
 
 276         if (totalUnits < parseThreshold) {
 
 277           parsedUnit = parser.parse(sourceUnits[i], unitResult, false);
 
 279           parsedUnit = parser.dietParse(sourceUnits[i], unitResult);
 
 281         if (options.verbose) {
 
 282           System.out.println(Util.bind("compilation.request", //$NON-NLS-1$
 
 283               new String[]{String.valueOf(i + 1), String.valueOf(maxUnits),
 
 284                   new String(sourceUnits[i].getFileName())}));
 
 286         // initial type binding creation
 
 287         //        lookupEnvironment.buildTypeBindings(parsedUnit);
 
 288         this.addCompilationUnit(sourceUnits[i], parsedUnit);
 
 289         //} catch (AbortCompilationUnit e) {
 
 290         //requestor.acceptResult(unitResult.tagAsAccepted());
 
 292         sourceUnits[i] = null; // no longer hold onto the unit
 
 295     // binding resolution
 
 296     lookupEnvironment.completeTypeBindings();
 
 299    * General API -> compile each of supplied files -> recompile any required
 
 300    * types for which we have an incomplete principle structure
 
 302   public void compile(ICompilationUnit[] sourceUnits) {
 
 303     CompilationUnitDeclaration unit = null;
 
 306       // build and record parsed units
 
 307       beginToCompile(sourceUnits);
 
 308       // process all units (some more could be injected in the loop by the
 
 309       // lookup environment)
 
 310       for (; i < totalUnits; i++) {
 
 311         unit = unitsToProcess[i];
 
 314             System.out.println(Util.bind("compilation.process", //$NON-NLS-1$
 
 315                 new String[]{String.valueOf(i + 1), String.valueOf(totalUnits),
 
 316                     new String(unitsToProcess[i].getFileName())}));
 
 319           // cleanup compilation unit result
 
 322             System.out.println(Util.bind("compilation.done", //$NON-NLS-1$
 
 323                 new String[]{String.valueOf(i + 1), String.valueOf(totalUnits),
 
 324                     new String(unitsToProcess[i].getFileName())}));
 
 326         unitsToProcess[i] = null; // release reference to processed unit
 
 328         requestor.acceptResult(unit.compilationResult.tagAsAccepted());
 
 330     } catch (AbortCompilation e) { 
 
 331       this.handleInternalException(e, unit);
 
 333       this.handleInternalException(e, unit, null);
 
 335     } catch (RuntimeException e) {
 
 336       this.handleInternalException(e, unit, null);
 
 341     //          if (options.verbose) {
 
 342     //                  if (totalUnits > 1) {
 
 343     //                          System.out.println(
 
 344     //                                  ProjectPrefUtil.bind("compilation.units" , String.valueOf(totalUnits)));
 
 347     //                          System.out.println(
 
 348     //                                  ProjectPrefUtil.bind("compilation.unit" , String.valueOf(totalUnits)));
 
 353   protected void getMethodBodies(CompilationUnitDeclaration unit, int place) {
 
 354     //fill the methods bodies in order for the code to be generated
 
 355     if (unit.ignoreMethodBodies) {
 
 356       unit.ignoreFurtherInvestigation = true;
 
 358       // if initial diet parse did not work, no need to dig into method bodies.
 
 360     if (place < parseThreshold)
 
 361       return; //work already done ...
 
 362     //real parse of the method....
 
 363     parser.scanner.setSource(unit.compilationResult.compilationUnit
 
 365     if (unit.types != null) {
 
 366       for (int i = unit.types.size(); --i >= 0;)
 
 367         if (unit.types.get(i) instanceof TypeDeclaration) {
 
 368           ((TypeDeclaration) unit.types.get(i)).parseMethod(parser, unit);
 
 373    * Compiler crash recovery in case of unexpected runtime exceptions
 
 375   protected void handleInternalException(Throwable internalException,
 
 376       CompilationUnitDeclaration unit, CompilationResult result) {
 
 377     /* dump a stack trace to the console */
 
 378     internalException.printStackTrace();
 
 379     /* find a compilation result */
 
 380     if ((unit != null)) // basing result upon the current unit if available
 
 381       result = unit.compilationResult; // current unit being processed ?
 
 382     if ((result == null) && (unitsToProcess != null) && (totalUnits > 0))
 
 383       result = unitsToProcess[totalUnits - 1].compilationResult;
 
 384     // last unit in beginToCompile ?
 
 385     if (result != null) {
 
 386       /* create and record a compilation problem */
 
 387       StringWriter stringWriter = new StringWriter();
 
 388       PrintWriter writer = new PrintWriter(stringWriter);
 
 389       internalException.printStackTrace(writer);
 
 390       StringBuffer buffer = stringWriter.getBuffer();
 
 391       String[] pbArguments = new String[]{Util
 
 392           .bind("compilation.internalError")
 
 395           + buffer.toString()};
 
 396       result.record(problemReporter.createProblem(result.getFileName(),
 
 397           IProblem.Unclassified, pbArguments, pbArguments, Error, // severity
 
 401           unit, result), unit);
 
 402       /* hand back the compilation result */
 
 403       if (!result.hasBeenAccepted) {
 
 404         requestor.acceptResult(result.tagAsAccepted());
 
 409    * Compiler recovery in case of internal AbortCompilation event
 
 411   protected void handleInternalException(AbortCompilation abortException,
 
 412       CompilationUnitDeclaration unit) {
 
 414      * special treatment for SilentAbort: silently cancelling the compilation
 
 417     if (abortException.isSilent) {
 
 418       if (abortException.silentException == null) {
 
 421         throw abortException.silentException;
 
 424     /* uncomment following line to see where the abort came from */
 
 425     // abortException.printStackTrace();
 
 426     // Exception may tell which compilation result it is related, and which
 
 428     CompilationResult result = abortException.compilationResult;
 
 429     if ((result == null) && (unit != null))
 
 430       result = unit.compilationResult; // current unit being processed ?
 
 431     if ((result == null) && (unitsToProcess != null) && (totalUnits > 0))
 
 432       result = unitsToProcess[totalUnits - 1].compilationResult;
 
 433     // last unit in beginToCompile ?
 
 434     if (result != null && !result.hasBeenAccepted) {
 
 435       /* distant problem which could not be reported back there */
 
 436       if (abortException.problemId != 0) {
 
 437         result.record(problemReporter.createProblem(result.getFileName(),
 
 438             abortException.problemId, abortException.problemArguments,
 
 439             abortException.messageArguments, Error, // severity
 
 443             unit, result), unit);
 
 445         /* distant internal exception which could not be reported back there */
 
 446         if (abortException.exception != null) {
 
 447           this.handleInternalException(abortException.exception, null, result);
 
 451       /* hand back the compilation result */
 
 452       if (!result.hasBeenAccepted) {
 
 453         requestor.acceptResult(result.tagAsAccepted());
 
 457        * if (abortException.problemId != 0){ IProblem problem =
 
 458        * problemReporter.createProblem( "???".toCharArray(),
 
 459        * abortException.problemId, abortException.problemArguments, Error, //
 
 460        * severity 0, // source start 0, // source end 0); // line number
 
 461        * System.out.println(problem.getMessage()); }
 
 463       abortException.printStackTrace();
 
 467    * Process a compilation unit already parsed and build.
 
 469   public void process(CompilationUnitDeclaration unit, int i) {
 
 470     getMethodBodies(unit, i);
 
 471     // fault in fields & methods
 
 472     if (unit.scope != null)
 
 473       unit.scope.faultInTypes();
 
 474     // verify inherited methods
 
 475     //    if (unit.scope != null)
 
 476     //      unit.scope.verifyMethods(lookupEnvironment.methodVerifier());
 
 482     //          unit.generateCode();
 
 484     //          if (options.produceReferenceInfo && unit.scope != null)
 
 485     //                  unit.scope.storeDependencyInfo();
 
 486     // refresh the total number of units known at this stage
 
 487     unit.compilationResult.totalUnitsKnown = totalUnits;
 
 489   public void reset() {
 
 490     lookupEnvironment.reset();
 
 491     parser.scanner.source = null;
 
 492     unitsToProcess = null;
 
 493     //          if (DebugRequestor != null) DebugRequestor.reset();
 
 496          * Internal API used to resolve a given compilation unit. Can run a subset of the compilation process
 
 498         public CompilationUnitDeclaration resolve(
 
 499                         CompilationUnitDeclaration unit, 
 
 500                         ICompilationUnit sourceUnit, 
 
 501                         boolean verifyMethods,
 
 502                         boolean analyzeCode) {
 
 506                                 // build and record parsed units
 
 507                                 parseThreshold = 0; // will request a full parse
 
 508                                 beginToCompile(new ICompilationUnit[] { sourceUnit });
 
 509                                 // process all units (some more could be injected in the loop by the lookup environment)
 
 510                                 unit = unitsToProcess[0];
 
 512                                 // initial type binding creation
 
 513                                 lookupEnvironment.buildTypeBindings(unit);
 
 515                                 // binding resolution
 
 516                                 lookupEnvironment.completeTypeBindings();
 
 518                         // TODO : jsurfer check this
 
 519 //                      this.parser.getMethodBodies(unit);
 
 520                         getMethodBodies(unit, 0);
 
 522                         if (unit.scope != null) {
 
 523                                 // fault in fields & methods
 
 524                                 unit.scope.faultInTypes();
 
 525                                 if (unit.scope != null && verifyMethods) {
 
 526                                         // http://dev.eclipse.org/bugs/show_bug.cgi?id=23117
 
 527                                         // verify inherited methods
 
 528                                         unit.scope.verifyMethods(lookupEnvironment.methodVerifier());
 
 534 //                              if (analyzeCode) unit.analyseCode();
 
 537 //                              if (generateCode) unit.generateCode();
 
 539                         if (unitsToProcess != null) unitsToProcess[0] = null; // release reference to processed unit declaration
 
 540                         requestor.acceptResult(unit.compilationResult.tagAsAccepted());
 
 542                 } catch (AbortCompilation e) {
 
 543                         this.handleInternalException(e, unit);
 
 544                         return unit == null ? unitsToProcess[0] : unit;
 
 546                         this.handleInternalException(e, unit, null);
 
 548                 } catch (RuntimeException e) {
 
 549                         this.handleInternalException(e, unit, null);
 
 552                         // No reset is performed there anymore since,
 
 553                         // within the CodeAssist (or related tools),
 
 554                         // the compiler may be called *after* a call
 
 555                         // to this resolve(...) method. And such a call
 
 556                         // needs to have a compiler with a non-empty
 
 562    * Internal API used to resolve a given compilation unit. Can run a subset of
 
 563    * the compilation process
 
 565   public CompilationUnitDeclaration resolve(ICompilationUnit sourceUnit,
 
 566       boolean verifyMethods, boolean analyzeCode) {
 
 567     //                  boolean generateCode) {
 
 568     CompilationUnitDeclaration unit = null;
 
 570       // build and record parsed units
 
 571       parseThreshold = 0; // will request a full parse
 
 572       beginToCompile(new ICompilationUnit[]{sourceUnit});
 
 573       // process all units (some more could be injected in the loop by the
 
 574       // lookup environment)
 
 575       unit = unitsToProcess[0];
 
 576       getMethodBodies(unit, 0);
 
 577       if (unit.scope != null) {
 
 578         //                              // fault in fields & methods
 
 579         //                              unit.scope.faultInTypes();
 
 580         //                              if (unit.scope != null && verifyMethods) {
 
 581         //                                      // http://dev.eclipse.org/bugs/show_bug.cgi?id=23117
 
 582         //                                      // verify inherited methods
 
 583         //                                      unit.scope.verifyMethods(lookupEnvironment.methodVerifier());
 
 588         //                              if (analyzeCode) unit.analyseCode();
 
 590         //                              if (generateCode) unit.generateCode();
 
 592       unitsToProcess[0] = null; // release reference to processed unit
 
 594       requestor.acceptResult(unit.compilationResult.tagAsAccepted());
 
 596     } catch (AbortCompilation e) {
 
 597       this.handleInternalException(e, unit);
 
 598       return unit == null ? unitsToProcess[0] : unit;
 
 600       this.handleInternalException(e, unit, null);
 
 602     } catch (RuntimeException e) {
 
 603       this.handleInternalException(e, unit, null);
 
 606       // No reset is performed there anymore since,
 
 607       // within the CodeAssist (or related tools),
 
 608       // the compiler may be called *after* a call
 
 609       // to this resolve(...) method. And such a call
 
 610       // needs to have a compiler with a non-empty