1 /*******************************************************************************
2 * Copyright (c) 2000, 2003 IBM Corporation and others.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Common Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/cpl-v10.html
9 * IBM Corporation - initial API and implementation
10 *******************************************************************************/
11 package net.sourceforge.phpdt.internal.core.builder;
13 import java.util.ArrayList;
15 import net.sourceforge.phpdt.core.compiler.CharOperation;
16 import net.sourceforge.phpdt.core.compiler.IProblem;
17 import net.sourceforge.phpdt.internal.compiler.CompilationResult;
18 import net.sourceforge.phpdt.internal.core.Util;
19 import net.sourceforge.phpdt.internal.core.util.SimpleLookupTable;
21 import org.eclipse.core.resources.IContainer;
22 import org.eclipse.core.resources.IFile;
23 import org.eclipse.core.resources.IFolder;
24 import org.eclipse.core.resources.IMarker;
25 import org.eclipse.core.resources.IResource;
26 import org.eclipse.core.resources.IResourceDelta;
27 import org.eclipse.core.runtime.CoreException;
28 import org.eclipse.core.runtime.IPath;
31 * The incremental image builder
33 public class IncrementalImageBuilder extends AbstractImageBuilder {
35 protected ArrayList sourceFiles;
36 protected ArrayList previousSourceFiles;
37 protected ArrayList qualifiedStrings;
38 protected ArrayList simpleStrings;
39 protected SimpleLookupTable secondaryTypesToRemove;
40 protected boolean hasStructuralChanges;
41 protected int compileLoop;
43 public static int MaxCompileLoop = 5; // perform a full build if it takes more than ? incremental compile loops
45 protected IncrementalImageBuilder(PHPBuilder javaBuilder) {
47 this.nameEnvironment.isIncrementalBuild = true;
48 this.newState.copyFrom(javaBuilder.lastState);
50 this.sourceFiles = new ArrayList(33);
51 this.previousSourceFiles = null;
52 this.qualifiedStrings = new ArrayList(33);
53 this.simpleStrings = new ArrayList(33);
54 this.hasStructuralChanges = false;
58 public boolean build(SimpleLookupTable deltas) {
60 // walk this project's deltas, find changed source files
61 // walk prereq projects' deltas, find changed class files & add affected source files
62 // use the build state # to skip the deltas for certain prereq projects
63 // ignore changed zip/jar files since they caused a full build
64 // compile the source files & acceptResult()
65 // compare the produced class files against the existing ones on disk
66 // recompile all dependent source files of any type with structural changes or new/removed secondary type
67 // keep a loop counter to abort & perform a full build
70 System.out.println("INCREMENTAL build"); //$NON-NLS-1$
75 notifier.subTask(Util.bind("build.analyzingDeltas")); //$NON-NLS-1$
76 IResourceDelta sourceDelta = (IResourceDelta) deltas.get(javaBuilder.currentProject);
77 if (sourceDelta != null)
78 if (!findSourceFiles(sourceDelta)) return false;
79 notifier.updateProgressDelta(0.10f);
81 Object[] keyTable = deltas.keyTable;
82 Object[] valueTable = deltas.valueTable;
83 for (int i = 0, l = valueTable.length; i < l; i++) {
84 IResourceDelta delta = (IResourceDelta) valueTable[i];
86 // ClasspathLocation[] classFoldersAndJars = (ClasspathLocation[]) javaBuilder.binaryLocationsPerProject.get(keyTable[i]);
87 // if (classFoldersAndJars != null)
88 // if (!findAffectedSourceFiles(delta, classFoldersAndJars)) return false;
91 notifier.updateProgressDelta(0.10f);
93 notifier.subTask(Util.bind("build.analyzingSources")); //$NON-NLS-1$
94 addAffectedSourceFiles();
95 notifier.updateProgressDelta(0.05f);
98 float increment = 0.40f;
99 while (sourceFiles.size() > 0) { // added to in acceptResult
100 if (++this.compileLoop > MaxCompileLoop) {
101 if (PHPBuilder.DEBUG)
102 System.out.println("ABORTING incremental build... exceeded loop count"); //$NON-NLS-1$
105 notifier.checkCancel();
107 SourceFile[] allSourceFiles = new SourceFile[sourceFiles.size()];
108 sourceFiles.toArray(allSourceFiles);
111 workQueue.addAll(allSourceFiles);
112 notifier.setProgressPerCompilationUnit(increment / allSourceFiles.length);
113 increment = increment / 2;
114 compile(allSourceFiles);
115 removeSecondaryTypes();
116 addAffectedSourceFiles();
118 if (this.hasStructuralChanges && javaBuilder.javaProject.hasCycleMarker())
119 javaBuilder.mustPropagateStructuralChanges();
120 } catch (AbortIncrementalBuildException e) {
121 // abort the incremental build and let the batch builder handle the problem
122 if (PHPBuilder.DEBUG)
123 System.out.println("ABORTING incremental build... cannot find " + e.qualifiedTypeName + //$NON-NLS-1$
124 ". Could have been renamed inside its existing source file."); //$NON-NLS-1$
126 } catch (CoreException e) {
127 throw internalException(e);
134 protected void addAffectedSourceFiles() {
135 if (qualifiedStrings.isEmpty() && simpleStrings.isEmpty()) return;
137 // the qualifiedStrings are of the form 'p1/p2' & the simpleStrings are just 'X'
138 char[][][] qualifiedNames = ReferenceCollection.internQualifiedNames(qualifiedStrings);
139 // if a well known qualified name was found then we can skip over these
140 if (qualifiedNames.length < qualifiedStrings.size())
141 qualifiedNames = null;
142 char[][] simpleNames = ReferenceCollection.internSimpleNames(simpleStrings);
143 // if a well known name was found then we can skip over these
144 if (simpleNames.length < simpleStrings.size())
147 Object[] keyTable = newState.references.keyTable;
148 Object[] valueTable = newState.references.valueTable;
149 next : for (int i = 0, l = valueTable.length; i < l; i++) {
150 ReferenceCollection refs = (ReferenceCollection) valueTable[i];
151 if (refs != null && refs.includes(qualifiedNames, simpleNames)) {
152 String typeLocator = (String) keyTable[i];
153 IFile file = javaBuilder.currentProject.getFile(typeLocator);
155 ClasspathMultiDirectory md = sourceLocations[0];
156 if (sourceLocations.length > 1) {
157 IPath sourceFileFullPath = file.getFullPath();
158 for (int j = 0, m = sourceLocations.length; j < m; j++) {
159 if (sourceLocations[j].sourceFolder.getFullPath().isPrefixOf(sourceFileFullPath)) {
160 md = sourceLocations[j];
161 if (md.exclusionPatterns == null || !Util.isExcluded(file, md.exclusionPatterns))
166 SourceFile sourceFile = new SourceFile(file, md, encoding);
167 if (sourceFiles.contains(sourceFile)) continue next;
168 if (compiledAllAtOnce && previousSourceFiles != null && previousSourceFiles.contains(sourceFile))
169 continue next; // can skip previously compiled files since already saw hierarchy related problems
171 if (PHPBuilder.DEBUG)
172 System.out.println(" adding affected source file " + typeLocator); //$NON-NLS-1$
173 sourceFiles.add(sourceFile);
179 protected void addDependentsOf(IPath path, boolean hasStructuralChanges) {
180 if (hasStructuralChanges) {
181 newState.tagAsStructurallyChanged();
182 this.hasStructuralChanges = true;
184 // the qualifiedStrings are of the form 'p1/p2' & the simpleStrings are just 'X'
185 path = path.setDevice(null);
186 String packageName = path.removeLastSegments(1).toString();
187 if (!qualifiedStrings.contains(packageName))
188 qualifiedStrings.add(packageName);
189 String typeName = path.lastSegment();
190 int memberIndex = typeName.indexOf('$');
192 typeName = typeName.substring(0, memberIndex);
193 if (!simpleStrings.contains(typeName)) {
194 if (PHPBuilder.DEBUG)
195 System.out.println(" will look for dependents of " //$NON-NLS-1$
196 + typeName + " in " + packageName); //$NON-NLS-1$
197 simpleStrings.add(typeName);
201 protected void cleanUp() {
204 this.sourceFiles = null;
205 this.previousSourceFiles = null;
206 this.qualifiedStrings = null;
207 this.simpleStrings = null;
208 this.secondaryTypesToRemove = null;
209 this.hasStructuralChanges = false;
210 this.compileLoop = 0;
213 //protected boolean findAffectedSourceFiles(IResourceDelta delta, ClasspathLocation[] classFoldersAndJars) {
214 // for (int i = 0, l = classFoldersAndJars.length; i < l; i++) {
215 // ClasspathLocation bLocation = classFoldersAndJars[i];
216 // // either a .class file folder or a zip/jar file
217 // if (bLocation != null) { // skip unchanged output folder
218 // IPath p = bLocation.getProjectRelativePath();
220 // IResourceDelta binaryDelta = delta.findMember(p);
221 // if (binaryDelta != null) {
222 // if (bLocation instanceof ClasspathJar) {
223 // if (JavaBuilder.DEBUG)
224 // System.out.println("ABORTING incremental build... found delta to jar/zip file"); //$NON-NLS-1$
225 // return false; // do full build since jar file was changed (added/removed were caught as classpath change)
227 // if (binaryDelta.getKind() == IResourceDelta.ADDED || binaryDelta.getKind() == IResourceDelta.REMOVED) {
228 // if (JavaBuilder.DEBUG)
229 // System.out.println("ABORTING incremental build... found added/removed binary folder"); //$NON-NLS-1$
230 // return false; // added/removed binary folder should not make it here (classpath change), but handle anyways
232 // int segmentCount = binaryDelta.getFullPath().segmentCount();
233 // IResourceDelta[] children = binaryDelta.getAffectedChildren(); // .class files from class folder
234 // for (int j = 0, m = children.length; j < m; j++)
235 // findAffectedSourceFiles(children[j], segmentCount);
236 // notifier.checkCancel();
244 protected void findAffectedSourceFiles(IResourceDelta binaryDelta, int segmentCount) {
245 // When a package becomes a type or vice versa, expect 2 deltas,
246 // one on the folder & one on the class file
247 IResource resource = binaryDelta.getResource();
248 switch(resource.getType()) {
249 case IResource.FOLDER :
250 switch (binaryDelta.getKind()) {
251 case IResourceDelta.ADDED :
252 case IResourceDelta.REMOVED :
253 IPath packagePath = resource.getFullPath().removeFirstSegments(segmentCount);
254 String packageName = packagePath.toString();
255 if (binaryDelta.getKind() == IResourceDelta.ADDED) {
256 // see if any known source file is from the same package... classpath already includes new package
257 if (!newState.isKnownPackage(packageName)) {
258 if (PHPBuilder.DEBUG)
259 System.out.println("Found added package " + packageName); //$NON-NLS-1$
260 addDependentsOf(packagePath, false);
263 if (PHPBuilder.DEBUG)
264 System.out.println("Skipped dependents of added package " + packageName); //$NON-NLS-1$
266 // see if the package still exists on the classpath
267 // if (!nameEnvironment.isPackage(packageName)) {
268 // if (JavaBuilder.DEBUG)
269 // System.out.println("Found removed package " + packageName); //$NON-NLS-1$
270 // addDependentsOf(packagePath, false);
273 if (PHPBuilder.DEBUG)
274 System.out.println("Skipped dependents of removed package " + packageName); //$NON-NLS-1$
276 // fall thru & traverse the sub-packages and .class files
277 case IResourceDelta.CHANGED :
278 IResourceDelta[] children = binaryDelta.getAffectedChildren();
279 for (int i = 0, l = children.length; i < l; i++)
280 findAffectedSourceFiles(children[i], segmentCount);
283 case IResource.FILE :
284 // if (Util.isClassFileName(resource.getName())) {
285 // IPath typePath = resource.getFullPath().removeFirstSegments(segmentCount).removeFileExtension();
286 // switch (binaryDelta.getKind()) {
287 // case IResourceDelta.ADDED :
288 // case IResourceDelta.REMOVED :
289 // if (JavaBuilder.DEBUG)
290 // System.out.println("Found added/removed class file " + typePath); //$NON-NLS-1$
291 // addDependentsOf(typePath, false);
293 // case IResourceDelta.CHANGED :
294 // if ((binaryDelta.getFlags() & IResourceDelta.CONTENT) == 0)
295 // return; // skip it since it really isn't changed
296 // if (JavaBuilder.DEBUG)
297 // System.out.println("Found changed class file " + typePath); //$NON-NLS-1$
298 // addDependentsOf(typePath, false);
305 protected boolean findSourceFiles(IResourceDelta delta) throws CoreException {
306 for (int i = 0, l = sourceLocations.length; i < l; i++) {
307 ClasspathMultiDirectory md = sourceLocations[i];
308 if (md.sourceFolder.equals(javaBuilder.currentProject)) {
309 // skip nested source & output folders when the project is a source folder
310 int segmentCount = delta.getFullPath().segmentCount();
311 IResourceDelta[] children = delta.getAffectedChildren();
312 for (int j = 0, m = children.length; j < m; j++)
313 if (!isExcludedFromProject(children[j].getFullPath()))
314 findSourceFiles(children[j], md, segmentCount);
316 IResourceDelta sourceDelta = delta.findMember(md.sourceFolder.getProjectRelativePath());
318 if (sourceDelta != null) {
319 if (sourceDelta.getKind() == IResourceDelta.REMOVED) {
320 if (PHPBuilder.DEBUG)
321 System.out.println("ABORTING incremental build... found removed source folder"); //$NON-NLS-1$
322 return false; // removed source folder should not make it here, but handle anyways (ADDED is supported)
324 int segmentCount = sourceDelta.getFullPath().segmentCount();
325 IResourceDelta[] children = sourceDelta.getAffectedChildren();
326 for (int j = 0, m = children.length; j < m; j++)
327 findSourceFiles(children[j], md, segmentCount);
330 notifier.checkCancel();
335 protected void findSourceFiles(IResourceDelta sourceDelta, ClasspathMultiDirectory md, int segmentCount) throws CoreException {
336 // When a package becomes a type or vice versa, expect 2 deltas,
337 // one on the folder & one on the source file
338 IResource resource = sourceDelta.getResource();
339 if (md.exclusionPatterns != null && Util.isExcluded(resource, md.exclusionPatterns)) return;
340 switch(resource.getType()) {
341 case IResource.FOLDER :
342 switch (sourceDelta.getKind()) {
343 case IResourceDelta.ADDED :
344 IPath addedPackagePath = resource.getFullPath().removeFirstSegments(segmentCount);
345 createFolder(addedPackagePath, md.binaryFolder); // ensure package exists in the output folder
346 // add dependents even when the package thinks it exists to be on the safe side
347 if (PHPBuilder.DEBUG)
348 System.out.println("Found added package " + addedPackagePath); //$NON-NLS-1$
349 addDependentsOf(addedPackagePath, true);
350 // fall thru & collect all the source files
351 case IResourceDelta.CHANGED :
352 IResourceDelta[] children = sourceDelta.getAffectedChildren();
353 for (int i = 0, l = children.length; i < l; i++)
354 findSourceFiles(children[i], md, segmentCount);
356 case IResourceDelta.REMOVED :
357 IPath removedPackagePath = resource.getFullPath().removeFirstSegments(segmentCount);
358 if (sourceLocations.length > 1) {
359 for (int i = 0, l = sourceLocations.length; i < l; i++) {
360 if (sourceLocations[i].sourceFolder.getFolder(removedPackagePath).exists()) {
361 // only a package fragment was removed, same as removing multiple source files
362 createFolder(removedPackagePath, md.binaryFolder); // ensure package exists in the output folder
363 IResourceDelta[] removedChildren = sourceDelta.getAffectedChildren();
364 for (int j = 0, m = removedChildren.length; j < m; j++)
365 findSourceFiles(removedChildren[j], md, segmentCount);
370 IFolder removedPackageFolder = md.binaryFolder.getFolder(removedPackagePath);
371 if (removedPackageFolder.exists())
372 removedPackageFolder.delete(IResource.FORCE, null);
373 // add dependents even when the package thinks it does not exist to be on the safe side
374 if (PHPBuilder.DEBUG)
375 System.out.println("Found removed package " + removedPackagePath); //$NON-NLS-1$
376 addDependentsOf(removedPackagePath, true);
377 newState.removePackage(sourceDelta);
380 case IResource.FILE :
381 String resourceName = resource.getName();
382 if (Util.isJavaFileName(resourceName)) {
383 IPath typePath = resource.getFullPath().removeFirstSegments(segmentCount).removeFileExtension();
384 String typeLocator = resource.getProjectRelativePath().toString();
385 switch (sourceDelta.getKind()) {
386 case IResourceDelta.ADDED :
387 if (PHPBuilder.DEBUG)
388 System.out.println("Compile this added source file " + typeLocator); //$NON-NLS-1$
389 sourceFiles.add(new SourceFile((IFile) resource, md, encoding));
390 String typeName = typePath.toString();
391 if (!newState.isDuplicateLocator(typeName, typeLocator)) { // adding dependents results in 2 duplicate errors
392 if (PHPBuilder.DEBUG)
393 System.out.println("Found added source file " + typeName); //$NON-NLS-1$
394 addDependentsOf(typePath, true);
397 case IResourceDelta.REMOVED :
398 char[][] definedTypeNames = newState.getDefinedTypeNamesFor(typeLocator);
399 if (definedTypeNames == null) { // defined a single type matching typePath
400 removeClassFile(typePath, md.binaryFolder);
401 if ((sourceDelta.getFlags() & IResourceDelta.MOVED_TO) != 0) {
402 // remove problems and tasks for a compilation unit that is being moved (to another package or renamed)
403 // if the target file is a compilation unit, the new cu will be recompiled
404 // if the target file is a non-java resource, then markers are removed
406 IResource movedFile = javaBuilder.workspaceRoot.getFile(sourceDelta.getMovedToPath());
407 PHPBuilder.removeProblemsAndTasksFor(movedFile);
410 if (PHPBuilder.DEBUG)
411 System.out.println("Found removed source file " + typePath.toString()); //$NON-NLS-1$
412 addDependentsOf(typePath, true); // add dependents of the source file since it may be involved in a name collision
413 if (definedTypeNames.length > 0) { // skip it if it failed to successfully define a type
414 IPath packagePath = typePath.removeLastSegments(1);
415 for (int i = 0, l = definedTypeNames.length; i < l; i++)
416 removeClassFile(packagePath.append(new String(definedTypeNames[i])), md.binaryFolder);
419 newState.removeLocator(typeLocator);
421 case IResourceDelta.CHANGED :
422 if ((sourceDelta.getFlags() & IResourceDelta.CONTENT) == 0)
423 return; // skip it since it really isn't changed
424 if (PHPBuilder.DEBUG)
425 System.out.println("Compile this changed source file " + typeLocator); //$NON-NLS-1$
426 sourceFiles.add(new SourceFile((IFile) resource, md, encoding));
429 // } else if (Util.isClassFileName(resourceName)) {
430 // return; // skip class files
431 } else if (md.hasIndependentOutputFolder) {
432 if (javaBuilder.filterExtraResource(resource)) return;
434 // copy all other resource deltas to the output folder
435 IPath resourcePath = resource.getFullPath().removeFirstSegments(segmentCount);
436 IResource outputFile = md.binaryFolder.getFile(resourcePath);
437 switch (sourceDelta.getKind()) {
438 case IResourceDelta.ADDED :
439 if (outputFile.exists()) {
440 if (PHPBuilder.DEBUG)
441 System.out.println("Deleting existing file " + resourcePath); //$NON-NLS-1$
442 outputFile.delete(IResource.FORCE, null);
444 if (PHPBuilder.DEBUG)
445 System.out.println("Copying added file " + resourcePath); //$NON-NLS-1$
446 createFolder(resourcePath.removeLastSegments(1), md.binaryFolder); // ensure package exists in the output folder
447 resource.copy(outputFile.getFullPath(), IResource.FORCE, null);
448 outputFile.setDerived(true);
450 case IResourceDelta.REMOVED :
451 if (outputFile.exists()) {
452 if (PHPBuilder.DEBUG)
453 System.out.println("Deleting removed file " + resourcePath); //$NON-NLS-1$
454 outputFile.delete(IResource.FORCE, null);
457 case IResourceDelta.CHANGED :
458 if ((sourceDelta.getFlags() & IResourceDelta.CONTENT) == 0)
459 return; // skip it since it really isn't changed
460 if (outputFile.exists()) {
461 if (PHPBuilder.DEBUG)
462 System.out.println("Deleting existing file " + resourcePath); //$NON-NLS-1$
463 outputFile.delete(IResource.FORCE, null);
465 if (PHPBuilder.DEBUG)
466 System.out.println("Copying changed file " + resourcePath); //$NON-NLS-1$
467 createFolder(resourcePath.removeLastSegments(1), md.binaryFolder); // ensure package exists in the output folder
468 resource.copy(outputFile.getFullPath(), IResource.FORCE, null);
469 outputFile.setDerived(true);
476 protected void finishedWith(String sourceLocator, CompilationResult result, char[] mainTypeName, ArrayList definedTypeNames, ArrayList duplicateTypeNames) throws CoreException {
477 char[][] previousTypeNames = newState.getDefinedTypeNamesFor(sourceLocator);
478 if (previousTypeNames == null)
479 previousTypeNames = new char[][] {mainTypeName};
480 IPath packagePath = null;
481 next : for (int i = 0, l = previousTypeNames.length; i < l; i++) {
482 char[] previous = previousTypeNames[i];
483 for (int j = 0, m = definedTypeNames.size(); j < m; j++)
484 if (CharOperation.equals(previous, (char[]) definedTypeNames.get(j)))
487 SourceFile sourceFile = (SourceFile) result.getCompilationUnit();
488 if (packagePath == null) {
489 int count = sourceFile.sourceLocation.sourceFolder.getFullPath().segmentCount();
490 packagePath = sourceFile.resource.getFullPath().removeFirstSegments(count).removeLastSegments(1);
492 if (secondaryTypesToRemove == null)
493 this.secondaryTypesToRemove = new SimpleLookupTable();
494 ArrayList types = (ArrayList) secondaryTypesToRemove.get(sourceFile.sourceLocation.binaryFolder);
496 types = new ArrayList(definedTypeNames.size());
497 types.add(packagePath.append(new String(previous)));
498 secondaryTypesToRemove.put(sourceFile.sourceLocation.binaryFolder, types);
500 // super.finishedWith(sourceLocator, result, mainTypeName, definedTypeNames, duplicateTypeNames);
503 protected void removeClassFile(IPath typePath, IContainer outputFolder) throws CoreException {
504 if (typePath.lastSegment().indexOf('$') == -1) { // is not a nested type
505 newState.removeQualifiedTypeName(typePath.toString());
506 // add dependents even when the type thinks it does not exist to be on the safe side
507 if (PHPBuilder.DEBUG)
508 System.out.println("Found removed type " + typePath); //$NON-NLS-1$
509 addDependentsOf(typePath, true); // when member types are removed, their enclosing type is structurally changed
511 IFile classFile = outputFolder.getFile(typePath.addFileExtension(PHPBuilder.CLASS_EXTENSION));
512 if (classFile.exists()) {
513 if (PHPBuilder.DEBUG)
514 System.out.println("Deleting class file of removed type " + typePath); //$NON-NLS-1$
515 classFile.delete(IResource.FORCE, null);
519 protected void removeSecondaryTypes() throws CoreException {
520 if (secondaryTypesToRemove != null) { // delayed deleting secondary types until the end of the compile loop
521 Object[] keyTable = secondaryTypesToRemove.keyTable;
522 Object[] valueTable = secondaryTypesToRemove.valueTable;
523 for (int i = 0, l = keyTable.length; i < l; i++) {
524 IContainer outputFolder = (IContainer) keyTable[i];
525 if (outputFolder != null) {
526 ArrayList paths = (ArrayList) valueTable[i];
527 for (int j = 0, m = paths.size(); j < m; j++)
528 removeClassFile((IPath) paths.get(j), outputFolder);
531 this.secondaryTypesToRemove = null;
532 if (previousSourceFiles != null && previousSourceFiles.size() > 1)
533 this.previousSourceFiles = null; // cannot optimize recompile case when a secondary type is deleted
537 protected void resetCollections() {
538 previousSourceFiles = sourceFiles.isEmpty() ? null : (ArrayList) sourceFiles.clone();
541 qualifiedStrings.clear();
542 simpleStrings.clear();
546 protected void updateProblemsFor(SourceFile sourceFile, CompilationResult result) throws CoreException {
547 IMarker[] markers = PHPBuilder.getProblemsFor(sourceFile.resource);
548 IProblem[] problems = result.getProblems();
549 if (problems == null && markers.length == 0) return;
551 notifier.updateProblemCounts(markers, problems);
552 PHPBuilder.removeProblemsFor(sourceFile.resource);
553 storeProblemsFor(sourceFile, problems);
556 protected void updateTasksFor(SourceFile sourceFile, CompilationResult result) throws CoreException {
557 IMarker[] markers = PHPBuilder.getTasksFor(sourceFile.resource);
558 IProblem[] tasks = result.getTasks();
559 if (tasks == null && markers.length == 0) return;
561 PHPBuilder.removeTasksFor(sourceFile.resource);
562 storeTasksFor(sourceFile, tasks);
565 //protected void writeClassFileBytes(byte[] bytes, IFile file, String qualifiedFileName, boolean isSecondaryType) throws CoreException {
566 // // Before writing out the class file, compare it to the previous file
567 // // If structural changes occured then add dependent source files
568 // if (file.exists()) {
569 // if (writeClassFileCheck(file, qualifiedFileName, bytes)) {
570 // if (JavaBuilder.DEBUG)
571 // System.out.println("Writing changed class file " + file.getName());//$NON-NLS-1$
572 // file.setContents(new ByteArrayInputStream(bytes), true, false, null);
573 // if (!file.isDerived())
574 // file.setDerived(true);
575 // } else if (JavaBuilder.DEBUG) {
576 // System.out.println("Skipped over unchanged class file " + file.getName());//$NON-NLS-1$
579 // if (isSecondaryType)
580 // addDependentsOf(new Path(qualifiedFileName), true); // new secondary type
581 // if (JavaBuilder.DEBUG)
582 // System.out.println("Writing new class file " + file.getName());//$NON-NLS-1$
583 // file.create(new ByteArrayInputStream(bytes), IResource.FORCE, null);
584 // file.setDerived(true);
588 //protected boolean writeClassFileCheck(IFile file, String fileName, byte[] newBytes) throws CoreException {
590 // byte[] oldBytes = Util.getResourceContentsAsByteArray(file);
591 // if (this.compileLoop > 1) { // only optimize files which were recompiled during the dependent pass, see 33990
592 // notEqual : if (newBytes.length == oldBytes.length) {
593 // for (int i = newBytes.length; --i >= 0;)
594 // if (newBytes[i] != oldBytes[i]) break notEqual;
595 // return false; // bytes are identical so skip them
598 // IPath location = file.getLocation();
599 // if (location == null) return false; // unable to determine location of this class file
600 // ClassFileReader reader = new ClassFileReader(oldBytes, location.toString().toCharArray());
601 // // ignore local types since they're only visible inside a single method
602 // if (!(reader.isLocal() || reader.isAnonymous()) && reader.hasStructuralChanges(newBytes)) {
603 // if (JavaBuilder.DEBUG)
604 // System.out.println("Type has structural changes " + fileName); //$NON-NLS-1$
605 // addDependentsOf(new Path(fileName), true);
607 // } catch (ClassFormatException e) {
608 // addDependentsOf(new Path(fileName), true);
613 public String toString() {
614 return "incremental image builder for:\n\tnew state: " + newState; //$NON-NLS-1$
620 static void dump(IResourceDelta delta) {
621 StringBuffer buffer = new StringBuffer();
622 IPath path = delta.getFullPath();
623 for (int i = path.segmentCount(); --i > 0;)
625 switch (delta.getKind()) {
626 case IResourceDelta.ADDED:
629 case IResourceDelta.REMOVED:
632 case IResourceDelta.CHANGED:
635 case IResourceDelta.NO_CHANGE:
643 System.out.println(buffer.toString());
644 IResourceDelta[] children = delta.getAffectedChildren();
645 for (int i = 0, l = children.length; i < l; i++)