initial implementation
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpdt / internal / compiler / Compiler.java
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
7  * 
8  * Contributors:
9  *     IBM Corporation - initial API and implementation
10  *******************************************************************************/
11 package net.sourceforge.phpdt.internal.compiler;
12
13 import java.io.PrintWriter;
14 import java.io.StringWriter;
15 import java.util.Map;
16
17 import net.sourceforge.phpdt.core.compiler.IProblem;
18 import net.sourceforge.phpdt.internal.compiler.env.IBinaryType;
19 import net.sourceforge.phpdt.internal.compiler.env.ICompilationUnit;
20 import net.sourceforge.phpdt.internal.compiler.env.INameEnvironment;
21 import net.sourceforge.phpdt.internal.compiler.env.ISourceType;
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;
33
34 public class Compiler implements ITypeRequestor, ProblemSeverities {
35         public UnitParser parser;
36         public ICompilerRequestor requestor;
37 //      public CompilerOptions options;
38         public ProblemReporter problemReporter;
39
40         // management of unit to be processed
41         //public CompilationUnitResult currentCompilationUnitResult;
42         public CompilationUnitDeclaration[] unitsToProcess;
43         public int totalUnits; // (totalUnits-1) gives the last unit in unitToProcess
44
45         // name lookup
46         public LookupEnvironment lookupEnvironment;
47
48         // ONCE STABILIZED, THESE SHOULD RETURN TO A FINAL FIELD
49         public static boolean DEBUG = false;
50         public int parseThreshold = -1;
51         // number of initial units parsed at once (-1: none)
52
53         /*
54          * Static requestor reserved to listening compilation results in debug mode,
55          * so as for example to monitor compiler activity independantly from a particular
56          * builder implementation. It is reset at the end of compilation, and should not 
57          * persist any information after having been reset.
58          */
59 //      public static IDebugRequestor DebugRequestor = null;
60
61         /**
62          * Answer a new compiler using the given name environment and compiler options.
63          * The environment and options will be in effect for the lifetime of the compiler.
64          * When the compiler is run, compilation results are sent to the given requestor.
65          *
66          *  @param environment org.eclipse.jdt.internal.compiler.api.env.INameEnvironment
67          *      Environment used by the compiler in order to resolve type and package
68          *      names. The name environment implements the actual connection of the compiler
69          *      to the outside world (e.g. in batch mode the name environment is performing
70          *      pure file accesses, reuse previous build state or connection to repositories).
71          *      Note: the name environment is responsible for implementing the actual classpath
72          *            rules.
73          *
74          *  @param policy org.eclipse.jdt.internal.compiler.api.problem.IErrorHandlingPolicy
75          *      Configurable part for problem handling, allowing the compiler client to
76          *      specify the rules for handling problems (stop on first error or accumulate
77          *      them all) and at the same time perform some actions such as opening a dialog
78          *      in UI when compiling interactively.
79          *      @see org.eclipse.jdt.internal.compiler.DefaultErrorHandlingPolicies
80          *      
81          *  @param requestor org.eclipse.jdt.internal.compiler.api.ICompilerRequestor
82          *      Component which will receive and persist all compilation results and is intended
83          *      to consume them as they are produced. Typically, in a batch compiler, it is 
84          *      responsible for writing out the actual .class files to the file system.
85          *      @see org.eclipse.jdt.internal.compiler.CompilationResult
86          *
87          *  @param problemFactory org.eclipse.jdt.internal.compiler.api.problem.IProblemFactory
88          *      Factory used inside the compiler to create problem descriptors. It allows the
89          *      compiler client to supply its own representation of compilation problems in
90          *      order to avoid object conversions. Note that the factory is not supposed
91          *      to accumulate the created problems, the compiler will gather them all and hand
92          *      them back as part of the compilation unit result.
93          */
94         public Compiler(
95                 INameEnvironment environment,
96                 IErrorHandlingPolicy policy,
97 //              Map settings,
98                 final ICompilerRequestor requestor,
99                 IProblemFactory problemFactory) {
100
101                 // create a problem handler given a handling policy
102 //              this.options = new CompilerOptions(settings);
103                 
104                 // wrap requestor in DebugRequestor if one is specified
105 //              if(DebugRequestor == null) {
106                         this.requestor = requestor;
107 //              } else {
108 //                      this.requestor = new ICompilerRequestor(){
109 //                              public void acceptResult(CompilationResult result){
110 //                                      if (DebugRequestor.isActive()){
111 //                                              DebugRequestor.acceptDebugResult(result);
112 //                                      }
113 //                                      requestor.acceptResult(result);
114 //                              }
115 //                      };
116 //              }
117                 this.problemReporter =
118                         new ProblemReporter(policy, problemFactory);//this.options, problemFactory);
119                 this.lookupEnvironment =
120                         new LookupEnvironment(this, problemReporter, environment); //options, problemReporter, environment);
121                 this.parser =
122                         new UnitParser(
123                                 problemReporter); 
124 //                              this.options.parseLiteralExpressionsAsConstants, 
125 //                              options.sourceLevel >= CompilerOptions.JDK1_4);
126         }
127         
128         /**
129          * Answer a new compiler using the given name environment and compiler options.
130          * The environment and options will be in effect for the lifetime of the compiler.
131          * When the compiler is run, compilation results are sent to the given requestor.
132          *
133          *  @param environment org.eclipse.jdt.internal.compiler.api.env.INameEnvironment
134          *      Environment used by the compiler in order to resolve type and package
135          *      names. The name environment implements the actual connection of the compiler
136          *      to the outside world (e.g. in batch mode the name environment is performing
137          *      pure file accesses, reuse previous build state or connection to repositories).
138          *      Note: the name environment is responsible for implementing the actual classpath
139          *            rules.
140          *
141          *  @param policy org.eclipse.jdt.internal.compiler.api.problem.IErrorHandlingPolicy
142          *      Configurable part for problem handling, allowing the compiler client to
143          *      specify the rules for handling problems (stop on first error or accumulate
144          *      them all) and at the same time perform some actions such as opening a dialog
145          *      in UI when compiling interactively.
146          *      @see org.eclipse.jdt.internal.compiler.DefaultErrorHandlingPolicies
147          *      
148          *  @param requestor org.eclipse.jdt.internal.compiler.api.ICompilerRequestor
149          *      Component which will receive and persist all compilation results and is intended
150          *      to consume them as they are produced. Typically, in a batch compiler, it is 
151          *      responsible for writing out the actual .class files to the file system.
152          *      @see org.eclipse.jdt.internal.compiler.CompilationResult
153          *
154          *  @param problemFactory org.eclipse.jdt.internal.compiler.api.problem.IProblemFactory
155          *      Factory used inside the compiler to create problem descriptors. It allows the
156          *      compiler client to supply its own representation of compilation problems in
157          *      order to avoid object conversions. Note that the factory is not supposed
158          *      to accumulate the created problems, the compiler will gather them all and hand
159          *      them back as part of the compilation unit result.
160          *      @param parseLiteralExpressionsAsConstants <code>boolean</code>
161          *              This parameter is used to optimize the literals or leave them as they are in the source.
162          *              If you put true, "Hello" + " world" will be converted to "Hello world".
163          */
164         public Compiler(
165                 INameEnvironment environment,
166                 IErrorHandlingPolicy policy,
167 //              Map settings,
168                 final ICompilerRequestor requestor,
169                 IProblemFactory problemFactory,
170                 boolean parseLiteralExpressionsAsConstants) {
171
172                 // create a problem handler given a handling policy
173 //              this.options = new CompilerOptions(settings);
174                 
175                 // wrap requestor in DebugRequestor if one is specified
176 //              if(DebugRequestor == null) {
177                         this.requestor = requestor;
178 //              } else {
179 //                      this.requestor = new ICompilerRequestor(){
180 //                              public void acceptResult(CompilationResult result){
181 //                                      if (DebugRequestor.isActive()){
182 //                                              DebugRequestor.acceptDebugResult(result);
183 //                                      }
184 //                                      requestor.acceptResult(result);
185 //                              }
186 //                      };
187 //              }
188                 this.problemReporter =
189                         new ProblemReporter(policy, problemFactory);//, this.options, problemFactory);
190                 this.lookupEnvironment =
191                         new LookupEnvironment(this, problemReporter, environment);//options, problemReporter, environment);
192                 this.parser =
193                         new UnitParser(
194                                 problemReporter); 
195 //                              parseLiteralExpressionsAsConstants,
196                                 //                              this.options.sourceLevel >= CompilerOptions.JDK1_4);
197         }
198         
199         /**
200          * Add an additional binary type
201          */
202         public void accept(IBinaryType binaryType, PackageBinding packageBinding) {
203                 lookupEnvironment.createBinaryTypeFrom(binaryType, packageBinding);
204         }
205
206         /**
207          * Add an additional compilation unit into the loop
208          *  ->  build compilation unit declarations, their bindings and record their results.
209          */
210         public void accept(ICompilationUnit sourceUnit) {
211                 // Switch the current policy and compilation result for this unit to the requested one.
212                 CompilationResult unitResult =
213                         new CompilationResult(sourceUnit, totalUnits, totalUnits, 10); //this.options.maxProblemsPerUnit);
214                 try {
215                         // diet parsing for large collection of unit
216                         CompilationUnitDeclaration parsedUnit;
217                         if (totalUnits < parseThreshold) {
218                                 parsedUnit = parser.parse(sourceUnit, unitResult);
219                         } else {
220                                 parsedUnit = parser.dietParse(sourceUnit, unitResult);
221                         }
222
223 //                      if (options.verbose) {
224 //                              String count = String.valueOf(totalUnits + 1);
225 //                              System.out.println(
226 //                                      Util.bind(
227 //                                              "compilation.request" , //$NON-NLS-1$
228 //                                              new String[] {
229 //                                                      count,
230 //                                                      count,
231 //                                                      new String(sourceUnit.getFileName())}));
232 //                      }
233
234                         // initial type binding creation
235                         lookupEnvironment.buildTypeBindings(parsedUnit);
236                         this.addCompilationUnit(sourceUnit, parsedUnit);
237
238                         // binding resolution
239                         lookupEnvironment.completeTypeBindings(parsedUnit);
240                 } catch (AbortCompilationUnit e) {
241                         // at this point, currentCompilationUnitResult may not be sourceUnit, but some other
242                         // one requested further along to resolve sourceUnit.
243                         if (unitResult.compilationUnit == sourceUnit) { // only report once
244                                 requestor.acceptResult(unitResult.tagAsAccepted());
245                         } else {
246                                 throw e; // want to abort enclosing request to compile
247                         }
248                 }
249         }
250
251         /**
252          * Add additional source types
253          */
254         public void accept(ISourceType[] sourceTypes, PackageBinding packageBinding) {
255                 problemReporter.abortDueToInternalError(
256                         Util.bind(
257                                 "abort.againstSourceModel " , //$NON-NLS-1$
258                                 String.valueOf(sourceTypes[0].getName()),
259                                 String.valueOf(sourceTypes[0].getFileName())));
260         }
261
262         protected void addCompilationUnit(
263                 ICompilationUnit sourceUnit,
264                 CompilationUnitDeclaration parsedUnit) {
265
266                 // append the unit to the list of ones to process later on
267                 int size = unitsToProcess.length;
268                 if (totalUnits == size)
269                         // when growing reposition units starting at position 0
270                         System.arraycopy(
271                                 unitsToProcess,
272                                 0,
273                                 (unitsToProcess = new CompilationUnitDeclaration[size * 2]),
274                                 0,
275                                 totalUnits);
276                 unitsToProcess[totalUnits++] = parsedUnit;
277         }
278
279         /**
280          * Add the initial set of compilation units into the loop
281          *  ->  build compilation unit declarations, their bindings and record their results.
282          */
283         protected void beginToCompile(ICompilationUnit[] sourceUnits) {
284                 int maxUnits = sourceUnits.length;
285                 totalUnits = 0;
286                 unitsToProcess = new CompilationUnitDeclaration[maxUnits];
287
288                 // Switch the current policy and compilation result for this unit to the requested one.
289                 for (int i = 0; i < maxUnits; i++) {
290                         CompilationUnitDeclaration parsedUnit;
291                         CompilationResult unitResult =
292                                 new CompilationResult(sourceUnits[i], i, maxUnits, 10);//, this.options.maxProblemsPerUnit);
293                         try {
294                                 // diet parsing for large collection of units
295                                 if (totalUnits < parseThreshold) {
296                                         parsedUnit = parser.parse(sourceUnits[i], unitResult);
297                                 } else {
298                                         parsedUnit = parser.dietParse(sourceUnits[i], unitResult);
299                                 }
300 //                              if (options.verbose) {
301 //                                      System.out.println(
302 //                                              Util.bind(
303 //                                                      "compilation.request" , //$NON-NLS-1$
304 //                                                      new String[] {
305 //                                                              String.valueOf(i + 1),
306 //                                                              String.valueOf(maxUnits),
307 //                                                              new String(sourceUnits[i].getFileName())}));
308 //                              }
309                                 // initial type binding creation
310                                 lookupEnvironment.buildTypeBindings(parsedUnit);
311                                 this.addCompilationUnit(sourceUnits[i], parsedUnit);
312                                 //} catch (AbortCompilationUnit e) {
313                                 //      requestor.acceptResult(unitResult.tagAsAccepted());
314                         } finally {
315                                 sourceUnits[i] = null; // no longer hold onto the unit
316                         }
317                 }
318                 // binding resolution
319                 lookupEnvironment.completeTypeBindings();
320         }
321
322         /**
323          * General API
324          * -> compile each of supplied files
325          * -> recompile any required types for which we have an incomplete principle structure
326          */
327         public void compile(ICompilationUnit[] sourceUnits) {
328                 CompilationUnitDeclaration unit = null;
329                 int i = 0;
330                 try {
331                         // build and record parsed units
332
333                         beginToCompile(sourceUnits);
334
335                         // process all units (some more could be injected in the loop by the lookup environment)
336                         for (; i < totalUnits; i++) {
337                                 unit = unitsToProcess[i];
338                                 try {
339 //                                      if (options.verbose)
340 //                                              System.out.println(
341 //                                                      Util.bind(
342 //                                                              "compilation.process" , //$NON-NLS-1$
343 //                                                              new String[] {
344 //                                                                      String.valueOf(i + 1),
345 //                                                                      String.valueOf(totalUnits),
346 //                                                                      new String(unitsToProcess[i].getFileName())}));
347                                         process(unit, i);
348                                 } finally {
349                                         // cleanup compilation unit result
350                                         unit.cleanUp();
351 //                                      if (options.verbose)
352 //                                              System.out.println(Util.bind("compilation.done", //$NON-NLS-1$
353 //                                      new String[] {
354 //                                              String.valueOf(i + 1),
355 //                                              String.valueOf(totalUnits),
356 //                                              new String(unitsToProcess[i].getFileName())}));
357                                 }
358                                 unitsToProcess[i] = null; // release reference to processed unit declaration
359                                 requestor.acceptResult(unit.compilationResult.tagAsAccepted());
360                         }
361                 } catch (AbortCompilation e) {
362                         this.handleInternalException(e, unit);
363                 } catch (Error e) {
364                         this.handleInternalException(e, unit, null);
365                         throw e; // rethrow
366                 } catch (RuntimeException e) {
367                         this.handleInternalException(e, unit, null);
368                         throw e; // rethrow
369                 } finally {
370                         this.reset();
371                 }
372 //              if (options.verbose) {
373 //                      if (totalUnits > 1) {
374 //                              System.out.println(
375 //                                      Util.bind("compilation.units" , String.valueOf(totalUnits))); //$NON-NLS-1$
376 //                      } else {
377 //                              System.out.println(
378 //                                      Util.bind("compilation.unit" , String.valueOf(totalUnits))); //$NON-NLS-1$
379 //                      }
380 //              }
381         }
382
383         protected void getMethodBodies(CompilationUnitDeclaration unit, int place) {
384                 //fill the methods bodies in order for the code to be generated
385
386                 if (unit.ignoreMethodBodies) {
387                         unit.ignoreFurtherInvestigation = true;
388                         return;
389                         // if initial diet parse did not work, no need to dig into method bodies.
390                 }
391
392                 if (place < parseThreshold)
393                         return; //work already done ...
394
395                 //real parse of the method....
396                 parser.scanner.setSource(
397                         unit.compilationResult.compilationUnit.getContents());
398                 if (unit.types != null) {
399                         for (int i = unit.types.size(); --i >= 0;)
400                           if (unit.types.get(i) instanceof TypeDeclaration) {
401                                   ((TypeDeclaration)unit.types.get(i)).parseMethod(parser, unit);
402                           }
403                 }
404         }
405
406         /*
407          * Compiler crash recovery in case of unexpected runtime exceptions
408          */
409         protected void handleInternalException(
410                 Throwable internalException,
411                 CompilationUnitDeclaration unit,
412                 CompilationResult result) {
413
414                 /* dump a stack trace to the console */
415                 internalException.printStackTrace();
416
417                 /* find a compilation result */
418                 if ((unit != null)) // basing result upon the current unit if available
419                         result = unit.compilationResult; // current unit being processed ?
420                 if ((result == null) && (unitsToProcess != null) && (totalUnits > 0))
421                         result = unitsToProcess[totalUnits - 1].compilationResult;
422                 // last unit in beginToCompile ?
423
424                 if (result != null) {
425                         /* create and record a compilation problem */
426                         StringWriter stringWriter = new StringWriter();
427                         PrintWriter writer = new PrintWriter(stringWriter);
428                         internalException.printStackTrace(writer);
429                         StringBuffer buffer = stringWriter.getBuffer();
430
431                         String[] pbArguments = new String[] {
432                                 Util.bind("compilation.internalError" ) //$NON-NLS-1$
433                                         + "\n"  //$NON-NLS-1$
434                                         + buffer.toString()};
435
436                         result
437                                 .record(
438                                         problemReporter
439                                         .createProblem(
440                                                 result.getFileName(),
441                                                 IProblem.Unclassified,
442                                                 pbArguments,
443                                                 pbArguments,
444                                                 Error, // severity
445                                                 0, // source start
446                                                 0, // source end
447                                                 0, // line number               
448                                                 unit,
449                                                 result),
450                                         unit);
451
452                         /* hand back the compilation result */
453                         if (!result.hasBeenAccepted) {
454                                 requestor.acceptResult(result.tagAsAccepted());
455                         }
456                 }
457         }
458
459         /*
460          * Compiler recovery in case of internal AbortCompilation event
461          */
462         protected void handleInternalException(
463                 AbortCompilation abortException,
464                 CompilationUnitDeclaration unit) {
465
466                 /* special treatment for SilentAbort: silently cancelling the compilation process */
467                 if (abortException.isSilent) {
468                         if (abortException.silentException == null) {
469                                 return;
470                         } else {
471                                 throw abortException.silentException;
472                         }
473                 }
474
475                 /* uncomment following line to see where the abort came from */
476                 // abortException.printStackTrace(); 
477
478                 // Exception may tell which compilation result it is related, and which problem caused it
479                 CompilationResult result = abortException.compilationResult;
480                 if ((result == null) && (unit != null))
481                         result = unit.compilationResult; // current unit being processed ?
482                 if ((result == null) && (unitsToProcess != null) && (totalUnits > 0))
483                         result = unitsToProcess[totalUnits - 1].compilationResult;
484                 // last unit in beginToCompile ?
485                 if (result != null && !result.hasBeenAccepted) {
486                         /* distant problem which could not be reported back there */
487                         if (abortException.problemId != 0) {
488                                 result
489                                         .record(
490                                                 problemReporter
491                                                 .createProblem(
492                                                         result.getFileName(),
493                                                         abortException.problemId,
494                                                         abortException.problemArguments,
495                                                         abortException.messageArguments,
496                                                         Error, // severity
497                                                         0, // source start
498                                                         0, // source end
499                                                         0, // line number               
500                                                         unit,
501                                                         result),
502                                                 unit);                          
503                         } else {
504                                 /* distant internal exception which could not be reported back there */
505                                 if (abortException.exception != null) {
506                                         this.handleInternalException(abortException.exception, null, result);
507                                         return;
508                                 }
509                         }
510                         /* hand back the compilation result */
511                         if (!result.hasBeenAccepted) {
512                                 requestor.acceptResult(result.tagAsAccepted());
513                         }
514                 } else {
515                         /*
516                         if (abortException.problemId != 0){ 
517                                 IProblem problem =
518                                         problemReporter.createProblem(
519                                                 "???".toCharArray(),
520                                                 abortException.problemId, 
521                                                 abortException.problemArguments, 
522                                                 Error, // severity
523                                                 0, // source start
524                                                 0, // source end
525                                                 0); // line number
526                                 System.out.println(problem.getMessage());
527                         }
528                         */
529                         abortException.printStackTrace();
530                 }
531         }
532
533         /**
534          * Process a compilation unit already parsed and build.
535          */
536         public void process(CompilationUnitDeclaration unit, int i) {
537
538                 getMethodBodies(unit, i);
539
540                 // fault in fields & methods
541                 if (unit.scope != null)
542                         unit.scope.faultInTypes();
543
544                 // verify inherited methods
545                 if (unit.scope != null)
546                         unit.scope.verifyMethods(lookupEnvironment.methodVerifier());
547
548                 // type checking
549                 unit.resolve();
550
551                 // flow analysis
552                 unit.analyseCode();
553
554                 // code generation
555 //              unit.generateCode();
556
557                 // reference info
558 //              if (options.produceReferenceInfo && unit.scope != null)
559 //                      unit.scope.storeDependencyInfo();
560
561                 // refresh the total number of units known at this stage
562                 unit.compilationResult.totalUnitsKnown = totalUnits;
563         }
564         public void reset() {
565                 lookupEnvironment.reset();
566                 parser.scanner.source = null;
567                 unitsToProcess = null;
568 //              if (DebugRequestor != null) DebugRequestor.reset();
569         }
570
571         /**
572          * Internal API used to resolve a given compilation unit. Can run a subset of the compilation process
573          */
574         public CompilationUnitDeclaration resolve(
575                         ICompilationUnit sourceUnit, 
576                         boolean verifyMethods,
577                         boolean analyzeCode) {
578 //                      boolean generateCode) {
579                                 
580                 CompilationUnitDeclaration unit = null;
581                 try {
582                         // build and record parsed units
583                         parseThreshold = 0; // will request a full parse
584                         beginToCompile(new ICompilationUnit[] { sourceUnit });
585                         // process all units (some more could be injected in the loop by the lookup environment)
586                         unit = unitsToProcess[0];
587                         getMethodBodies(unit, 0);
588                         if (unit.scope != null) {
589 //                              // fault in fields & methods
590 //                              unit.scope.faultInTypes();
591                                 
592 //                              if (unit.scope != null && verifyMethods) {
593 //                                      // http://dev.eclipse.org/bugs/show_bug.cgi?id=23117
594 //                                      // verify inherited methods
595 //                                      unit.scope.verifyMethods(lookupEnvironment.methodVerifier());
596 //                              }
597 //                              // type checking
598 //                              unit.resolve();         
599
600                                 // flow analysis
601 //                              if (analyzeCode) unit.analyseCode();
602                 
603                                 // code generation
604 //                              if (generateCode) unit.generateCode();
605                         }
606                         unitsToProcess[0] = null; // release reference to processed unit declaration
607                         requestor.acceptResult(unit.compilationResult.tagAsAccepted());
608                         return unit;
609                 } catch (AbortCompilation e) {
610                         this.handleInternalException(e, unit);
611                         return unit == null ? unitsToProcess[0] : unit;
612                 } catch (Error e) {
613                         this.handleInternalException(e, unit, null);
614                         throw e; // rethrow
615                 } catch (RuntimeException e) {
616                         this.handleInternalException(e, unit, null);
617                         throw e; // rethrow
618                 } finally {
619                         // No reset is performed there anymore since,
620                         // within the CodeAssist (or related tools),
621                         // the compiler may be called *after* a call
622                         // to this resolve(...) method. And such a call
623                         // needs to have a compiler with a non-empty
624                         // environment.
625                         // this.reset();
626                 }
627         }
628 }