11/*******************************************************************************
2- * Copyright (c) 2000, 2004 IBM Corporation and others.
2+ * Copyright (c) 2000, 2006 IBM Corporation and others.
33 * All rights reserved. This program and the accompanying materials
44 * are made available under the terms of the Eclipse Public License v1.0
55 * which accompanies this distribution, and is available at
1414import org .eclipse .core .runtime .*;
1515
1616import org .eclipse .jdt .core .JavaCore ;
17+ import org .eclipse .jdt .internal .compiler .ClassFile ;
1718import org .eclipse .jdt .internal .core .util .Messages ;
1819import org .eclipse .jdt .internal .core .util .Util ;
1920
2021import java .util .*;
2122
2223public class BatchImageBuilder extends AbstractImageBuilder {
2324
24- protected BatchImageBuilder (JavaBuilder javaBuilder ) {
25- super (javaBuilder );
25+ IncrementalImageBuilder incrementalBuilder ; // if annotations or secondary types have to be processed after the compile loop
26+ ArrayList missingSecondaryTypes ; // qualified names for any secondary types found after the first compile loop
27+
28+ protected BatchImageBuilder (JavaBuilder javaBuilder , boolean buildStarting ) {
29+ super (javaBuilder , buildStarting , null );
2630 this .nameEnvironment .isIncrementalBuild = false ;
31+ this .incrementalBuilder = null ;
32+ this .missingSecondaryTypes = null ;
2733}
2834
2935public void build () {
3036 if (JavaBuilder .DEBUG )
3137 System .out .println ("FULL build" ); //$NON-NLS-1$
3238
3339 try {
34- notifier .subTask (Messages .build_cleaningOutput );
40+ notifier .subTask (Messages .bind ( Messages . build_cleaningOutput , this . javaBuilder . currentProject . getName ()));
3541 JavaBuilder .removeProblemsAndTasksFor (javaBuilder .currentProject );
3642 cleanOutputFolders (true );
37- notifier .updateProgressDelta (0.1f );
43+ notifier .updateProgressDelta (0.05f );
3844
3945 notifier .subTask (Messages .build_analyzingSources );
4046 ArrayList sourceFiles = new ArrayList (33 );
4147 addAllSourceFiles (sourceFiles );
42- notifier .updateProgressDelta (0.15f );
48+ notifier .updateProgressDelta (0.10f );
4349
4450 if (sourceFiles .size () > 0 ) {
4551 SourceFile [] allSourceFiles = new SourceFile [sourceFiles .size ()];
@@ -48,6 +54,11 @@ public void build() {
4854 notifier .setProgressPerCompilationUnit (0.75f / allSourceFiles .length );
4955 workQueue .addAll (allSourceFiles );
5056 compile (allSourceFiles );
57+
58+ if (this .missingSecondaryTypes != null && !this .missingSecondaryTypes .isEmpty ())
59+ rebuildTypesAffectedByMissingSecondaryTypes ();
60+ if (this .incrementalBuilder != null )
61+ this .incrementalBuilder .buildAfterBatchBuild ();
5162 }
5263
5364 if (javaBuilder .javaProject .hasCycleMarker ())
@@ -59,6 +70,11 @@ public void build() {
5970 }
6071}
6172
73+ protected void acceptSecondaryType (ClassFile classFile ) {
74+ if (this .missingSecondaryTypes != null )
75+ this .missingSecondaryTypes .add (classFile .fileName ());
76+ }
77+
6278protected void addAllSourceFiles (final ArrayList sourceFiles ) throws CoreException {
6379 for (int i = 0 , l = sourceLocations .length ; i < l ; i ++) {
6480 final ClasspathMultiDirectory sourceLocation = sourceLocations [i ];
@@ -102,9 +118,13 @@ protected void cleanOutputFolders(boolean copyBack) throws CoreException {
102118 boolean deleteAll = JavaCore .CLEAN .equals (
103119 javaBuilder .javaProject .getOption (JavaCore .CORE_JAVA_BUILD_CLEAN_OUTPUT_FOLDER , true ));
104120 if (deleteAll ) {
121+ if (this .javaBuilder .participants != null )
122+ for (int i = 0 , l = this .javaBuilder .participants .length ; i < l ; i ++)
123+ this .javaBuilder .participants [i ].cleanStarting (this .javaBuilder .javaProject );
124+
105125 ArrayList visited = new ArrayList (sourceLocations .length );
106126 for (int i = 0 , l = sourceLocations .length ; i < l ; i ++) {
107- notifier .subTask (Messages .build_cleaningOutput );
127+ notifier .subTask (Messages .bind ( Messages . build_cleaningOutput , this . javaBuilder . currentProject . getName ()) );
108128 ClasspathMultiDirectory sourceLocation = sourceLocations [i ];
109129 if (sourceLocation .hasIndependentOutputFolder ) {
110130 IContainer outputFolder = sourceLocation .binaryFolder ;
@@ -185,6 +205,18 @@ else if (!sourceLocation.sourceFolder.equals(sourceLocation.binaryFolder))
185205 }
186206}
187207
208+ protected void cleanUp () {
209+ this .incrementalBuilder = null ;
210+ this .missingSecondaryTypes = null ;
211+ super .cleanUp ();
212+ }
213+
214+ protected void compile (SourceFile [] units , SourceFile [] additionalUnits , boolean compilingFirstGroup ) {
215+ if (!compilingFirstGroup && this .missingSecondaryTypes == null )
216+ this .missingSecondaryTypes = new ArrayList (7 );
217+ super .compile (units , additionalUnits , compilingFirstGroup );
218+ }
219+
188220protected void copyExtraResourcesBack (ClasspathMultiDirectory sourceLocation , final boolean deletedAll ) throws CoreException {
189221 // When, if ever, does a builder need to copy resources files (not .java or .class) into the output folder?
190222 // If we wipe the output folder at the beginning of the build then all 'extra' resources must be copied to the output folder.
@@ -225,8 +257,7 @@ public boolean visit(IResourceProxy proxy) throws CoreException {
225257 }
226258 copiedResource .delete (IResource .FORCE , null ); // last one wins
227259 }
228- resource .copy (copiedResource .getFullPath (), IResource .FORCE , null );
229- copiedResource .setDerived (true );
260+ resource .copy (copiedResource .getFullPath (), IResource .FORCE | IResource .DERIVED , null );
230261 Util .setReadOnly (copiedResource , false ); // just in case the original was read only
231262 return false ;
232263 case IResource .FOLDER :
@@ -284,6 +315,24 @@ protected IResource findOriginalResource(IPath partialPath) {
284315 return null ;
285316}
286317
318+ protected void processAnnotationResults (CompilationParticipantResult [] results ) {
319+ // to compile the compilation participant results, we need to incrementally recompile all affected types
320+ // whenever the generated types are initially added or structurally changed
321+ if (this .incrementalBuilder == null )
322+ this .incrementalBuilder = new IncrementalImageBuilder (this );
323+ this .incrementalBuilder .processAnnotationResults (results );
324+ }
325+
326+ protected void rebuildTypesAffectedByMissingSecondaryTypes () {
327+ // to compile types that could not find 'missing' secondary types because of multiple
328+ // compile groups, we need to incrementally recompile all affected types as if the missing
329+ // secondary types have just been added
330+ if (this .incrementalBuilder == null )
331+ this .incrementalBuilder = new IncrementalImageBuilder (this );
332+ for (int i = this .missingSecondaryTypes .size (); --i >=0 ; )
333+ this .incrementalBuilder .addAffectedSourceFiles ((char []) this .missingSecondaryTypes .get (i ));
334+ }
335+
287336public String toString () {
288337 return "batch image builder for:\n \t new state: " + newState ; //$NON-NLS-1$
289338}
0 commit comments