X-Git-Url: http://git.phpeclipse.com

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
index 6583d9e..cbfdcfc 100644
--- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/Compiler.java
+++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/Compiler.java
@@ -9,16 +9,15 @@
  *     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.CompilerOptions;
 import net.sourceforge.phpdt.internal.compiler.impl.ITypeRequestor;
 import net.sourceforge.phpdt.internal.compiler.lookup.LookupEnvironment;
 import net.sourceforge.phpdt.internal.compiler.lookup.PackageBinding;
@@ -30,572 +29,504 @@ 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();
-	}
-
-	/**
+  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 = true;
+  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, 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, 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, this.options.maxProblemsPerUnit);
+    try {
+      // diet parsing for large collection of unit
+      CompilationUnitDeclaration parsedUnit;
+      if (totalUnits < parseThreshold) {
+        parsedUnit = parser.parse(sourceUnit, unitResult, false);
+      } 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, this.options.maxProblemsPerUnit);
+      try {
+        // diet parsing for large collection of units
+        if (totalUnits < parseThreshold) {
+          parsedUnit = parser.parse(sourceUnits[i], unitResult, false);
+        } 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(
+			CompilationUnitDeclaration unit, 
 			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];
+			if (unit == null) {
+				// 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];
+			} else {
+				// initial type binding creation
+				lookupEnvironment.buildTypeBindings(unit);
+
+				// binding resolution
+				lookupEnvironment.completeTypeBindings();
+			}
+			// TODO : jsurfer check this
+//			this.parser.getMethodBodies(unit);
 			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();		
+				// 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();
@@ -603,7 +534,7 @@ public class Compiler implements ITypeRequestor, ProblemSeverities {
 				// code generation
 //				if (generateCode) unit.generateCode();
 			}
-			unitsToProcess[0] = null; // release reference to processed unit declaration
+			if (unitsToProcess != null) unitsToProcess[0] = null; // release reference to processed unit declaration
 			requestor.acceptResult(unit.compilationResult.tagAsAccepted());
 			return unit;
 		} catch (AbortCompilation e) {
@@ -625,4 +556,59 @@ public class Compiler implements ITypeRequestor, ProblemSeverities {
 			// this.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();
+    }
+  }
+
 }