blob: 010003961d8adcaa0f151c0068f3889360ea2068 [file] [log] [blame]
package org.eclipse.jdt.internal.core.builder.impl;
/*
* (c) Copyright IBM Corp. 2000, 2001.
* All Rights Reserved.
*/
import org.eclipse.jdt.internal.compiler.*;
import org.eclipse.jdt.internal.compiler.Compiler;
import org.eclipse.jdt.internal.compiler.impl.*;
import org.eclipse.jdt.internal.core.builder.*;
import java.util.*;
/**
* The abstract superclass of image builders.
* Provides the building and compilation mechanism
* in common with the batch and incremental builders.
*/
public abstract class AbstractImageBuilder implements IImageBuilder, ICompilerRequestor {
protected JavaDevelopmentContextImpl fDC;
protected StateImpl fOldState;
protected StateImpl fNewState;
protected WorkQueue fWorkQueue;
protected BuilderEnvironment fBuilderEnvironment;
protected BuildNotifier fNotifier;
protected org.eclipse.jdt.internal.compiler.Compiler fCompiler;
protected Map fCompilerOptions;
protected Vector fCompilationResults;
public int MAX_AT_ONCE = 1000;
/**
* Creates a new builder.
*/
protected AbstractImageBuilder() {
}
public void acceptResult(CompilationResult result) {
ConvertedCompilationResult convertedResult = fNewState.convertCompilationResult(result, getBuilderEnvironment().getDefaultPackage());
PackageElement element = convertedResult.getPackageElement();
if (!fWorkQueue.hasBeenCompiled(element)) {
fCompilationResults.addElement(convertedResult);
fNotifier.compiled((CompilerCompilationUnit) result.getCompilationUnit());
fWorkQueue.compiled(element);
}
}
/**
* Check whether the build has been canceled.
*/
protected void checkCancel() {
fNotifier.checkCancel();
}
/**
* Since the image builder is given as a result, let go of
* any unneeded structures.
*/
protected void cleanUp() {
fCompiler = null;
fCompilationResults = null;
fWorkQueue = null;
fBuilderEnvironment = null;
fNotifier = null;
fNewState.cleanUp();
}
/**
* Compile the given elements, adding more elements to the work queue
* if they are affected by the changes.
*/
protected void compile(Vector vToCompile) {
int i = 0;
Vector vToCompileAtOnce = new Vector(Math.min(vToCompile.size(), MAX_AT_ONCE));
while (i < vToCompile.size()) {
vToCompileAtOnce.removeAllElements();
while (i < vToCompile.size() && vToCompileAtOnce.size() < MAX_AT_ONCE) {
PackageElement unit = (PackageElement) vToCompile.elementAt(i);
// Although it needed compiling when this method was called,
// it may have already been compiled due to being brought in
// by another unit.
if (fWorkQueue.needsCompile(unit)) {
SourceEntry sEntry = fNewState.getSourceEntry(unit);
CompilerCompilationUnit compUnit = new CompilerCompilationUnit(fNewState, sEntry, fNotifier);
compiling(compUnit);
vToCompileAtOnce.addElement(compUnit);
checkCancel();
}
++i;
}
if (vToCompileAtOnce.size() > 0) {
CompilerCompilationUnit[] toCompile = new CompilerCompilationUnit[vToCompileAtOnce.size()];
vToCompileAtOnce.copyInto(toCompile);
try {
fDC.inCompiler = true;
getCompiler().compile(toCompile);
} finally {
fDC.inCompiler = false;
}
/* Check for cancel immediately after a compile, because the compile may have been
* canceled but without propagating the build canceled exception. */
checkCancel();
/* store results in new state and get new units to compile */
ConvertedCompilationResult[] results = getCompilationResults();
updateState(results);
checkCancel();
}
}
}
/**
* A unit is being (re)compiled. Save any previous type structure.
*/
protected void compiling(CompilerCompilationUnit unit) {
}
/**
* Returns the builder environment to use for this builder.
*/
public BuilderEnvironment getBuilderEnvironment() {
if (fBuilderEnvironment == null) {
fBuilderEnvironment = new BuilderEnvironment(this);
fBuilderEnvironment.setDefaultPackage(fNewState.defaultPackageForProject());
}
return fBuilderEnvironment;
}
/**
* Returns the results of the last compile.
*/
protected ConvertedCompilationResult[] getCompilationResults() {
ConvertedCompilationResult[] results = new ConvertedCompilationResult[fCompilationResults.size()];
fCompilationResults.copyInto(results);
fCompilationResults = null;
return results;
}
/**
* Returns the compiler to use.
*/
protected Compiler getCompiler() {
// Make sure to clear the results before starting a new compile.
fCompilationResults = new Vector();
if (fCompiler == null) {
IErrorHandlingPolicy errorPolicy = DefaultErrorHandlingPolicies.proceedWithAllProblems();
IProblemFactory problemFactory = ProblemFactory.getProblemFactory(Locale.getDefault());
fCompiler = new Compiler(getBuilderEnvironment(), errorPolicy, fCompilerOptions, this, problemFactory);
}
return fCompiler;
}
/**
* Returns the state that is being built.
*/
public IState getNewState() {
return fNewState;
}
/**
* Returns the old state if the image is being built incrementally
*/
public IState getOldState() {
return fOldState;
}
/**
* Returns true if the given source entry must be recompiled, false otherwise.
*/
protected boolean isInvalid(SourceEntry sEntry) {
return fWorkQueue.needsCompile(fNewState.packageElementFromSourceEntry(sEntry));
}
/**
* Stores the results of a compilation in the appropriate state tables.
* Keeps track of what compilation units need to be compiled as a result
* of the changes.
*/
protected void updateState(ConvertedCompilationResult[] results) {
// Must store all compilation results, so state has sufficient information
// to calculate changes.
fNewState.putCompilationResults(results);
// Notify listeners
fNotifier.notifyElementsChanged(results, fOldState, fNewState);
}
}