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.IFolder;
23 import org.eclipse.core.resources.IMarker;
24 import org.eclipse.core.resources.IResource;
25 import org.eclipse.core.resources.IResourceDelta;
26 import org.eclipse.core.runtime.CoreException;
27 import org.eclipse.core.runtime.IPath;
30 * The incremental image builder
32 public class IncrementalImageBuilder extends AbstractImageBuilder {
33 protected ArrayList sourceFiles;
35 protected ArrayList previousSourceFiles;
37 protected ArrayList qualifiedStrings;
39 protected ArrayList simpleStrings;
41 protected SimpleLookupTable secondaryTypesToRemove;
43 protected boolean hasStructuralChanges;
45 protected int compileLoop;
47 public static int MaxCompileLoop = 5; // perform a full build if it takes
49 // more than ? incremental compile
51 protected IncrementalImageBuilder(PHPBuilder javaBuilder) {
53 this.nameEnvironment.isIncrementalBuild = true;
54 this.newState.copyFrom(javaBuilder.lastState);
55 this.sourceFiles = new ArrayList(33);
56 this.previousSourceFiles = null;
57 this.qualifiedStrings = new ArrayList(33);
58 this.simpleStrings = new ArrayList(33);
59 this.hasStructuralChanges = false;
63 public boolean build(SimpleLookupTable deltas) {
65 // walk this project's deltas, find changed source files
66 // walk prereq projects' deltas, find changed class files & add affected
68 // use the build state # to skip the deltas for certain prereq projects
69 // ignore changed zip/jar files since they caused a full build
70 // compile the source files & acceptResult()
71 // compare the produced class files against the existing ones on disk
72 // recompile all dependent source files of any type with structural changes
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.get(javaBuilder.currentProject);
81 if (sourceDelta != null) {
82 sourceDelta.accept(new ParserVisitor(javaBuilder.currentProject, notifier.monitor));
84 if (!findSourceFiles(sourceDelta))
87 notifier.updateProgressDelta(0.10f);
88 // Object[] keyTable = deltas.keyTable;
89 // Object[] valueTable = deltas.valueTable;
90 //// final IdentifierIndexManager indexManager = PHPeclipsePlugin.getDefault()
91 //// .getIndexManager(javaBuilder.currentProject);
92 // for (int i = 0, l = valueTable.length; i < l; i++) {
93 // IResourceDelta delta = (IResourceDelta) valueTable[i];
94 // if (delta != null) {
95 // IResource resource = delta.getResource();
96 // int resourceType = resource.getType();
97 // if (resourceType == IResource.FILE) {
98 // switch (delta.getKind()) {
99 // case IResourceDelta.ADDED :
100 // if ((resource.getFileExtension() != null)
101 // && PHPFileUtil.isPHPFile((IFile) resource)) {
102 // // update indexfile for the project:
103 //// indexManager.addFile((IFile) resource);
106 // case IResourceDelta.CHANGED :
107 // if ((resource.getFileExtension() != null)
108 // && PHPFileUtil.isPHPFile((IFile) resource)) {
109 // // update indexfile for the project:
110 //// indexManager.changeFile((IFile) resource);
113 // case IResourceDelta.REMOVED :
114 // if ((resource.getFileExtension() != null)
115 // && PHPFileUtil.isPHPFile((IFile) resource)) {
116 // // update indexfile for the project:
117 //// indexManager.removeFile((IFile) resource);
122 // // ClasspathLocation[] classFoldersAndJars = (ClasspathLocation[])
123 // // javaBuilder.binaryLocationsPerProject.get(keyTable[i]);
124 // // if (classFoldersAndJars != null)
125 // // if (!findAffectedSourceFiles(delta, classFoldersAndJars)) return
129 notifier.updateProgressDelta(0.10f);
130 notifier.subTask(Util.bind("build.analyzingSources")); //$NON-NLS-1$
131 addAffectedSourceFiles();
132 notifier.updateProgressDelta(0.05f);
133 this.compileLoop = 0;
134 float increment = 0.40f;
135 while (sourceFiles.size() > 0) { // added to in acceptResult
136 if (++this.compileLoop > MaxCompileLoop) {
137 if (PHPBuilder.DEBUG)
138 System.out.println("ABORTING incremental build... exceeded loop count"); //$NON-NLS-1$
141 notifier.checkCancel();
142 SourceFile[] allSourceFiles = new SourceFile[sourceFiles.size()];
143 sourceFiles.toArray(allSourceFiles);
145 workQueue.addAll(allSourceFiles);
146 notifier.setProgressPerCompilationUnit(increment / allSourceFiles.length);
147 increment = increment / 2;
148 compile(allSourceFiles);
149 // removeSecondaryTypes();
150 addAffectedSourceFiles();
152 if (this.hasStructuralChanges && javaBuilder.javaProject.hasCycleMarker())
153 javaBuilder.mustPropagateStructuralChanges();
154 } catch (AbortIncrementalBuildException e) {
155 // abort the incremental build and let the batch builder handle the
157 if (PHPBuilder.DEBUG)
158 System.out.println("ABORTING incremental build... cannot find " + e.qualifiedTypeName + //$NON-NLS-1$
159 ". Could have been renamed inside its existing source file."); //$NON-NLS-1$
161 } catch (CoreException e) {
162 throw internalException(e);
169 protected void addAffectedSourceFiles() {
170 if (qualifiedStrings.isEmpty() && simpleStrings.isEmpty())
172 // the qualifiedStrings are of the form 'p1/p2' & the simpleStrings are
174 // char[][][] qualifiedNames = ReferenceCollection
175 // .internQualifiedNames(qualifiedStrings);
176 // if a well known qualified name was found then we can skip over these
177 // if (qualifiedNames.length < qualifiedStrings.size())
178 // qualifiedNames = null;
179 // char[][] simpleNames = ReferenceCollection.internSimpleNames(simpleStrings);
180 // if a well known name was found then we can skip over these
181 // if (simpleNames.length < simpleStrings.size())
182 // simpleNames = null;
183 // Object[] keyTable = newState.references.keyTable;
184 // Object[] valueTable = newState.references.valueTable;
185 // next : for (int i = 0, l = valueTable.length; i < l; i++) {
186 // ReferenceCollection refs = (ReferenceCollection) valueTable[i];
187 // if (refs != null && refs.includes(qualifiedNames, simpleNames)) {
188 // String typeLocator = (String) keyTable[i];
189 // IFile file = javaBuilder.currentProject.getFile(typeLocator);
190 // if (file.exists()) {
191 // ClasspathMultiDirectory md = sourceLocations[0];
192 // if (sourceLocations.length > 1) {
193 // IPath sourceFileFullPath = file.getFullPath();
194 // for (int j = 0, m = sourceLocations.length; j < m; j++) {
195 // if (sourceLocations[j].sourceFolder.getFullPath().isPrefixOf(
196 // sourceFileFullPath)) {
197 // md = sourceLocations[j];
198 // if (md.exclusionPatterns == null
199 // || !ProjectPrefUtil.isExcluded(file, md.exclusionPatterns))
204 // SourceFile sourceFile = new SourceFile(file, md, encoding);
205 // if (sourceFiles.contains(sourceFile))
207 // if (compiledAllAtOnce && previousSourceFiles != null
208 // && previousSourceFiles.contains(sourceFile))
209 // continue next; // can skip previously compiled files since already
210 // // saw hierarchy related problems
211 // if (PHPBuilder.DEBUG)
212 // System.out.println(" adding affected source file " + typeLocator); //$NON-NLS-1$
213 // // // update indexfile for the project:
214 // sourceFiles.add(sourceFile);
220 protected void addDependentsOf(IPath path, boolean hasStructuralChanges) {
221 if (hasStructuralChanges) {
222 newState.tagAsStructurallyChanged();
223 this.hasStructuralChanges = true;
225 // the qualifiedStrings are of the form 'p1/p2' & the simpleStrings are
227 path = path.setDevice(null);
228 String packageName = path.removeLastSegments(1).toString();
229 if (!qualifiedStrings.contains(packageName))
230 qualifiedStrings.add(packageName);
231 String typeName = path.lastSegment();
232 int memberIndex = typeName.indexOf('$');
234 typeName = typeName.substring(0, memberIndex);
235 if (!simpleStrings.contains(typeName)) {
236 if (PHPBuilder.DEBUG)
237 System.out.println(" will look for dependents of " //$NON-NLS-1$
238 + typeName + " in " + packageName); //$NON-NLS-1$
239 simpleStrings.add(typeName);
243 protected void cleanUp() {
245 this.sourceFiles = null;
246 this.previousSourceFiles = null;
247 this.qualifiedStrings = null;
248 this.simpleStrings = null;
249 this.secondaryTypesToRemove = null;
250 this.hasStructuralChanges = false;
251 this.compileLoop = 0;
254 //protected boolean findAffectedSourceFiles(IResourceDelta delta,
255 // ClasspathLocation[] classFoldersAndJars) {
256 // for (int i = 0, l = classFoldersAndJars.length; i < l; i++) {
257 // ClasspathLocation bLocation = classFoldersAndJars[i];
258 // // either a .class file folder or a zip/jar file
259 // if (bLocation != null) { // skip unchanged output folder
260 // IPath p = bLocation.getProjectRelativePath();
262 // IResourceDelta binaryDelta = delta.findMember(p);
263 // if (binaryDelta != null) {
264 // if (bLocation instanceof ClasspathJar) {
265 // if (JavaBuilder.DEBUG)
266 // System.out.println("ABORTING incremental build... found delta to jar/zip
267 // file"); //$NON-NLS-1$
268 // return false; // do full build since jar file was changed (added/removed
269 // were caught as classpath change)
271 // if (binaryDelta.getKind() == IResourceDelta.ADDED || binaryDelta.getKind()
272 // == IResourceDelta.REMOVED) {
273 // if (JavaBuilder.DEBUG)
274 // System.out.println("ABORTING incremental build... found added/removed
275 // binary folder"); //$NON-NLS-1$
276 // return false; // added/removed binary folder should not make it here
277 // (classpath change), but handle anyways
279 // int segmentCount = binaryDelta.getFullPath().segmentCount();
280 // IResourceDelta[] children = binaryDelta.getAffectedChildren(); // .class
281 // files from class folder
282 // for (int j = 0, m = children.length; j < m; j++)
283 // findAffectedSourceFiles(children[j], segmentCount);
284 // notifier.checkCancel();
291 protected void findAffectedSourceFiles(IResourceDelta binaryDelta, int segmentCount) {
292 // When a package becomes a type or vice versa, expect 2 deltas,
293 // one on the folder & one on the class file
294 IResource resource = binaryDelta.getResource();
295 switch (resource.getType()) {
296 case IResource.FOLDER:
297 switch (binaryDelta.getKind()) {
298 case IResourceDelta.ADDED:
299 case IResourceDelta.REMOVED:
300 IPath packagePath = resource.getFullPath().removeFirstSegments(segmentCount);
301 String packageName = packagePath.toString();
302 if (binaryDelta.getKind() == IResourceDelta.ADDED) {
303 // see if any known source file is from the same package...
304 // classpath already includes new package
305 // if (!newState.isKnownPackage(packageName)) {
306 // if (PHPBuilder.DEBUG)
307 // System.out.println("Found added package " + packageName); //$NON-NLS-1$
308 // addDependentsOf(packagePath, false);
311 if (PHPBuilder.DEBUG)
312 System.out.println("Skipped dependents of added package " + packageName); //$NON-NLS-1$
314 // see if the package still exists on the classpath
315 // if (!nameEnvironment.isPackage(packageName)) {
316 // if (JavaBuilder.DEBUG)
317 // System.out.println("Found removed package " + packageName);
319 // addDependentsOf(packagePath, false);
322 if (PHPBuilder.DEBUG)
323 System.out.println("Skipped dependents of removed package " + packageName); //$NON-NLS-1$
325 // fall thru & traverse the sub-packages and .class files
326 case IResourceDelta.CHANGED:
327 IResourceDelta[] children = binaryDelta.getAffectedChildren();
328 for (int i = 0, l = children.length; i < l; i++)
329 findAffectedSourceFiles(children[i], segmentCount);
333 // if (ProjectPrefUtil.isClassFileName(resource.getName())) {
335 // resource.getFullPath().removeFirstSegments(segmentCount).removeFileExtension();
336 // switch (binaryDelta.getKind()) {
337 // case IResourceDelta.ADDED :
338 // case IResourceDelta.REMOVED :
339 // if (JavaBuilder.DEBUG)
340 // System.out.println("Found added/removed class file " + typePath);
342 // addDependentsOf(typePath, false);
344 // case IResourceDelta.CHANGED :
345 // if ((binaryDelta.getFlags() & IResourceDelta.CONTENT) == 0)
346 // return; // skip it since it really isn't changed
347 // if (JavaBuilder.DEBUG)
348 // System.out.println("Found changed class file " + typePath);
350 // addDependentsOf(typePath, false);
357 protected boolean findSourceFiles(IResourceDelta delta) throws CoreException {
358 for (int i = 0, l = sourceLocations.length; i < l; i++) {
359 ClasspathMultiDirectory md = sourceLocations[i];
360 if (md.sourceFolder.equals(javaBuilder.currentProject)) {
361 // skip nested source & output folders when the project is a source
363 int segmentCount = delta.getFullPath().segmentCount();
364 IResourceDelta[] children = delta.getAffectedChildren();
365 for (int j = 0, m = children.length; j < m; j++)
366 if (!isExcludedFromProject(children[j].getFullPath()))
367 findSourceFiles(children[j], md, segmentCount);
369 IResourceDelta sourceDelta = delta.findMember(md.sourceFolder.getProjectRelativePath());
370 if (sourceDelta != null) {
371 if (sourceDelta.getKind() == IResourceDelta.REMOVED) {
372 if (PHPBuilder.DEBUG)
373 System.out.println("ABORTING incremental build... found removed source folder"); //$NON-NLS-1$
374 return false; // removed source folder should not make it here, but
375 // handle anyways (ADDED is supported)
377 int segmentCount = sourceDelta.getFullPath().segmentCount();
378 IResourceDelta[] children = sourceDelta.getAffectedChildren();
379 for (int j = 0, m = children.length; j < m; j++)
380 findSourceFiles(children[j], md, segmentCount);
383 notifier.checkCancel();
388 protected void findSourceFiles(IResourceDelta sourceDelta, ClasspathMultiDirectory md, int segmentCount) throws CoreException {
389 // When a package becomes a type or vice versa, expect 2 deltas,
390 // one on the folder & one on the source file
391 IResource resource = sourceDelta.getResource();
392 if (md.exclusionPatterns != null && Util.isExcluded(resource, md.exclusionPatterns))
394 switch (resource.getType()) {
395 case IResource.FOLDER:
396 switch (sourceDelta.getKind()) {
397 case IResourceDelta.ADDED:
398 IPath addedPackagePath = resource.getFullPath().removeFirstSegments(segmentCount);
399 // createFolder(addedPackagePath, md.binaryFolder); // ensure package
402 // add dependents even when the package thinks it exists to be on
404 if (PHPBuilder.DEBUG)
405 System.out.println("Found added package " + addedPackagePath); //$NON-NLS-1$
406 addDependentsOf(addedPackagePath, true);
407 // fall thru & collect all the source files
408 case IResourceDelta.CHANGED:
409 IResourceDelta[] children = sourceDelta.getAffectedChildren();
410 for (int i = 0, l = children.length; i < l; i++)
411 findSourceFiles(children[i], md, segmentCount);
413 case IResourceDelta.REMOVED:
414 IPath removedPackagePath = resource.getFullPath().removeFirstSegments(segmentCount);
415 if (sourceLocations.length > 1) {
416 for (int i = 0, l = sourceLocations.length; i < l; i++) {
417 if (sourceLocations[i].sourceFolder.getFolder(removedPackagePath).exists()) {
418 // only a package fragment was removed, same as removing
419 // multiple source files
420 // createFolder(removedPackagePath, md.binaryFolder); // ensure
426 IResourceDelta[] removedChildren = sourceDelta.getAffectedChildren();
427 for (int j = 0, m = removedChildren.length; j < m; j++)
428 findSourceFiles(removedChildren[j], md, segmentCount);
433 // IFolder removedPackageFolder = md.binaryFolder
434 // .getFolder(removedPackagePath);
435 // if (removedPackageFolder.exists())
436 // removedPackageFolder.delete(IResource.FORCE, null);
437 // add dependents even when the package thinks it does not exist to
438 // be on the safe side
439 if (PHPBuilder.DEBUG)
440 System.out.println("Found removed package " + removedPackagePath); //$NON-NLS-1$
441 addDependentsOf(removedPackagePath, true);
442 newState.removePackage(sourceDelta);
446 String resourceName = resource.getName();
447 if (net.sourceforge.phpdt.internal.compiler.util.Util.isJavaFileName(resourceName)) {
448 IPath typePath = resource.getFullPath().removeFirstSegments(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 " + typeLocator); //$NON-NLS-1$
454 sourceFiles.add(new SourceFile((IFile) resource, md, encoding));
455 String typeName = typePath.toString();
456 // if (!newState.isDuplicateLocator(typeName, typeLocator)) { // adding
463 // if (PHPBuilder.DEBUG)
464 // System.out.println("Found added source file " + typeName); //$NON-NLS-1$
465 // addDependentsOf(typePath, true);
468 case IResourceDelta.REMOVED:
469 // char[][] definedTypeNames = newState
470 // .getDefinedTypeNamesFor(typeLocator);
471 // if (definedTypeNames == null) { // defined a single type matching
473 // removeClassFile(typePath, md.binaryFolder);
474 // if ((sourceDelta.getFlags() & IResourceDelta.MOVED_TO) != 0) {
475 // // remove problems and tasks for a compilation unit that is
476 // // being moved (to another package or renamed)
477 // // if the target file is a compilation unit, the new cu will
479 // // if the target file is a non-java resource, then markers
482 // IResource movedFile = javaBuilder.workspaceRoot
483 // .getFile(sourceDelta.getMovedToPath());
484 // PHPBuilder.removeProblemsAndTasksFor(movedFile);
487 if (PHPBuilder.DEBUG)
488 System.out.println("Found removed source file " + typePath.toString()); //$NON-NLS-1$
489 addDependentsOf(typePath, true); // add dependents of the
490 // source file since it may be
491 // involved in a name
493 // if (definedTypeNames.length > 0) { // skip it if it failed to
494 // // successfully define a
496 // IPath packagePath = typePath.removeLastSegments(1);
497 // for (int i = 0, l = definedTypeNames.length; i < l; i++)
498 // removeClassFile(packagePath.append(new String(
499 // definedTypeNames[i])), md.binaryFolder);
502 // newState.removeLocator(typeLocator);
504 case IResourceDelta.CHANGED:
505 if ((sourceDelta.getFlags() & IResourceDelta.CONTENT) == 0)
506 return; // skip it since it really isn't changed
507 if (PHPBuilder.DEBUG)
508 System.out.println("Compile this changed source file " + typeLocator); //$NON-NLS-1$
509 sourceFiles.add(new SourceFile((IFile) resource, md, encoding));
512 // } else if (ProjectPrefUtil.isClassFileName(resourceName)) {
513 // return; // skip class files
514 } else if (md.hasIndependentOutputFolder) {
515 if (javaBuilder.filterExtraResource(resource))
517 // copy all other resource deltas to the output folder
518 IPath resourcePath = resource.getFullPath().removeFirstSegments(segmentCount);
519 // IResource outputFile = md.binaryFolder.getFile(resourcePath);
520 switch (sourceDelta.getKind()) {
521 case IResourceDelta.ADDED:
522 // if (outputFile.exists()) {
523 // if (PHPBuilder.DEBUG)
524 // System.out.println("Deleting existing file " + resourcePath); //$NON-NLS-1$
525 // outputFile.delete(IResource.FORCE, null);
527 if (PHPBuilder.DEBUG)
528 System.out.println("Copying added file " + resourcePath); //$NON-NLS-1$
529 // createFolder(resourcePath.removeLastSegments(1), md.binaryFolder); // ensure
536 // resource.copy(outputFile.getFullPath(), IResource.FORCE, null);
537 // outputFile.setDerived(true);
539 case IResourceDelta.REMOVED:
540 // if (outputFile.exists()) {
541 // if (PHPBuilder.DEBUG)
542 // System.out.println("Deleting removed file " + resourcePath); //$NON-NLS-1$
543 // outputFile.delete(IResource.FORCE, null);
546 case IResourceDelta.CHANGED:
547 if ((sourceDelta.getFlags() & IResourceDelta.CONTENT) == 0)
548 return; // skip it since it really isn't changed
549 // if (outputFile.exists()) {
550 // if (PHPBuilder.DEBUG)
551 // System.out.println("Deleting existing file " + resourcePath); //$NON-NLS-1$
552 // outputFile.delete(IResource.FORCE, null);
554 if (PHPBuilder.DEBUG)
555 System.out.println("Copying changed file " + resourcePath); //$NON-NLS-1$
556 // createFolder(resourcePath.removeLastSegments(1), md.binaryFolder); // ensure
563 // resource.copy(outputFile.getFullPath(), IResource.FORCE, null);
564 // outputFile.setDerived(true);
571 protected void finishedWith(String sourceLocator, CompilationResult result, char[] mainTypeName, ArrayList definedTypeNames,
572 ArrayList duplicateTypeNames) throws CoreException {
573 // char[][] previousTypeNames = newState.getDefinedTypeNamesFor(sourceLocator);
574 // if (previousTypeNames == null)
575 // previousTypeNames = new char[][]{mainTypeName};
576 // IPath packagePath = null;
577 // next : for (int i = 0, l = previousTypeNames.length; i < l; i++) {
578 // char[] previous = previousTypeNames[i];
579 // for (int j = 0, m = definedTypeNames.size(); j < m; j++)
580 // if (CharOperation.equals(previous, (char[]) definedTypeNames.get(j)))
582 // SourceFile sourceFile = (SourceFile) result.getCompilationUnit();
583 // if (packagePath == null) {
584 // int count = sourceFile.sourceLocation.sourceFolder.getFullPath()
586 // packagePath = sourceFile.resource.getFullPath().removeFirstSegments(
587 // count).removeLastSegments(1);
589 // if (secondaryTypesToRemove == null)
590 // this.secondaryTypesToRemove = new SimpleLookupTable();
591 // ArrayList types = (ArrayList) secondaryTypesToRemove
592 // .get(sourceFile.sourceLocation.binaryFolder);
593 // if (types == null)
594 // types = new ArrayList(definedTypeNames.size());
595 // types.add(packagePath.append(new String(previous)));
596 // secondaryTypesToRemove.put(sourceFile.sourceLocation.binaryFolder, types);
598 // super.finishedWith(sourceLocator, result, mainTypeName,
599 // definedTypeNames, duplicateTypeNames);
602 // protected void removeClassFile(IPath typePath, IContainer outputFolder)
603 // throws CoreException {
604 // if (typePath.lastSegment().indexOf('$') == -1) { // is not a nested type
605 // newState.removeQualifiedTypeName(typePath.toString());
606 // // add dependents even when the type thinks it does not exist to be on
608 // if (PHPBuilder.DEBUG)
609 // System.out.println("Found removed type " + typePath); //$NON-NLS-1$
610 // addDependentsOf(typePath, true); // when member types are removed, their
611 // // enclosing type is structurally
614 // IFile classFile = outputFolder.getFile(typePath
615 // .addFileExtension(PHPBuilder.CLASS_EXTENSION));
616 // if (classFile.exists()) {
617 // if (PHPBuilder.DEBUG)
618 // System.out.println("Deleting class file of removed type " + typePath); //$NON-NLS-1$
619 // classFile.delete(IResource.FORCE, null);
622 // protected void removeSecondaryTypes() throws CoreException {
623 // if (secondaryTypesToRemove != null) { // delayed deleting secondary types
624 // // until the end of the compile loop
625 // Object[] keyTable = secondaryTypesToRemove.keyTable;
626 // Object[] valueTable = secondaryTypesToRemove.valueTable;
627 // for (int i = 0, l = keyTable.length; i < l; i++) {
628 // IContainer outputFolder = (IContainer) keyTable[i];
629 // if (outputFolder != null) {
630 // ArrayList paths = (ArrayList) valueTable[i];
631 // for (int j = 0, m = paths.size(); j < m; j++)
632 // removeClassFile((IPath) paths.get(j), outputFolder);
635 // this.secondaryTypesToRemove = null;
636 // if (previousSourceFiles != null && previousSourceFiles.size() > 1)
637 // this.previousSourceFiles = null; // cannot optimize recompile case when
638 // // a secondary type is deleted
641 protected void resetCollections() {
642 previousSourceFiles = sourceFiles.isEmpty() ? null : (ArrayList) sourceFiles.clone();
644 qualifiedStrings.clear();
645 simpleStrings.clear();
649 protected void updateProblemsFor(SourceFile sourceFile, CompilationResult result) throws CoreException {
650 IMarker[] markers = PHPBuilder.getProblemsFor(sourceFile.resource);
651 IProblem[] problems = result.getProblems();
652 if (problems == null && markers.length == 0)
655 // axelcl start insert - calculate line numbers
656 if (problems != null) {
657 for (int i = 0; i < problems.length; i++) {
658 if (problems[i].getSourceLineNumber() == 1) {
659 problems[i].setSourceLineNumber(ProblemHandler.searchLineNumber(result.lineSeparatorPositions, problems[i]
666 notifier.updateProblemCounts(markers, problems);
667 PHPBuilder.removeProblemsFor(sourceFile.resource);
668 storeProblemsFor(sourceFile, problems);
671 protected void updateTasksFor(SourceFile sourceFile, CompilationResult result) throws CoreException {
672 IMarker[] markers = PHPBuilder.getTasksFor(sourceFile.resource);
673 IProblem[] tasks = result.getTasks();
674 if (tasks == null && markers.length == 0)
676 PHPBuilder.removeTasksFor(sourceFile.resource);
677 storeTasksFor(sourceFile, tasks);
680 //protected void writeClassFileBytes(byte[] bytes, IFile file, String
681 // qualifiedFileName, boolean isSecondaryType) throws CoreException {
682 // // Before writing out the class file, compare it to the previous file
683 // // If structural changes occured then add dependent source files
684 // if (file.exists()) {
685 // if (writeClassFileCheck(file, qualifiedFileName, bytes)) {
686 // if (JavaBuilder.DEBUG)
687 // System.out.println("Writing changed class file " +
688 // file.getName());//$NON-NLS-1$
689 // file.setContents(new ByteArrayInputStream(bytes), true, false, null);
690 // if (!file.isDerived())
691 // file.setDerived(true);
692 // } else if (JavaBuilder.DEBUG) {
693 // System.out.println("Skipped over unchanged class file " +
694 // file.getName());//$NON-NLS-1$
697 // if (isSecondaryType)
698 // addDependentsOf(new Path(qualifiedFileName), true); // new secondary type
699 // if (JavaBuilder.DEBUG)
700 // System.out.println("Writing new class file " +
701 // file.getName());//$NON-NLS-1$
702 // file.create(new ByteArrayInputStream(bytes), IResource.FORCE, null);
703 // file.setDerived(true);
706 //protected boolean writeClassFileCheck(IFile file, String fileName, byte[]
707 // newBytes) throws CoreException {
709 // byte[] oldBytes = ProjectPrefUtil.getResourceContentsAsByteArray(file);
710 // if (this.compileLoop > 1) { // only optimize files which were recompiled
711 // during the dependent pass, see 33990
712 // notEqual : if (newBytes.length == oldBytes.length) {
713 // for (int i = newBytes.length; --i >= 0;)
714 // if (newBytes[i] != oldBytes[i]) break notEqual;
715 // return false; // bytes are identical so skip them
718 // IPath location = file.getLocation();
719 // if (location == null) return false; // unable to determine location of
721 // ClassFileReader reader = new ClassFileReader(oldBytes,
722 // location.toString().toCharArray());
723 // // ignore local types since they're only visible inside a single method
724 // if (!(reader.isLocal() || reader.isAnonymous()) &&
725 // reader.hasStructuralChanges(newBytes)) {
726 // if (JavaBuilder.DEBUG)
727 // System.out.println("Type has structural changes " + fileName);
729 // addDependentsOf(new Path(fileName), true);
731 // } catch (ClassFormatException e) {
732 // addDependentsOf(new Path(fileName), true);
736 public String toString() {
737 return "incremental image builder for:\n\tnew state: " + newState; //$NON-NLS-1$
742 * static void dump(IResourceDelta delta) { StringBuffer buffer = new StringBuffer(); IPath path = delta.getFullPath(); for (int i =
743 * path.segmentCount(); --i > 0;) buffer.append(" "); switch (delta.getKind()) { case IResourceDelta.ADDED: buffer.append('+');
744 * break; case IResourceDelta.REMOVED: buffer.append('-'); break; case IResourceDelta.CHANGED: '); break; case
745 * IResourceDelta.NO_CHANGE: buffer.append('='); break; default: buffer.append('?'); break; } buffer.append(path);
746 * System.out.println(buffer.toString()); IResourceDelta[] children = delta.getAffectedChildren(); for (int i = 0, l =
747 * children.length; i < l; i++) dump(children[i]); }