Lines 1-569
Link Here
|
1 |
/******************************************************************************* |
1 |
/******************************************************************************* |
2 |
* Copyright (c) 2000, 2001, 2002 International Business Machines Corp. and others. |
2 |
* Copyright (c) 2000, 2001, 2002 International Business Machines Corp. and others. |
3 |
* All rights reserved. This program and the accompanying materials |
3 |
* All rights reserved. This program and the accompanying materials |
4 |
* are made available under the terms of the Common Public License v0.5 |
4 |
* are made available under the terms of the Common Public License v0.5 |
5 |
* which accompanies this distribution, and is available at |
5 |
* which accompanies this distribution, and is available at |
6 |
* http://www.eclipse.org/legal/cpl-v05.html |
6 |
* http://www.eclipse.org/legal/cpl-v05.html |
7 |
* |
7 |
* |
8 |
* Contributors: |
8 |
* Contributors: |
9 |
* IBM Corporation - initial API and implementation |
9 |
* IBM Corporation - initial API and implementation |
10 |
******************************************************************************/ |
10 |
******************************************************************************/ |
11 |
package org.eclipse.jdt.internal.core.builder; |
11 |
package org.eclipse.jdt.internal.core.builder; |
12 |
|
12 |
|
13 |
import org.eclipse.core.resources.*; |
13 |
import org.eclipse.core.resources.*; |
14 |
import org.eclipse.core.runtime.*; |
14 |
import org.eclipse.core.runtime.*; |
15 |
|
15 |
|
16 |
import org.eclipse.jdt.core.compiler.IProblem; |
16 |
import org.eclipse.jdt.core.compiler.IProblem; |
17 |
import org.eclipse.jdt.internal.compiler.*; |
17 |
import org.eclipse.jdt.internal.compiler.*; |
18 |
import org.eclipse.jdt.internal.compiler.classfmt.*; |
18 |
import org.eclipse.jdt.internal.compiler.classfmt.*; |
19 |
import org.eclipse.jdt.internal.compiler.util.CharOperation; |
19 |
import org.eclipse.jdt.internal.compiler.util.CharOperation; |
20 |
import org.eclipse.jdt.internal.core.Util; |
20 |
import org.eclipse.jdt.internal.core.Util; |
21 |
|
21 |
|
22 |
import java.util.*; |
22 |
import java.util.*; |
23 |
|
23 |
|
24 |
/** |
24 |
/** |
25 |
* The incremental image builder |
25 |
* The incremental image builder |
26 |
*/ |
26 |
*/ |
27 |
public class IncrementalImageBuilder extends AbstractImageBuilder { |
27 |
public class IncrementalImageBuilder extends AbstractImageBuilder { |
28 |
|
28 |
|
29 |
protected ArrayList locations; |
29 |
protected ArrayList locations; |
30 |
protected ArrayList previousLocations; |
30 |
protected ArrayList previousLocations; |
31 |
protected ArrayList typeNames; |
31 |
protected ArrayList typeNames; |
32 |
protected ArrayList qualifiedStrings; |
32 |
protected ArrayList qualifiedStrings; |
33 |
protected ArrayList simpleStrings; |
33 |
protected ArrayList simpleStrings; |
34 |
protected ArrayList secondaryTypesToRemove; |
34 |
protected ArrayList secondaryTypesToRemove; |
35 |
|
35 |
|
36 |
public static int MaxCompileLoop = 5; // perform a full build if it takes more than ? incremental compile loops |
36 |
public static int MaxCompileLoop = 5; // perform a full build if it takes more than ? incremental compile loops |
37 |
|
37 |
|
38 |
protected IncrementalImageBuilder(JavaBuilder javaBuilder) { |
38 |
protected IncrementalImageBuilder(JavaBuilder javaBuilder) { |
39 |
super(javaBuilder); |
39 |
super(javaBuilder); |
40 |
this.nameEnvironment.tagAsIncrementalBuild(); |
40 |
this.nameEnvironment.tagAsIncrementalBuild(); |
41 |
this.newState.copyFrom(javaBuilder.lastState); |
41 |
this.newState.copyFrom(javaBuilder.lastState); |
42 |
|
42 |
|
43 |
this.locations = new ArrayList(33); |
43 |
this.locations = new ArrayList(33); |
44 |
this.previousLocations = null; |
44 |
this.previousLocations = null; |
45 |
this.typeNames = new ArrayList(33); |
45 |
this.typeNames = new ArrayList(33); |
46 |
this.qualifiedStrings = new ArrayList(33); |
46 |
this.qualifiedStrings = new ArrayList(33); |
47 |
this.simpleStrings = new ArrayList(33); |
47 |
this.simpleStrings = new ArrayList(33); |
48 |
} |
48 |
} |
49 |
|
49 |
|
50 |
public boolean build(SimpleLookupTable deltas) { |
50 |
public boolean build(SimpleLookupTable deltas) { |
51 |
// initialize builder |
51 |
// initialize builder |
52 |
// walk this project's deltas, find changed source files |
52 |
// walk this project's deltas, find changed source files |
53 |
// walk prereq projects' deltas, find changed class files & add affected source files |
53 |
// walk prereq projects' deltas, find changed class files & add affected source files |
54 |
// use the build state # to skip the deltas for certain prereq projects |
54 |
// use the build state # to skip the deltas for certain prereq projects |
55 |
// ignore changed zip/jar files since they caused a full build |
55 |
// ignore changed zip/jar files since they caused a full build |
56 |
// compile the source files & acceptResult() |
56 |
// compile the source files & acceptResult() |
57 |
// compare the produced class files against the existing ones on disk |
57 |
// compare the produced class files against the existing ones on disk |
58 |
// recompile all dependent source files of any type with structural changes or new/removed secondary type |
58 |
// recompile all dependent source files of any type with structural changes or new/removed secondary type |
59 |
// keep a loop counter to abort & perform a full build |
59 |
// keep a loop counter to abort & perform a full build |
60 |
|
60 |
|
61 |
if (JavaBuilder.DEBUG) |
61 |
if (JavaBuilder.DEBUG) |
62 |
System.out.println("INCREMENTAL build"); //$NON-NLS-1$ |
62 |
System.out.println("INCREMENTAL build"); //$NON-NLS-1$ |
63 |
|
63 |
|
64 |
try { |
64 |
try { |
65 |
resetCollections(); |
65 |
resetCollections(); |
66 |
|
66 |
|
67 |
notifier.subTask(Util.bind("build.analyzingDeltas")); //$NON-NLS-1$ |
67 |
notifier.subTask(Util.bind("build.analyzingDeltas")); //$NON-NLS-1$ |
68 |
IResourceDelta sourceDelta = (IResourceDelta) deltas.get(javaBuilder.currentProject); |
68 |
IResourceDelta sourceDelta = (IResourceDelta) deltas.get(javaBuilder.currentProject); |
69 |
if (sourceDelta != null) |
69 |
if (sourceDelta != null) |
70 |
if (!findSourceFiles(sourceDelta)) return false; |
70 |
if (!findSourceFiles(sourceDelta)) return false; |
71 |
notifier.updateProgressDelta(0.10f); |
71 |
notifier.updateProgressDelta(0.10f); |
72 |
|
72 |
|
73 |
Object[] keyTable = deltas.keyTable; |
73 |
Object[] keyTable = deltas.keyTable; |
74 |
Object[] valueTable = deltas.valueTable; |
74 |
Object[] valueTable = deltas.valueTable; |
75 |
for (int i = 0, l = keyTable.length; i < l; i++) { |
75 |
for (int i = 0, l = keyTable.length; i < l; i++) { |
76 |
IResourceDelta delta = (IResourceDelta) valueTable[i]; |
76 |
IResourceDelta delta = (IResourceDelta) valueTable[i]; |
77 |
if (delta != null) { |
77 |
if (delta != null) { |
78 |
IResource[] binaryResources = (IResource[]) javaBuilder.binaryResources.get(keyTable[i]); |
78 |
IResource[] binaryResources = (IResource[]) javaBuilder.binaryResources.get(keyTable[i]); |
79 |
if (binaryResources != null) |
79 |
if (binaryResources != null) |
80 |
if (!findAffectedSourceFiles(delta, binaryResources)) return false; |
80 |
if (!findAffectedSourceFiles(delta, binaryResources)) return false; |
81 |
} |
81 |
} |
82 |
} |
82 |
} |
83 |
notifier.updateProgressDelta(0.10f); |
83 |
notifier.updateProgressDelta(0.10f); |
84 |
|
84 |
|
85 |
notifier.subTask(Util.bind("build.analyzingSources")); //$NON-NLS-1$ |
85 |
notifier.subTask(Util.bind("build.analyzingSources")); //$NON-NLS-1$ |
86 |
addAffectedSourceFiles(); |
86 |
addAffectedSourceFiles(); |
87 |
notifier.updateProgressDelta(0.05f); |
87 |
notifier.updateProgressDelta(0.05f); |
88 |
|
88 |
|
89 |
int compileLoop = 0; |
89 |
int compileLoop = 0; |
90 |
float increment = 0.40f; |
90 |
float increment = 0.40f; |
91 |
while (locations.size() > 0) { // added to in acceptResult |
91 |
while (locations.size() > 0) { // added to in acceptResult |
92 |
if (++compileLoop > MaxCompileLoop) { |
92 |
if (++compileLoop > MaxCompileLoop) { |
93 |
if (JavaBuilder.DEBUG) |
93 |
if (JavaBuilder.DEBUG) |
94 |
System.out.println("ABORTING incremental build... exceeded loop count"); //$NON-NLS-1$ |
94 |
System.out.println("ABORTING incremental build... exceeded loop count"); //$NON-NLS-1$ |
95 |
return false; |
95 |
return false; |
96 |
} |
96 |
} |
97 |
notifier.checkCancel(); |
97 |
notifier.checkCancel(); |
98 |
|
98 |
|
99 |
String[] allSourceFiles = new String[locations.size()]; |
99 |
String[] allSourceFiles = new String[locations.size()]; |
100 |
locations.toArray(allSourceFiles); |
100 |
locations.toArray(allSourceFiles); |
101 |
String[] initialTypeStrings = new String[typeNames.size()]; |
101 |
String[] initialTypeStrings = new String[typeNames.size()]; |
102 |
typeNames.toArray(initialTypeStrings); |
102 |
typeNames.toArray(initialTypeStrings); |
103 |
resetCollections(); |
103 |
resetCollections(); |
104 |
|
104 |
|
105 |
workQueue.addAll(allSourceFiles); |
105 |
workQueue.addAll(allSourceFiles); |
106 |
notifier.setProgressPerCompilationUnit(increment / allSourceFiles.length); |
106 |
notifier.setProgressPerCompilationUnit(increment / allSourceFiles.length); |
107 |
increment = increment / 2; |
107 |
increment = increment / 2; |
108 |
compile(allSourceFiles, initialTypeStrings); |
108 |
compile(allSourceFiles, initialTypeStrings); |
109 |
removeSecondaryTypes(); |
109 |
removeSecondaryTypes(); |
110 |
addAffectedSourceFiles(); |
110 |
addAffectedSourceFiles(); |
111 |
} |
111 |
} |
112 |
} catch (AbortIncrementalBuildException e) { |
112 |
} catch (AbortIncrementalBuildException e) { |
113 |
// abort the incremental build and let the batch builder handle the problem |
113 |
// abort the incremental build and let the batch builder handle the problem |
114 |
if (JavaBuilder.DEBUG) |
114 |
if (JavaBuilder.DEBUG) |
115 |
System.out.println("ABORTING incremental build... cannot find " + e.qualifiedTypeName + //$NON-NLS-1$ |
115 |
System.out.println("ABORTING incremental build... cannot find " + e.qualifiedTypeName + //$NON-NLS-1$ |
116 |
". Could have been renamed inside its existing source file."); //$NON-NLS-1$ |
116 |
". Could have been renamed inside its existing source file."); //$NON-NLS-1$ |
117 |
return false; |
117 |
return false; |
118 |
} catch (CoreException e) { |
118 |
} catch (CoreException e) { |
119 |
throw internalException(e); |
119 |
throw internalException(e); |
120 |
} finally { |
120 |
} finally { |
121 |
cleanUp(); |
121 |
cleanUp(); |
122 |
} |
122 |
} |
123 |
return true; |
123 |
return true; |
124 |
} |
124 |
} |
125 |
|
125 |
|
126 |
protected void addAffectedSourceFiles() { |
126 |
protected void addAffectedSourceFiles() { |
127 |
if (qualifiedStrings.isEmpty() && simpleStrings.isEmpty()) return; |
127 |
if (qualifiedStrings.isEmpty() && simpleStrings.isEmpty()) return; |
128 |
|
128 |
|
129 |
// the qualifiedStrings are of the form 'p1/p2' & the simpleStrings are just 'X' |
129 |
// the qualifiedStrings are of the form 'p1/p2' & the simpleStrings are just 'X' |
130 |
char[][][] qualifiedNames = ReferenceCollection.internQualifiedNames(qualifiedStrings); |
130 |
char[][][] qualifiedNames = ReferenceCollection.internQualifiedNames(qualifiedStrings); |
131 |
// if a well known qualified name was found then we can skip over these |
131 |
// if a well known qualified name was found then we can skip over these |
132 |
if (qualifiedNames.length < qualifiedStrings.size()) |
132 |
if (qualifiedNames.length < qualifiedStrings.size()) |
133 |
qualifiedNames = null; |
133 |
qualifiedNames = null; |
134 |
char[][] simpleNames = ReferenceCollection.internSimpleNames(simpleStrings); |
134 |
char[][] simpleNames = ReferenceCollection.internSimpleNames(simpleStrings); |
135 |
// if a well known name was found then we can skip over these |
135 |
// if a well known name was found then we can skip over these |
136 |
if (simpleNames.length < simpleStrings.size()) |
136 |
if (simpleNames.length < simpleStrings.size()) |
137 |
simpleNames = null; |
137 |
simpleNames = null; |
138 |
|
138 |
|
139 |
Object[] keyTable = newState.references.keyTable; |
139 |
Object[] keyTable = newState.references.keyTable; |
140 |
Object[] valueTable = newState.references.valueTable; |
140 |
Object[] valueTable = newState.references.valueTable; |
141 |
next : for (int i = 0, l = keyTable.length; i < l; i++) { |
141 |
next : for (int i = 0, l = keyTable.length; i < l; i++) { |
142 |
String sourceLocation = (String) keyTable[i]; |
142 |
String sourceLocation = (String) keyTable[i]; |
143 |
if (sourceLocation != null && !locations.contains(sourceLocation)) { |
143 |
if (sourceLocation != null && !locations.contains(sourceLocation)) { |
144 |
if (compiledAllAtOnce && previousLocations != null && previousLocations.contains(sourceLocation)) |
144 |
if (compiledAllAtOnce && previousLocations != null && previousLocations.contains(sourceLocation)) |
145 |
continue next; // can skip previously compiled locations since already saw hierarchy related problems |
145 |
continue next; // can skip previously compiled locations since already saw hierarchy related problems |
146 |
|
146 |
|
147 |
ReferenceCollection refs = (ReferenceCollection) valueTable[i]; |
147 |
ReferenceCollection refs = (ReferenceCollection) valueTable[i]; |
148 |
if (refs.includes(qualifiedNames, simpleNames)) { |
148 |
if (refs.includes(qualifiedNames, simpleNames)) { |
149 |
// check that the file still exists... the file or its package may have been deleted |
149 |
// check that the file still exists... the file or its package may have been deleted |
150 |
IResource affectedFile = resourceForLocation(sourceLocation); |
150 |
IResource affectedFile = resourceForLocation(sourceLocation); |
151 |
if (affectedFile != null && affectedFile.exists()) { |
151 |
if (affectedFile != null && affectedFile.exists()) { |
152 |
if (JavaBuilder.DEBUG) |
152 |
if (JavaBuilder.DEBUG) |
153 |
System.out.println(" adding affected source file " + sourceLocation); //$NON-NLS-1$ |
153 |
System.out.println(" adding affected source file " + sourceLocation); //$NON-NLS-1$ |
154 |
locations.add(sourceLocation); |
154 |
locations.add(sourceLocation); |
155 |
typeNames.add(extractTypeNameFrom(sourceLocation)); |
155 |
typeNames.add(extractTypeNameFrom(sourceLocation)); |
156 |
} |
156 |
} |
157 |
} |
157 |
} |
158 |
} |
158 |
} |
159 |
} |
159 |
} |
160 |
} |
160 |
} |
161 |
|
161 |
|
162 |
protected void addDependentsOf(IPath path, boolean hasStructuralChanges) { |
162 |
protected void addDependentsOf(IPath path, boolean hasStructuralChanges) { |
163 |
if (hasStructuralChanges) |
163 |
if (hasStructuralChanges) |
164 |
newState.tagAsStructurallyChanged(); |
164 |
newState.tagAsStructurallyChanged(); |
165 |
// the qualifiedStrings are of the form 'p1/p1' & the simpleStrings are just 'X' |
165 |
// the qualifiedStrings are of the form 'p1/p1' & the simpleStrings are just 'X' |
166 |
path = path.setDevice(null); |
166 |
path = path.setDevice(null); |
167 |
String packageName = path.uptoSegment(path.segmentCount() - 1).toString(); |
167 |
String packageName = path.uptoSegment(path.segmentCount() - 1).toString(); |
168 |
if (!qualifiedStrings.contains(packageName)) |
168 |
if (!qualifiedStrings.contains(packageName)) |
169 |
qualifiedStrings.add(packageName); |
169 |
qualifiedStrings.add(packageName); |
170 |
String typeName = path.lastSegment(); |
170 |
String typeName = path.lastSegment(); |
171 |
int memberIndex = typeName.indexOf('$'); |
171 |
int memberIndex = typeName.indexOf('$'); |
172 |
if (memberIndex > 0) |
172 |
if (memberIndex > 0) |
173 |
typeName = typeName.substring(0, memberIndex); |
173 |
typeName = typeName.substring(0, memberIndex); |
174 |
if (!simpleStrings.contains(typeName)) { |
174 |
if (!simpleStrings.contains(typeName)) { |
175 |
if (JavaBuilder.DEBUG) |
175 |
if (JavaBuilder.DEBUG) |
176 |
System.out.println(" adding dependents of " //$NON-NLS-1$ |
176 |
System.out.println(" adding dependents of " //$NON-NLS-1$ |
177 |
+ typeName + " in " + packageName); //$NON-NLS-1$ |
177 |
+ typeName + " in " + packageName); //$NON-NLS-1$ |
178 |
simpleStrings.add(typeName); |
178 |
simpleStrings.add(typeName); |
179 |
} |
179 |
} |
180 |
} |
180 |
} |
181 |
|
181 |
|
182 |
protected void cleanUp() { |
182 |
protected void cleanUp() { |
183 |
super.cleanUp(); |
183 |
super.cleanUp(); |
184 |
|
184 |
|
185 |
this.locations = null; |
185 |
this.locations = null; |
186 |
this.previousLocations = null; |
186 |
this.previousLocations = null; |
187 |
this.typeNames = null; |
187 |
this.typeNames = null; |
188 |
this.qualifiedStrings = null; |
188 |
this.qualifiedStrings = null; |
189 |
this.simpleStrings = null; |
189 |
this.simpleStrings = null; |
190 |
} |
190 |
} |
191 |
|
191 |
|
192 |
protected boolean findAffectedSourceFiles(IResourceDelta delta, IResource[] binaryResources) { |
192 |
protected boolean findAffectedSourceFiles(IResourceDelta delta, IResource[] binaryResources) { |
193 |
for (int j = 0, k = binaryResources.length; j < k; j++) { |
193 |
for (int j = 0, k = binaryResources.length; j < k; j++) { |
194 |
IResource binaryResource = binaryResources[j]; |
194 |
IResource binaryResource = binaryResources[j]; |
195 |
// either a .class file folder or a zip/jar file |
195 |
// either a .class file folder or a zip/jar file |
196 |
if (binaryResource != null) { // skip unchanged output folder |
196 |
if (binaryResource != null) { // skip unchanged output folder |
197 |
IResourceDelta binaryDelta = delta.findMember(binaryResource.getProjectRelativePath()); |
197 |
IResourceDelta binaryDelta = delta.findMember(binaryResource.getProjectRelativePath()); |
198 |
if (binaryDelta != null) { |
198 |
if (binaryDelta != null) { |
199 |
if (binaryResource instanceof IFile) { |
199 |
if (binaryResource instanceof IFile) { |
200 |
if (JavaBuilder.DEBUG) |
200 |
if (JavaBuilder.DEBUG) |
201 |
System.out.println("ABORTING incremental build... found delta to jar/zip file"); //$NON-NLS-1$ |
201 |
System.out.println("ABORTING incremental build... found delta to jar/zip file"); //$NON-NLS-1$ |
202 |
return false; // do full build since jar file was added/removed/changed |
202 |
return false; // do full build since jar file was added/removed/changed |
203 |
} |
203 |
} |
204 |
if (binaryDelta.getKind() == IResourceDelta.ADDED || binaryDelta.getKind() == IResourceDelta.REMOVED) { |
204 |
if (binaryDelta.getKind() == IResourceDelta.ADDED || binaryDelta.getKind() == IResourceDelta.REMOVED) { |
205 |
if (JavaBuilder.DEBUG) |
205 |
if (JavaBuilder.DEBUG) |
206 |
System.out.println("ABORTING incremental build... found added/removed binary folder"); //$NON-NLS-1$ |
206 |
System.out.println("ABORTING incremental build... found added/removed binary folder"); //$NON-NLS-1$ |
207 |
return false; // added/removed binary folder should not make it here, but handle anyways |
207 |
return false; // added/removed binary folder should not make it here, but handle anyways |
208 |
} |
208 |
} |
209 |
int segmentCount = binaryResource.getLocation().segmentCount(); |
209 |
int segmentCount = binaryResource.getLocation().segmentCount(); |
210 |
IResourceDelta[] children = binaryDelta.getAffectedChildren(); // .class files from class folder |
210 |
IResourceDelta[] children = binaryDelta.getAffectedChildren(); // .class files from class folder |
211 |
for (int i = 0, length = children.length; i < length; ++i) |
211 |
for (int i = 0, length = children.length; i < length; ++i) |
212 |
findAffectedSourceFiles(children[i], segmentCount); |
212 |
findAffectedSourceFiles(children[i], segmentCount); |
213 |
notifier.checkCancel(); |
213 |
notifier.checkCancel(); |
214 |
} |
214 |
} |
215 |
} |
215 |
} |
216 |
} |
216 |
} |
217 |
return true; |
217 |
return true; |
218 |
} |
218 |
} |
219 |
|
219 |
|
220 |
protected void findAffectedSourceFiles(IResourceDelta binaryDelta, int segmentCount) { |
220 |
protected void findAffectedSourceFiles(IResourceDelta binaryDelta, int segmentCount) { |
221 |
// When a package becomes a type or vice versa, expect 2 deltas, |
221 |
// When a package becomes a type or vice versa, expect 2 deltas, |
222 |
// one on the folder & one on the class file |
222 |
// one on the folder & one on the class file |
223 |
IResource resource = binaryDelta.getResource(); |
223 |
IResource resource = binaryDelta.getResource(); |
224 |
IPath location = resource.getLocation(); |
224 |
IPath location = resource.getLocation(); |
225 |
switch(resource.getType()) { |
225 |
switch(resource.getType()) { |
226 |
case IResource.PROJECT : |
226 |
case IResource.PROJECT : |
227 |
case IResource.FOLDER : |
227 |
case IResource.FOLDER : |
228 |
switch (binaryDelta.getKind()) { |
228 |
switch (binaryDelta.getKind()) { |
229 |
case IResourceDelta.ADDED : |
229 |
case IResourceDelta.ADDED : |
230 |
case IResourceDelta.REMOVED : |
230 |
case IResourceDelta.REMOVED : |
231 |
IPath packagePath = location.removeFirstSegments(segmentCount).makeRelative().setDevice(null); |
231 |
IPath packagePath = location.removeFirstSegments(segmentCount).makeRelative().setDevice(null); |
232 |
String packageName = packagePath.toString(); |
232 |
String packageName = packagePath.toString(); |
233 |
if (binaryDelta.getKind() == IResourceDelta.ADDED) { |
233 |
if (binaryDelta.getKind() == IResourceDelta.ADDED) { |
234 |
// see if any known source file is from the same package... classpath already includes new package |
234 |
// see if any known source file is from the same package... classpath already includes new package |
235 |
if (!newState.isKnownPackage(packageName)) { |
235 |
if (!newState.isKnownPackage(packageName)) { |
236 |
if (JavaBuilder.DEBUG) |
236 |
if (JavaBuilder.DEBUG) |
237 |
System.out.println("Add dependents of added package " + packageName); //$NON-NLS-1$ |
237 |
System.out.println("Add dependents of added package " + packageName); //$NON-NLS-1$ |
238 |
addDependentsOf(packagePath, false); |
238 |
addDependentsOf(packagePath, false); |
239 |
return; |
239 |
return; |
240 |
} |
240 |
} |
241 |
if (JavaBuilder.DEBUG) |
241 |
if (JavaBuilder.DEBUG) |
242 |
System.out.println("Skipped dependents of added package " + packageName); //$NON-NLS-1$ |
242 |
System.out.println("Skipped dependents of added package " + packageName); //$NON-NLS-1$ |
243 |
} else { |
243 |
} else { |
244 |
// see if the package still exists on the classpath |
244 |
// see if the package still exists on the classpath |
245 |
if (!nameEnvironment.isPackage(packageName)) { |
245 |
if (!nameEnvironment.isPackage(packageName)) { |
246 |
if (JavaBuilder.DEBUG) |
246 |
if (JavaBuilder.DEBUG) |
247 |
System.out.println("Add dependents of removed package " + packageName); //$NON-NLS-1$ |
247 |
System.out.println("Add dependents of removed package " + packageName); //$NON-NLS-1$ |
248 |
addDependentsOf(packagePath, false); |
248 |
addDependentsOf(packagePath, false); |
249 |
return; |
249 |
return; |
250 |
} |
250 |
} |
251 |
if (JavaBuilder.DEBUG) |
251 |
if (JavaBuilder.DEBUG) |
252 |
System.out.println("Skipped dependents of removed package " + packageName); //$NON-NLS-1$ |
252 |
System.out.println("Skipped dependents of removed package " + packageName); //$NON-NLS-1$ |
253 |
} |
253 |
} |
254 |
// fall thru & traverse the sub-packages and .class files |
254 |
// fall thru & traverse the sub-packages and .class files |
255 |
case IResourceDelta.CHANGED : |
255 |
case IResourceDelta.CHANGED : |
256 |
IResourceDelta[] children = binaryDelta.getAffectedChildren(); |
256 |
IResourceDelta[] children = binaryDelta.getAffectedChildren(); |
257 |
for (int i = 0, length = children.length; i < length; i++) |
257 |
for (int i = 0, length = children.length; i < length; i++) |
258 |
findAffectedSourceFiles(children[i], segmentCount); |
258 |
findAffectedSourceFiles(children[i], segmentCount); |
259 |
} |
259 |
} |
260 |
return; |
260 |
return; |
261 |
case IResource.FILE : |
261 |
case IResource.FILE : |
262 |
if (JavaBuilder.CLASS_EXTENSION.equalsIgnoreCase(location.getFileExtension())) { |
262 |
if (JavaBuilder.CLASS_EXTENSION.equalsIgnoreCase(location.getFileExtension())) { |
263 |
IPath typePath = location.removeFirstSegments(segmentCount).removeFileExtension().makeRelative().setDevice(null); |
263 |
IPath typePath = location.removeFirstSegments(segmentCount).removeFileExtension().makeRelative().setDevice(null); |
264 |
switch (binaryDelta.getKind()) { |
264 |
switch (binaryDelta.getKind()) { |
265 |
case IResourceDelta.ADDED : |
265 |
case IResourceDelta.ADDED : |
266 |
case IResourceDelta.REMOVED : |
266 |
case IResourceDelta.REMOVED : |
267 |
if (JavaBuilder.DEBUG) |
267 |
if (JavaBuilder.DEBUG) |
268 |
System.out.println("Add dependents of added/removed class file " + typePath); //$NON-NLS-1$ |
268 |
System.out.println("Add dependents of added/removed class file " + typePath); //$NON-NLS-1$ |
269 |
addDependentsOf(typePath, false); |
269 |
addDependentsOf(typePath, false); |
270 |
return; |
270 |
return; |
271 |
case IResourceDelta.CHANGED : |
271 |
case IResourceDelta.CHANGED : |
272 |
if ((binaryDelta.getFlags() & IResourceDelta.CONTENT) == 0) |
272 |
if ((binaryDelta.getFlags() & IResourceDelta.CONTENT) == 0) |
273 |
return; // skip it since it really isn't changed |
273 |
return; // skip it since it really isn't changed |
274 |
if (JavaBuilder.DEBUG) |
274 |
if (JavaBuilder.DEBUG) |
275 |
System.out.println("Add dependents of changed class file " + typePath); //$NON-NLS-1$ |
275 |
System.out.println("Add dependents of changed class file " + typePath); //$NON-NLS-1$ |
276 |
addDependentsOf(typePath, false); |
276 |
addDependentsOf(typePath, false); |
277 |
} |
277 |
} |
278 |
return; |
278 |
return; |
279 |
} |
279 |
} |
280 |
} |
280 |
} |
281 |
} |
281 |
} |
282 |
|
282 |
|
283 |
protected boolean findSourceFiles(IResourceDelta delta) throws CoreException { |
283 |
protected boolean findSourceFiles(IResourceDelta delta) throws CoreException { |
284 |
for (int i = 0, length = sourceFolders.length; i < length; i++) { |
284 |
for (int i = 0, length = sourceFolders.length; i < length; i++) { |
285 |
IResourceDelta sourceDelta = delta.findMember(sourceFolders[i].getProjectRelativePath()); |
285 |
IResourceDelta sourceDelta = delta.findMember(sourceFolders[i].getProjectRelativePath()); |
286 |
if (sourceDelta != null) { |
286 |
if (sourceDelta != null) { |
287 |
if (sourceDelta.getKind() == IResourceDelta.REMOVED) { |
287 |
if (sourceDelta.getKind() == IResourceDelta.REMOVED) { |
288 |
if (JavaBuilder.DEBUG) |
288 |
if (JavaBuilder.DEBUG) |
289 |
System.out.println("ABORTING incremental build... found removed source folder"); //$NON-NLS-1$ |
289 |
System.out.println("ABORTING incremental build... found removed source folder"); //$NON-NLS-1$ |
290 |
return false; // removed source folder should not make it here, but handle anyways (ADDED is supported) |
290 |
return false; // removed source folder should not make it here, but handle anyways (ADDED is supported) |
291 |
} |
291 |
} |
292 |
int segmentCount = sourceFolders[i].getLocation().segmentCount(); |
292 |
int segmentCount = sourceFolders[i].getLocation().segmentCount(); |
293 |
IResourceDelta[] children = sourceDelta.getAffectedChildren(); |
293 |
IResourceDelta[] children = sourceDelta.getAffectedChildren(); |
294 |
for (int c = 0, clength = children.length; c < clength; c++) |
294 |
for (int c = 0, clength = children.length; c < clength; c++) |
295 |
findSourceFiles(children[c], segmentCount); |
295 |
findSourceFiles(children[c], segmentCount); |
296 |
notifier.checkCancel(); |
296 |
notifier.checkCancel(); |
297 |
} |
297 |
} |
298 |
} |
298 |
} |
299 |
return true; |
299 |
return true; |
300 |
} |
300 |
} |
301 |
|
301 |
|
302 |
protected void findSourceFiles(IResourceDelta sourceDelta, int segmentCount) throws CoreException { |
302 |
protected void findSourceFiles(IResourceDelta sourceDelta, int segmentCount) throws CoreException { |
303 |
// When a package becomes a type or vice versa, expect 2 deltas, |
303 |
// When a package becomes a type or vice versa, expect 2 deltas, |
304 |
// one on the folder & one on the source file |
304 |
// one on the folder & one on the source file |
305 |
IResource resource = sourceDelta.getResource(); |
305 |
IResource resource = sourceDelta.getResource(); |
306 |
IPath location = resource.getLocation(); |
306 |
IPath location = resource.getLocation(); |
307 |
switch(resource.getType()) { |
307 |
switch(resource.getType()) { |
308 |
case IResource.PROJECT : |
308 |
case IResource.PROJECT : |
309 |
case IResource.FOLDER : |
309 |
case IResource.FOLDER : |
310 |
switch (sourceDelta.getKind()) { |
310 |
switch (sourceDelta.getKind()) { |
311 |
case IResourceDelta.ADDED : |
311 |
case IResourceDelta.ADDED : |
312 |
IPath addedPackagePath = location.removeFirstSegments(segmentCount).makeRelative().setDevice(null); |
312 |
IPath addedPackagePath = location.removeFirstSegments(segmentCount).makeRelative().setDevice(null); |
313 |
getOutputFolder(addedPackagePath); // ensure package exists in the output folder |
313 |
getOutputFolder(addedPackagePath); // ensure package exists in the output folder |
314 |
// add dependents even when the package thinks it exists to be on the safe side |
314 |
// add dependents even when the package thinks it exists to be on the safe side |
315 |
if (JavaBuilder.DEBUG) |
315 |
if (JavaBuilder.DEBUG) |
316 |
System.out.println("Add dependents of added package " + addedPackagePath); //$NON-NLS-1$ |
316 |
System.out.println("Add dependents of added package " + addedPackagePath); //$NON-NLS-1$ |
317 |
addDependentsOf(addedPackagePath, true); |
317 |
addDependentsOf(addedPackagePath, true); |
318 |
// fall thru & collect all the source files |
318 |
// fall thru & collect all the source files |
319 |
case IResourceDelta.CHANGED : |
319 |
case IResourceDelta.CHANGED : |
320 |
IResourceDelta[] children = sourceDelta.getAffectedChildren(); |
320 |
IResourceDelta[] children = sourceDelta.getAffectedChildren(); |
321 |
for (int i = 0, length = children.length; i < length; i++) |
321 |
for (int i = 0, length = children.length; i < length; i++) |
322 |
findSourceFiles(children[i], segmentCount); |
322 |
findSourceFiles(children[i], segmentCount); |
323 |
return; |
323 |
return; |
324 |
case IResourceDelta.REMOVED : |
324 |
case IResourceDelta.REMOVED : |
325 |
IPath removedPackagePath = location.removeFirstSegments(segmentCount).makeRelative().setDevice(null); |
325 |
IPath removedPackagePath = location.removeFirstSegments(segmentCount).makeRelative().setDevice(null); |
326 |
for (int i = 0, length = sourceFolders.length; i < length; i++) { |
326 |
for (int i = 0, length = sourceFolders.length; i < length; i++) { |
327 |
if (sourceFolders[i].findMember(removedPackagePath) != null) { |
327 |
if (sourceFolders[i].findMember(removedPackagePath) != null) { |
328 |
// only a package fragment was removed, same as removing multiple source files |
328 |
// only a package fragment was removed, same as removing multiple source files |
329 |
getOutputFolder(removedPackagePath); // ensure package exists in the output folder |
329 |
getOutputFolder(removedPackagePath); // ensure package exists in the output folder |
330 |
IResourceDelta[] removedChildren = sourceDelta.getAffectedChildren(); |
330 |
IResourceDelta[] removedChildren = sourceDelta.getAffectedChildren(); |
331 |
for (int j = 0, rlength = removedChildren.length; j < rlength; j++) |
331 |
for (int j = 0, rlength = removedChildren.length; j < rlength; j++) |
332 |
findSourceFiles(removedChildren[j], segmentCount); |
332 |
findSourceFiles(removedChildren[j], segmentCount); |
333 |
return; |
333 |
return; |
334 |
} |
334 |
} |
335 |
} |
335 |
} |
336 |
IFolder removedPackageFolder = outputFolder.getFolder(removedPackagePath); |
336 |
IFolder removedPackageFolder = outputFolder.getFolder(removedPackagePath); |
337 |
if (removedPackageFolder.exists()) |
337 |
if (removedPackageFolder.exists()) |
338 |
removedPackageFolder.delete(IResource.FORCE, null); |
338 |
removedPackageFolder.delete(IResource.FORCE, null); |
339 |
// add dependents even when the package thinks it does not exist to be on the safe side |
339 |
// add dependents even when the package thinks it does not exist to be on the safe side |
340 |
if (JavaBuilder.DEBUG) |
340 |
if (JavaBuilder.DEBUG) |
341 |
System.out.println("Add dependents of removed package " + removedPackagePath); //$NON-NLS-1$ |
341 |
System.out.println("Add dependents of removed package " + removedPackagePath); //$NON-NLS-1$ |
342 |
addDependentsOf(removedPackagePath, true); |
342 |
addDependentsOf(removedPackagePath, true); |
343 |
newState.removePackage(sourceDelta); |
343 |
newState.removePackage(sourceDelta); |
344 |
} |
344 |
} |
345 |
return; |
345 |
return; |
346 |
case IResource.FILE : |
346 |
case IResource.FILE : |
347 |
String extension = location.getFileExtension(); |
347 |
String extension = location.getFileExtension(); |
348 |
if (JavaBuilder.JAVA_EXTENSION.equalsIgnoreCase(extension)) { |
348 |
if (JavaBuilder.JAVA_EXTENSION.equalsIgnoreCase(extension)) { |
349 |
IPath typePath = location.removeFirstSegments(segmentCount).removeFileExtension().makeRelative().setDevice(null); |
349 |
IPath typePath = location.removeFirstSegments(segmentCount).removeFileExtension().makeRelative().setDevice(null); |
350 |
String sourceLocation = location.toString(); |
350 |
String sourceLocation = location.toString(); |
351 |
switch (sourceDelta.getKind()) { |
351 |
switch (sourceDelta.getKind()) { |
352 |
case IResourceDelta.ADDED : |
352 |
case IResourceDelta.ADDED : |
353 |
if (JavaBuilder.DEBUG) |
353 |
if (JavaBuilder.DEBUG) |
354 |
System.out.println("Compile this added source file " + sourceLocation); //$NON-NLS-1$ |
354 |
System.out.println("Compile this added source file " + sourceLocation); //$NON-NLS-1$ |
355 |
locations.add(sourceLocation); |
355 |
locations.add(sourceLocation); |
356 |
String typeName = typePath.toString(); |
356 |
String typeName = typePath.toString(); |
357 |
typeNames.add(typeName); |
357 |
typeNames.add(typeName); |
358 |
if (!newState.isDuplicateLocation(typeName, sourceLocation)) { // adding dependents results in 2 duplicate errors |
358 |
if (!newState.isDuplicateLocation(typeName, sourceLocation)) { // adding dependents results in 2 duplicate errors |
359 |
if (JavaBuilder.DEBUG) |
359 |
if (JavaBuilder.DEBUG) |
360 |
System.out.println("Add dependents of added source file " + typeName); //$NON-NLS-1$ |
360 |
System.out.println("Add dependents of added source file " + typeName); //$NON-NLS-1$ |
361 |
addDependentsOf(typePath, true); |
361 |
addDependentsOf(typePath, true); |
362 |
} |
362 |
} |
363 |
return; |
363 |
return; |
364 |
case IResourceDelta.REMOVED : |
364 |
case IResourceDelta.REMOVED : |
365 |
char[][] definedTypeNames = newState.getDefinedTypeNamesFor(sourceLocation); |
365 |
char[][] definedTypeNames = newState.getDefinedTypeNamesFor(sourceLocation); |
366 |
if (definedTypeNames == null) { // defined a single type matching typePath |
366 |
if (definedTypeNames == null) { // defined a single type matching typePath |
367 |
removeClassFile(typePath); |
367 |
removeClassFile(typePath); |
368 |
} else { |
368 |
} else { |
369 |
if (JavaBuilder.DEBUG) |
369 |
if (JavaBuilder.DEBUG) |
370 |
System.out.println("Add dependents of removed source file " + typePath.toString()); //$NON-NLS-1$ |
370 |
System.out.println("Add dependents of removed source file " + typePath.toString()); //$NON-NLS-1$ |
371 |
addDependentsOf(typePath, true); // add dependents of the source file since it may be involved in a name collision |
371 |
addDependentsOf(typePath, true); // add dependents of the source file since it may be involved in a name collision |
372 |
if (definedTypeNames.length > 0) { // skip it if it failed to successfully define a type |
372 |
if (definedTypeNames.length > 0) { // skip it if it failed to successfully define a type |
373 |
IPath packagePath = typePath.removeLastSegments(1); |
373 |
IPath packagePath = typePath.removeLastSegments(1); |
374 |
for (int i = 0, length = definedTypeNames.length; i < length; i++) |
374 |
for (int i = 0, length = definedTypeNames.length; i < length; i++) |
375 |
removeClassFile(packagePath.append(new String(definedTypeNames[i]))); |
375 |
removeClassFile(packagePath.append(new String(definedTypeNames[i]))); |
376 |
} |
376 |
} |
377 |
} |
377 |
} |
378 |
newState.remove(sourceLocation); |
378 |
newState.remove(sourceLocation); |
379 |
return; |
379 |
return; |
380 |
case IResourceDelta.CHANGED : |
380 |
case IResourceDelta.CHANGED : |
381 |
if ((sourceDelta.getFlags() & IResourceDelta.CONTENT) == 0) |
381 |
if ((sourceDelta.getFlags() & IResourceDelta.CONTENT) == 0) |
382 |
return; // skip it since it really isn't changed |
382 |
return; // skip it since it really isn't changed |
383 |
if (JavaBuilder.DEBUG) |
383 |
if (JavaBuilder.DEBUG) |
384 |
System.out.println("Compile this changed source file " + sourceLocation); //$NON-NLS-1$ |
384 |
System.out.println("Compile this changed source file " + sourceLocation); //$NON-NLS-1$ |
385 |
locations.add(sourceLocation); |
385 |
locations.add(sourceLocation); |
386 |
typeNames.add(typePath.toString()); |
386 |
typeNames.add(typePath.toString()); |
387 |
} |
387 |
} |
388 |
return; |
388 |
return; |
389 |
} else if (JavaBuilder.CLASS_EXTENSION.equalsIgnoreCase(extension)) { |
389 |
} else if (JavaBuilder.CLASS_EXTENSION.equalsIgnoreCase(extension)) { |
390 |
return; // skip class files |
390 |
return; // skip class files |
391 |
} else if (hasSeparateOutputFolder) { |
391 |
} else if (hasSeparateOutputFolder) { |
392 |
if (javaBuilder.filterResource(resource)) return; |
392 |
if (javaBuilder.filterResource(resource)) return; |
393 |
|
393 |
|
394 |
// copy all other resource deltas to the output folder |
394 |
// copy all other resource deltas to the output folder |
395 |
IPath resourcePath = location.removeFirstSegments(segmentCount).makeRelative(); |
395 |
IPath resourcePath = location.removeFirstSegments(segmentCount).makeRelative(); |
396 |
IResource outputFile = outputFolder.getFile(resourcePath); |
396 |
IResource outputFile = outputFolder.getFile(resourcePath); |
397 |
switch (sourceDelta.getKind()) { |
397 |
switch (sourceDelta.getKind()) { |
398 |
case IResourceDelta.ADDED : |
398 |
case IResourceDelta.ADDED : |
399 |
if (outputFile.exists()) { |
399 |
if (outputFile.exists()) { |
400 |
if (JavaBuilder.DEBUG) |
400 |
if (JavaBuilder.DEBUG) |
401 |
System.out.println("Deleting existing file " + resourcePath); //$NON-NLS-1$ |
401 |
System.out.println("Deleting existing file " + resourcePath); //$NON-NLS-1$ |
402 |
outputFile.delete(IResource.FORCE, null); |
402 |
outputFile.delete(IResource.FORCE, null); |
403 |
} |
403 |
} |
404 |
if (JavaBuilder.DEBUG) |
404 |
if (JavaBuilder.DEBUG) |
405 |
System.out.println("Copying added file " + resourcePath); //$NON-NLS-1$ |
405 |
System.out.println("Copying added file " + resourcePath); //$NON-NLS-1$ |
406 |
getOutputFolder(resourcePath.removeLastSegments(1)); // ensure package exists in the output folder |
406 |
getOutputFolder(resourcePath.removeLastSegments(1)); // ensure package exists in the output folder |
407 |
resource.copy(outputFile.getFullPath(), IResource.FORCE, null); |
407 |
resource.copy(outputFile.getFullPath(), IResource.FORCE, null); |
408 |
outputFile.setDerived(true); |
408 |
outputFile.setDerived(true); |
409 |
return; |
409 |
return; |
410 |
case IResourceDelta.REMOVED : |
410 |
case IResourceDelta.REMOVED : |
411 |
if (outputFile.exists()) { |
411 |
if (outputFile.exists()) { |
412 |
if (JavaBuilder.DEBUG) |
412 |
if (JavaBuilder.DEBUG) |
413 |
System.out.println("Deleting removed file " + resourcePath); //$NON-NLS-1$ |
413 |
System.out.println("Deleting removed file " + resourcePath); //$NON-NLS-1$ |
414 |
outputFile.delete(IResource.FORCE, null); |
414 |
outputFile.delete(IResource.FORCE, null); |
415 |
} |
415 |
} |
416 |
return; |
416 |
return; |
417 |
case IResourceDelta.CHANGED : |
417 |
case IResourceDelta.CHANGED : |
418 |
if ((sourceDelta.getFlags() & IResourceDelta.CONTENT) == 0) |
418 |
if ((sourceDelta.getFlags() & IResourceDelta.CONTENT) == 0) |
419 |
return; // skip it since it really isn't changed |
419 |
return; // skip it since it really isn't changed |
420 |
if (outputFile.exists()) { |
420 |
if (outputFile.exists()) { |
421 |
if (JavaBuilder.DEBUG) |
421 |
if (JavaBuilder.DEBUG) |
422 |
System.out.println("Deleting existing file " + resourcePath); //$NON-NLS-1$ |
422 |
System.out.println("Deleting existing file " + resourcePath); //$NON-NLS-1$ |
423 |
outputFile.delete(IResource.FORCE, null); |
423 |
outputFile.delete(IResource.FORCE, null); |
424 |
} |
424 |
} |
425 |
if (JavaBuilder.DEBUG) |
425 |
if (JavaBuilder.DEBUG) |
426 |
System.out.println("Copying changed file " + resourcePath); //$NON-NLS-1$ |
426 |
System.out.println("Copying changed file " + resourcePath); //$NON-NLS-1$ |
427 |
getOutputFolder(resourcePath.removeLastSegments(1)); // ensure package exists in the output folder |
427 |
getOutputFolder(resourcePath.removeLastSegments(1)); // ensure package exists in the output folder |
428 |
resource.copy(outputFile.getFullPath(), IResource.FORCE, null); |
428 |
resource.copy(outputFile.getFullPath(), IResource.FORCE, null); |
429 |
outputFile.setDerived(true); |
429 |
outputFile.setDerived(true); |
430 |
} |
430 |
} |
431 |
return; |
431 |
return; |
432 |
} |
432 |
} |
433 |
} |
433 |
} |
434 |
} |
434 |
} |
435 |
|
435 |
|
436 |
protected void finishedWith(String sourceLocation, CompilationResult result, char[] mainTypeName, ArrayList definedTypeNames, ArrayList duplicateTypeNames) throws CoreException { |
436 |
protected void finishedWith(String sourceLocation, CompilationResult result, char[] mainTypeName, ArrayList definedTypeNames, ArrayList duplicateTypeNames) throws CoreException { |
437 |
char[][] previousTypeNames = newState.getDefinedTypeNamesFor(sourceLocation); |
437 |
char[][] previousTypeNames = newState.getDefinedTypeNamesFor(sourceLocation); |
438 |
if (previousTypeNames == null) |
438 |
if (previousTypeNames == null) |
439 |
previousTypeNames = new char[][] {mainTypeName}; |
439 |
previousTypeNames = new char[][] {mainTypeName}; |
440 |
IPath packagePath = null; |
440 |
IPath packagePath = null; |
441 |
next : for (int i = 0, x = previousTypeNames.length; i < x; i++) { |
441 |
next : for (int i = 0, x = previousTypeNames.length; i < x; i++) { |
442 |
char[] previous = previousTypeNames[i]; |
442 |
char[] previous = previousTypeNames[i]; |
443 |
for (int j = 0, y = definedTypeNames.size(); j < y; j++) |
443 |
for (int j = 0, y = definedTypeNames.size(); j < y; j++) |
444 |
if (CharOperation.equals(previous, (char[]) definedTypeNames.get(j))) |
444 |
if (CharOperation.equals(previous, (char[]) definedTypeNames.get(j))) |
445 |
continue next; |
445 |
continue next; |
446 |
|
446 |
|
447 |
if (packagePath == null) |
447 |
if (packagePath == null) |
448 |
packagePath = new Path(extractTypeNameFrom(sourceLocation)).removeLastSegments(1); |
448 |
packagePath = new Path(extractTypeNameFrom(sourceLocation)).removeLastSegments(1); |
449 |
if (secondaryTypesToRemove == null) |
449 |
if (secondaryTypesToRemove == null) |
450 |
this.secondaryTypesToRemove = new ArrayList(); |
450 |
this.secondaryTypesToRemove = new ArrayList(); |
451 |
secondaryTypesToRemove.add(packagePath.append(new String(previous))); |
451 |
secondaryTypesToRemove.add(packagePath.append(new String(previous))); |
452 |
} |
452 |
} |
453 |
super.finishedWith(sourceLocation, result, mainTypeName, definedTypeNames, duplicateTypeNames); |
453 |
super.finishedWith(sourceLocation, result, mainTypeName, definedTypeNames, duplicateTypeNames); |
454 |
} |
454 |
} |
455 |
|
455 |
|
456 |
protected void removeClassFile(IPath typePath) throws CoreException { |
456 |
protected void removeClassFile(IPath typePath) throws CoreException { |
457 |
if (typePath.lastSegment().indexOf('$') == -1) { // is not a nested type |
457 |
if (typePath.lastSegment().indexOf('$') == -1) { // is not a nested type |
458 |
newState.removeTypeLocation(typePath.toString()); |
458 |
newState.removeTypeLocation(typePath.toString()); |
459 |
// add dependents even when the type thinks it does not exist to be on the safe side |
459 |
// add dependents even when the type thinks it does not exist to be on the safe side |
460 |
if (JavaBuilder.DEBUG) |
460 |
if (JavaBuilder.DEBUG) |
461 |
System.out.println("Add dependents of removed type " + typePath); //$NON-NLS-1$ |
461 |
System.out.println("Add dependents of removed type " + typePath); //$NON-NLS-1$ |
462 |
addDependentsOf(typePath, true); // when member types are removed, their enclosing type is structurally changed |
462 |
addDependentsOf(typePath, true); // when member types are removed, their enclosing type is structurally changed |
463 |
} |
463 |
} |
464 |
IFile classFile = outputFolder.getFile(typePath.addFileExtension(JavaBuilder.CLASS_EXTENSION)); |
464 |
IFile classFile = outputFolder.getFile(typePath.addFileExtension(JavaBuilder.CLASS_EXTENSION)); |
465 |
if (classFile.exists()) { |
465 |
if (classFile.exists()) { |
466 |
if (JavaBuilder.DEBUG) |
466 |
if (JavaBuilder.DEBUG) |
467 |
System.out.println("Deleting class file of removed type " + typePath); //$NON-NLS-1$ |
467 |
System.out.println("Deleting class file of removed type " + typePath); //$NON-NLS-1$ |
468 |
classFile.delete(IResource.FORCE, null); |
468 |
classFile.delete(IResource.FORCE, null); |
469 |
} |
469 |
} |
470 |
} |
470 |
} |
471 |
|
471 |
|
472 |
protected void removeSecondaryTypes() throws CoreException { |
472 |
protected void removeSecondaryTypes() throws CoreException { |
473 |
if (secondaryTypesToRemove != null) { // delayed deleting secondary types until the end of the compile loop |
473 |
if (secondaryTypesToRemove != null) { // delayed deleting secondary types until the end of the compile loop |
474 |
for (int i = 0, length = secondaryTypesToRemove.size(); i < length; i++) |
474 |
for (int i = 0, length = secondaryTypesToRemove.size(); i < length; i++) |
475 |
removeClassFile((IPath) secondaryTypesToRemove.get(i)); |
475 |
removeClassFile((IPath) secondaryTypesToRemove.get(i)); |
476 |
this.secondaryTypesToRemove = null; |
476 |
this.secondaryTypesToRemove = null; |
477 |
if (previousLocations != null && previousLocations.size() > 1) |
477 |
if (previousLocations != null && previousLocations.size() > 1) |
478 |
this.previousLocations = null; // cannot optimize recompile case when a secondary type is deleted |
478 |
this.previousLocations = null; // cannot optimize recompile case when a secondary type is deleted |
479 |
} |
479 |
} |
480 |
} |
480 |
} |
481 |
|
481 |
|
482 |
protected void resetCollections() { |
482 |
protected void resetCollections() { |
483 |
previousLocations = locations.isEmpty() ? null : (ArrayList) locations.clone(); |
483 |
previousLocations = locations.isEmpty() ? null : (ArrayList) locations.clone(); |
484 |
|
484 |
|
485 |
locations.clear(); |
485 |
locations.clear(); |
486 |
typeNames.clear(); |
486 |
typeNames.clear(); |
487 |
qualifiedStrings.clear(); |
487 |
qualifiedStrings.clear(); |
488 |
simpleStrings.clear(); |
488 |
simpleStrings.clear(); |
489 |
workQueue.clear(); |
489 |
workQueue.clear(); |
490 |
} |
490 |
} |
491 |
|
491 |
|
492 |
protected void updateProblemsFor(String sourceLocation, CompilationResult result) throws CoreException { |
492 |
protected void updateProblemsFor(String sourceLocation, CompilationResult result) throws CoreException { |
493 |
IResource resource = resourceForLocation(sourceLocation); |
493 |
IResource resource = resourceForLocation(sourceLocation); |
494 |
IMarker[] markers = JavaBuilder.getProblemsFor(resource); |
494 |
IMarker[] markers = JavaBuilder.getProblemsFor(resource); |
495 |
IProblem[] problems = result.getProblems(); |
495 |
IProblem[] problems = result.getProblems(); |
496 |
if (problems == null || problems.length == 0) |
496 |
if (problems == null || problems.length == 0) |
497 |
if (markers.length == 0) return; |
497 |
if (markers.length == 0) return; |
498 |
|
498 |
|
499 |
notifier.updateProblemCounts(markers, problems); |
499 |
notifier.updateProblemCounts(markers, problems); |
500 |
JavaBuilder.removeProblemsFor(resource); |
500 |
JavaBuilder.removeProblemsFor(resource); |
501 |
storeProblemsFor(resource, problems); |
501 |
storeProblemsFor(resource, problems); |
502 |
} |
502 |
} |
503 |
|
503 |
|
504 |
protected boolean writeClassFileCheck(IFile file, String fileName, byte[] newBytes, boolean isSecondaryType) throws CoreException { |
504 |
protected boolean writeClassFileCheck(IFile file, String fileName, byte[] newBytes, boolean isSecondaryType, boolean exists) throws CoreException { |
505 |
// Before writing out the class file, compare it to the previous file |
505 |
// Before writing out the class file, compare it to the previous file |
506 |
// If structural changes occured then add dependent source files |
506 |
// If structural changes occured then add dependent source files |
507 |
if (file.exists()) { |
507 |
if (exists) { |
508 |
try { |
508 |
try { |
509 |
byte[] oldBytes = Util.getResourceContentsAsByteArray(file); |
509 |
byte[] oldBytes = Util.getResourceContentsAsByteArray(file); |
510 |
notEqual : if (newBytes.length == oldBytes.length) { |
510 |
notEqual : if (newBytes.length == oldBytes.length) { |
511 |
for (int i = newBytes.length; --i >= 0;) |
511 |
for (int i = newBytes.length; --i >= 0;) |
512 |
if (newBytes[i] != oldBytes[i]) break notEqual; |
512 |
if (newBytes[i] != oldBytes[i]) break notEqual; |
513 |
return false; // bytes are identical so skip them |
513 |
return false; // bytes are identical so skip them |
514 |
} |
514 |
} |
515 |
ClassFileReader reader = new ClassFileReader(oldBytes, file.getLocation().toString().toCharArray()); |
515 |
ClassFileReader reader = new ClassFileReader(oldBytes, file.getLocation().toString().toCharArray()); |
516 |
// ignore local types since they're only visible inside a single method |
516 |
// ignore local types since they're only visible inside a single method |
517 |
if (!(reader.isLocal() || reader.isAnonymous()) && reader.hasStructuralChanges(newBytes)) { |
517 |
if (!(reader.isLocal() || reader.isAnonymous()) && reader.hasStructuralChanges(newBytes)) { |
518 |
if (JavaBuilder.DEBUG) |
518 |
if (JavaBuilder.DEBUG) |
519 |
System.out.println("Type has structural changes " + fileName); //$NON-NLS-1$ |
519 |
System.out.println("Type has structural changes " + fileName); //$NON-NLS-1$ |
520 |
addDependentsOf(new Path(fileName), true); |
520 |
addDependentsOf(new Path(fileName), true); |
521 |
} |
521 |
} |
522 |
} catch (ClassFormatException e) { |
522 |
} catch (ClassFormatException e) { |
523 |
addDependentsOf(new Path(fileName), true); |
523 |
addDependentsOf(new Path(fileName), true); |
524 |
} |
524 |
} |
525 |
|
525 |
|
526 |
file.delete(IResource.FORCE, null); |
526 |
// file.delete(IResource.FORCE, null); |
527 |
} else if (isSecondaryType) { |
527 |
} else if (isSecondaryType) { |
528 |
addDependentsOf(new Path(fileName), true); // new secondary type |
528 |
addDependentsOf(new Path(fileName), true); // new secondary type |
529 |
} |
529 |
} |
530 |
return true; |
530 |
return true; |
531 |
} |
531 |
} |
532 |
|
532 |
|
533 |
public String toString() { |
533 |
public String toString() { |
534 |
return "incremental image builder for:\n\tnew state: " + newState; //$NON-NLS-1$ |
534 |
return "incremental image builder for:\n\tnew state: " + newState; //$NON-NLS-1$ |
535 |
} |
535 |
} |
536 |
|
536 |
|
537 |
|
537 |
|
538 |
/* Debug helper |
538 |
/* Debug helper |
539 |
|
539 |
|
540 |
static void dump(IResourceDelta delta) { |
540 |
static void dump(IResourceDelta delta) { |
541 |
StringBuffer buffer = new StringBuffer(); |
541 |
StringBuffer buffer = new StringBuffer(); |
542 |
IPath path = delta.getFullPath(); |
542 |
IPath path = delta.getFullPath(); |
543 |
for (int i = path.segmentCount(); --i > 0;) |
543 |
for (int i = path.segmentCount(); --i > 0;) |
544 |
buffer.append(" "); |
544 |
buffer.append(" "); |
545 |
switch (delta.getKind()) { |
545 |
switch (delta.getKind()) { |
546 |
case IResourceDelta.ADDED: |
546 |
case IResourceDelta.ADDED: |
547 |
buffer.append('+'); |
547 |
buffer.append('+'); |
548 |
break; |
548 |
break; |
549 |
case IResourceDelta.REMOVED: |
549 |
case IResourceDelta.REMOVED: |
550 |
buffer.append('-'); |
550 |
buffer.append('-'); |
551 |
break; |
551 |
break; |
552 |
case IResourceDelta.CHANGED: |
552 |
case IResourceDelta.CHANGED: |
553 |
buffer.append('*'); |
553 |
buffer.append('*'); |
554 |
break; |
554 |
break; |
555 |
case IResourceDelta.NO_CHANGE: |
555 |
case IResourceDelta.NO_CHANGE: |
556 |
buffer.append('='); |
556 |
buffer.append('='); |
557 |
break; |
557 |
break; |
558 |
default: |
558 |
default: |
559 |
buffer.append('?'); |
559 |
buffer.append('?'); |
560 |
break; |
560 |
break; |
561 |
} |
561 |
} |
562 |
buffer.append(path); |
562 |
buffer.append(path); |
563 |
System.out.println(buffer.toString()); |
563 |
System.out.println(buffer.toString()); |
564 |
IResourceDelta[] children = delta.getAffectedChildren(); |
564 |
IResourceDelta[] children = delta.getAffectedChildren(); |
565 |
for (int i = 0, length = children.length; i < length; ++i) |
565 |
for (int i = 0, length = children.length; i < length; ++i) |
566 |
dump(children[i]); |
566 |
dump(children[i]); |
567 |
} |
567 |
} |
568 |
*/ |
568 |
*/ |
569 |
} |
569 |
} |