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 changes
72 // or new/removed secondary type
73 // keep a loop counter to abort & perform a full build
75 System.out.println("INCREMENTAL build"); //$NON-NLS-1$
78 notifier.subTask(Util.bind("build.analyzingDeltas")); //$NON-NLS-1$
79 IResourceDelta sourceDelta = (IResourceDelta) deltas.get(javaBuilder.currentProject);
80 if (sourceDelta != null) {
81 sourceDelta.accept(new ParserVisitor(javaBuilder.currentProject, notifier.monitor));
83 if (!findSourceFiles(sourceDelta))
86 notifier.updateProgressDelta(0.10f);
87 // Object[] keyTable = deltas.keyTable;
88 // Object[] valueTable = deltas.valueTable;
89 //// final IdentifierIndexManager indexManager = PHPeclipsePlugin.getDefault()
90 //// .getIndexManager(javaBuilder.currentProject);
91 // for (int i = 0, l = valueTable.length; i < l; i++) {
92 // IResourceDelta delta = (IResourceDelta) valueTable[i];
93 // if (delta != null) {
94 // IResource resource = delta.getResource();
95 // int resourceType = resource.getType();
96 // if (resourceType == IResource.FILE) {
97 // switch (delta.getKind()) {
98 // case IResourceDelta.ADDED :
99 // if ((resource.getFileExtension() != null)
100 // && PHPFileUtil.isPHPFile((IFile) resource)) {
101 // // update indexfile for the project:
102 //// indexManager.addFile((IFile) resource);
105 // case IResourceDelta.CHANGED :
106 // if ((resource.getFileExtension() != null)
107 // && PHPFileUtil.isPHPFile((IFile) resource)) {
108 // // update indexfile for the project:
109 //// indexManager.changeFile((IFile) resource);
112 // case IResourceDelta.REMOVED :
113 // if ((resource.getFileExtension() != null)
114 // && PHPFileUtil.isPHPFile((IFile) resource)) {
115 // // update indexfile for the project:
116 //// indexManager.removeFile((IFile) resource);
121 // // ClasspathLocation[] classFoldersAndJars = (ClasspathLocation[])
122 // // javaBuilder.binaryLocationsPerProject.get(keyTable[i]);
123 // // if (classFoldersAndJars != null)
124 // // if (!findAffectedSourceFiles(delta, classFoldersAndJars)) return
128 notifier.updateProgressDelta(0.10f);
129 notifier.subTask(Util.bind("build.analyzingSources")); //$NON-NLS-1$
130 addAffectedSourceFiles();
131 notifier.updateProgressDelta(0.05f);
132 this.compileLoop = 0;
133 float increment = 0.40f;
134 while (sourceFiles.size() > 0) { // added to in acceptResult
135 if (++this.compileLoop > MaxCompileLoop) {
136 if (PHPBuilder.DEBUG)
137 System.out.println("ABORTING incremental build... exceeded loop count"); //$NON-NLS-1$
140 notifier.checkCancel();
141 SourceFile[] allSourceFiles = new SourceFile[sourceFiles.size()];
142 sourceFiles.toArray(allSourceFiles);
144 workQueue.addAll(allSourceFiles);
145 notifier.setProgressPerCompilationUnit(increment / allSourceFiles.length);
146 increment = increment / 2;
147 compile(allSourceFiles);
148 // removeSecondaryTypes();
149 addAffectedSourceFiles();
151 if (this.hasStructuralChanges && javaBuilder.javaProject.hasCycleMarker())
152 javaBuilder.mustPropagateStructuralChanges();
153 } catch (AbortIncrementalBuildException e) {
154 // abort the incremental build and let the batch builder handle the
156 if (PHPBuilder.DEBUG)
157 System.out.println("ABORTING incremental build... cannot find " + e.qualifiedTypeName + //$NON-NLS-1$
158 ". Could have been renamed inside its existing source file."); //$NON-NLS-1$
160 } catch (CoreException e) {
161 throw internalException(e);
168 protected void addAffectedSourceFiles() {
169 if (qualifiedStrings.isEmpty() && simpleStrings.isEmpty())
171 // the qualifiedStrings are of the form 'p1/p2' & the simpleStrings are
173 // char[][][] qualifiedNames = ReferenceCollection
174 // .internQualifiedNames(qualifiedStrings);
175 // if a well known qualified name was found then we can skip over these
176 // if (qualifiedNames.length < qualifiedStrings.size())
177 // qualifiedNames = null;
178 // char[][] simpleNames = ReferenceCollection.internSimpleNames(simpleStrings);
179 // if a well known name was found then we can skip over these
180 // if (simpleNames.length < simpleStrings.size())
181 // simpleNames = null;
182 // Object[] keyTable = newState.references.keyTable;
183 // Object[] valueTable = newState.references.valueTable;
184 // next : for (int i = 0, l = valueTable.length; i < l; i++) {
185 // ReferenceCollection refs = (ReferenceCollection) valueTable[i];
186 // if (refs != null && refs.includes(qualifiedNames, simpleNames)) {
187 // String typeLocator = (String) keyTable[i];
188 // IFile file = javaBuilder.currentProject.getFile(typeLocator);
189 // if (file.exists()) {
190 // ClasspathMultiDirectory md = sourceLocations[0];
191 // if (sourceLocations.length > 1) {
192 // IPath sourceFileFullPath = file.getFullPath();
193 // for (int j = 0, m = sourceLocations.length; j < m; j++) {
194 // if (sourceLocations[j].sourceFolder.getFullPath().isPrefixOf(
195 // sourceFileFullPath)) {
196 // md = sourceLocations[j];
197 // if (md.exclusionPatterns == null
198 // || !ProjectPrefUtil.isExcluded(file, md.exclusionPatterns))
203 // SourceFile sourceFile = new SourceFile(file, md, encoding);
204 // if (sourceFiles.contains(sourceFile))
206 // if (compiledAllAtOnce && previousSourceFiles != null
207 // && previousSourceFiles.contains(sourceFile))
208 // continue next; // can skip previously compiled files since already
209 // // saw hierarchy related problems
210 // if (PHPBuilder.DEBUG)
211 // System.out.println(" adding affected source file " + typeLocator); //$NON-NLS-1$
212 // // // update indexfile for the project:
213 // sourceFiles.add(sourceFile);
219 protected void addDependentsOf(IPath path, boolean hasStructuralChanges) {
220 if (hasStructuralChanges) {
221 newState.tagAsStructurallyChanged();
222 this.hasStructuralChanges = true;
224 // the qualifiedStrings are of the form 'p1/p2' & the simpleStrings are
226 path = path.setDevice(null);
227 String packageName = path.removeLastSegments(1).toString();
228 if (!qualifiedStrings.contains(packageName))
229 qualifiedStrings.add(packageName);
230 String typeName = path.lastSegment();
231 int memberIndex = typeName.indexOf('$');
233 typeName = typeName.substring(0, memberIndex);
234 if (!simpleStrings.contains(typeName)) {
235 if (PHPBuilder.DEBUG)
236 System.out.println(" will look for dependents of " //$NON-NLS-1$
237 + typeName + " in " + packageName); //$NON-NLS-1$
238 simpleStrings.add(typeName);
242 protected void cleanUp() {
244 this.sourceFiles = null;
245 this.previousSourceFiles = null;
246 this.qualifiedStrings = null;
247 this.simpleStrings = null;
248 this.secondaryTypesToRemove = null;
249 this.hasStructuralChanges = false;
250 this.compileLoop = 0;
253 //protected boolean findAffectedSourceFiles(IResourceDelta delta,
254 // ClasspathLocation[] classFoldersAndJars) {
255 // for (int i = 0, l = classFoldersAndJars.length; i < l; i++) {
256 // ClasspathLocation bLocation = classFoldersAndJars[i];
257 // // either a .class file folder or a zip/jar file
258 // if (bLocation != null) { // skip unchanged output folder
259 // IPath p = bLocation.getProjectRelativePath();
261 // IResourceDelta binaryDelta = delta.findMember(p);
262 // if (binaryDelta != null) {
263 // if (bLocation instanceof ClasspathJar) {
264 // if (JavaBuilder.DEBUG)
265 // System.out.println("ABORTING incremental build... found delta to jar/zip
266 // file"); //$NON-NLS-1$
267 // return false; // do full build since jar file was changed (added/removed
268 // were caught as classpath change)
270 // if (binaryDelta.getKind() == IResourceDelta.ADDED || binaryDelta.getKind()
271 // == IResourceDelta.REMOVED) {
272 // if (JavaBuilder.DEBUG)
273 // System.out.println("ABORTING incremental build... found added/removed
274 // binary folder"); //$NON-NLS-1$
275 // return false; // added/removed binary folder should not make it here
276 // (classpath change), but handle anyways
278 // int segmentCount = binaryDelta.getFullPath().segmentCount();
279 // IResourceDelta[] children = binaryDelta.getAffectedChildren(); // .class
280 // files from class folder
281 // for (int j = 0, m = children.length; j < m; j++)
282 // findAffectedSourceFiles(children[j], segmentCount);
283 // notifier.checkCancel();
290 protected void findAffectedSourceFiles(IResourceDelta binaryDelta, int segmentCount) {
291 // When a package becomes a type or vice versa, expect 2 deltas,
292 // one on the folder & one on the class file
293 IResource resource = binaryDelta.getResource();
294 switch (resource.getType()) {
295 case IResource.FOLDER:
296 switch (binaryDelta.getKind()) {
297 case IResourceDelta.ADDED:
298 case IResourceDelta.REMOVED:
299 IPath packagePath = resource.getFullPath().removeFirstSegments(segmentCount);
300 String packageName = packagePath.toString();
301 if (binaryDelta.getKind() == IResourceDelta.ADDED) {
302 // see if any known source file is from the same package...
303 // classpath already includes new package
304 // if (!newState.isKnownPackage(packageName)) {
305 // if (PHPBuilder.DEBUG)
306 // System.out.println("Found added package " + packageName); //$NON-NLS-1$
307 // addDependentsOf(packagePath, false);
310 if (PHPBuilder.DEBUG)
311 System.out.println("Skipped dependents of added package " + packageName); //$NON-NLS-1$
313 // see if the package still exists on the classpath
314 // if (!nameEnvironment.isPackage(packageName)) {
315 // if (JavaBuilder.DEBUG)
316 // System.out.println("Found removed package " + packageName);
318 // addDependentsOf(packagePath, false);
321 if (PHPBuilder.DEBUG)
322 System.out.println("Skipped dependents of removed package " + packageName); //$NON-NLS-1$
324 // fall thru & traverse the sub-packages and .class files
325 case IResourceDelta.CHANGED:
326 IResourceDelta[] children = binaryDelta.getAffectedChildren();
327 for (int i = 0, l = children.length; i < l; i++)
328 findAffectedSourceFiles(children[i], segmentCount);
332 // if (ProjectPrefUtil.isClassFileName(resource.getName())) {
334 // resource.getFullPath().removeFirstSegments(segmentCount).removeFileExtension();
335 // switch (binaryDelta.getKind()) {
336 // case IResourceDelta.ADDED :
337 // case IResourceDelta.REMOVED :
338 // if (JavaBuilder.DEBUG)
339 // System.out.println("Found added/removed class file " + typePath);
341 // addDependentsOf(typePath, false);
343 // case IResourceDelta.CHANGED :
344 // if ((binaryDelta.getFlags() & IResourceDelta.CONTENT) == 0)
345 // return; // skip it since it really isn't changed
346 // if (JavaBuilder.DEBUG)
347 // System.out.println("Found changed class file " + typePath);
349 // addDependentsOf(typePath, false);
356 protected boolean findSourceFiles(IResourceDelta delta) throws CoreException {
357 for (int i = 0, l = sourceLocations.length; i < l; i++) {
358 ClasspathMultiDirectory md = sourceLocations[i];
359 if (md.sourceFolder.equals(javaBuilder.currentProject)) {
360 // skip nested source & output folders when the project is a source
362 int segmentCount = delta.getFullPath().segmentCount();
363 IResourceDelta[] children = delta.getAffectedChildren();
364 for (int j = 0, m = children.length; j < m; j++)
365 if (!isExcludedFromProject(children[j].getFullPath()))
366 findSourceFiles(children[j], md, segmentCount);
368 IResourceDelta sourceDelta = delta.findMember(md.sourceFolder.getProjectRelativePath());
369 if (sourceDelta != null) {
370 if (sourceDelta.getKind() == IResourceDelta.REMOVED) {
371 if (PHPBuilder.DEBUG)
372 System.out.println("ABORTING incremental build... found removed source folder"); //$NON-NLS-1$
373 return false; // removed source folder should not make it here, but
374 // handle anyways (ADDED is supported)
376 int segmentCount = sourceDelta.getFullPath().segmentCount();
377 IResourceDelta[] children = sourceDelta.getAffectedChildren();
378 for (int j = 0, m = children.length; j < m; j++)
379 findSourceFiles(children[j], md, segmentCount);
382 notifier.checkCancel();
387 protected void findSourceFiles(IResourceDelta sourceDelta, ClasspathMultiDirectory md, int segmentCount) throws CoreException {
388 // When a package becomes a type or vice versa, expect 2 deltas,
389 // one on the folder & one on the source file
390 IResource resource = sourceDelta.getResource();
391 if (md.exclusionPatterns != null && Util.isExcluded(resource, md.exclusionPatterns))
393 switch (resource.getType()) {
394 case IResource.FOLDER:
395 switch (sourceDelta.getKind()) {
396 case IResourceDelta.ADDED:
397 IPath addedPackagePath = resource.getFullPath().removeFirstSegments(segmentCount);
398 // createFolder(addedPackagePath, md.binaryFolder); // ensure package
401 // add dependents even when the package thinks it exists to be on
403 if (PHPBuilder.DEBUG)
404 System.out.println("Found added package " + addedPackagePath); //$NON-NLS-1$
405 addDependentsOf(addedPackagePath, true);
406 // fall thru & collect all the source files
407 case IResourceDelta.CHANGED:
408 IResourceDelta[] children = sourceDelta.getAffectedChildren();
409 for (int i = 0, l = children.length; i < l; i++)
410 findSourceFiles(children[i], md, segmentCount);
412 case IResourceDelta.REMOVED:
413 IPath removedPackagePath = resource.getFullPath().removeFirstSegments(segmentCount);
414 if (sourceLocations.length > 1) {
415 for (int i = 0, l = sourceLocations.length; i < l; i++) {
416 if (sourceLocations[i].sourceFolder.getFolder(removedPackagePath).exists()) {
417 // only a package fragment was removed, same as removing
418 // multiple source files
419 // createFolder(removedPackagePath, md.binaryFolder); // ensure
425 IResourceDelta[] removedChildren = sourceDelta.getAffectedChildren();
426 for (int j = 0, m = removedChildren.length; j < m; j++)
427 findSourceFiles(removedChildren[j], md, segmentCount);
432 // IFolder removedPackageFolder = md.binaryFolder
433 // .getFolder(removedPackagePath);
434 // if (removedPackageFolder.exists())
435 // removedPackageFolder.delete(IResource.FORCE, null);
436 // add dependents even when the package thinks it does not exist to
437 // be on the safe side
438 if (PHPBuilder.DEBUG)
439 System.out.println("Found removed package " + removedPackagePath); //$NON-NLS-1$
440 addDependentsOf(removedPackagePath, true);
441 newState.removePackage(sourceDelta);
445 String resourceName = resource.getName();
446 if (net.sourceforge.phpdt.internal.compiler.util.Util.isJavaFileName(resourceName)) {
447 IPath typePath = resource.getFullPath().removeFirstSegments(segmentCount).removeFileExtension();
448 String typeLocator = resource.getProjectRelativePath().toString();
449 switch (sourceDelta.getKind()) {
450 case IResourceDelta.ADDED:
451 if (PHPBuilder.DEBUG)
452 System.out.println("Compile this added source file " + typeLocator); //$NON-NLS-1$
453 sourceFiles.add(new SourceFile((IFile) resource, md, encoding));
454 String typeName = typePath.toString();
455 // if (!newState.isDuplicateLocator(typeName, typeLocator)) { // adding
462 // if (PHPBuilder.DEBUG)
463 // System.out.println("Found added source file " + typeName); //$NON-NLS-1$
464 // addDependentsOf(typePath, true);
467 case IResourceDelta.REMOVED:
468 // char[][] definedTypeNames = newState
469 // .getDefinedTypeNamesFor(typeLocator);
470 // if (definedTypeNames == null) { // defined a single type matching
472 // removeClassFile(typePath, md.binaryFolder);
473 // if ((sourceDelta.getFlags() & IResourceDelta.MOVED_TO) != 0) {
474 // // remove problems and tasks for a compilation unit that is
475 // // being moved (to another package or renamed)
476 // // if the target file is a compilation unit, the new cu will
478 // // if the target file is a non-java resource, then markers
481 // IResource movedFile = javaBuilder.workspaceRoot
482 // .getFile(sourceDelta.getMovedToPath());
483 // PHPBuilder.removeProblemsAndTasksFor(movedFile);
486 if (PHPBuilder.DEBUG)
487 System.out.println("Found removed source file " + typePath.toString()); //$NON-NLS-1$
488 addDependentsOf(typePath, true); // add dependents of the
489 // source file since it may be
490 // involved in a name
492 // if (definedTypeNames.length > 0) { // skip it if it failed to
493 // // successfully define a
495 // IPath packagePath = typePath.removeLastSegments(1);
496 // for (int i = 0, l = definedTypeNames.length; i < l; i++)
497 // removeClassFile(packagePath.append(new String(
498 // definedTypeNames[i])), md.binaryFolder);
501 // newState.removeLocator(typeLocator);
503 case IResourceDelta.CHANGED:
504 if ((sourceDelta.getFlags() & IResourceDelta.CONTENT) == 0)
505 return; // skip it since it really isn't changed
506 if (PHPBuilder.DEBUG)
507 System.out.println("Compile this changed source file " + typeLocator); //$NON-NLS-1$
508 sourceFiles.add(new SourceFile((IFile) resource, md, encoding));
511 // } else if (ProjectPrefUtil.isClassFileName(resourceName)) {
512 // return; // skip class files
513 } else if (md.hasIndependentOutputFolder) {
514 if (javaBuilder.filterExtraResource(resource))
516 // copy all other resource deltas to the output folder
517 IPath resourcePath = resource.getFullPath().removeFirstSegments(segmentCount);
518 // IResource outputFile = md.binaryFolder.getFile(resourcePath);
519 switch (sourceDelta.getKind()) {
520 case IResourceDelta.ADDED:
521 // if (outputFile.exists()) {
522 // if (PHPBuilder.DEBUG)
523 // System.out.println("Deleting existing file " + resourcePath); //$NON-NLS-1$
524 // outputFile.delete(IResource.FORCE, null);
526 if (PHPBuilder.DEBUG)
527 System.out.println("Copying added file " + resourcePath); //$NON-NLS-1$
528 // createFolder(resourcePath.removeLastSegments(1), md.binaryFolder); // ensure
535 // resource.copy(outputFile.getFullPath(), IResource.FORCE, null);
536 // outputFile.setDerived(true);
538 case IResourceDelta.REMOVED:
539 // if (outputFile.exists()) {
540 // if (PHPBuilder.DEBUG)
541 // System.out.println("Deleting removed file " + resourcePath); //$NON-NLS-1$
542 // outputFile.delete(IResource.FORCE, null);
545 case IResourceDelta.CHANGED:
546 if ((sourceDelta.getFlags() & IResourceDelta.CONTENT) == 0)
547 return; // skip it since it really isn't changed
548 // if (outputFile.exists()) {
549 // if (PHPBuilder.DEBUG)
550 // System.out.println("Deleting existing file " + resourcePath); //$NON-NLS-1$
551 // outputFile.delete(IResource.FORCE, null);
553 if (PHPBuilder.DEBUG)
554 System.out.println("Copying changed file " + resourcePath); //$NON-NLS-1$
555 // createFolder(resourcePath.removeLastSegments(1), md.binaryFolder); // ensure
562 // resource.copy(outputFile.getFullPath(), IResource.FORCE, null);
563 // outputFile.setDerived(true);
570 protected void finishedWith(String sourceLocator, CompilationResult result, char[] mainTypeName, ArrayList definedTypeNames,
571 ArrayList duplicateTypeNames) throws CoreException {
572 // char[][] previousTypeNames = newState.getDefinedTypeNamesFor(sourceLocator);
573 // if (previousTypeNames == null)
574 // previousTypeNames = new char[][]{mainTypeName};
575 // IPath packagePath = null;
576 // next : for (int i = 0, l = previousTypeNames.length; i < l; i++) {
577 // char[] previous = previousTypeNames[i];
578 // for (int j = 0, m = definedTypeNames.size(); j < m; j++)
579 // if (CharOperation.equals(previous, (char[]) definedTypeNames.get(j)))
581 // SourceFile sourceFile = (SourceFile) result.getCompilationUnit();
582 // if (packagePath == null) {
583 // int count = sourceFile.sourceLocation.sourceFolder.getFullPath()
585 // packagePath = sourceFile.resource.getFullPath().removeFirstSegments(
586 // count).removeLastSegments(1);
588 // if (secondaryTypesToRemove == null)
589 // this.secondaryTypesToRemove = new SimpleLookupTable();
590 // ArrayList types = (ArrayList) secondaryTypesToRemove
591 // .get(sourceFile.sourceLocation.binaryFolder);
592 // if (types == null)
593 // types = new ArrayList(definedTypeNames.size());
594 // types.add(packagePath.append(new String(previous)));
595 // secondaryTypesToRemove.put(sourceFile.sourceLocation.binaryFolder, types);
597 // super.finishedWith(sourceLocator, result, mainTypeName,
598 // definedTypeNames, duplicateTypeNames);
601 // protected void removeClassFile(IPath typePath, IContainer outputFolder)
602 // throws CoreException {
603 // if (typePath.lastSegment().indexOf('$') == -1) { // is not a nested type
604 // newState.removeQualifiedTypeName(typePath.toString());
605 // // add dependents even when the type thinks it does not exist to be on
607 // if (PHPBuilder.DEBUG)
608 // System.out.println("Found removed type " + typePath); //$NON-NLS-1$
609 // addDependentsOf(typePath, true); // when member types are removed, their
610 // // enclosing type is structurally
613 // IFile classFile = outputFolder.getFile(typePath
614 // .addFileExtension(PHPBuilder.CLASS_EXTENSION));
615 // if (classFile.exists()) {
616 // if (PHPBuilder.DEBUG)
617 // System.out.println("Deleting class file of removed type " + typePath); //$NON-NLS-1$
618 // classFile.delete(IResource.FORCE, null);
621 // protected void removeSecondaryTypes() throws CoreException {
622 // if (secondaryTypesToRemove != null) { // delayed deleting secondary types
623 // // until the end of the compile loop
624 // Object[] keyTable = secondaryTypesToRemove.keyTable;
625 // Object[] valueTable = secondaryTypesToRemove.valueTable;
626 // for (int i = 0, l = keyTable.length; i < l; i++) {
627 // IContainer outputFolder = (IContainer) keyTable[i];
628 // if (outputFolder != null) {
629 // ArrayList paths = (ArrayList) valueTable[i];
630 // for (int j = 0, m = paths.size(); j < m; j++)
631 // removeClassFile((IPath) paths.get(j), outputFolder);
634 // this.secondaryTypesToRemove = null;
635 // if (previousSourceFiles != null && previousSourceFiles.size() > 1)
636 // this.previousSourceFiles = null; // cannot optimize recompile case when
637 // // a secondary type is deleted
640 protected void resetCollections() {
641 previousSourceFiles = sourceFiles.isEmpty() ? null : (ArrayList) sourceFiles.clone();
643 qualifiedStrings.clear();
644 simpleStrings.clear();
648 protected void updateProblemsFor(SourceFile sourceFile, CompilationResult result) throws CoreException {
649 IMarker[] markers = PHPBuilder.getProblemsFor(sourceFile.resource);
650 IProblem[] problems = result.getProblems();
651 if (problems == null && markers.length == 0)
654 // axelcl start insert - calculate line numbers
655 if (problems != null) {
656 for (int i = 0; i < problems.length; i++) {
657 if (problems[i].getSourceLineNumber() == 1) {
658 problems[i].setSourceLineNumber(ProblemHandler.searchLineNumber(result.lineSeparatorPositions, problems[i]
665 notifier.updateProblemCounts(markers, problems);
666 PHPBuilder.removeProblemsFor(sourceFile.resource);
667 storeProblemsFor(sourceFile, problems);
670 protected void updateTasksFor(SourceFile sourceFile, CompilationResult result) throws CoreException {
671 IMarker[] markers = PHPBuilder.getTasksFor(sourceFile.resource);
672 IProblem[] tasks = result.getTasks();
673 if (tasks == null && markers.length == 0)
675 PHPBuilder.removeTasksFor(sourceFile.resource);
676 storeTasksFor(sourceFile, tasks);
679 //protected void writeClassFileBytes(byte[] bytes, IFile file, String
680 // qualifiedFileName, boolean isSecondaryType) throws CoreException {
681 // // Before writing out the class file, compare it to the previous file
682 // // If structural changes occured then add dependent source files
683 // if (file.exists()) {
684 // if (writeClassFileCheck(file, qualifiedFileName, bytes)) {
685 // if (JavaBuilder.DEBUG)
686 // System.out.println("Writing changed class file " +
687 // file.getName());//$NON-NLS-1$
688 // file.setContents(new ByteArrayInputStream(bytes), true, false, null);
689 // if (!file.isDerived())
690 // file.setDerived(true);
691 // } else if (JavaBuilder.DEBUG) {
692 // System.out.println("Skipped over unchanged class file " +
693 // file.getName());//$NON-NLS-1$
696 // if (isSecondaryType)
697 // addDependentsOf(new Path(qualifiedFileName), true); // new secondary type
698 // if (JavaBuilder.DEBUG)
699 // System.out.println("Writing new class file " +
700 // file.getName());//$NON-NLS-1$
701 // file.create(new ByteArrayInputStream(bytes), IResource.FORCE, null);
702 // file.setDerived(true);
705 //protected boolean writeClassFileCheck(IFile file, String fileName, byte[]
706 // newBytes) throws CoreException {
708 // byte[] oldBytes = ProjectPrefUtil.getResourceContentsAsByteArray(file);
709 // if (this.compileLoop > 1) { // only optimize files which were recompiled
710 // during the dependent pass, see 33990
711 // notEqual : if (newBytes.length == oldBytes.length) {
712 // for (int i = newBytes.length; --i >= 0;)
713 // if (newBytes[i] != oldBytes[i]) break notEqual;
714 // return false; // bytes are identical so skip them
717 // IPath location = file.getLocation();
718 // if (location == null) return false; // unable to determine location of
720 // ClassFileReader reader = new ClassFileReader(oldBytes,
721 // location.toString().toCharArray());
722 // // ignore local types since they're only visible inside a single method
723 // if (!(reader.isLocal() || reader.isAnonymous()) &&
724 // reader.hasStructuralChanges(newBytes)) {
725 // if (JavaBuilder.DEBUG)
726 // System.out.println("Type has structural changes " + fileName);
728 // addDependentsOf(new Path(fileName), true);
730 // } catch (ClassFormatException e) {
731 // addDependentsOf(new Path(fileName), true);
735 public String toString() {
736 return "incremental image builder for:\n\tnew state: " + newState; //$NON-NLS-1$
741 * static void dump(IResourceDelta delta) { StringBuffer buffer = new StringBuffer(); IPath path = delta.getFullPath(); for (int i =
742 * path.segmentCount(); --i > 0;) buffer.append(" "); switch (delta.getKind()) { case IResourceDelta.ADDED: buffer.append('+');
743 * break; case IResourceDelta.REMOVED: buffer.append('-'); break; case IResourceDelta.CHANGED: '); break; case
744 * IResourceDelta.NO_CHANGE: buffer.append('='); break; default: buffer.append('?'); break; } buffer.append(path);
745 * System.out.println(buffer.toString()); IResourceDelta[] children = delta.getAffectedChildren(); for (int i = 0, l =
746 * children.length; i < l; i++) dump(children[i]); }