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;
12 import java.util.ArrayList;
14 import net.sourceforge.phpdt.core.compiler.IProblem;
15 import net.sourceforge.phpdt.internal.compiler.CompilationResult;
16 import net.sourceforge.phpdt.internal.compiler.problem.ProblemHandler;
17 import net.sourceforge.phpdt.internal.core.util.SimpleLookupTable;
18 import net.sourceforge.phpdt.internal.core.util.Util;
20 import org.eclipse.core.resources.IFile;
21 import org.eclipse.core.resources.IFolder;
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;
28 * The incremental image builder
30 public class IncrementalImageBuilder extends AbstractImageBuilder {
31 protected ArrayList sourceFiles;
32 protected ArrayList previousSourceFiles;
33 protected ArrayList qualifiedStrings;
34 protected ArrayList simpleStrings;
35 protected SimpleLookupTable secondaryTypesToRemove;
36 protected boolean hasStructuralChanges;
37 protected int compileLoop;
38 public static int MaxCompileLoop = 5; // perform a full build if it takes
39 // more than ? incremental compile
41 protected IncrementalImageBuilder(PHPBuilder javaBuilder) {
43 this.nameEnvironment.isIncrementalBuild = true;
44 this.newState.copyFrom(javaBuilder.lastState);
45 this.sourceFiles = new ArrayList(33);
46 this.previousSourceFiles = null;
47 this.qualifiedStrings = new ArrayList(33);
48 this.simpleStrings = new ArrayList(33);
49 this.hasStructuralChanges = false;
52 public boolean build(SimpleLookupTable deltas) {
54 // walk this project's deltas, find changed source files
55 // walk prereq projects' deltas, find changed class files & add affected
57 // use the build state # to skip the deltas for certain prereq projects
58 // ignore changed zip/jar files since they caused a full build
59 // compile the source files & acceptResult()
60 // compare the produced class files against the existing ones on disk
61 // recompile all dependent source files of any type with structural changes
62 // or new/removed secondary type
63 // keep a loop counter to abort & perform a full build
65 System.out.println("INCREMENTAL build"); //$NON-NLS-1$
68 notifier.subTask(Util.bind("build.analyzingDeltas")); //$NON-NLS-1$
69 IResourceDelta sourceDelta = (IResourceDelta) deltas
70 .get(javaBuilder.currentProject);
71 if (sourceDelta != null) {
72 sourceDelta.accept(new ParserVisitor(javaBuilder.currentProject, notifier.monitor));
74 if (!findSourceFiles(sourceDelta))
77 notifier.updateProgressDelta(0.10f);
78 // Object[] keyTable = deltas.keyTable;
79 // Object[] valueTable = deltas.valueTable;
80 //// final IdentifierIndexManager indexManager = PHPeclipsePlugin.getDefault()
81 //// .getIndexManager(javaBuilder.currentProject);
82 // for (int i = 0, l = valueTable.length; i < l; i++) {
83 // IResourceDelta delta = (IResourceDelta) valueTable[i];
84 // if (delta != null) {
85 // IResource resource = delta.getResource();
86 // int resourceType = resource.getType();
87 // if (resourceType == IResource.FILE) {
88 // switch (delta.getKind()) {
89 // case IResourceDelta.ADDED :
90 // if ((resource.getFileExtension() != null)
91 // && PHPFileUtil.isPHPFile((IFile) resource)) {
92 // // update indexfile for the project:
93 //// indexManager.addFile((IFile) resource);
96 // case IResourceDelta.CHANGED :
97 // if ((resource.getFileExtension() != null)
98 // && PHPFileUtil.isPHPFile((IFile) resource)) {
99 // // update indexfile for the project:
100 //// indexManager.changeFile((IFile) resource);
103 // case IResourceDelta.REMOVED :
104 // if ((resource.getFileExtension() != null)
105 // && PHPFileUtil.isPHPFile((IFile) resource)) {
106 // // update indexfile for the project:
107 //// indexManager.removeFile((IFile) resource);
112 // // ClasspathLocation[] classFoldersAndJars = (ClasspathLocation[])
113 // // javaBuilder.binaryLocationsPerProject.get(keyTable[i]);
114 // // if (classFoldersAndJars != null)
115 // // if (!findAffectedSourceFiles(delta, classFoldersAndJars)) return
119 notifier.updateProgressDelta(0.10f);
120 notifier.subTask(Util.bind("build.analyzingSources")); //$NON-NLS-1$
121 addAffectedSourceFiles();
122 notifier.updateProgressDelta(0.05f);
123 this.compileLoop = 0;
124 float increment = 0.40f;
125 while (sourceFiles.size() > 0) { // added to in acceptResult
126 if (++this.compileLoop > MaxCompileLoop) {
127 if (PHPBuilder.DEBUG)
129 .println("ABORTING incremental build... exceeded loop count"); //$NON-NLS-1$
132 notifier.checkCancel();
133 SourceFile[] allSourceFiles = new SourceFile[sourceFiles.size()];
134 sourceFiles.toArray(allSourceFiles);
136 workQueue.addAll(allSourceFiles);
137 notifier.setProgressPerCompilationUnit(increment
138 / allSourceFiles.length);
139 increment = increment / 2;
140 compile(allSourceFiles);
141 // removeSecondaryTypes();
142 addAffectedSourceFiles();
144 if (this.hasStructuralChanges && javaBuilder.javaProject.hasCycleMarker())
145 javaBuilder.mustPropagateStructuralChanges();
146 } catch (AbortIncrementalBuildException e) {
147 // abort the incremental build and let the batch builder handle the
149 if (PHPBuilder.DEBUG)
150 System.out.println("ABORTING incremental build... cannot find "
151 + e.qualifiedTypeName + //$NON-NLS-1$
152 ". Could have been renamed inside its existing source file."); //$NON-NLS-1$
154 } catch (CoreException e) {
155 throw internalException(e);
161 protected void addAffectedSourceFiles() {
162 if (qualifiedStrings.isEmpty() && simpleStrings.isEmpty())
164 // the qualifiedStrings are of the form 'p1/p2' & the simpleStrings are
166 // char[][][] qualifiedNames = ReferenceCollection
167 // .internQualifiedNames(qualifiedStrings);
168 // if a well known qualified name was found then we can skip over these
169 // if (qualifiedNames.length < qualifiedStrings.size())
170 // qualifiedNames = null;
171 // char[][] simpleNames = ReferenceCollection.internSimpleNames(simpleStrings);
172 // if a well known name was found then we can skip over these
173 // if (simpleNames.length < simpleStrings.size())
174 // simpleNames = null;
175 // Object[] keyTable = newState.references.keyTable;
176 // Object[] valueTable = newState.references.valueTable;
177 // next : for (int i = 0, l = valueTable.length; i < l; i++) {
178 // ReferenceCollection refs = (ReferenceCollection) valueTable[i];
179 // if (refs != null && refs.includes(qualifiedNames, simpleNames)) {
180 // String typeLocator = (String) keyTable[i];
181 // IFile file = javaBuilder.currentProject.getFile(typeLocator);
182 // if (file.exists()) {
183 // ClasspathMultiDirectory md = sourceLocations[0];
184 // if (sourceLocations.length > 1) {
185 // IPath sourceFileFullPath = file.getFullPath();
186 // for (int j = 0, m = sourceLocations.length; j < m; j++) {
187 // if (sourceLocations[j].sourceFolder.getFullPath().isPrefixOf(
188 // sourceFileFullPath)) {
189 // md = sourceLocations[j];
190 // if (md.exclusionPatterns == null
191 // || !ProjectPrefUtil.isExcluded(file, md.exclusionPatterns))
196 // SourceFile sourceFile = new SourceFile(file, md, encoding);
197 // if (sourceFiles.contains(sourceFile))
199 // if (compiledAllAtOnce && previousSourceFiles != null
200 // && previousSourceFiles.contains(sourceFile))
201 // continue next; // can skip previously compiled files since already
202 // // saw hierarchy related problems
203 // if (PHPBuilder.DEBUG)
204 // System.out.println(" adding affected source file " + typeLocator); //$NON-NLS-1$
205 // // // update indexfile for the project:
206 // sourceFiles.add(sourceFile);
211 protected void addDependentsOf(IPath path, boolean hasStructuralChanges) {
212 if (hasStructuralChanges) {
213 newState.tagAsStructurallyChanged();
214 this.hasStructuralChanges = true;
216 // the qualifiedStrings are of the form 'p1/p2' & the simpleStrings are
218 path = path.setDevice(null);
219 String packageName = path.removeLastSegments(1).toString();
220 if (!qualifiedStrings.contains(packageName))
221 qualifiedStrings.add(packageName);
222 String typeName = path.lastSegment();
223 int memberIndex = typeName.indexOf('$');
225 typeName = typeName.substring(0, memberIndex);
226 if (!simpleStrings.contains(typeName)) {
227 if (PHPBuilder.DEBUG)
228 System.out.println(" will look for dependents of " //$NON-NLS-1$
229 + typeName + " in " + packageName); //$NON-NLS-1$
230 simpleStrings.add(typeName);
233 protected void cleanUp() {
235 this.sourceFiles = null;
236 this.previousSourceFiles = null;
237 this.qualifiedStrings = null;
238 this.simpleStrings = null;
239 this.secondaryTypesToRemove = null;
240 this.hasStructuralChanges = false;
241 this.compileLoop = 0;
243 //protected boolean findAffectedSourceFiles(IResourceDelta delta,
244 // ClasspathLocation[] classFoldersAndJars) {
245 // for (int i = 0, l = classFoldersAndJars.length; i < l; i++) {
246 // ClasspathLocation bLocation = classFoldersAndJars[i];
247 // // either a .class file folder or a zip/jar file
248 // if (bLocation != null) { // skip unchanged output folder
249 // IPath p = bLocation.getProjectRelativePath();
251 // IResourceDelta binaryDelta = delta.findMember(p);
252 // if (binaryDelta != null) {
253 // if (bLocation instanceof ClasspathJar) {
254 // if (JavaBuilder.DEBUG)
255 // System.out.println("ABORTING incremental build... found delta to jar/zip
256 // file"); //$NON-NLS-1$
257 // return false; // do full build since jar file was changed (added/removed
258 // were caught as classpath change)
260 // if (binaryDelta.getKind() == IResourceDelta.ADDED || binaryDelta.getKind()
261 // == IResourceDelta.REMOVED) {
262 // if (JavaBuilder.DEBUG)
263 // System.out.println("ABORTING incremental build... found added/removed
264 // binary folder"); //$NON-NLS-1$
265 // return false; // added/removed binary folder should not make it here
266 // (classpath change), but handle anyways
268 // int segmentCount = binaryDelta.getFullPath().segmentCount();
269 // IResourceDelta[] children = binaryDelta.getAffectedChildren(); // .class
270 // files from class folder
271 // for (int j = 0, m = children.length; j < m; j++)
272 // findAffectedSourceFiles(children[j], segmentCount);
273 // notifier.checkCancel();
280 protected void findAffectedSourceFiles(IResourceDelta binaryDelta,
282 // When a package becomes a type or vice versa, expect 2 deltas,
283 // one on the folder & one on the class file
284 IResource resource = binaryDelta.getResource();
285 switch (resource.getType()) {
286 case IResource.FOLDER :
287 switch (binaryDelta.getKind()) {
288 case IResourceDelta.ADDED :
289 case IResourceDelta.REMOVED :
290 IPath packagePath = resource.getFullPath().removeFirstSegments(
292 String packageName = packagePath.toString();
293 if (binaryDelta.getKind() == IResourceDelta.ADDED) {
294 // see if any known source file is from the same package...
295 // classpath already includes new package
296 // if (!newState.isKnownPackage(packageName)) {
297 // if (PHPBuilder.DEBUG)
298 // System.out.println("Found added package " + packageName); //$NON-NLS-1$
299 // addDependentsOf(packagePath, false);
302 if (PHPBuilder.DEBUG)
303 System.out.println("Skipped dependents of added package "
304 + packageName); //$NON-NLS-1$
306 // see if the package still exists on the classpath
307 // if (!nameEnvironment.isPackage(packageName)) {
308 // if (JavaBuilder.DEBUG)
309 // System.out.println("Found removed package " + packageName);
311 // addDependentsOf(packagePath, false);
314 if (PHPBuilder.DEBUG)
315 System.out.println("Skipped dependents of removed package "
316 + packageName); //$NON-NLS-1$
318 // fall thru & traverse the sub-packages and .class files
319 case IResourceDelta.CHANGED :
320 IResourceDelta[] children = binaryDelta.getAffectedChildren();
321 for (int i = 0, l = children.length; i < l; i++)
322 findAffectedSourceFiles(children[i], segmentCount);
325 case IResource.FILE :
326 // if (ProjectPrefUtil.isClassFileName(resource.getName())) {
328 // resource.getFullPath().removeFirstSegments(segmentCount).removeFileExtension();
329 // switch (binaryDelta.getKind()) {
330 // case IResourceDelta.ADDED :
331 // case IResourceDelta.REMOVED :
332 // if (JavaBuilder.DEBUG)
333 // System.out.println("Found added/removed class file " + typePath);
335 // addDependentsOf(typePath, false);
337 // case IResourceDelta.CHANGED :
338 // if ((binaryDelta.getFlags() & IResourceDelta.CONTENT) == 0)
339 // return; // skip it since it really isn't changed
340 // if (JavaBuilder.DEBUG)
341 // System.out.println("Found changed class file " + typePath);
343 // addDependentsOf(typePath, false);
349 protected boolean findSourceFiles(IResourceDelta delta) throws CoreException {
350 for (int i = 0, l = sourceLocations.length; i < l; i++) {
351 ClasspathMultiDirectory md = sourceLocations[i];
352 if (md.sourceFolder.equals(javaBuilder.currentProject)) {
353 // skip nested source & output folders when the project is a source
355 int segmentCount = delta.getFullPath().segmentCount();
356 IResourceDelta[] children = delta.getAffectedChildren();
357 for (int j = 0, m = children.length; j < m; j++)
358 if (!isExcludedFromProject(children[j].getFullPath()))
359 findSourceFiles(children[j], md, segmentCount);
361 IResourceDelta sourceDelta = delta.findMember(md.sourceFolder
362 .getProjectRelativePath());
363 if (sourceDelta != null) {
364 if (sourceDelta.getKind() == IResourceDelta.REMOVED) {
365 if (PHPBuilder.DEBUG)
367 .println("ABORTING incremental build... found removed source folder"); //$NON-NLS-1$
368 return false; // removed source folder should not make it here, but
369 // handle anyways (ADDED is supported)
371 int segmentCount = sourceDelta.getFullPath().segmentCount();
372 IResourceDelta[] children = sourceDelta.getAffectedChildren();
373 for (int j = 0, m = children.length; j < m; j++)
374 findSourceFiles(children[j], md, segmentCount);
377 notifier.checkCancel();
381 protected void findSourceFiles(IResourceDelta sourceDelta,
382 ClasspathMultiDirectory md, int segmentCount) throws CoreException {
383 // When a package becomes a type or vice versa, expect 2 deltas,
384 // one on the folder & one on the source file
385 IResource resource = sourceDelta.getResource();
386 if (md.exclusionPatterns != null
387 && Util.isExcluded(resource, md.exclusionPatterns))
389 switch (resource.getType()) {
390 case IResource.FOLDER :
391 switch (sourceDelta.getKind()) {
392 case IResourceDelta.ADDED :
393 IPath addedPackagePath = resource.getFullPath()
394 .removeFirstSegments(segmentCount);
395 // createFolder(addedPackagePath, md.binaryFolder); // ensure package
398 // add dependents even when the package thinks it exists to be on
400 if (PHPBuilder.DEBUG)
401 System.out.println("Found added package " + addedPackagePath); //$NON-NLS-1$
402 addDependentsOf(addedPackagePath, true);
403 // fall thru & collect all the source files
404 case IResourceDelta.CHANGED :
405 IResourceDelta[] children = sourceDelta.getAffectedChildren();
406 for (int i = 0, l = children.length; i < l; i++)
407 findSourceFiles(children[i], md, segmentCount);
409 case IResourceDelta.REMOVED :
410 IPath removedPackagePath = resource.getFullPath()
411 .removeFirstSegments(segmentCount);
412 if (sourceLocations.length > 1) {
413 for (int i = 0, l = sourceLocations.length; i < l; i++) {
414 if (sourceLocations[i].sourceFolder.getFolder(
415 removedPackagePath).exists()) {
416 // only a package fragment was removed, same as removing
417 // multiple source files
418 // createFolder(removedPackagePath, md.binaryFolder); // ensure
424 IResourceDelta[] removedChildren = sourceDelta
425 .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);
444 case IResource.FILE :
445 String resourceName = resource.getName();
446 if (net.sourceforge.phpdt.internal.compiler.util.Util.isJavaFileName(resourceName)) {
447 IPath typePath = resource.getFullPath().removeFirstSegments(
448 segmentCount).removeFileExtension();
449 String typeLocator = resource.getProjectRelativePath().toString();
450 switch (sourceDelta.getKind()) {
451 case IResourceDelta.ADDED :
452 if (PHPBuilder.DEBUG)
453 System.out.println("Compile this added source file "
454 + typeLocator); //$NON-NLS-1$
455 sourceFiles.add(new SourceFile((IFile) resource, md, encoding));
456 String typeName = typePath.toString();
457 // if (!newState.isDuplicateLocator(typeName, typeLocator)) { // adding
464 // if (PHPBuilder.DEBUG)
465 // System.out.println("Found added source file " + typeName); //$NON-NLS-1$
466 // addDependentsOf(typePath, true);
469 case IResourceDelta.REMOVED :
470 // char[][] definedTypeNames = newState
471 // .getDefinedTypeNamesFor(typeLocator);
472 // if (definedTypeNames == null) { // defined a single type matching
474 // removeClassFile(typePath, md.binaryFolder);
475 // if ((sourceDelta.getFlags() & IResourceDelta.MOVED_TO) != 0) {
476 // // remove problems and tasks for a compilation unit that is
477 // // being moved (to another package or renamed)
478 // // if the target file is a compilation unit, the new cu will
480 // // if the target file is a non-java resource, then markers
483 // IResource movedFile = javaBuilder.workspaceRoot
484 // .getFile(sourceDelta.getMovedToPath());
485 // PHPBuilder.removeProblemsAndTasksFor(movedFile);
488 if (PHPBuilder.DEBUG)
489 System.out.println("Found removed source file "
490 + typePath.toString()); //$NON-NLS-1$
491 addDependentsOf(typePath, true); // add dependents of the
492 // source file since it may be
493 // involved in a name
495 // if (definedTypeNames.length > 0) { // skip it if it failed to
496 // // successfully define a
498 // IPath packagePath = typePath.removeLastSegments(1);
499 // for (int i = 0, l = definedTypeNames.length; i < l; i++)
500 // removeClassFile(packagePath.append(new String(
501 // definedTypeNames[i])), md.binaryFolder);
504 // newState.removeLocator(typeLocator);
506 case IResourceDelta.CHANGED :
507 if ((sourceDelta.getFlags() & IResourceDelta.CONTENT) == 0)
508 return; // skip it since it really isn't changed
509 if (PHPBuilder.DEBUG)
510 System.out.println("Compile this changed source file "
511 + typeLocator); //$NON-NLS-1$
512 sourceFiles.add(new SourceFile((IFile) resource, md, encoding));
515 // } else if (ProjectPrefUtil.isClassFileName(resourceName)) {
516 // return; // skip class files
517 } else if (md.hasIndependentOutputFolder) {
518 if (javaBuilder.filterExtraResource(resource))
520 // copy all other resource deltas to the output folder
521 IPath resourcePath = resource.getFullPath().removeFirstSegments(
523 // IResource outputFile = md.binaryFolder.getFile(resourcePath);
524 switch (sourceDelta.getKind()) {
525 case IResourceDelta.ADDED :
526 // if (outputFile.exists()) {
527 // if (PHPBuilder.DEBUG)
528 // System.out.println("Deleting existing file " + resourcePath); //$NON-NLS-1$
529 // outputFile.delete(IResource.FORCE, null);
531 if (PHPBuilder.DEBUG)
532 System.out.println("Copying added file " + resourcePath); //$NON-NLS-1$
533 // createFolder(resourcePath.removeLastSegments(1), md.binaryFolder); // ensure
540 // resource.copy(outputFile.getFullPath(), IResource.FORCE, null);
541 // outputFile.setDerived(true);
543 case IResourceDelta.REMOVED :
544 // if (outputFile.exists()) {
545 // if (PHPBuilder.DEBUG)
546 // System.out.println("Deleting removed file " + resourcePath); //$NON-NLS-1$
547 // outputFile.delete(IResource.FORCE, null);
550 case IResourceDelta.CHANGED :
551 if ((sourceDelta.getFlags() & IResourceDelta.CONTENT) == 0)
552 return; // skip it since it really isn't changed
553 // if (outputFile.exists()) {
554 // if (PHPBuilder.DEBUG)
555 // System.out.println("Deleting existing file " + resourcePath); //$NON-NLS-1$
556 // outputFile.delete(IResource.FORCE, null);
558 if (PHPBuilder.DEBUG)
559 System.out.println("Copying changed file " + resourcePath); //$NON-NLS-1$
560 // createFolder(resourcePath.removeLastSegments(1), md.binaryFolder); // ensure
567 // resource.copy(outputFile.getFullPath(), IResource.FORCE, null);
568 // outputFile.setDerived(true);
574 protected void finishedWith(String sourceLocator, CompilationResult result,
575 char[] mainTypeName, ArrayList definedTypeNames,
576 ArrayList duplicateTypeNames) throws CoreException {
577 // char[][] previousTypeNames = newState.getDefinedTypeNamesFor(sourceLocator);
578 // if (previousTypeNames == null)
579 // previousTypeNames = new char[][]{mainTypeName};
580 // IPath packagePath = null;
581 // next : for (int i = 0, l = previousTypeNames.length; i < l; i++) {
582 // char[] previous = previousTypeNames[i];
583 // for (int j = 0, m = definedTypeNames.size(); j < m; j++)
584 // if (CharOperation.equals(previous, (char[]) definedTypeNames.get(j)))
586 // SourceFile sourceFile = (SourceFile) result.getCompilationUnit();
587 // if (packagePath == null) {
588 // int count = sourceFile.sourceLocation.sourceFolder.getFullPath()
590 // packagePath = sourceFile.resource.getFullPath().removeFirstSegments(
591 // count).removeLastSegments(1);
593 // if (secondaryTypesToRemove == null)
594 // this.secondaryTypesToRemove = new SimpleLookupTable();
595 // ArrayList types = (ArrayList) secondaryTypesToRemove
596 // .get(sourceFile.sourceLocation.binaryFolder);
597 // if (types == null)
598 // types = new ArrayList(definedTypeNames.size());
599 // types.add(packagePath.append(new String(previous)));
600 // secondaryTypesToRemove.put(sourceFile.sourceLocation.binaryFolder, types);
602 // super.finishedWith(sourceLocator, result, mainTypeName,
603 // definedTypeNames, duplicateTypeNames);
605 // protected void removeClassFile(IPath typePath, IContainer outputFolder)
606 // throws CoreException {
607 // if (typePath.lastSegment().indexOf('$') == -1) { // is not a nested type
608 // newState.removeQualifiedTypeName(typePath.toString());
609 // // add dependents even when the type thinks it does not exist to be on
611 // if (PHPBuilder.DEBUG)
612 // System.out.println("Found removed type " + typePath); //$NON-NLS-1$
613 // addDependentsOf(typePath, true); // when member types are removed, their
614 // // enclosing type is structurally
617 // IFile classFile = outputFolder.getFile(typePath
618 // .addFileExtension(PHPBuilder.CLASS_EXTENSION));
619 // if (classFile.exists()) {
620 // if (PHPBuilder.DEBUG)
621 // System.out.println("Deleting class file of removed type " + typePath); //$NON-NLS-1$
622 // classFile.delete(IResource.FORCE, null);
625 // protected void removeSecondaryTypes() throws CoreException {
626 // if (secondaryTypesToRemove != null) { // delayed deleting secondary types
627 // // until the end of the compile loop
628 // Object[] keyTable = secondaryTypesToRemove.keyTable;
629 // Object[] valueTable = secondaryTypesToRemove.valueTable;
630 // for (int i = 0, l = keyTable.length; i < l; i++) {
631 // IContainer outputFolder = (IContainer) keyTable[i];
632 // if (outputFolder != null) {
633 // ArrayList paths = (ArrayList) valueTable[i];
634 // for (int j = 0, m = paths.size(); j < m; j++)
635 // removeClassFile((IPath) paths.get(j), outputFolder);
638 // this.secondaryTypesToRemove = null;
639 // if (previousSourceFiles != null && previousSourceFiles.size() > 1)
640 // this.previousSourceFiles = null; // cannot optimize recompile case when
641 // // a secondary type is deleted
644 protected void resetCollections() {
645 previousSourceFiles = sourceFiles.isEmpty()
647 : (ArrayList) sourceFiles.clone();
649 qualifiedStrings.clear();
650 simpleStrings.clear();
653 protected void updateProblemsFor(SourceFile sourceFile,
654 CompilationResult result) throws CoreException {
655 IMarker[] markers = PHPBuilder.getProblemsFor(sourceFile.resource);
656 IProblem[] problems = result.getProblems();
657 if (problems == null && markers.length == 0)
660 // axelcl start insert - calculate line numbers
661 for (int i = 0; i < problems.length; i++) {
662 if (problems[i].getSourceLineNumber() == 1) {
663 problems[i].setSourceLineNumber(ProblemHandler
664 .searchLineNumber(result.lineSeparatorPositions, problems[i].getSourceStart()));
669 notifier.updateProblemCounts(markers, problems);
670 PHPBuilder.removeProblemsFor(sourceFile.resource);
671 storeProblemsFor(sourceFile, problems);
673 protected void updateTasksFor(SourceFile sourceFile, CompilationResult result)
674 throws CoreException {
675 IMarker[] markers = PHPBuilder.getTasksFor(sourceFile.resource);
676 IProblem[] tasks = result.getTasks();
677 if (tasks == null && markers.length == 0)
679 PHPBuilder.removeTasksFor(sourceFile.resource);
680 storeTasksFor(sourceFile, tasks);
682 //protected void writeClassFileBytes(byte[] bytes, IFile file, String
683 // qualifiedFileName, boolean isSecondaryType) throws CoreException {
684 // // Before writing out the class file, compare it to the previous file
685 // // If structural changes occured then add dependent source files
686 // if (file.exists()) {
687 // if (writeClassFileCheck(file, qualifiedFileName, bytes)) {
688 // if (JavaBuilder.DEBUG)
689 // System.out.println("Writing changed class file " +
690 // file.getName());//$NON-NLS-1$
691 // file.setContents(new ByteArrayInputStream(bytes), true, false, null);
692 // if (!file.isDerived())
693 // file.setDerived(true);
694 // } else if (JavaBuilder.DEBUG) {
695 // System.out.println("Skipped over unchanged class file " +
696 // file.getName());//$NON-NLS-1$
699 // if (isSecondaryType)
700 // addDependentsOf(new Path(qualifiedFileName), true); // new secondary type
701 // if (JavaBuilder.DEBUG)
702 // System.out.println("Writing new class file " +
703 // file.getName());//$NON-NLS-1$
704 // file.create(new ByteArrayInputStream(bytes), IResource.FORCE, null);
705 // file.setDerived(true);
708 //protected boolean writeClassFileCheck(IFile file, String fileName, byte[]
709 // newBytes) throws CoreException {
711 // byte[] oldBytes = ProjectPrefUtil.getResourceContentsAsByteArray(file);
712 // if (this.compileLoop > 1) { // only optimize files which were recompiled
713 // during the dependent pass, see 33990
714 // notEqual : if (newBytes.length == oldBytes.length) {
715 // for (int i = newBytes.length; --i >= 0;)
716 // if (newBytes[i] != oldBytes[i]) break notEqual;
717 // return false; // bytes are identical so skip them
720 // IPath location = file.getLocation();
721 // if (location == null) return false; // unable to determine location of
723 // ClassFileReader reader = new ClassFileReader(oldBytes,
724 // location.toString().toCharArray());
725 // // ignore local types since they're only visible inside a single method
726 // if (!(reader.isLocal() || reader.isAnonymous()) &&
727 // reader.hasStructuralChanges(newBytes)) {
728 // if (JavaBuilder.DEBUG)
729 // System.out.println("Type has structural changes " + fileName);
731 // addDependentsOf(new Path(fileName), true);
733 // } catch (ClassFormatException e) {
734 // addDependentsOf(new Path(fileName), true);
738 public String toString() {
739 return "incremental image builder for:\n\tnew state: " + newState; //$NON-NLS-1$
744 * static void dump(IResourceDelta delta) { StringBuffer buffer = new
745 * StringBuffer(); IPath path = delta.getFullPath(); for (int i =
746 * path.segmentCount(); --i > 0;) buffer.append(" "); switch
747 * (delta.getKind()) { case IResourceDelta.ADDED: buffer.append('+'); break;
748 * case IResourceDelta.REMOVED: buffer.append('-'); break; case
749 * IResourceDelta.CHANGED: '); break; case IResourceDelta.NO_CHANGE:
750 * buffer.append('='); break; default: buffer.append('?'); break; }
751 * buffer.append(path); System.out.println(buffer.toString());
752 * IResourceDelta[] children = delta.getAffectedChildren(); for (int i = 0, l =
753 * children.length; i < l; i++) dump(children[i]); }