/******************************************************************************* * Copyright (c) 2000, 2008 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ package org.eclipse.wst.jsdt.internal.core.builder; import java.util.ArrayList; import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.Path; import org.eclipse.wst.jsdt.core.compiler.CategorizedProblem; import org.eclipse.wst.jsdt.core.compiler.IProblem; import org.eclipse.wst.jsdt.internal.core.util.Messages; public class BatchImageBuilder extends AbstractImageBuilder { IncrementalImageBuilder incrementalBuilder; // if annotations or secondary types have to be processed after the compile loop ArrayList secondaryTypes; // qualified names for all secondary types found during batch compile StringSet typeLocatorsWithUndefinedTypes; // type locators for all source files with errors that may be caused by 'not found' secondary types protected BatchImageBuilder(JavaBuilder javaBuilder, boolean buildStarting) { super(javaBuilder, buildStarting, null); this.nameEnvironment.isIncrementalBuild = false; this.incrementalBuilder = null; this.secondaryTypes = null; this.typeLocatorsWithUndefinedTypes = null; } public void build() { if (JavaBuilder.DEBUG) System.out.println("FULL build"); //$NON-NLS-1$ try { // notifier.subTask(Messages.bind(Messages.build_cleaningOutput, this.javaBuilder.currentProject.getName())); JavaBuilder.removeProblemsAndTasksFor(javaBuilder.currentProject); // cleanOutputFolders(true); notifier.updateProgressDelta(0.05f); notifier.subTask(Messages.build_analyzingSources); ArrayList sourceFiles = new ArrayList(33); addAllSourceFiles(sourceFiles); notifier.updateProgressDelta(0.10f); if (sourceFiles.size() > 0) { SourceFile[] allSourceFiles = new SourceFile[sourceFiles.size()]; sourceFiles.toArray(allSourceFiles); notifier.setProgressPerCompilationUnit(0.75f / allSourceFiles.length); workQueue.addAll(allSourceFiles); compile(allSourceFiles); if (this.typeLocatorsWithUndefinedTypes != null) if (this.secondaryTypes != null && !this.secondaryTypes.isEmpty()) rebuildTypesAffectedBySecondaryTypes(); if (this.incrementalBuilder != null) this.incrementalBuilder.buildAfterBatchBuild(); } if (javaBuilder.javaProject.hasCycleMarker()) javaBuilder.mustPropagateStructuralChanges(); } catch (CoreException e) { throw internalException(e); } finally { cleanUp(); } } protected void cleanUp() { this.incrementalBuilder = null; this.secondaryTypes = null; this.typeLocatorsWithUndefinedTypes = null; super.cleanUp(); } protected void compile(SourceFile[] units, SourceFile[] additionalUnits, boolean compilingFirstGroup) { if (additionalUnits != null && this.secondaryTypes == null) this.secondaryTypes = new ArrayList(7); super.compile(units, additionalUnits, compilingFirstGroup); } protected IResource findOriginalResource(IPath partialPath) { for (int i = 0, l = sourceLocations.length; i < l; i++) { ClasspathMultiDirectory sourceLocation = sourceLocations[i]; if (sourceLocation.hasIndependentOutputFolder) { IResource originalResource = sourceLocation.sourceFolder.getFile(partialPath); if (originalResource.exists()) return originalResource; } } return null; } protected void rebuildTypesAffectedBySecondaryTypes() { // to compile types that could not find 'missing' secondary types because of multiple // compile groups, we need to incrementally recompile all affected types as if the missing // secondary types have just been added, see bug 146324 if (this.incrementalBuilder == null) this.incrementalBuilder = new IncrementalImageBuilder(this); for (int i = this.secondaryTypes.size(); --i >=0;) { char[] secondaryTypeName = (char[]) this.secondaryTypes.get(i); IPath path = new Path(null, new String(secondaryTypeName)); this.incrementalBuilder.addDependentsOf(path, false); } this.incrementalBuilder.addAffectedSourceFiles( this.incrementalBuilder.qualifiedStrings, this.incrementalBuilder.simpleStrings, this.typeLocatorsWithUndefinedTypes); } protected void storeProblemsFor(SourceFile sourceFile, CategorizedProblem[] problems) throws CoreException { if (sourceFile == null || problems == null || problems.length == 0) return; for (int i = problems.length; --i >= 0;) { CategorizedProblem problem = problems[i]; if (problem != null && problem.getID() == IProblem.UndefinedType) { if (this.typeLocatorsWithUndefinedTypes == null) this.typeLocatorsWithUndefinedTypes = new StringSet(3); this.typeLocatorsWithUndefinedTypes.add(sourceFile.typeLocator()); break; } } super.storeProblemsFor(sourceFile, problems); } public String toString() { return "batch image builder for:\n\tnew state: " + newState; //$NON-NLS-1$ } }