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.IProblem;
16 import net.sourceforge.phpdt.internal.compiler.CompilationResult;
17 import net.sourceforge.phpdt.internal.compiler.problem.ProblemHandler;
18 import net.sourceforge.phpdt.internal.core.util.SimpleLookupTable;
19 import net.sourceforge.phpdt.internal.core.util.Util;
21 import org.eclipse.core.resources.IFile;
22 import org.eclipse.core.resources.IMarker;
23 import org.eclipse.core.resources.IResource;
24 import org.eclipse.core.resources.IResourceDelta;
25 import org.eclipse.core.runtime.CoreException;
26 import org.eclipse.core.runtime.IPath;
29 * The incremental image builder
31 public class IncrementalImageBuilder extends AbstractImageBuilder {
32 protected ArrayList sourceFiles;
34 protected ArrayList previousSourceFiles;
36 protected ArrayList qualifiedStrings;
38 protected ArrayList simpleStrings;
40 protected SimpleLookupTable secondaryTypesToRemove;
42 protected boolean hasStructuralChanges;
44 protected int compileLoop;
46 public static int MaxCompileLoop = 5; // perform a full build if it takes
48 // more than ? incremental compile
50 protected IncrementalImageBuilder(PHPBuilder javaBuilder) {
52 this.nameEnvironment.isIncrementalBuild = true;
53 this.newState.copyFrom(javaBuilder.lastState);
54 this.sourceFiles = new ArrayList(33);
55 this.previousSourceFiles = null;
56 this.qualifiedStrings = new ArrayList(33);
57 this.simpleStrings = new ArrayList(33);
58 this.hasStructuralChanges = false;
62 public boolean build(SimpleLookupTable deltas) {
64 // walk this project's deltas, find changed source files
65 // walk prereq projects' deltas, find changed class files & add affected
67 // use the build state # to skip the deltas for certain prereq projects
68 // ignore changed zip/jar files since they caused a full build
69 // compile the source files & acceptResult()
70 // compare the produced class files against the existing ones on disk
71 // recompile all dependent source files of any type with structural
73 // or new/removed secondary type
74 // keep a loop counter to abort & perform a full build
76 System.out.println("INCREMENTAL build"); //$NON-NLS-1$
79 notifier.subTask(Util.bind("build.analyzingDeltas")); //$NON-NLS-1$
80 IResourceDelta sourceDelta = (IResourceDelta) deltas
81 .get(javaBuilder.currentProject);
82 if (sourceDelta != null) {
83 sourceDelta.accept(new ParserVisitor(
84 javaBuilder.currentProject, notifier.monitor));
86 if (!findSourceFiles(sourceDelta))
89 notifier.updateProgressDelta(0.10f);
90 // Object[] keyTable = deltas.keyTable;
91 // Object[] valueTable = deltas.valueTable;
92 // // final IdentifierIndexManager indexManager =
93 // PHPeclipsePlugin.getDefault()
94 // // .getIndexManager(javaBuilder.currentProject);
95 // for (int i = 0, l = valueTable.length; i < l; i++) {
96 // IResourceDelta delta = (IResourceDelta) valueTable[i];
97 // if (delta != null) {
98 // IResource resource = delta.getResource();
99 // int resourceType = resource.getType();
100 // if (resourceType == IResource.FILE) {
101 // switch (delta.getKind()) {
102 // case IResourceDelta.ADDED :
103 // if ((resource.getFileExtension() != null)
104 // && PHPFileUtil.isPHPFile((IFile) resource)) {
105 // // update indexfile for the project:
106 // // indexManager.addFile((IFile) resource);
109 // case IResourceDelta.CHANGED :
110 // if ((resource.getFileExtension() != null)
111 // && PHPFileUtil.isPHPFile((IFile) resource)) {
112 // // update indexfile for the project:
113 // // indexManager.changeFile((IFile) resource);
116 // case IResourceDelta.REMOVED :
117 // if ((resource.getFileExtension() != null)
118 // && PHPFileUtil.isPHPFile((IFile) resource)) {
119 // // update indexfile for the project:
120 // // indexManager.removeFile((IFile) resource);
125 // // ClasspathLocation[] classFoldersAndJars =
126 // (ClasspathLocation[])
127 // // javaBuilder.binaryLocationsPerProject.get(keyTable[i]);
128 // // if (classFoldersAndJars != null)
129 // // if (!findAffectedSourceFiles(delta, classFoldersAndJars))
134 notifier.updateProgressDelta(0.10f);
135 notifier.subTask(Util.bind("build.analyzingSources")); //$NON-NLS-1$
136 addAffectedSourceFiles();
137 notifier.updateProgressDelta(0.05f);
138 this.compileLoop = 0;
139 float increment = 0.40f;
140 while (sourceFiles.size() > 0) { // added to in acceptResult
141 if (++this.compileLoop > MaxCompileLoop) {
142 if (PHPBuilder.DEBUG)
144 .println("ABORTING incremental build... exceeded loop count"); //$NON-NLS-1$
147 notifier.checkCancel();
148 SourceFile[] allSourceFiles = new SourceFile[sourceFiles.size()];
149 sourceFiles.toArray(allSourceFiles);
151 workQueue.addAll(allSourceFiles);
152 notifier.setProgressPerCompilationUnit(increment
153 / allSourceFiles.length);
154 increment = increment / 2;
155 compile(allSourceFiles);
156 // removeSecondaryTypes();
157 addAffectedSourceFiles();
159 if (this.hasStructuralChanges
160 && javaBuilder.javaProject.hasCycleMarker())
161 javaBuilder.mustPropagateStructuralChanges();
162 } catch (AbortIncrementalBuildException e) {
163 // abort the incremental build and let the batch builder handle the
165 if (PHPBuilder.DEBUG)
167 .println("ABORTING incremental build... cannot find " + e.qualifiedTypeName + //$NON-NLS-1$
168 ". Could have been renamed inside its existing source file."); //$NON-NLS-1$
170 } catch (CoreException e) {
171 throw internalException(e);
178 protected void addAffectedSourceFiles() {
179 if (qualifiedStrings.isEmpty() && simpleStrings.isEmpty())
181 // the qualifiedStrings are of the form 'p1/p2' & the simpleStrings are
183 // char[][][] qualifiedNames = ReferenceCollection
184 // .internQualifiedNames(qualifiedStrings);
185 // if a well known qualified name was found then we can skip over these
186 // if (qualifiedNames.length < qualifiedStrings.size())
187 // qualifiedNames = null;
188 // char[][] simpleNames =
189 // ReferenceCollection.internSimpleNames(simpleStrings);
190 // if a well known name was found then we can skip over these
191 // if (simpleNames.length < simpleStrings.size())
192 // simpleNames = null;
193 // Object[] keyTable = newState.references.keyTable;
194 // Object[] valueTable = newState.references.valueTable;
195 // next : for (int i = 0, l = valueTable.length; i < l; i++) {
196 // ReferenceCollection refs = (ReferenceCollection) valueTable[i];
197 // if (refs != null && refs.includes(qualifiedNames, simpleNames)) {
198 // String typeLocator = (String) keyTable[i];
199 // IFile file = javaBuilder.currentProject.getFile(typeLocator);
200 // if (file.exists()) {
201 // ClasspathMultiDirectory md = sourceLocations[0];
202 // if (sourceLocations.length > 1) {
203 // IPath sourceFileFullPath = file.getFullPath();
204 // for (int j = 0, m = sourceLocations.length; j < m; j++) {
205 // if (sourceLocations[j].sourceFolder.getFullPath().isPrefixOf(
206 // sourceFileFullPath)) {
207 // md = sourceLocations[j];
208 // if (md.exclusionPatterns == null
209 // || !ProjectPrefUtil.isExcluded(file, md.exclusionPatterns))
214 // SourceFile sourceFile = new SourceFile(file, md, encoding);
215 // if (sourceFiles.contains(sourceFile))
217 // if (compiledAllAtOnce && previousSourceFiles != null
218 // && previousSourceFiles.contains(sourceFile))
219 // continue next; // can skip previously compiled files since already
220 // // saw hierarchy related problems
221 // if (PHPBuilder.DEBUG)
222 // System.out.println(" adding affected source file " + typeLocator);
224 // // // update indexfile for the project:
225 // sourceFiles.add(sourceFile);
231 protected void addDependentsOf(IPath path, boolean hasStructuralChanges) {
232 if (hasStructuralChanges) {
233 newState.tagAsStructurallyChanged();
234 this.hasStructuralChanges = true;
236 // the qualifiedStrings are of the form 'p1/p2' & the simpleStrings are
238 path = path.setDevice(null);
239 String packageName = path.removeLastSegments(1).toString();
240 if (!qualifiedStrings.contains(packageName))
241 qualifiedStrings.add(packageName);
242 String typeName = path.lastSegment();
243 int memberIndex = typeName.indexOf('$');
245 typeName = typeName.substring(0, memberIndex);
246 if (!simpleStrings.contains(typeName)) {
247 if (PHPBuilder.DEBUG)
248 System.out.println(" will look for dependents of " //$NON-NLS-1$
249 + typeName + " in " + packageName); //$NON-NLS-1$
250 simpleStrings.add(typeName);
254 protected void cleanUp() {
256 this.sourceFiles = null;
257 this.previousSourceFiles = null;
258 this.qualifiedStrings = null;
259 this.simpleStrings = null;
260 this.secondaryTypesToRemove = null;
261 this.hasStructuralChanges = false;
262 this.compileLoop = 0;
265 // protected boolean findAffectedSourceFiles(IResourceDelta delta,
266 // ClasspathLocation[] classFoldersAndJars) {
267 // for (int i = 0, l = classFoldersAndJars.length; i < l; i++) {
268 // ClasspathLocation bLocation = classFoldersAndJars[i];
269 // // either a .class file folder or a zip/jar file
270 // if (bLocation != null) { // skip unchanged output folder
271 // IPath p = bLocation.getProjectRelativePath();
273 // IResourceDelta binaryDelta = delta.findMember(p);
274 // if (binaryDelta != null) {
275 // if (bLocation instanceof ClasspathJar) {
276 // if (JavaBuilder.DEBUG)
277 // System.out.println("ABORTING incremental build... found delta to jar/zip
278 // file"); //$NON-NLS-1$
279 // return false; // do full build since jar file was changed (added/removed
280 // were caught as classpath change)
282 // if (binaryDelta.getKind() == IResourceDelta.ADDED ||
283 // binaryDelta.getKind()
284 // == IResourceDelta.REMOVED) {
285 // if (JavaBuilder.DEBUG)
286 // System.out.println("ABORTING incremental build... found added/removed
287 // binary folder"); //$NON-NLS-1$
288 // return false; // added/removed binary folder should not make it here
289 // (classpath change), but handle anyways
291 // int segmentCount = binaryDelta.getFullPath().segmentCount();
292 // IResourceDelta[] children = binaryDelta.getAffectedChildren(); // .class
293 // files from class folder
294 // for (int j = 0, m = children.length; j < m; j++)
295 // findAffectedSourceFiles(children[j], segmentCount);
296 // notifier.checkCancel();
303 protected void findAffectedSourceFiles(IResourceDelta binaryDelta,
305 // When a package becomes a type or vice versa, expect 2 deltas,
306 // one on the folder & one on the class file
307 IResource resource = binaryDelta.getResource();
308 switch (resource.getType()) {
309 case IResource.FOLDER:
310 switch (binaryDelta.getKind()) {
311 case IResourceDelta.ADDED:
312 case IResourceDelta.REMOVED:
313 IPath packagePath = resource.getFullPath().removeFirstSegments(
315 String packageName = packagePath.toString();
316 if (binaryDelta.getKind() == IResourceDelta.ADDED) {
317 // see if any known source file is from the same package...
318 // classpath already includes new package
319 // if (!newState.isKnownPackage(packageName)) {
320 // if (PHPBuilder.DEBUG)
321 // System.out.println("Found added package " + packageName);
323 // addDependentsOf(packagePath, false);
326 if (PHPBuilder.DEBUG)
328 .println("Skipped dependents of added package " + packageName); //$NON-NLS-1$
330 // see if the package still exists on the classpath
331 // if (!nameEnvironment.isPackage(packageName)) {
332 // if (JavaBuilder.DEBUG)
333 // System.out.println("Found removed package " +
336 // addDependentsOf(packagePath, false);
339 if (PHPBuilder.DEBUG)
341 .println("Skipped dependents of removed package " + packageName); //$NON-NLS-1$
343 // fall thru & traverse the sub-packages and .class files
344 case IResourceDelta.CHANGED:
345 IResourceDelta[] children = binaryDelta.getAffectedChildren();
346 for (int i = 0, l = children.length; i < l; i++)
347 findAffectedSourceFiles(children[i], segmentCount);
351 // if (ProjectPrefUtil.isClassFileName(resource.getName())) {
353 // resource.getFullPath().removeFirstSegments(segmentCount).removeFileExtension();
354 // switch (binaryDelta.getKind()) {
355 // case IResourceDelta.ADDED :
356 // case IResourceDelta.REMOVED :
357 // if (JavaBuilder.DEBUG)
358 // System.out.println("Found added/removed class file " + typePath);
360 // addDependentsOf(typePath, false);
362 // case IResourceDelta.CHANGED :
363 // if ((binaryDelta.getFlags() & IResourceDelta.CONTENT) == 0)
364 // return; // skip it since it really isn't changed
365 // if (JavaBuilder.DEBUG)
366 // System.out.println("Found changed class file " + typePath);
368 // addDependentsOf(typePath, false);
375 protected boolean findSourceFiles(IResourceDelta delta)
376 throws CoreException {
377 for (int i = 0, l = sourceLocations.length; i < l; i++) {
378 ClasspathMultiDirectory md = sourceLocations[i];
379 if (md.sourceFolder.equals(javaBuilder.currentProject)) {
380 // skip nested source & output folders when the project is a
383 int segmentCount = delta.getFullPath().segmentCount();
384 IResourceDelta[] children = delta.getAffectedChildren();
385 for (int j = 0, m = children.length; j < m; j++)
386 if (!isExcludedFromProject(children[j].getFullPath()))
387 findSourceFiles(children[j], md, segmentCount);
389 IResourceDelta sourceDelta = delta.findMember(md.sourceFolder
390 .getProjectRelativePath());
391 if (sourceDelta != null) {
392 if (sourceDelta.getKind() == IResourceDelta.REMOVED) {
393 if (PHPBuilder.DEBUG)
395 .println("ABORTING incremental build... found removed source folder"); //$NON-NLS-1$
396 return false; // removed source folder should not make
398 // handle anyways (ADDED is supported)
400 int segmentCount = sourceDelta.getFullPath().segmentCount();
401 IResourceDelta[] children = sourceDelta
402 .getAffectedChildren();
403 for (int j = 0, m = children.length; j < m; j++)
404 findSourceFiles(children[j], md, segmentCount);
407 notifier.checkCancel();
412 protected void findSourceFiles(IResourceDelta sourceDelta,
413 ClasspathMultiDirectory md, int segmentCount) throws CoreException {
414 // When a package becomes a type or vice versa, expect 2 deltas,
415 // one on the folder & one on the source file
416 IResource resource = sourceDelta.getResource();
417 if (md.exclusionPatterns != null
418 && Util.isExcluded(resource, md.exclusionPatterns))
420 switch (resource.getType()) {
421 case IResource.FOLDER:
422 switch (sourceDelta.getKind()) {
423 case IResourceDelta.ADDED:
424 IPath addedPackagePath = resource.getFullPath()
425 .removeFirstSegments(segmentCount);
426 // createFolder(addedPackagePath, md.binaryFolder); // ensure
430 // add dependents even when the package thinks it exists to be
433 if (PHPBuilder.DEBUG)
435 .println("Found added package " + addedPackagePath); //$NON-NLS-1$
436 addDependentsOf(addedPackagePath, true);
437 // fall thru & collect all the source files
438 case IResourceDelta.CHANGED:
439 IResourceDelta[] children = sourceDelta.getAffectedChildren();
440 for (int i = 0, l = children.length; i < l; i++)
441 findSourceFiles(children[i], md, segmentCount);
443 case IResourceDelta.REMOVED:
444 IPath removedPackagePath = resource.getFullPath()
445 .removeFirstSegments(segmentCount);
446 if (sourceLocations.length > 1) {
447 for (int i = 0, l = sourceLocations.length; i < l; i++) {
448 if (sourceLocations[i].sourceFolder.getFolder(
449 removedPackagePath).exists()) {
450 // only a package fragment was removed, same as
452 // multiple source files
453 // createFolder(removedPackagePath,
454 // md.binaryFolder); // ensure
460 IResourceDelta[] removedChildren = sourceDelta
461 .getAffectedChildren();
462 for (int j = 0, m = removedChildren.length; j < m; j++)
463 findSourceFiles(removedChildren[j], md,
469 // IFolder removedPackageFolder = md.binaryFolder
470 // .getFolder(removedPackagePath);
471 // if (removedPackageFolder.exists())
472 // removedPackageFolder.delete(IResource.FORCE, null);
473 // add dependents even when the package thinks it does not exist
475 // be on the safe side
476 if (PHPBuilder.DEBUG)
478 .println("Found removed package " + removedPackagePath); //$NON-NLS-1$
479 addDependentsOf(removedPackagePath, true);
480 newState.removePackage(sourceDelta);
484 String resourceName = resource.getName();
485 if (net.sourceforge.phpdt.internal.compiler.util.Util
486 .isJavaFileName(resourceName)) {
487 IPath typePath = resource.getFullPath().removeFirstSegments(
488 segmentCount).removeFileExtension();
489 String typeLocator = resource.getProjectRelativePath()
491 switch (sourceDelta.getKind()) {
492 case IResourceDelta.ADDED:
493 if (PHPBuilder.DEBUG)
495 .println("Compile this added source file " + typeLocator); //$NON-NLS-1$
496 sourceFiles.add(new SourceFile((IFile) resource, md,
498 String typeName = typePath.toString();
499 // if (!newState.isDuplicateLocator(typeName, typeLocator))
507 // if (PHPBuilder.DEBUG)
508 // System.out.println("Found added source file " +
509 // typeName); //$NON-NLS-1$
510 // addDependentsOf(typePath, true);
513 case IResourceDelta.REMOVED:
514 // char[][] definedTypeNames = newState
515 // .getDefinedTypeNamesFor(typeLocator);
516 // if (definedTypeNames == null) { // defined a single type
519 // removeClassFile(typePath, md.binaryFolder);
520 // if ((sourceDelta.getFlags() & IResourceDelta.MOVED_TO) !=
522 // // remove problems and tasks for a compilation unit that
524 // // being moved (to another package or renamed)
525 // // if the target file is a compilation unit, the new cu
528 // // if the target file is a non-java resource, then
532 // IResource movedFile = javaBuilder.workspaceRoot
533 // .getFile(sourceDelta.getMovedToPath());
534 // PHPBuilder.removeProblemsAndTasksFor(movedFile);
537 if (PHPBuilder.DEBUG)
539 .println("Found removed source file " + typePath.toString()); //$NON-NLS-1$
540 addDependentsOf(typePath, true); // add dependents of the
541 // source file since it may be
542 // involved in a name
544 // if (definedTypeNames.length > 0) { // skip it if it
546 // // successfully define a
548 // IPath packagePath = typePath.removeLastSegments(1);
549 // for (int i = 0, l = definedTypeNames.length; i < l; i++)
550 // removeClassFile(packagePath.append(new String(
551 // definedTypeNames[i])), md.binaryFolder);
554 // newState.removeLocator(typeLocator);
556 case IResourceDelta.CHANGED:
557 if ((sourceDelta.getFlags() & IResourceDelta.CONTENT) == 0)
558 return; // skip it since it really isn't changed
559 if (PHPBuilder.DEBUG)
561 .println("Compile this changed source file " + typeLocator); //$NON-NLS-1$
562 sourceFiles.add(new SourceFile((IFile) resource, md,
566 // } else if (ProjectPrefUtil.isClassFileName(resourceName)) {
567 // return; // skip class files
568 } else if (md.hasIndependentOutputFolder) {
569 if (javaBuilder.filterExtraResource(resource))
571 // copy all other resource deltas to the output folder
572 IPath resourcePath = resource.getFullPath()
573 .removeFirstSegments(segmentCount);
574 // IResource outputFile = md.binaryFolder.getFile(resourcePath);
575 switch (sourceDelta.getKind()) {
576 case IResourceDelta.ADDED:
577 // if (outputFile.exists()) {
578 // if (PHPBuilder.DEBUG)
579 // System.out.println("Deleting existing file " +
580 // resourcePath); //$NON-NLS-1$
581 // outputFile.delete(IResource.FORCE, null);
583 if (PHPBuilder.DEBUG)
585 .println("Copying added file " + resourcePath); //$NON-NLS-1$
586 // createFolder(resourcePath.removeLastSegments(1),
587 // md.binaryFolder); // ensure
594 // resource.copy(outputFile.getFullPath(), IResource.FORCE,
596 // outputFile.setDerived(true);
598 case IResourceDelta.REMOVED:
599 // if (outputFile.exists()) {
600 // if (PHPBuilder.DEBUG)
601 // System.out.println("Deleting removed file " +
602 // resourcePath); //$NON-NLS-1$
603 // outputFile.delete(IResource.FORCE, null);
606 case IResourceDelta.CHANGED:
607 if ((sourceDelta.getFlags() & IResourceDelta.CONTENT) == 0)
608 return; // skip it since it really isn't changed
609 // if (outputFile.exists()) {
610 // if (PHPBuilder.DEBUG)
611 // System.out.println("Deleting existing file " +
612 // resourcePath); //$NON-NLS-1$
613 // outputFile.delete(IResource.FORCE, null);
615 if (PHPBuilder.DEBUG)
617 .println("Copying changed file " + resourcePath); //$NON-NLS-1$
618 // createFolder(resourcePath.removeLastSegments(1),
619 // md.binaryFolder); // ensure
626 // resource.copy(outputFile.getFullPath(), IResource.FORCE,
628 // outputFile.setDerived(true);
635 protected void finishedWith(String sourceLocator, CompilationResult result,
636 char[] mainTypeName, ArrayList definedTypeNames,
637 ArrayList duplicateTypeNames) throws CoreException {
638 // char[][] previousTypeNames =
639 // newState.getDefinedTypeNamesFor(sourceLocator);
640 // if (previousTypeNames == null)
641 // previousTypeNames = new char[][]{mainTypeName};
642 // IPath packagePath = null;
643 // next : for (int i = 0, l = previousTypeNames.length; i < l; i++) {
644 // char[] previous = previousTypeNames[i];
645 // for (int j = 0, m = definedTypeNames.size(); j < m; j++)
646 // if (CharOperation.equals(previous, (char[]) definedTypeNames.get(j)))
648 // SourceFile sourceFile = (SourceFile) result.getCompilationUnit();
649 // if (packagePath == null) {
650 // int count = sourceFile.sourceLocation.sourceFolder.getFullPath()
652 // packagePath = sourceFile.resource.getFullPath().removeFirstSegments(
653 // count).removeLastSegments(1);
655 // if (secondaryTypesToRemove == null)
656 // this.secondaryTypesToRemove = new SimpleLookupTable();
657 // ArrayList types = (ArrayList) secondaryTypesToRemove
658 // .get(sourceFile.sourceLocation.binaryFolder);
659 // if (types == null)
660 // types = new ArrayList(definedTypeNames.size());
661 // types.add(packagePath.append(new String(previous)));
662 // secondaryTypesToRemove.put(sourceFile.sourceLocation.binaryFolder,
665 // super.finishedWith(sourceLocator, result, mainTypeName,
666 // definedTypeNames, duplicateTypeNames);
669 // protected void removeClassFile(IPath typePath, IContainer outputFolder)
670 // throws CoreException {
671 // if (typePath.lastSegment().indexOf('$') == -1) { // is not a nested type
672 // newState.removeQualifiedTypeName(typePath.toString());
673 // // add dependents even when the type thinks it does not exist to be on
675 // if (PHPBuilder.DEBUG)
676 // System.out.println("Found removed type " + typePath); //$NON-NLS-1$
677 // addDependentsOf(typePath, true); // when member types are removed, their
678 // // enclosing type is structurally
681 // IFile classFile = outputFolder.getFile(typePath
682 // .addFileExtension(PHPBuilder.CLASS_EXTENSION));
683 // if (classFile.exists()) {
684 // if (PHPBuilder.DEBUG)
685 // System.out.println("Deleting class file of removed type " + typePath);
687 // classFile.delete(IResource.FORCE, null);
690 // protected void removeSecondaryTypes() throws CoreException {
691 // if (secondaryTypesToRemove != null) { // delayed deleting secondary types
692 // // until the end of the compile loop
693 // Object[] keyTable = secondaryTypesToRemove.keyTable;
694 // Object[] valueTable = secondaryTypesToRemove.valueTable;
695 // for (int i = 0, l = keyTable.length; i < l; i++) {
696 // IContainer outputFolder = (IContainer) keyTable[i];
697 // if (outputFolder != null) {
698 // ArrayList paths = (ArrayList) valueTable[i];
699 // for (int j = 0, m = paths.size(); j < m; j++)
700 // removeClassFile((IPath) paths.get(j), outputFolder);
703 // this.secondaryTypesToRemove = null;
704 // if (previousSourceFiles != null && previousSourceFiles.size() > 1)
705 // this.previousSourceFiles = null; // cannot optimize recompile case when
706 // // a secondary type is deleted
709 protected void resetCollections() {
710 previousSourceFiles = sourceFiles.isEmpty() ? null
711 : (ArrayList) sourceFiles.clone();
713 qualifiedStrings.clear();
714 simpleStrings.clear();
718 protected void updateProblemsFor(SourceFile sourceFile,
719 CompilationResult result) throws CoreException {
720 IMarker[] markers = PHPBuilder.getProblemsFor(sourceFile.resource);
721 IProblem[] problems = result.getProblems();
722 if (problems == null && markers.length == 0)
725 // axelcl start insert - calculate line numbers
726 if (problems != null) {
727 for (int i = 0; i < problems.length; i++) {
728 if (problems[i].getSourceLineNumber() == 1) {
729 problems[i].setSourceLineNumber(ProblemHandler
730 .searchLineNumber(result.lineSeparatorPositions,
731 problems[i].getSourceStart()));
737 notifier.updateProblemCounts(markers, problems);
738 PHPBuilder.removeProblemsFor(sourceFile.resource);
739 storeProblemsFor(sourceFile, problems);
742 protected void updateTasksFor(SourceFile sourceFile,
743 CompilationResult result) throws CoreException {
744 IMarker[] markers = PHPBuilder.getTasksFor(sourceFile.resource);
745 IProblem[] tasks = result.getTasks();
746 if (tasks == null && markers.length == 0)
748 PHPBuilder.removeTasksFor(sourceFile.resource);
749 storeTasksFor(sourceFile, tasks);
752 // protected void writeClassFileBytes(byte[] bytes, IFile file, String
753 // qualifiedFileName, boolean isSecondaryType) throws CoreException {
754 // // Before writing out the class file, compare it to the previous file
755 // // If structural changes occured then add dependent source files
756 // if (file.exists()) {
757 // if (writeClassFileCheck(file, qualifiedFileName, bytes)) {
758 // if (JavaBuilder.DEBUG)
759 // System.out.println("Writing changed class file " +
760 // file.getName());//$NON-NLS-1$
761 // file.setContents(new ByteArrayInputStream(bytes), true, false, null);
762 // if (!file.isDerived())
763 // file.setDerived(true);
764 // } else if (JavaBuilder.DEBUG) {
765 // System.out.println("Skipped over unchanged class file " +
766 // file.getName());//$NON-NLS-1$
769 // if (isSecondaryType)
770 // addDependentsOf(new Path(qualifiedFileName), true); // new secondary type
771 // if (JavaBuilder.DEBUG)
772 // System.out.println("Writing new class file " +
773 // file.getName());//$NON-NLS-1$
774 // file.create(new ByteArrayInputStream(bytes), IResource.FORCE, null);
775 // file.setDerived(true);
778 // protected boolean writeClassFileCheck(IFile file, String fileName, byte[]
779 // newBytes) throws CoreException {
781 // byte[] oldBytes = ProjectPrefUtil.getResourceContentsAsByteArray(file);
782 // if (this.compileLoop > 1) { // only optimize files which were recompiled
783 // during the dependent pass, see 33990
784 // notEqual : if (newBytes.length == oldBytes.length) {
785 // for (int i = newBytes.length; --i >= 0;)
786 // if (newBytes[i] != oldBytes[i]) break notEqual;
787 // return false; // bytes are identical so skip them
790 // IPath location = file.getLocation();
791 // if (location == null) return false; // unable to determine location of
793 // ClassFileReader reader = new ClassFileReader(oldBytes,
794 // location.toString().toCharArray());
795 // // ignore local types since they're only visible inside a single method
796 // if (!(reader.isLocal() || reader.isAnonymous()) &&
797 // reader.hasStructuralChanges(newBytes)) {
798 // if (JavaBuilder.DEBUG)
799 // System.out.println("Type has structural changes " + fileName);
801 // addDependentsOf(new Path(fileName), true);
803 // } catch (ClassFormatException e) {
804 // addDependentsOf(new Path(fileName), true);
808 public String toString() {
809 return "incremental image builder for:\n\tnew state: " + newState; //$NON-NLS-1$
814 * static void dump(IResourceDelta delta) { StringBuffer buffer = new
815 * StringBuffer(); IPath path = delta.getFullPath(); for (int i =
816 * path.segmentCount(); --i > 0;) buffer.append(" "); switch
817 * (delta.getKind()) { case IResourceDelta.ADDED: buffer.append('+'); break;
818 * case IResourceDelta.REMOVED: buffer.append('-'); break; case
819 * IResourceDelta.CHANGED: '); break; case IResourceDelta.NO_CHANGE:
820 * buffer.append('='); break; default: buffer.append('?'); break; }
821 * buffer.append(path); System.out.println(buffer.toString());
822 * IResourceDelta[] children = delta.getAffectedChildren(); for (int i = 0,
823 * l = children.length; i < l; i++) dump(children[i]); }