1
1
/*******************************************************************************
2
- * Copyright (c) 2000, 2004 IBM Corporation and others.
2
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
3
3
* All rights reserved. This program and the accompanying materials
4
4
* are made available under the terms of the Eclipse Public License v1.0
5
5
* which accompanies this distribution, and is available at
14
14
import org .eclipse .core .runtime .*;
15
15
16
16
import org .eclipse .jdt .core .JavaCore ;
17
+ import org .eclipse .jdt .internal .compiler .ClassFile ;
17
18
import org .eclipse .jdt .internal .core .util .Messages ;
18
19
import org .eclipse .jdt .internal .core .util .Util ;
19
20
20
21
import java .util .*;
21
22
22
23
public class BatchImageBuilder extends AbstractImageBuilder {
23
24
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 );
26
30
this .nameEnvironment .isIncrementalBuild = false ;
31
+ this .incrementalBuilder = null ;
32
+ this .missingSecondaryTypes = null ;
27
33
}
28
34
29
35
public void build () {
30
36
if (JavaBuilder .DEBUG )
31
37
System .out .println ("FULL build" ); //$NON-NLS-1$
32
38
33
39
try {
34
- notifier .subTask (Messages .build_cleaningOutput );
40
+ notifier .subTask (Messages .bind ( Messages . build_cleaningOutput , this . javaBuilder . currentProject . getName ()));
35
41
JavaBuilder .removeProblemsAndTasksFor (javaBuilder .currentProject );
36
42
cleanOutputFolders (true );
37
- notifier .updateProgressDelta (0.1f );
43
+ notifier .updateProgressDelta (0.05f );
38
44
39
45
notifier .subTask (Messages .build_analyzingSources );
40
46
ArrayList sourceFiles = new ArrayList (33 );
41
47
addAllSourceFiles (sourceFiles );
42
- notifier .updateProgressDelta (0.15f );
48
+ notifier .updateProgressDelta (0.10f );
43
49
44
50
if (sourceFiles .size () > 0 ) {
45
51
SourceFile [] allSourceFiles = new SourceFile [sourceFiles .size ()];
@@ -48,6 +54,11 @@ public void build() {
48
54
notifier .setProgressPerCompilationUnit (0.75f / allSourceFiles .length );
49
55
workQueue .addAll (allSourceFiles );
50
56
compile (allSourceFiles );
57
+
58
+ if (this .missingSecondaryTypes != null && !this .missingSecondaryTypes .isEmpty ())
59
+ rebuildTypesAffectedByMissingSecondaryTypes ();
60
+ if (this .incrementalBuilder != null )
61
+ this .incrementalBuilder .buildAfterBatchBuild ();
51
62
}
52
63
53
64
if (javaBuilder .javaProject .hasCycleMarker ())
@@ -59,6 +70,11 @@ public void build() {
59
70
}
60
71
}
61
72
73
+ protected void acceptSecondaryType (ClassFile classFile ) {
74
+ if (this .missingSecondaryTypes != null )
75
+ this .missingSecondaryTypes .add (classFile .fileName ());
76
+ }
77
+
62
78
protected void addAllSourceFiles (final ArrayList sourceFiles ) throws CoreException {
63
79
for (int i = 0 , l = sourceLocations .length ; i < l ; i ++) {
64
80
final ClasspathMultiDirectory sourceLocation = sourceLocations [i ];
@@ -102,9 +118,13 @@ protected void cleanOutputFolders(boolean copyBack) throws CoreException {
102
118
boolean deleteAll = JavaCore .CLEAN .equals (
103
119
javaBuilder .javaProject .getOption (JavaCore .CORE_JAVA_BUILD_CLEAN_OUTPUT_FOLDER , true ));
104
120
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
+
105
125
ArrayList visited = new ArrayList (sourceLocations .length );
106
126
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 ()) );
108
128
ClasspathMultiDirectory sourceLocation = sourceLocations [i ];
109
129
if (sourceLocation .hasIndependentOutputFolder ) {
110
130
IContainer outputFolder = sourceLocation .binaryFolder ;
@@ -185,6 +205,18 @@ else if (!sourceLocation.sourceFolder.equals(sourceLocation.binaryFolder))
185
205
}
186
206
}
187
207
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
+
188
220
protected void copyExtraResourcesBack (ClasspathMultiDirectory sourceLocation , final boolean deletedAll ) throws CoreException {
189
221
// When, if ever, does a builder need to copy resources files (not .java or .class) into the output folder?
190
222
// 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 {
225
257
}
226
258
copiedResource .delete (IResource .FORCE , null ); // last one wins
227
259
}
228
- resource .copy (copiedResource .getFullPath (), IResource .FORCE , null );
229
- copiedResource .setDerived (true );
260
+ resource .copy (copiedResource .getFullPath (), IResource .FORCE | IResource .DERIVED , null );
230
261
Util .setReadOnly (copiedResource , false ); // just in case the original was read only
231
262
return false ;
232
263
case IResource .FOLDER :
@@ -284,6 +315,24 @@ protected IResource findOriginalResource(IPath partialPath) {
284
315
return null ;
285
316
}
286
317
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
+
287
336
public String toString () {
288
337
return "batch image builder for:\n \t new state: " + newState ; //$NON-NLS-1$
289
338
}
0 commit comments