new version with WorkingCopy Management
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpdt / internal / compiler / Compiler.java
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/Compiler.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/Compiler.java
new file mode 100644 (file)
index 0000000..6583d9e
--- /dev/null
@@ -0,0 +1,628 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.compiler;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.Map;
+
+import net.sourceforge.phpdt.core.compiler.IProblem;
+import net.sourceforge.phpdt.internal.compiler.env.IBinaryType;
+import net.sourceforge.phpdt.internal.compiler.env.ICompilationUnit;
+import net.sourceforge.phpdt.internal.compiler.env.INameEnvironment;
+import net.sourceforge.phpdt.internal.compiler.env.ISourceType;
+import net.sourceforge.phpdt.internal.compiler.impl.ITypeRequestor;
+import net.sourceforge.phpdt.internal.compiler.lookup.LookupEnvironment;
+import net.sourceforge.phpdt.internal.compiler.lookup.PackageBinding;
+import net.sourceforge.phpdt.internal.compiler.parser.UnitParser;
+import net.sourceforge.phpdt.internal.compiler.problem.AbortCompilation;
+import net.sourceforge.phpdt.internal.compiler.problem.AbortCompilationUnit;
+import net.sourceforge.phpdt.internal.compiler.problem.ProblemReporter;
+import net.sourceforge.phpdt.internal.compiler.problem.ProblemSeverities;
+import net.sourceforge.phpdt.internal.compiler.util.Util;
+import net.sourceforge.phpeclipse.internal.compiler.ast.CompilationUnitDeclaration;
+import net.sourceforge.phpeclipse.internal.compiler.ast.TypeDeclaration;
+
+public class Compiler implements ITypeRequestor, ProblemSeverities {
+       public UnitParser parser;
+       public ICompilerRequestor requestor;
+//     public CompilerOptions options;
+       public ProblemReporter problemReporter;
+
+       // management of unit to be processed
+       //public CompilationUnitResult currentCompilationUnitResult;
+       public CompilationUnitDeclaration[] unitsToProcess;
+       public int totalUnits; // (totalUnits-1) gives the last unit in unitToProcess
+
+       // name lookup
+       public LookupEnvironment lookupEnvironment;
+
+       // ONCE STABILIZED, THESE SHOULD RETURN TO A FINAL FIELD
+       public static boolean DEBUG = false;
+       public int parseThreshold = -1;
+       // number of initial units parsed at once (-1: none)
+
+       /*
+        * Static requestor reserved to listening compilation results in debug mode,
+        * so as for example to monitor compiler activity independantly from a particular
+        * builder implementation. It is reset at the end of compilation, and should not 
+        * persist any information after having been reset.
+        */
+//     public static IDebugRequestor DebugRequestor = null;
+
+       /**
+        * Answer a new compiler using the given name environment and compiler options.
+        * The environment and options will be in effect for the lifetime of the compiler.
+        * When the compiler is run, compilation results are sent to the given requestor.
+        *
+        *  @param environment org.eclipse.jdt.internal.compiler.api.env.INameEnvironment
+        *      Environment used by the compiler in order to resolve type and package
+        *      names. The name environment implements the actual connection of the compiler
+        *      to the outside world (e.g. in batch mode the name environment is performing
+        *      pure file accesses, reuse previous build state or connection to repositories).
+        *      Note: the name environment is responsible for implementing the actual classpath
+        *            rules.
+        *
+        *  @param policy org.eclipse.jdt.internal.compiler.api.problem.IErrorHandlingPolicy
+        *      Configurable part for problem handling, allowing the compiler client to
+        *      specify the rules for handling problems (stop on first error or accumulate
+        *      them all) and at the same time perform some actions such as opening a dialog
+        *      in UI when compiling interactively.
+        *      @see org.eclipse.jdt.internal.compiler.DefaultErrorHandlingPolicies
+        *      
+        *  @param requestor org.eclipse.jdt.internal.compiler.api.ICompilerRequestor
+        *      Component which will receive and persist all compilation results and is intended
+        *      to consume them as they are produced. Typically, in a batch compiler, it is 
+        *      responsible for writing out the actual .class files to the file system.
+        *      @see org.eclipse.jdt.internal.compiler.CompilationResult
+        *
+        *  @param problemFactory org.eclipse.jdt.internal.compiler.api.problem.IProblemFactory
+        *      Factory used inside the compiler to create problem descriptors. It allows the
+        *      compiler client to supply its own representation of compilation problems in
+        *      order to avoid object conversions. Note that the factory is not supposed
+        *      to accumulate the created problems, the compiler will gather them all and hand
+        *      them back as part of the compilation unit result.
+        */
+       public Compiler(
+               INameEnvironment environment,
+               IErrorHandlingPolicy policy,
+//             Map settings,
+               final ICompilerRequestor requestor,
+               IProblemFactory problemFactory) {
+
+               // create a problem handler given a handling policy
+//             this.options = new CompilerOptions(settings);
+               
+               // wrap requestor in DebugRequestor if one is specified
+//             if(DebugRequestor == null) {
+                       this.requestor = requestor;
+//             } else {
+//                     this.requestor = new ICompilerRequestor(){
+//                             public void acceptResult(CompilationResult result){
+//                                     if (DebugRequestor.isActive()){
+//                                             DebugRequestor.acceptDebugResult(result);
+//                                     }
+//                                     requestor.acceptResult(result);
+//                             }
+//                     };
+//             }
+               this.problemReporter =
+                       new ProblemReporter(policy, problemFactory);//this.options, problemFactory);
+               this.lookupEnvironment =
+                       new LookupEnvironment(this, problemReporter, environment); //options, problemReporter, environment);
+               this.parser =
+                       new UnitParser(
+                               problemReporter); 
+//                             this.options.parseLiteralExpressionsAsConstants, 
+//                             options.sourceLevel >= CompilerOptions.JDK1_4);
+       }
+       
+       /**
+        * Answer a new compiler using the given name environment and compiler options.
+        * The environment and options will be in effect for the lifetime of the compiler.
+        * When the compiler is run, compilation results are sent to the given requestor.
+        *
+        *  @param environment org.eclipse.jdt.internal.compiler.api.env.INameEnvironment
+        *      Environment used by the compiler in order to resolve type and package
+        *      names. The name environment implements the actual connection of the compiler
+        *      to the outside world (e.g. in batch mode the name environment is performing
+        *      pure file accesses, reuse previous build state or connection to repositories).
+        *      Note: the name environment is responsible for implementing the actual classpath
+        *            rules.
+        *
+        *  @param policy org.eclipse.jdt.internal.compiler.api.problem.IErrorHandlingPolicy
+        *      Configurable part for problem handling, allowing the compiler client to
+        *      specify the rules for handling problems (stop on first error or accumulate
+        *      them all) and at the same time perform some actions such as opening a dialog
+        *      in UI when compiling interactively.
+        *      @see org.eclipse.jdt.internal.compiler.DefaultErrorHandlingPolicies
+        *      
+        *  @param requestor org.eclipse.jdt.internal.compiler.api.ICompilerRequestor
+        *      Component which will receive and persist all compilation results and is intended
+        *      to consume them as they are produced. Typically, in a batch compiler, it is 
+        *      responsible for writing out the actual .class files to the file system.
+        *      @see org.eclipse.jdt.internal.compiler.CompilationResult
+        *
+        *  @param problemFactory org.eclipse.jdt.internal.compiler.api.problem.IProblemFactory
+        *      Factory used inside the compiler to create problem descriptors. It allows the
+        *      compiler client to supply its own representation of compilation problems in
+        *      order to avoid object conversions. Note that the factory is not supposed
+        *      to accumulate the created problems, the compiler will gather them all and hand
+        *      them back as part of the compilation unit result.
+        *      @param parseLiteralExpressionsAsConstants <code>boolean</code>
+        *              This parameter is used to optimize the literals or leave them as they are in the source.
+        *              If you put true, "Hello" + " world" will be converted to "Hello world".
+        */
+       public Compiler(
+               INameEnvironment environment,
+               IErrorHandlingPolicy policy,
+//             Map settings,
+               final ICompilerRequestor requestor,
+               IProblemFactory problemFactory,
+               boolean parseLiteralExpressionsAsConstants) {
+
+               // create a problem handler given a handling policy
+//             this.options = new CompilerOptions(settings);
+               
+               // wrap requestor in DebugRequestor if one is specified
+//             if(DebugRequestor == null) {
+                       this.requestor = requestor;
+//             } else {
+//                     this.requestor = new ICompilerRequestor(){
+//                             public void acceptResult(CompilationResult result){
+//                                     if (DebugRequestor.isActive()){
+//                                             DebugRequestor.acceptDebugResult(result);
+//                                     }
+//                                     requestor.acceptResult(result);
+//                             }
+//                     };
+//             }
+               this.problemReporter =
+                       new ProblemReporter(policy, problemFactory);//, this.options, problemFactory);
+               this.lookupEnvironment =
+                       new LookupEnvironment(this, problemReporter, environment);//options, problemReporter, environment);
+               this.parser =
+                       new UnitParser(
+                               problemReporter); 
+//                             parseLiteralExpressionsAsConstants,
+                               //                              this.options.sourceLevel >= CompilerOptions.JDK1_4);
+       }
+       
+       /**
+        * Add an additional binary type
+        */
+       public void accept(IBinaryType binaryType, PackageBinding packageBinding) {
+               lookupEnvironment.createBinaryTypeFrom(binaryType, packageBinding);
+       }
+
+       /**
+        * Add an additional compilation unit into the loop
+        *  ->  build compilation unit declarations, their bindings and record their results.
+        */
+       public void accept(ICompilationUnit sourceUnit) {
+               // Switch the current policy and compilation result for this unit to the requested one.
+               CompilationResult unitResult =
+                       new CompilationResult(sourceUnit, totalUnits, totalUnits, 10); //this.options.maxProblemsPerUnit);
+               try {
+                       // diet parsing for large collection of unit
+                       CompilationUnitDeclaration parsedUnit;
+                       if (totalUnits < parseThreshold) {
+                               parsedUnit = parser.parse(sourceUnit, unitResult);
+                       } else {
+                               parsedUnit = parser.dietParse(sourceUnit, unitResult);
+                       }
+
+//                     if (options.verbose) {
+//                             String count = String.valueOf(totalUnits + 1);
+//                             System.out.println(
+//                                     Util.bind(
+//                                             "compilation.request" , //$NON-NLS-1$
+//                                             new String[] {
+//                                                     count,
+//                                                     count,
+//                                                     new String(sourceUnit.getFileName())}));
+//                     }
+
+                       // initial type binding creation
+                       lookupEnvironment.buildTypeBindings(parsedUnit);
+                       this.addCompilationUnit(sourceUnit, parsedUnit);
+
+                       // binding resolution
+                       lookupEnvironment.completeTypeBindings(parsedUnit);
+               } catch (AbortCompilationUnit e) {
+                       // at this point, currentCompilationUnitResult may not be sourceUnit, but some other
+                       // one requested further along to resolve sourceUnit.
+                       if (unitResult.compilationUnit == sourceUnit) { // only report once
+                               requestor.acceptResult(unitResult.tagAsAccepted());
+                       } else {
+                               throw e; // want to abort enclosing request to compile
+                       }
+               }
+       }
+
+       /**
+        * Add additional source types
+        */
+       public void accept(ISourceType[] sourceTypes, PackageBinding packageBinding) {
+               problemReporter.abortDueToInternalError(
+                       Util.bind(
+                               "abort.againstSourceModel " , //$NON-NLS-1$
+                               String.valueOf(sourceTypes[0].getName()),
+                               String.valueOf(sourceTypes[0].getFileName())));
+       }
+
+       protected void addCompilationUnit(
+               ICompilationUnit sourceUnit,
+               CompilationUnitDeclaration parsedUnit) {
+
+               // append the unit to the list of ones to process later on
+               int size = unitsToProcess.length;
+               if (totalUnits == size)
+                       // when growing reposition units starting at position 0
+                       System.arraycopy(
+                               unitsToProcess,
+                               0,
+                               (unitsToProcess = new CompilationUnitDeclaration[size * 2]),
+                               0,
+                               totalUnits);
+               unitsToProcess[totalUnits++] = parsedUnit;
+       }
+
+       /**
+        * Add the initial set of compilation units into the loop
+        *  ->  build compilation unit declarations, their bindings and record their results.
+        */
+       protected void beginToCompile(ICompilationUnit[] sourceUnits) {
+               int maxUnits = sourceUnits.length;
+               totalUnits = 0;
+               unitsToProcess = new CompilationUnitDeclaration[maxUnits];
+
+               // Switch the current policy and compilation result for this unit to the requested one.
+               for (int i = 0; i < maxUnits; i++) {
+                       CompilationUnitDeclaration parsedUnit;
+                       CompilationResult unitResult =
+                               new CompilationResult(sourceUnits[i], i, maxUnits, 10);//, this.options.maxProblemsPerUnit);
+                       try {
+                               // diet parsing for large collection of units
+                               if (totalUnits < parseThreshold) {
+                                       parsedUnit = parser.parse(sourceUnits[i], unitResult);
+                               } else {
+                                       parsedUnit = parser.dietParse(sourceUnits[i], unitResult);
+                               }
+//                             if (options.verbose) {
+//                                     System.out.println(
+//                                             Util.bind(
+//                                                     "compilation.request" , //$NON-NLS-1$
+//                                                     new String[] {
+//                                                             String.valueOf(i + 1),
+//                                                             String.valueOf(maxUnits),
+//                                                             new String(sourceUnits[i].getFileName())}));
+//                             }
+                               // initial type binding creation
+                               lookupEnvironment.buildTypeBindings(parsedUnit);
+                               this.addCompilationUnit(sourceUnits[i], parsedUnit);
+                               //} catch (AbortCompilationUnit e) {
+                               //      requestor.acceptResult(unitResult.tagAsAccepted());
+                       } finally {
+                               sourceUnits[i] = null; // no longer hold onto the unit
+                       }
+               }
+               // binding resolution
+               lookupEnvironment.completeTypeBindings();
+       }
+
+       /**
+        * General API
+        * -> compile each of supplied files
+        * -> recompile any required types for which we have an incomplete principle structure
+        */
+       public void compile(ICompilationUnit[] sourceUnits) {
+               CompilationUnitDeclaration unit = null;
+               int i = 0;
+               try {
+                       // build and record parsed units
+
+                       beginToCompile(sourceUnits);
+
+                       // process all units (some more could be injected in the loop by the lookup environment)
+                       for (; i < totalUnits; i++) {
+                               unit = unitsToProcess[i];
+                               try {
+//                                     if (options.verbose)
+//                                             System.out.println(
+//                                                     Util.bind(
+//                                                             "compilation.process" , //$NON-NLS-1$
+//                                                             new String[] {
+//                                                                     String.valueOf(i + 1),
+//                                                                     String.valueOf(totalUnits),
+//                                                                     new String(unitsToProcess[i].getFileName())}));
+                                       process(unit, i);
+                               } finally {
+                                       // cleanup compilation unit result
+                                       unit.cleanUp();
+//                                     if (options.verbose)
+//                                             System.out.println(Util.bind("compilation.done", //$NON-NLS-1$
+//                                     new String[] {
+//                                             String.valueOf(i + 1),
+//                                             String.valueOf(totalUnits),
+//                                             new String(unitsToProcess[i].getFileName())}));
+                               }
+                               unitsToProcess[i] = null; // release reference to processed unit declaration
+                               requestor.acceptResult(unit.compilationResult.tagAsAccepted());
+                       }
+               } catch (AbortCompilation e) {
+                       this.handleInternalException(e, unit);
+               } catch (Error e) {
+                       this.handleInternalException(e, unit, null);
+                       throw e; // rethrow
+               } catch (RuntimeException e) {
+                       this.handleInternalException(e, unit, null);
+                       throw e; // rethrow
+               } finally {
+                       this.reset();
+               }
+//             if (options.verbose) {
+//                     if (totalUnits > 1) {
+//                             System.out.println(
+//                                     Util.bind("compilation.units" , String.valueOf(totalUnits))); //$NON-NLS-1$
+//                     } else {
+//                             System.out.println(
+//                                     Util.bind("compilation.unit" , String.valueOf(totalUnits))); //$NON-NLS-1$
+//                     }
+//             }
+       }
+
+       protected void getMethodBodies(CompilationUnitDeclaration unit, int place) {
+               //fill the methods bodies in order for the code to be generated
+
+               if (unit.ignoreMethodBodies) {
+                       unit.ignoreFurtherInvestigation = true;
+                       return;
+                       // if initial diet parse did not work, no need to dig into method bodies.
+               }
+
+               if (place < parseThreshold)
+                       return; //work already done ...
+
+               //real parse of the method....
+               parser.scanner.setSource(
+                       unit.compilationResult.compilationUnit.getContents());
+               if (unit.types != null) {
+                       for (int i = unit.types.size(); --i >= 0;)
+                         if (unit.types.get(i) instanceof TypeDeclaration) {
+                                 ((TypeDeclaration)unit.types.get(i)).parseMethod(parser, unit);
+                         }
+               }
+       }
+
+       /*
+        * Compiler crash recovery in case of unexpected runtime exceptions
+        */
+       protected void handleInternalException(
+               Throwable internalException,
+               CompilationUnitDeclaration unit,
+               CompilationResult result) {
+
+               /* dump a stack trace to the console */
+               internalException.printStackTrace();
+
+               /* find a compilation result */
+               if ((unit != null)) // basing result upon the current unit if available
+                       result = unit.compilationResult; // current unit being processed ?
+               if ((result == null) && (unitsToProcess != null) && (totalUnits > 0))
+                       result = unitsToProcess[totalUnits - 1].compilationResult;
+               // last unit in beginToCompile ?
+
+               if (result != null) {
+                       /* create and record a compilation problem */
+                       StringWriter stringWriter = new StringWriter();
+                       PrintWriter writer = new PrintWriter(stringWriter);
+                       internalException.printStackTrace(writer);
+                       StringBuffer buffer = stringWriter.getBuffer();
+
+                       String[] pbArguments = new String[] {
+                               Util.bind("compilation.internalError" ) //$NON-NLS-1$
+                                       + "\n"  //$NON-NLS-1$
+                                       + buffer.toString()};
+
+                       result
+                               .record(
+                                       problemReporter
+                                       .createProblem(
+                                               result.getFileName(),
+                                               IProblem.Unclassified,
+                                               pbArguments,
+                                               pbArguments,
+                                               Error, // severity
+                                               0, // source start
+                                               0, // source end
+                                               0, // line number               
+                                               unit,
+                                               result),
+                                       unit);
+
+                       /* hand back the compilation result */
+                       if (!result.hasBeenAccepted) {
+                               requestor.acceptResult(result.tagAsAccepted());
+                       }
+               }
+       }
+
+       /*
+        * Compiler recovery in case of internal AbortCompilation event
+        */
+       protected void handleInternalException(
+               AbortCompilation abortException,
+               CompilationUnitDeclaration unit) {
+
+               /* special treatment for SilentAbort: silently cancelling the compilation process */
+               if (abortException.isSilent) {
+                       if (abortException.silentException == null) {
+                               return;
+                       } else {
+                               throw abortException.silentException;
+                       }
+               }
+
+               /* uncomment following line to see where the abort came from */
+               // abortException.printStackTrace(); 
+
+               // Exception may tell which compilation result it is related, and which problem caused it
+               CompilationResult result = abortException.compilationResult;
+               if ((result == null) && (unit != null))
+                       result = unit.compilationResult; // current unit being processed ?
+               if ((result == null) && (unitsToProcess != null) && (totalUnits > 0))
+                       result = unitsToProcess[totalUnits - 1].compilationResult;
+               // last unit in beginToCompile ?
+               if (result != null && !result.hasBeenAccepted) {
+                       /* distant problem which could not be reported back there */
+                       if (abortException.problemId != 0) {
+                               result
+                                       .record(
+                                               problemReporter
+                                               .createProblem(
+                                                       result.getFileName(),
+                                                       abortException.problemId,
+                                                       abortException.problemArguments,
+                                                       abortException.messageArguments,
+                                                       Error, // severity
+                                                       0, // source start
+                                                       0, // source end
+                                                       0, // line number               
+                                                       unit,
+                                                       result),
+                                               unit);                          
+                       } else {
+                               /* distant internal exception which could not be reported back there */
+                               if (abortException.exception != null) {
+                                       this.handleInternalException(abortException.exception, null, result);
+                                       return;
+                               }
+                       }
+                       /* hand back the compilation result */
+                       if (!result.hasBeenAccepted) {
+                               requestor.acceptResult(result.tagAsAccepted());
+                       }
+               } else {
+                       /*
+                       if (abortException.problemId != 0){ 
+                               IProblem problem =
+                                       problemReporter.createProblem(
+                                               "???".toCharArray(),
+                                               abortException.problemId, 
+                                               abortException.problemArguments, 
+                                               Error, // severity
+                                               0, // source start
+                                               0, // source end
+                                               0); // line number
+                               System.out.println(problem.getMessage());
+                       }
+                       */
+                       abortException.printStackTrace();
+               }
+       }
+
+       /**
+        * Process a compilation unit already parsed and build.
+        */
+       public void process(CompilationUnitDeclaration unit, int i) {
+
+               getMethodBodies(unit, i);
+
+               // fault in fields & methods
+               if (unit.scope != null)
+                       unit.scope.faultInTypes();
+
+               // verify inherited methods
+               if (unit.scope != null)
+                       unit.scope.verifyMethods(lookupEnvironment.methodVerifier());
+
+               // type checking
+               unit.resolve();
+
+               // flow analysis
+               unit.analyseCode();
+
+               // code generation
+//             unit.generateCode();
+
+               // reference info
+//             if (options.produceReferenceInfo && unit.scope != null)
+//                     unit.scope.storeDependencyInfo();
+
+               // refresh the total number of units known at this stage
+               unit.compilationResult.totalUnitsKnown = totalUnits;
+       }
+       public void reset() {
+               lookupEnvironment.reset();
+               parser.scanner.source = null;
+               unitsToProcess = null;
+//             if (DebugRequestor != null) DebugRequestor.reset();
+       }
+
+       /**
+        * Internal API used to resolve a given compilation unit. Can run a subset of the compilation process
+        */
+       public CompilationUnitDeclaration resolve(
+                       ICompilationUnit sourceUnit, 
+                       boolean verifyMethods,
+                       boolean analyzeCode) {
+//                     boolean generateCode) {
+                               
+               CompilationUnitDeclaration unit = null;
+               try {
+                       // build and record parsed units
+                       parseThreshold = 0; // will request a full parse
+                       beginToCompile(new ICompilationUnit[] { sourceUnit });
+                       // process all units (some more could be injected in the loop by the lookup environment)
+                       unit = unitsToProcess[0];
+                       getMethodBodies(unit, 0);
+                       if (unit.scope != null) {
+//                             // fault in fields & methods
+//                             unit.scope.faultInTypes();
+                               
+//                             if (unit.scope != null && verifyMethods) {
+//                                     // http://dev.eclipse.org/bugs/show_bug.cgi?id=23117
+//                                     // verify inherited methods
+//                                     unit.scope.verifyMethods(lookupEnvironment.methodVerifier());
+//                             }
+//                             // type checking
+//                             unit.resolve();         
+
+                               // flow analysis
+//                             if (analyzeCode) unit.analyseCode();
+               
+                               // code generation
+//                             if (generateCode) unit.generateCode();
+                       }
+                       unitsToProcess[0] = null; // release reference to processed unit declaration
+                       requestor.acceptResult(unit.compilationResult.tagAsAccepted());
+                       return unit;
+               } catch (AbortCompilation e) {
+                       this.handleInternalException(e, unit);
+                       return unit == null ? unitsToProcess[0] : unit;
+               } catch (Error e) {
+                       this.handleInternalException(e, unit, null);
+                       throw e; // rethrow
+               } catch (RuntimeException e) {
+                       this.handleInternalException(e, unit, null);
+                       throw e; // rethrow
+               } finally {
+                       // No reset is performed there anymore since,
+                       // within the CodeAssist (or related tools),
+                       // the compiler may be called *after* a call
+                       // to this resolve(...) method. And such a call
+                       // needs to have a compiler with a non-empty
+                       // environment.
+                       // this.reset();
+               }
+       }
+}