* IBM Corporation - initial API and implementation
*******************************************************************************/
package net.sourceforge.phpdt.internal.core.builder;
-
import java.util.ArrayList;
-
import net.sourceforge.phpdt.core.compiler.CharOperation;
import net.sourceforge.phpdt.core.compiler.IProblem;
import net.sourceforge.phpdt.internal.compiler.CompilationResult;
import net.sourceforge.phpdt.internal.core.Util;
import net.sourceforge.phpdt.internal.core.util.SimpleLookupTable;
-
+import net.sourceforge.phpdt.internal.ui.util.PHPFileUtil;
+import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import net.sourceforge.phpeclipse.builder.IdentifierIndexManager;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IResourceDelta;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
-
/**
* The incremental image builder
*/
public class IncrementalImageBuilder extends AbstractImageBuilder {
-
-protected ArrayList sourceFiles;
-protected ArrayList previousSourceFiles;
-protected ArrayList qualifiedStrings;
-protected ArrayList simpleStrings;
-protected SimpleLookupTable secondaryTypesToRemove;
-protected boolean hasStructuralChanges;
-protected int compileLoop;
-
-public static int MaxCompileLoop = 5; // perform a full build if it takes more than ? incremental compile loops
-
-protected IncrementalImageBuilder(PHPBuilder javaBuilder) {
- super(javaBuilder);
- this.nameEnvironment.isIncrementalBuild = true;
- this.newState.copyFrom(javaBuilder.lastState);
-
- this.sourceFiles = new ArrayList(33);
- this.previousSourceFiles = null;
- this.qualifiedStrings = new ArrayList(33);
- this.simpleStrings = new ArrayList(33);
- this.hasStructuralChanges = false;
- this.compileLoop = 0;
-}
-
-public boolean build(SimpleLookupTable deltas) {
- // initialize builder
- // walk this project's deltas, find changed source files
- // walk prereq projects' deltas, find changed class files & add affected source files
- // use the build state # to skip the deltas for certain prereq projects
- // ignore changed zip/jar files since they caused a full build
- // compile the source files & acceptResult()
- // compare the produced class files against the existing ones on disk
- // recompile all dependent source files of any type with structural changes or new/removed secondary type
- // keep a loop counter to abort & perform a full build
-
- if (PHPBuilder.DEBUG)
- System.out.println("INCREMENTAL build"); //$NON-NLS-1$
-
- try {
- resetCollections();
-
- notifier.subTask(Util.bind("build.analyzingDeltas")); //$NON-NLS-1$
- IResourceDelta sourceDelta = (IResourceDelta) deltas.get(javaBuilder.currentProject);
- if (sourceDelta != null)
- if (!findSourceFiles(sourceDelta)) return false;
- notifier.updateProgressDelta(0.10f);
-
- Object[] keyTable = deltas.keyTable;
- Object[] valueTable = deltas.valueTable;
- for (int i = 0, l = valueTable.length; i < l; i++) {
- IResourceDelta delta = (IResourceDelta) valueTable[i];
- if (delta != null) {
-// ClasspathLocation[] classFoldersAndJars = (ClasspathLocation[]) javaBuilder.binaryLocationsPerProject.get(keyTable[i]);
-// if (classFoldersAndJars != null)
-// if (!findAffectedSourceFiles(delta, classFoldersAndJars)) return false;
- }
- }
- notifier.updateProgressDelta(0.10f);
-
- notifier.subTask(Util.bind("build.analyzingSources")); //$NON-NLS-1$
- addAffectedSourceFiles();
- notifier.updateProgressDelta(0.05f);
-
- this.compileLoop = 0;
- float increment = 0.40f;
- while (sourceFiles.size() > 0) { // added to in acceptResult
- if (++this.compileLoop > MaxCompileLoop) {
- if (PHPBuilder.DEBUG)
- System.out.println("ABORTING incremental build... exceeded loop count"); //$NON-NLS-1$
- return false;
- }
- notifier.checkCancel();
-
- SourceFile[] allSourceFiles = new SourceFile[sourceFiles.size()];
- sourceFiles.toArray(allSourceFiles);
- resetCollections();
-
- workQueue.addAll(allSourceFiles);
- notifier.setProgressPerCompilationUnit(increment / allSourceFiles.length);
- increment = increment / 2;
- compile(allSourceFiles);
- removeSecondaryTypes();
- addAffectedSourceFiles();
- }
- if (this.hasStructuralChanges && javaBuilder.javaProject.hasCycleMarker())
- javaBuilder.mustPropagateStructuralChanges();
- } catch (AbortIncrementalBuildException e) {
- // abort the incremental build and let the batch builder handle the problem
- if (PHPBuilder.DEBUG)
- System.out.println("ABORTING incremental build... cannot find " + e.qualifiedTypeName + //$NON-NLS-1$
- ". Could have been renamed inside its existing source file."); //$NON-NLS-1$
- return false;
- } catch (CoreException e) {
- throw internalException(e);
- } finally {
- cleanUp();
- }
- return true;
-}
-
-protected void addAffectedSourceFiles() {
- if (qualifiedStrings.isEmpty() && simpleStrings.isEmpty()) return;
-
- // the qualifiedStrings are of the form 'p1/p2' & the simpleStrings are just 'X'
- char[][][] qualifiedNames = ReferenceCollection.internQualifiedNames(qualifiedStrings);
- // if a well known qualified name was found then we can skip over these
- if (qualifiedNames.length < qualifiedStrings.size())
- qualifiedNames = null;
- char[][] simpleNames = ReferenceCollection.internSimpleNames(simpleStrings);
- // if a well known name was found then we can skip over these
- if (simpleNames.length < simpleStrings.size())
- simpleNames = null;
-
- Object[] keyTable = newState.references.keyTable;
- Object[] valueTable = newState.references.valueTable;
- next : for (int i = 0, l = valueTable.length; i < l; i++) {
- ReferenceCollection refs = (ReferenceCollection) valueTable[i];
- if (refs != null && refs.includes(qualifiedNames, simpleNames)) {
- String typeLocator = (String) keyTable[i];
- IFile file = javaBuilder.currentProject.getFile(typeLocator);
- if (file.exists()) {
- ClasspathMultiDirectory md = sourceLocations[0];
- if (sourceLocations.length > 1) {
- IPath sourceFileFullPath = file.getFullPath();
- for (int j = 0, m = sourceLocations.length; j < m; j++) {
- if (sourceLocations[j].sourceFolder.getFullPath().isPrefixOf(sourceFileFullPath)) {
- md = sourceLocations[j];
- if (md.exclusionPatterns == null || !Util.isExcluded(file, md.exclusionPatterns))
- break;
- }
- }
- }
- SourceFile sourceFile = new SourceFile(file, md, encoding);
- if (sourceFiles.contains(sourceFile)) continue next;
- if (compiledAllAtOnce && previousSourceFiles != null && previousSourceFiles.contains(sourceFile))
- continue next; // can skip previously compiled files since already saw hierarchy related problems
-
- if (PHPBuilder.DEBUG)
- System.out.println(" adding affected source file " + typeLocator); //$NON-NLS-1$
- sourceFiles.add(sourceFile);
- }
- }
- }
-}
-
-protected void addDependentsOf(IPath path, boolean hasStructuralChanges) {
- if (hasStructuralChanges) {
- newState.tagAsStructurallyChanged();
- this.hasStructuralChanges = true;
- }
- // the qualifiedStrings are of the form 'p1/p2' & the simpleStrings are just 'X'
- path = path.setDevice(null);
- String packageName = path.removeLastSegments(1).toString();
- if (!qualifiedStrings.contains(packageName))
- qualifiedStrings.add(packageName);
- String typeName = path.lastSegment();
- int memberIndex = typeName.indexOf('$');
- if (memberIndex > 0)
- typeName = typeName.substring(0, memberIndex);
- if (!simpleStrings.contains(typeName)) {
- if (PHPBuilder.DEBUG)
- System.out.println(" will look for dependents of " //$NON-NLS-1$
- + typeName + " in " + packageName); //$NON-NLS-1$
- simpleStrings.add(typeName);
- }
-}
-
-protected void cleanUp() {
- super.cleanUp();
-
- this.sourceFiles = null;
- this.previousSourceFiles = null;
- this.qualifiedStrings = null;
- this.simpleStrings = null;
- this.secondaryTypesToRemove = null;
- this.hasStructuralChanges = false;
- this.compileLoop = 0;
-}
-
-//protected boolean findAffectedSourceFiles(IResourceDelta delta, ClasspathLocation[] classFoldersAndJars) {
-// for (int i = 0, l = classFoldersAndJars.length; i < l; i++) {
-// ClasspathLocation bLocation = classFoldersAndJars[i];
-// // either a .class file folder or a zip/jar file
-// if (bLocation != null) { // skip unchanged output folder
-// IPath p = bLocation.getProjectRelativePath();
-// if (p != null) {
-// IResourceDelta binaryDelta = delta.findMember(p);
-// if (binaryDelta != null) {
-// if (bLocation instanceof ClasspathJar) {
-// if (JavaBuilder.DEBUG)
-// System.out.println("ABORTING incremental build... found delta to jar/zip file"); //$NON-NLS-1$
-// return false; // do full build since jar file was changed (added/removed were caught as classpath change)
-// }
-// if (binaryDelta.getKind() == IResourceDelta.ADDED || binaryDelta.getKind() == IResourceDelta.REMOVED) {
-// if (JavaBuilder.DEBUG)
-// System.out.println("ABORTING incremental build... found added/removed binary folder"); //$NON-NLS-1$
-// return false; // added/removed binary folder should not make it here (classpath change), but handle anyways
-// }
-// int segmentCount = binaryDelta.getFullPath().segmentCount();
-// IResourceDelta[] children = binaryDelta.getAffectedChildren(); // .class files from class folder
-// for (int j = 0, m = children.length; j < m; j++)
-// findAffectedSourceFiles(children[j], segmentCount);
-// notifier.checkCancel();
-// }
-// }
-// }
-// }
-// return true;
-//}
-
-protected void findAffectedSourceFiles(IResourceDelta binaryDelta, int segmentCount) {
- // When a package becomes a type or vice versa, expect 2 deltas,
- // one on the folder & one on the class file
- IResource resource = binaryDelta.getResource();
- switch(resource.getType()) {
- case IResource.FOLDER :
- switch (binaryDelta.getKind()) {
- case IResourceDelta.ADDED :
- case IResourceDelta.REMOVED :
- IPath packagePath = resource.getFullPath().removeFirstSegments(segmentCount);
- String packageName = packagePath.toString();
- if (binaryDelta.getKind() == IResourceDelta.ADDED) {
- // see if any known source file is from the same package... classpath already includes new package
- if (!newState.isKnownPackage(packageName)) {
- if (PHPBuilder.DEBUG)
- System.out.println("Found added package " + packageName); //$NON-NLS-1$
- addDependentsOf(packagePath, false);
- return;
- }
- if (PHPBuilder.DEBUG)
- System.out.println("Skipped dependents of added package " + packageName); //$NON-NLS-1$
- } else {
- // see if the package still exists on the classpath
-// if (!nameEnvironment.isPackage(packageName)) {
-// if (JavaBuilder.DEBUG)
-// System.out.println("Found removed package " + packageName); //$NON-NLS-1$
-// addDependentsOf(packagePath, false);
-// return;
-// }
- if (PHPBuilder.DEBUG)
- System.out.println("Skipped dependents of removed package " + packageName); //$NON-NLS-1$
- }
- // fall thru & traverse the sub-packages and .class files
- case IResourceDelta.CHANGED :
- IResourceDelta[] children = binaryDelta.getAffectedChildren();
- for (int i = 0, l = children.length; i < l; i++)
- findAffectedSourceFiles(children[i], segmentCount);
- }
- return;
- case IResource.FILE :
-// if (Util.isClassFileName(resource.getName())) {
-// IPath typePath = resource.getFullPath().removeFirstSegments(segmentCount).removeFileExtension();
-// switch (binaryDelta.getKind()) {
-// case IResourceDelta.ADDED :
-// case IResourceDelta.REMOVED :
-// if (JavaBuilder.DEBUG)
-// System.out.println("Found added/removed class file " + typePath); //$NON-NLS-1$
-// addDependentsOf(typePath, false);
-// return;
-// case IResourceDelta.CHANGED :
-// if ((binaryDelta.getFlags() & IResourceDelta.CONTENT) == 0)
-// return; // skip it since it really isn't changed
-// if (JavaBuilder.DEBUG)
-// System.out.println("Found changed class file " + typePath); //$NON-NLS-1$
-// addDependentsOf(typePath, false);
-// }
-// return;
-// }
- }
-}
-
-protected boolean findSourceFiles(IResourceDelta delta) throws CoreException {
- for (int i = 0, l = sourceLocations.length; i < l; i++) {
- ClasspathMultiDirectory md = sourceLocations[i];
- if (md.sourceFolder.equals(javaBuilder.currentProject)) {
- // skip nested source & output folders when the project is a source folder
- int segmentCount = delta.getFullPath().segmentCount();
- IResourceDelta[] children = delta.getAffectedChildren();
- for (int j = 0, m = children.length; j < m; j++)
- if (!isExcludedFromProject(children[j].getFullPath()))
- findSourceFiles(children[j], md, segmentCount);
- } else {
- IResourceDelta sourceDelta = delta.findMember(md.sourceFolder.getProjectRelativePath());
-
- if (sourceDelta != null) {
- if (sourceDelta.getKind() == IResourceDelta.REMOVED) {
- if (PHPBuilder.DEBUG)
- System.out.println("ABORTING incremental build... found removed source folder"); //$NON-NLS-1$
- return false; // removed source folder should not make it here, but handle anyways (ADDED is supported)
- }
- int segmentCount = sourceDelta.getFullPath().segmentCount();
- IResourceDelta[] children = sourceDelta.getAffectedChildren();
- for (int j = 0, m = children.length; j < m; j++)
- findSourceFiles(children[j], md, segmentCount);
- }
- }
- notifier.checkCancel();
- }
- return true;
-}
-
-protected void findSourceFiles(IResourceDelta sourceDelta, ClasspathMultiDirectory md, int segmentCount) throws CoreException {
- // When a package becomes a type or vice versa, expect 2 deltas,
- // one on the folder & one on the source file
- IResource resource = sourceDelta.getResource();
- if (md.exclusionPatterns != null && Util.isExcluded(resource, md.exclusionPatterns)) return;
- switch(resource.getType()) {
- case IResource.FOLDER :
- switch (sourceDelta.getKind()) {
- case IResourceDelta.ADDED :
- IPath addedPackagePath = resource.getFullPath().removeFirstSegments(segmentCount);
- createFolder(addedPackagePath, md.binaryFolder); // ensure package exists in the output folder
- // add dependents even when the package thinks it exists to be on the safe side
- if (PHPBuilder.DEBUG)
- System.out.println("Found added package " + addedPackagePath); //$NON-NLS-1$
- addDependentsOf(addedPackagePath, true);
- // fall thru & collect all the source files
- case IResourceDelta.CHANGED :
- IResourceDelta[] children = sourceDelta.getAffectedChildren();
- for (int i = 0, l = children.length; i < l; i++)
- findSourceFiles(children[i], md, segmentCount);
- return;
- case IResourceDelta.REMOVED :
- IPath removedPackagePath = resource.getFullPath().removeFirstSegments(segmentCount);
- if (sourceLocations.length > 1) {
- for (int i = 0, l = sourceLocations.length; i < l; i++) {
- if (sourceLocations[i].sourceFolder.getFolder(removedPackagePath).exists()) {
- // only a package fragment was removed, same as removing multiple source files
- createFolder(removedPackagePath, md.binaryFolder); // ensure package exists in the output folder
- IResourceDelta[] removedChildren = sourceDelta.getAffectedChildren();
- for (int j = 0, m = removedChildren.length; j < m; j++)
- findSourceFiles(removedChildren[j], md, segmentCount);
- return;
- }
- }
- }
- IFolder removedPackageFolder = md.binaryFolder.getFolder(removedPackagePath);
- if (removedPackageFolder.exists())
- removedPackageFolder.delete(IResource.FORCE, null);
- // add dependents even when the package thinks it does not exist to be on the safe side
- if (PHPBuilder.DEBUG)
- System.out.println("Found removed package " + removedPackagePath); //$NON-NLS-1$
- addDependentsOf(removedPackagePath, true);
- newState.removePackage(sourceDelta);
- }
- return;
- case IResource.FILE :
- String resourceName = resource.getName();
- if (Util.isJavaFileName(resourceName)) {
- IPath typePath = resource.getFullPath().removeFirstSegments(segmentCount).removeFileExtension();
- String typeLocator = resource.getProjectRelativePath().toString();
- switch (sourceDelta.getKind()) {
- case IResourceDelta.ADDED :
- if (PHPBuilder.DEBUG)
- System.out.println("Compile this added source file " + typeLocator); //$NON-NLS-1$
- sourceFiles.add(new SourceFile((IFile) resource, md, encoding));
- String typeName = typePath.toString();
- if (!newState.isDuplicateLocator(typeName, typeLocator)) { // adding dependents results in 2 duplicate errors
- if (PHPBuilder.DEBUG)
- System.out.println("Found added source file " + typeName); //$NON-NLS-1$
- addDependentsOf(typePath, true);
- }
- return;
- case IResourceDelta.REMOVED :
- char[][] definedTypeNames = newState.getDefinedTypeNamesFor(typeLocator);
- if (definedTypeNames == null) { // defined a single type matching typePath
- removeClassFile(typePath, md.binaryFolder);
- if ((sourceDelta.getFlags() & IResourceDelta.MOVED_TO) != 0) {
- // remove problems and tasks for a compilation unit that is being moved (to another package or renamed)
- // if the target file is a compilation unit, the new cu will be recompiled
- // if the target file is a non-java resource, then markers are removed
- // see bug 2857
- IResource movedFile = javaBuilder.workspaceRoot.getFile(sourceDelta.getMovedToPath());
- PHPBuilder.removeProblemsAndTasksFor(movedFile);
- }
- } else {
- if (PHPBuilder.DEBUG)
- System.out.println("Found removed source file " + typePath.toString()); //$NON-NLS-1$
- addDependentsOf(typePath, true); // add dependents of the source file since it may be involved in a name collision
- if (definedTypeNames.length > 0) { // skip it if it failed to successfully define a type
- IPath packagePath = typePath.removeLastSegments(1);
- for (int i = 0, l = definedTypeNames.length; i < l; i++)
- removeClassFile(packagePath.append(new String(definedTypeNames[i])), md.binaryFolder);
- }
- }
- newState.removeLocator(typeLocator);
- return;
- case IResourceDelta.CHANGED :
- if ((sourceDelta.getFlags() & IResourceDelta.CONTENT) == 0)
- return; // skip it since it really isn't changed
- if (PHPBuilder.DEBUG)
- System.out.println("Compile this changed source file " + typeLocator); //$NON-NLS-1$
- sourceFiles.add(new SourceFile((IFile) resource, md, encoding));
- }
- return;
-// } else if (Util.isClassFileName(resourceName)) {
-// return; // skip class files
- } else if (md.hasIndependentOutputFolder) {
- if (javaBuilder.filterExtraResource(resource)) return;
-
- // copy all other resource deltas to the output folder
- IPath resourcePath = resource.getFullPath().removeFirstSegments(segmentCount);
- IResource outputFile = md.binaryFolder.getFile(resourcePath);
- switch (sourceDelta.getKind()) {
- case IResourceDelta.ADDED :
- if (outputFile.exists()) {
- if (PHPBuilder.DEBUG)
- System.out.println("Deleting existing file " + resourcePath); //$NON-NLS-1$
- outputFile.delete(IResource.FORCE, null);
- }
- if (PHPBuilder.DEBUG)
- System.out.println("Copying added file " + resourcePath); //$NON-NLS-1$
- createFolder(resourcePath.removeLastSegments(1), md.binaryFolder); // ensure package exists in the output folder
- resource.copy(outputFile.getFullPath(), IResource.FORCE, null);
- outputFile.setDerived(true);
- return;
- case IResourceDelta.REMOVED :
- if (outputFile.exists()) {
- if (PHPBuilder.DEBUG)
- System.out.println("Deleting removed file " + resourcePath); //$NON-NLS-1$
- outputFile.delete(IResource.FORCE, null);
- }
- return;
- case IResourceDelta.CHANGED :
- if ((sourceDelta.getFlags() & IResourceDelta.CONTENT) == 0)
- return; // skip it since it really isn't changed
- if (outputFile.exists()) {
- if (PHPBuilder.DEBUG)
- System.out.println("Deleting existing file " + resourcePath); //$NON-NLS-1$
- outputFile.delete(IResource.FORCE, null);
- }
- if (PHPBuilder.DEBUG)
- System.out.println("Copying changed file " + resourcePath); //$NON-NLS-1$
- createFolder(resourcePath.removeLastSegments(1), md.binaryFolder); // ensure package exists in the output folder
- resource.copy(outputFile.getFullPath(), IResource.FORCE, null);
- outputFile.setDerived(true);
- }
- return;
- }
- }
-}
-
-protected void finishedWith(String sourceLocator, CompilationResult result, char[] mainTypeName, ArrayList definedTypeNames, ArrayList duplicateTypeNames) throws CoreException {
- char[][] previousTypeNames = newState.getDefinedTypeNamesFor(sourceLocator);
- if (previousTypeNames == null)
- previousTypeNames = new char[][] {mainTypeName};
- IPath packagePath = null;
- next : for (int i = 0, l = previousTypeNames.length; i < l; i++) {
- char[] previous = previousTypeNames[i];
- for (int j = 0, m = definedTypeNames.size(); j < m; j++)
- if (CharOperation.equals(previous, (char[]) definedTypeNames.get(j)))
- continue next;
-
- SourceFile sourceFile = (SourceFile) result.getCompilationUnit();
- if (packagePath == null) {
- int count = sourceFile.sourceLocation.sourceFolder.getFullPath().segmentCount();
- packagePath = sourceFile.resource.getFullPath().removeFirstSegments(count).removeLastSegments(1);
- }
- if (secondaryTypesToRemove == null)
- this.secondaryTypesToRemove = new SimpleLookupTable();
- ArrayList types = (ArrayList) secondaryTypesToRemove.get(sourceFile.sourceLocation.binaryFolder);
- if (types == null)
- types = new ArrayList(definedTypeNames.size());
- types.add(packagePath.append(new String(previous)));
- secondaryTypesToRemove.put(sourceFile.sourceLocation.binaryFolder, types);
- }
-// super.finishedWith(sourceLocator, result, mainTypeName, definedTypeNames, duplicateTypeNames);
-}
-
-protected void removeClassFile(IPath typePath, IContainer outputFolder) throws CoreException {
- if (typePath.lastSegment().indexOf('$') == -1) { // is not a nested type
- newState.removeQualifiedTypeName(typePath.toString());
- // add dependents even when the type thinks it does not exist to be on the safe side
- if (PHPBuilder.DEBUG)
- System.out.println("Found removed type " + typePath); //$NON-NLS-1$
- addDependentsOf(typePath, true); // when member types are removed, their enclosing type is structurally changed
- }
- IFile classFile = outputFolder.getFile(typePath.addFileExtension(PHPBuilder.CLASS_EXTENSION));
- if (classFile.exists()) {
- if (PHPBuilder.DEBUG)
- System.out.println("Deleting class file of removed type " + typePath); //$NON-NLS-1$
- classFile.delete(IResource.FORCE, null);
- }
-}
-
-protected void removeSecondaryTypes() throws CoreException {
- if (secondaryTypesToRemove != null) { // delayed deleting secondary types until the end of the compile loop
- Object[] keyTable = secondaryTypesToRemove.keyTable;
- Object[] valueTable = secondaryTypesToRemove.valueTable;
- for (int i = 0, l = keyTable.length; i < l; i++) {
- IContainer outputFolder = (IContainer) keyTable[i];
- if (outputFolder != null) {
- ArrayList paths = (ArrayList) valueTable[i];
- for (int j = 0, m = paths.size(); j < m; j++)
- removeClassFile((IPath) paths.get(j), outputFolder);
- }
- }
- this.secondaryTypesToRemove = null;
- if (previousSourceFiles != null && previousSourceFiles.size() > 1)
- this.previousSourceFiles = null; // cannot optimize recompile case when a secondary type is deleted
- }
-}
-
-protected void resetCollections() {
- previousSourceFiles = sourceFiles.isEmpty() ? null : (ArrayList) sourceFiles.clone();
-
- sourceFiles.clear();
- qualifiedStrings.clear();
- simpleStrings.clear();
- workQueue.clear();
-}
-
-protected void updateProblemsFor(SourceFile sourceFile, CompilationResult result) throws CoreException {
- IMarker[] markers = PHPBuilder.getProblemsFor(sourceFile.resource);
- IProblem[] problems = result.getProblems();
- if (problems == null && markers.length == 0) return;
-
- notifier.updateProblemCounts(markers, problems);
- PHPBuilder.removeProblemsFor(sourceFile.resource);
- storeProblemsFor(sourceFile, problems);
-}
-
-protected void updateTasksFor(SourceFile sourceFile, CompilationResult result) throws CoreException {
- IMarker[] markers = PHPBuilder.getTasksFor(sourceFile.resource);
- IProblem[] tasks = result.getTasks();
- if (tasks == null && markers.length == 0) return;
-
- PHPBuilder.removeTasksFor(sourceFile.resource);
- storeTasksFor(sourceFile, tasks);
-}
-
-//protected void writeClassFileBytes(byte[] bytes, IFile file, String qualifiedFileName, boolean isSecondaryType) throws CoreException {
-// // Before writing out the class file, compare it to the previous file
-// // If structural changes occured then add dependent source files
-// if (file.exists()) {
-// if (writeClassFileCheck(file, qualifiedFileName, bytes)) {
-// if (JavaBuilder.DEBUG)
-// System.out.println("Writing changed class file " + file.getName());//$NON-NLS-1$
-// file.setContents(new ByteArrayInputStream(bytes), true, false, null);
-// if (!file.isDerived())
-// file.setDerived(true);
-// } else if (JavaBuilder.DEBUG) {
-// System.out.println("Skipped over unchanged class file " + file.getName());//$NON-NLS-1$
-// }
-// } else {
-// if (isSecondaryType)
-// addDependentsOf(new Path(qualifiedFileName), true); // new secondary type
-// if (JavaBuilder.DEBUG)
-// System.out.println("Writing new class file " + file.getName());//$NON-NLS-1$
-// file.create(new ByteArrayInputStream(bytes), IResource.FORCE, null);
-// file.setDerived(true);
-// }
-//}
-
-//protected boolean writeClassFileCheck(IFile file, String fileName, byte[] newBytes) throws CoreException {
-// try {
-// byte[] oldBytes = Util.getResourceContentsAsByteArray(file);
-// if (this.compileLoop > 1) { // only optimize files which were recompiled during the dependent pass, see 33990
-// notEqual : if (newBytes.length == oldBytes.length) {
-// for (int i = newBytes.length; --i >= 0;)
-// if (newBytes[i] != oldBytes[i]) break notEqual;
-// return false; // bytes are identical so skip them
-// }
-// }
-// IPath location = file.getLocation();
-// if (location == null) return false; // unable to determine location of this class file
-// ClassFileReader reader = new ClassFileReader(oldBytes, location.toString().toCharArray());
-// // ignore local types since they're only visible inside a single method
-// if (!(reader.isLocal() || reader.isAnonymous()) && reader.hasStructuralChanges(newBytes)) {
-// if (JavaBuilder.DEBUG)
-// System.out.println("Type has structural changes " + fileName); //$NON-NLS-1$
-// addDependentsOf(new Path(fileName), true);
-// }
-// } catch (ClassFormatException e) {
-// addDependentsOf(new Path(fileName), true);
-// }
-// return true;
-//}
-
-public String toString() {
- return "incremental image builder for:\n\tnew state: " + newState; //$NON-NLS-1$
-}
-
-
-/* Debug helper
-
-static void dump(IResourceDelta delta) {
- StringBuffer buffer = new StringBuffer();
- IPath path = delta.getFullPath();
- for (int i = path.segmentCount(); --i > 0;)
- buffer.append(" ");
- switch (delta.getKind()) {
- case IResourceDelta.ADDED:
- buffer.append('+');
- break;
- case IResourceDelta.REMOVED:
- buffer.append('-');
- break;
- case IResourceDelta.CHANGED:
- buffer.append('*');
- break;
- case IResourceDelta.NO_CHANGE:
- buffer.append('=');
- break;
- default:
- buffer.append('?');
- break;
- }
- buffer.append(path);
- System.out.println(buffer.toString());
- IResourceDelta[] children = delta.getAffectedChildren();
- for (int i = 0, l = children.length; i < l; i++)
- dump(children[i]);
-}
-*/
+ protected ArrayList sourceFiles;
+ protected ArrayList previousSourceFiles;
+ protected ArrayList qualifiedStrings;
+ protected ArrayList simpleStrings;
+ protected SimpleLookupTable secondaryTypesToRemove;
+ protected boolean hasStructuralChanges;
+ protected int compileLoop;
+ public static int MaxCompileLoop = 5; // perform a full build if it takes
+ // more than ? incremental compile
+ // loops
+ protected IncrementalImageBuilder(PHPBuilder javaBuilder) {
+ super(javaBuilder);
+ this.nameEnvironment.isIncrementalBuild = true;
+ this.newState.copyFrom(javaBuilder.lastState);
+ this.sourceFiles = new ArrayList(33);
+ this.previousSourceFiles = null;
+ this.qualifiedStrings = new ArrayList(33);
+ this.simpleStrings = new ArrayList(33);
+ this.hasStructuralChanges = false;
+ this.compileLoop = 0;
+ }
+ public boolean build(SimpleLookupTable deltas) {
+ // initialize builder
+ // walk this project's deltas, find changed source files
+ // walk prereq projects' deltas, find changed class files & add affected
+ // source files
+ // use the build state # to skip the deltas for certain prereq projects
+ // ignore changed zip/jar files since they caused a full build
+ // compile the source files & acceptResult()
+ // compare the produced class files against the existing ones on disk
+ // recompile all dependent source files of any type with structural changes
+ // or new/removed secondary type
+ // keep a loop counter to abort & perform a full build
+ if (PHPBuilder.DEBUG)
+ System.out.println("INCREMENTAL build"); //$NON-NLS-1$
+ try {
+ resetCollections();
+ notifier.subTask(Util.bind("build.analyzingDeltas")); //$NON-NLS-1$
+ IResourceDelta sourceDelta = (IResourceDelta) deltas
+ .get(javaBuilder.currentProject);
+ if (sourceDelta != null)
+ if (!findSourceFiles(sourceDelta))
+ return false;
+ notifier.updateProgressDelta(0.10f);
+ Object[] keyTable = deltas.keyTable;
+ Object[] valueTable = deltas.valueTable;
+ final IdentifierIndexManager indexManager = PHPeclipsePlugin.getDefault()
+ .getIndexManager(javaBuilder.currentProject);
+ for (int i = 0, l = valueTable.length; i < l; i++) {
+ IResourceDelta delta = (IResourceDelta) valueTable[i];
+ if (delta != null) {
+ IResource resource = delta.getResource();
+ int resourceType = resource.getType();
+ if (resourceType == IResource.FILE) {
+ switch (delta.getKind()) {
+ case IResourceDelta.ADDED :
+ if ((resource.getFileExtension() != null)
+ && PHPFileUtil.isPHPFile((IFile) resource)) {
+ // update indexfile for the project:
+ indexManager.addFile((IFile) resource);
+ }
+ break;
+ case IResourceDelta.CHANGED :
+ if ((resource.getFileExtension() != null)
+ && PHPFileUtil.isPHPFile((IFile) resource)) {
+ // update indexfile for the project:
+ indexManager.changeFile((IFile) resource);
+ }
+ break;
+ case IResourceDelta.REMOVED :
+ if ((resource.getFileExtension() != null)
+ && PHPFileUtil.isPHPFile((IFile) resource)) {
+ // update indexfile for the project:
+ indexManager.removeFile((IFile) resource);
+ }
+ break;
+ }
+ }
+ // ClasspathLocation[] classFoldersAndJars = (ClasspathLocation[])
+ // javaBuilder.binaryLocationsPerProject.get(keyTable[i]);
+ // if (classFoldersAndJars != null)
+ // if (!findAffectedSourceFiles(delta, classFoldersAndJars)) return
+ // false;
+ }
+ }
+ notifier.updateProgressDelta(0.10f);
+ notifier.subTask(Util.bind("build.analyzingSources")); //$NON-NLS-1$
+ addAffectedSourceFiles();
+ notifier.updateProgressDelta(0.05f);
+ this.compileLoop = 0;
+ float increment = 0.40f;
+ while (sourceFiles.size() > 0) { // added to in acceptResult
+ if (++this.compileLoop > MaxCompileLoop) {
+ if (PHPBuilder.DEBUG)
+ System.out
+ .println("ABORTING incremental build... exceeded loop count"); //$NON-NLS-1$
+ return false;
+ }
+ notifier.checkCancel();
+ SourceFile[] allSourceFiles = new SourceFile[sourceFiles.size()];
+ sourceFiles.toArray(allSourceFiles);
+ resetCollections();
+ workQueue.addAll(allSourceFiles);
+ notifier.setProgressPerCompilationUnit(increment
+ / allSourceFiles.length);
+ increment = increment / 2;
+ compile(allSourceFiles);
+ removeSecondaryTypes();
+ addAffectedSourceFiles();
+ }
+ if (this.hasStructuralChanges && javaBuilder.javaProject.hasCycleMarker())
+ javaBuilder.mustPropagateStructuralChanges();
+ } catch (AbortIncrementalBuildException e) {
+ // abort the incremental build and let the batch builder handle the
+ // problem
+ if (PHPBuilder.DEBUG)
+ System.out.println("ABORTING incremental build... cannot find "
+ + e.qualifiedTypeName + //$NON-NLS-1$
+ ". Could have been renamed inside its existing source file."); //$NON-NLS-1$
+ return false;
+ } catch (CoreException e) {
+ throw internalException(e);
+ } finally {
+ cleanUp();
+ }
+ return true;
+ }
+ protected void addAffectedSourceFiles() {
+ if (qualifiedStrings.isEmpty() && simpleStrings.isEmpty())
+ return;
+ // the qualifiedStrings are of the form 'p1/p2' & the simpleStrings are
+ // just 'X'
+ char[][][] qualifiedNames = ReferenceCollection
+ .internQualifiedNames(qualifiedStrings);
+ // if a well known qualified name was found then we can skip over these
+ if (qualifiedNames.length < qualifiedStrings.size())
+ qualifiedNames = null;
+ char[][] simpleNames = ReferenceCollection.internSimpleNames(simpleStrings);
+ // if a well known name was found then we can skip over these
+ if (simpleNames.length < simpleStrings.size())
+ simpleNames = null;
+ Object[] keyTable = newState.references.keyTable;
+ Object[] valueTable = newState.references.valueTable;
+ next : for (int i = 0, l = valueTable.length; i < l; i++) {
+ ReferenceCollection refs = (ReferenceCollection) valueTable[i];
+ if (refs != null && refs.includes(qualifiedNames, simpleNames)) {
+ String typeLocator = (String) keyTable[i];
+ IFile file = javaBuilder.currentProject.getFile(typeLocator);
+ if (file.exists()) {
+ ClasspathMultiDirectory md = sourceLocations[0];
+ if (sourceLocations.length > 1) {
+ IPath sourceFileFullPath = file.getFullPath();
+ for (int j = 0, m = sourceLocations.length; j < m; j++) {
+ if (sourceLocations[j].sourceFolder.getFullPath().isPrefixOf(
+ sourceFileFullPath)) {
+ md = sourceLocations[j];
+ if (md.exclusionPatterns == null
+ || !Util.isExcluded(file, md.exclusionPatterns))
+ break;
+ }
+ }
+ }
+ SourceFile sourceFile = new SourceFile(file, md, encoding);
+ if (sourceFiles.contains(sourceFile))
+ continue next;
+ if (compiledAllAtOnce && previousSourceFiles != null
+ && previousSourceFiles.contains(sourceFile))
+ continue next; // can skip previously compiled files since already
+ // saw hierarchy related problems
+ if (PHPBuilder.DEBUG)
+ System.out.println(" adding affected source file " + typeLocator); //$NON-NLS-1$
+ // // update indexfile for the project:
+ sourceFiles.add(sourceFile);
+ }
+ }
+ }
+ }
+ protected void addDependentsOf(IPath path, boolean hasStructuralChanges) {
+ if (hasStructuralChanges) {
+ newState.tagAsStructurallyChanged();
+ this.hasStructuralChanges = true;
+ }
+ // the qualifiedStrings are of the form 'p1/p2' & the simpleStrings are
+ // just 'X'
+ path = path.setDevice(null);
+ String packageName = path.removeLastSegments(1).toString();
+ if (!qualifiedStrings.contains(packageName))
+ qualifiedStrings.add(packageName);
+ String typeName = path.lastSegment();
+ int memberIndex = typeName.indexOf('$');
+ if (memberIndex > 0)
+ typeName = typeName.substring(0, memberIndex);
+ if (!simpleStrings.contains(typeName)) {
+ if (PHPBuilder.DEBUG)
+ System.out.println(" will look for dependents of " //$NON-NLS-1$
+ + typeName + " in " + packageName); //$NON-NLS-1$
+ simpleStrings.add(typeName);
+ }
+ }
+ protected void cleanUp() {
+ super.cleanUp();
+ this.sourceFiles = null;
+ this.previousSourceFiles = null;
+ this.qualifiedStrings = null;
+ this.simpleStrings = null;
+ this.secondaryTypesToRemove = null;
+ this.hasStructuralChanges = false;
+ this.compileLoop = 0;
+ }
+ //protected boolean findAffectedSourceFiles(IResourceDelta delta,
+ // ClasspathLocation[] classFoldersAndJars) {
+ // for (int i = 0, l = classFoldersAndJars.length; i < l; i++) {
+ // ClasspathLocation bLocation = classFoldersAndJars[i];
+ // // either a .class file folder or a zip/jar file
+ // if (bLocation != null) { // skip unchanged output folder
+ // IPath p = bLocation.getProjectRelativePath();
+ // if (p != null) {
+ // IResourceDelta binaryDelta = delta.findMember(p);
+ // if (binaryDelta != null) {
+ // if (bLocation instanceof ClasspathJar) {
+ // if (JavaBuilder.DEBUG)
+ // System.out.println("ABORTING incremental build... found delta to jar/zip
+ // file"); //$NON-NLS-1$
+ // return false; // do full build since jar file was changed (added/removed
+ // were caught as classpath change)
+ // }
+ // if (binaryDelta.getKind() == IResourceDelta.ADDED || binaryDelta.getKind()
+ // == IResourceDelta.REMOVED) {
+ // if (JavaBuilder.DEBUG)
+ // System.out.println("ABORTING incremental build... found added/removed
+ // binary folder"); //$NON-NLS-1$
+ // return false; // added/removed binary folder should not make it here
+ // (classpath change), but handle anyways
+ // }
+ // int segmentCount = binaryDelta.getFullPath().segmentCount();
+ // IResourceDelta[] children = binaryDelta.getAffectedChildren(); // .class
+ // files from class folder
+ // for (int j = 0, m = children.length; j < m; j++)
+ // findAffectedSourceFiles(children[j], segmentCount);
+ // notifier.checkCancel();
+ // }
+ // }
+ // }
+ // }
+ // return true;
+ //}
+ protected void findAffectedSourceFiles(IResourceDelta binaryDelta,
+ int segmentCount) {
+ // When a package becomes a type or vice versa, expect 2 deltas,
+ // one on the folder & one on the class file
+ IResource resource = binaryDelta.getResource();
+ switch (resource.getType()) {
+ case IResource.FOLDER :
+ switch (binaryDelta.getKind()) {
+ case IResourceDelta.ADDED :
+ case IResourceDelta.REMOVED :
+ IPath packagePath = resource.getFullPath().removeFirstSegments(
+ segmentCount);
+ String packageName = packagePath.toString();
+ if (binaryDelta.getKind() == IResourceDelta.ADDED) {
+ // see if any known source file is from the same package...
+ // classpath already includes new package
+ if (!newState.isKnownPackage(packageName)) {
+ if (PHPBuilder.DEBUG)
+ System.out.println("Found added package " + packageName); //$NON-NLS-1$
+ addDependentsOf(packagePath, false);
+ return;
+ }
+ if (PHPBuilder.DEBUG)
+ System.out.println("Skipped dependents of added package "
+ + packageName); //$NON-NLS-1$
+ } else {
+ // see if the package still exists on the classpath
+ // if (!nameEnvironment.isPackage(packageName)) {
+ // if (JavaBuilder.DEBUG)
+ // System.out.println("Found removed package " + packageName);
+ // //$NON-NLS-1$
+ // addDependentsOf(packagePath, false);
+ // return;
+ // }
+ if (PHPBuilder.DEBUG)
+ System.out.println("Skipped dependents of removed package "
+ + packageName); //$NON-NLS-1$
+ }
+ // fall thru & traverse the sub-packages and .class files
+ case IResourceDelta.CHANGED :
+ IResourceDelta[] children = binaryDelta.getAffectedChildren();
+ for (int i = 0, l = children.length; i < l; i++)
+ findAffectedSourceFiles(children[i], segmentCount);
+ }
+ return;
+ case IResource.FILE :
+ // if (Util.isClassFileName(resource.getName())) {
+ // IPath typePath =
+ // resource.getFullPath().removeFirstSegments(segmentCount).removeFileExtension();
+ // switch (binaryDelta.getKind()) {
+ // case IResourceDelta.ADDED :
+ // case IResourceDelta.REMOVED :
+ // if (JavaBuilder.DEBUG)
+ // System.out.println("Found added/removed class file " + typePath);
+ // //$NON-NLS-1$
+ // addDependentsOf(typePath, false);
+ // return;
+ // case IResourceDelta.CHANGED :
+ // if ((binaryDelta.getFlags() & IResourceDelta.CONTENT) == 0)
+ // return; // skip it since it really isn't changed
+ // if (JavaBuilder.DEBUG)
+ // System.out.println("Found changed class file " + typePath);
+ // //$NON-NLS-1$
+ // addDependentsOf(typePath, false);
+ // }
+ // return;
+ // }
+ }
+ }
+ protected boolean findSourceFiles(IResourceDelta delta) throws CoreException {
+ for (int i = 0, l = sourceLocations.length; i < l; i++) {
+ ClasspathMultiDirectory md = sourceLocations[i];
+ if (md.sourceFolder.equals(javaBuilder.currentProject)) {
+ // skip nested source & output folders when the project is a source
+ // folder
+ int segmentCount = delta.getFullPath().segmentCount();
+ IResourceDelta[] children = delta.getAffectedChildren();
+ for (int j = 0, m = children.length; j < m; j++)
+ if (!isExcludedFromProject(children[j].getFullPath()))
+ findSourceFiles(children[j], md, segmentCount);
+ } else {
+ IResourceDelta sourceDelta = delta.findMember(md.sourceFolder
+ .getProjectRelativePath());
+ if (sourceDelta != null) {
+ if (sourceDelta.getKind() == IResourceDelta.REMOVED) {
+ if (PHPBuilder.DEBUG)
+ System.out
+ .println("ABORTING incremental build... found removed source folder"); //$NON-NLS-1$
+ return false; // removed source folder should not make it here, but
+ // handle anyways (ADDED is supported)
+ }
+ int segmentCount = sourceDelta.getFullPath().segmentCount();
+ IResourceDelta[] children = sourceDelta.getAffectedChildren();
+ for (int j = 0, m = children.length; j < m; j++)
+ findSourceFiles(children[j], md, segmentCount);
+ }
+ }
+ notifier.checkCancel();
+ }
+ return true;
+ }
+ protected void findSourceFiles(IResourceDelta sourceDelta,
+ ClasspathMultiDirectory md, int segmentCount) throws CoreException {
+ // When a package becomes a type or vice versa, expect 2 deltas,
+ // one on the folder & one on the source file
+ IResource resource = sourceDelta.getResource();
+ if (md.exclusionPatterns != null
+ && Util.isExcluded(resource, md.exclusionPatterns))
+ return;
+ switch (resource.getType()) {
+ case IResource.FOLDER :
+ switch (sourceDelta.getKind()) {
+ case IResourceDelta.ADDED :
+ IPath addedPackagePath = resource.getFullPath()
+ .removeFirstSegments(segmentCount);
+ createFolder(addedPackagePath, md.binaryFolder); // ensure package
+ // exists in the
+ // output folder
+ // add dependents even when the package thinks it exists to be on
+ // the safe side
+ if (PHPBuilder.DEBUG)
+ System.out.println("Found added package " + addedPackagePath); //$NON-NLS-1$
+ addDependentsOf(addedPackagePath, true);
+ // fall thru & collect all the source files
+ case IResourceDelta.CHANGED :
+ IResourceDelta[] children = sourceDelta.getAffectedChildren();
+ for (int i = 0, l = children.length; i < l; i++)
+ findSourceFiles(children[i], md, segmentCount);
+ return;
+ case IResourceDelta.REMOVED :
+ IPath removedPackagePath = resource.getFullPath()
+ .removeFirstSegments(segmentCount);
+ if (sourceLocations.length > 1) {
+ for (int i = 0, l = sourceLocations.length; i < l; i++) {
+ if (sourceLocations[i].sourceFolder.getFolder(
+ removedPackagePath).exists()) {
+ // only a package fragment was removed, same as removing
+ // multiple source files
+ createFolder(removedPackagePath, md.binaryFolder); // ensure
+ // package
+ // exists
+ // in the
+ // output
+ // folder
+ IResourceDelta[] removedChildren = sourceDelta
+ .getAffectedChildren();
+ for (int j = 0, m = removedChildren.length; j < m; j++)
+ findSourceFiles(removedChildren[j], md, segmentCount);
+ return;
+ }
+ }
+ }
+ IFolder removedPackageFolder = md.binaryFolder
+ .getFolder(removedPackagePath);
+ if (removedPackageFolder.exists())
+ removedPackageFolder.delete(IResource.FORCE, null);
+ // add dependents even when the package thinks it does not exist to
+ // be on the safe side
+ if (PHPBuilder.DEBUG)
+ System.out.println("Found removed package " + removedPackagePath); //$NON-NLS-1$
+ addDependentsOf(removedPackagePath, true);
+ newState.removePackage(sourceDelta);
+ }
+ return;
+ case IResource.FILE :
+ String resourceName = resource.getName();
+ if (Util.isJavaFileName(resourceName)) {
+ IPath typePath = resource.getFullPath().removeFirstSegments(
+ segmentCount).removeFileExtension();
+ String typeLocator = resource.getProjectRelativePath().toString();
+ switch (sourceDelta.getKind()) {
+ case IResourceDelta.ADDED :
+ if (PHPBuilder.DEBUG)
+ System.out.println("Compile this added source file "
+ + typeLocator); //$NON-NLS-1$
+ sourceFiles.add(new SourceFile((IFile) resource, md, encoding));
+ String typeName = typePath.toString();
+ if (!newState.isDuplicateLocator(typeName, typeLocator)) { // adding
+ // dependents
+ // results
+ // in
+ // 2
+ // duplicate
+ // errors
+ if (PHPBuilder.DEBUG)
+ System.out.println("Found added source file " + typeName); //$NON-NLS-1$
+ addDependentsOf(typePath, true);
+ }
+ return;
+ case IResourceDelta.REMOVED :
+ char[][] definedTypeNames = newState
+ .getDefinedTypeNamesFor(typeLocator);
+ if (definedTypeNames == null) { // defined a single type matching
+ // typePath
+ removeClassFile(typePath, md.binaryFolder);
+ if ((sourceDelta.getFlags() & IResourceDelta.MOVED_TO) != 0) {
+ // remove problems and tasks for a compilation unit that is
+ // being moved (to another package or renamed)
+ // if the target file is a compilation unit, the new cu will
+ // be recompiled
+ // if the target file is a non-java resource, then markers
+ // are removed
+ // see bug 2857
+ IResource movedFile = javaBuilder.workspaceRoot
+ .getFile(sourceDelta.getMovedToPath());
+ PHPBuilder.removeProblemsAndTasksFor(movedFile);
+ }
+ } else {
+ if (PHPBuilder.DEBUG)
+ System.out.println("Found removed source file "
+ + typePath.toString()); //$NON-NLS-1$
+ addDependentsOf(typePath, true); // add dependents of the
+ // source file since it may be
+ // involved in a name
+ // collision
+ if (definedTypeNames.length > 0) { // skip it if it failed to
+ // successfully define a
+ // type
+ IPath packagePath = typePath.removeLastSegments(1);
+ for (int i = 0, l = definedTypeNames.length; i < l; i++)
+ removeClassFile(packagePath.append(new String(
+ definedTypeNames[i])), md.binaryFolder);
+ }
+ }
+ newState.removeLocator(typeLocator);
+ return;
+ case IResourceDelta.CHANGED :
+ if ((sourceDelta.getFlags() & IResourceDelta.CONTENT) == 0)
+ return; // skip it since it really isn't changed
+ if (PHPBuilder.DEBUG)
+ System.out.println("Compile this changed source file "
+ + typeLocator); //$NON-NLS-1$
+ sourceFiles.add(new SourceFile((IFile) resource, md, encoding));
+ }
+ return;
+ // } else if (Util.isClassFileName(resourceName)) {
+ // return; // skip class files
+ } else if (md.hasIndependentOutputFolder) {
+ if (javaBuilder.filterExtraResource(resource))
+ return;
+ // copy all other resource deltas to the output folder
+ IPath resourcePath = resource.getFullPath().removeFirstSegments(
+ segmentCount);
+ IResource outputFile = md.binaryFolder.getFile(resourcePath);
+ switch (sourceDelta.getKind()) {
+ case IResourceDelta.ADDED :
+ if (outputFile.exists()) {
+ if (PHPBuilder.DEBUG)
+ System.out.println("Deleting existing file " + resourcePath); //$NON-NLS-1$
+ outputFile.delete(IResource.FORCE, null);
+ }
+ if (PHPBuilder.DEBUG)
+ System.out.println("Copying added file " + resourcePath); //$NON-NLS-1$
+ createFolder(resourcePath.removeLastSegments(1), md.binaryFolder); // ensure
+ // package
+ // exists
+ // in
+ // the
+ // output
+ // folder
+ resource.copy(outputFile.getFullPath(), IResource.FORCE, null);
+ outputFile.setDerived(true);
+ return;
+ case IResourceDelta.REMOVED :
+ if (outputFile.exists()) {
+ if (PHPBuilder.DEBUG)
+ System.out.println("Deleting removed file " + resourcePath); //$NON-NLS-1$
+ outputFile.delete(IResource.FORCE, null);
+ }
+ return;
+ case IResourceDelta.CHANGED :
+ if ((sourceDelta.getFlags() & IResourceDelta.CONTENT) == 0)
+ return; // skip it since it really isn't changed
+ if (outputFile.exists()) {
+ if (PHPBuilder.DEBUG)
+ System.out.println("Deleting existing file " + resourcePath); //$NON-NLS-1$
+ outputFile.delete(IResource.FORCE, null);
+ }
+ if (PHPBuilder.DEBUG)
+ System.out.println("Copying changed file " + resourcePath); //$NON-NLS-1$
+ createFolder(resourcePath.removeLastSegments(1), md.binaryFolder); // ensure
+ // package
+ // exists
+ // in
+ // the
+ // output
+ // folder
+ resource.copy(outputFile.getFullPath(), IResource.FORCE, null);
+ outputFile.setDerived(true);
+ }
+ return;
+ }
+ }
+ }
+ protected void finishedWith(String sourceLocator, CompilationResult result,
+ char[] mainTypeName, ArrayList definedTypeNames,
+ ArrayList duplicateTypeNames) throws CoreException {
+ char[][] previousTypeNames = newState.getDefinedTypeNamesFor(sourceLocator);
+ if (previousTypeNames == null)
+ previousTypeNames = new char[][]{mainTypeName};
+ IPath packagePath = null;
+ next : for (int i = 0, l = previousTypeNames.length; i < l; i++) {
+ char[] previous = previousTypeNames[i];
+ for (int j = 0, m = definedTypeNames.size(); j < m; j++)
+ if (CharOperation.equals(previous, (char[]) definedTypeNames.get(j)))
+ continue next;
+ SourceFile sourceFile = (SourceFile) result.getCompilationUnit();
+ if (packagePath == null) {
+ int count = sourceFile.sourceLocation.sourceFolder.getFullPath()
+ .segmentCount();
+ packagePath = sourceFile.resource.getFullPath().removeFirstSegments(
+ count).removeLastSegments(1);
+ }
+ if (secondaryTypesToRemove == null)
+ this.secondaryTypesToRemove = new SimpleLookupTable();
+ ArrayList types = (ArrayList) secondaryTypesToRemove
+ .get(sourceFile.sourceLocation.binaryFolder);
+ if (types == null)
+ types = new ArrayList(definedTypeNames.size());
+ types.add(packagePath.append(new String(previous)));
+ secondaryTypesToRemove.put(sourceFile.sourceLocation.binaryFolder, types);
+ }
+ // super.finishedWith(sourceLocator, result, mainTypeName,
+ // definedTypeNames, duplicateTypeNames);
+ }
+ protected void removeClassFile(IPath typePath, IContainer outputFolder)
+ throws CoreException {
+ if (typePath.lastSegment().indexOf('$') == -1) { // is not a nested type
+ newState.removeQualifiedTypeName(typePath.toString());
+ // add dependents even when the type thinks it does not exist to be on
+ // the safe side
+ if (PHPBuilder.DEBUG)
+ System.out.println("Found removed type " + typePath); //$NON-NLS-1$
+ addDependentsOf(typePath, true); // when member types are removed, their
+ // enclosing type is structurally
+ // changed
+ }
+ IFile classFile = outputFolder.getFile(typePath
+ .addFileExtension(PHPBuilder.CLASS_EXTENSION));
+ if (classFile.exists()) {
+ if (PHPBuilder.DEBUG)
+ System.out.println("Deleting class file of removed type " + typePath); //$NON-NLS-1$
+ classFile.delete(IResource.FORCE, null);
+ }
+ }
+ protected void removeSecondaryTypes() throws CoreException {
+ if (secondaryTypesToRemove != null) { // delayed deleting secondary types
+ // until the end of the compile loop
+ Object[] keyTable = secondaryTypesToRemove.keyTable;
+ Object[] valueTable = secondaryTypesToRemove.valueTable;
+ for (int i = 0, l = keyTable.length; i < l; i++) {
+ IContainer outputFolder = (IContainer) keyTable[i];
+ if (outputFolder != null) {
+ ArrayList paths = (ArrayList) valueTable[i];
+ for (int j = 0, m = paths.size(); j < m; j++)
+ removeClassFile((IPath) paths.get(j), outputFolder);
+ }
+ }
+ this.secondaryTypesToRemove = null;
+ if (previousSourceFiles != null && previousSourceFiles.size() > 1)
+ this.previousSourceFiles = null; // cannot optimize recompile case when
+ // a secondary type is deleted
+ }
+ }
+ protected void resetCollections() {
+ previousSourceFiles = sourceFiles.isEmpty()
+ ? null
+ : (ArrayList) sourceFiles.clone();
+ sourceFiles.clear();
+ qualifiedStrings.clear();
+ simpleStrings.clear();
+ workQueue.clear();
+ }
+ protected void updateProblemsFor(SourceFile sourceFile,
+ CompilationResult result) throws CoreException {
+ IMarker[] markers = PHPBuilder.getProblemsFor(sourceFile.resource);
+ IProblem[] problems = result.getProblems();
+ if (problems == null && markers.length == 0)
+ return;
+ notifier.updateProblemCounts(markers, problems);
+ PHPBuilder.removeProblemsFor(sourceFile.resource);
+ storeProblemsFor(sourceFile, problems);
+ }
+ protected void updateTasksFor(SourceFile sourceFile, CompilationResult result)
+ throws CoreException {
+ IMarker[] markers = PHPBuilder.getTasksFor(sourceFile.resource);
+ IProblem[] tasks = result.getTasks();
+ if (tasks == null && markers.length == 0)
+ return;
+ PHPBuilder.removeTasksFor(sourceFile.resource);
+ storeTasksFor(sourceFile, tasks);
+ }
+ //protected void writeClassFileBytes(byte[] bytes, IFile file, String
+ // qualifiedFileName, boolean isSecondaryType) throws CoreException {
+ // // Before writing out the class file, compare it to the previous file
+ // // If structural changes occured then add dependent source files
+ // if (file.exists()) {
+ // if (writeClassFileCheck(file, qualifiedFileName, bytes)) {
+ // if (JavaBuilder.DEBUG)
+ // System.out.println("Writing changed class file " +
+ // file.getName());//$NON-NLS-1$
+ // file.setContents(new ByteArrayInputStream(bytes), true, false, null);
+ // if (!file.isDerived())
+ // file.setDerived(true);
+ // } else if (JavaBuilder.DEBUG) {
+ // System.out.println("Skipped over unchanged class file " +
+ // file.getName());//$NON-NLS-1$
+ // }
+ // } else {
+ // if (isSecondaryType)
+ // addDependentsOf(new Path(qualifiedFileName), true); // new secondary type
+ // if (JavaBuilder.DEBUG)
+ // System.out.println("Writing new class file " +
+ // file.getName());//$NON-NLS-1$
+ // file.create(new ByteArrayInputStream(bytes), IResource.FORCE, null);
+ // file.setDerived(true);
+ // }
+ //}
+ //protected boolean writeClassFileCheck(IFile file, String fileName, byte[]
+ // newBytes) throws CoreException {
+ // try {
+ // byte[] oldBytes = Util.getResourceContentsAsByteArray(file);
+ // if (this.compileLoop > 1) { // only optimize files which were recompiled
+ // during the dependent pass, see 33990
+ // notEqual : if (newBytes.length == oldBytes.length) {
+ // for (int i = newBytes.length; --i >= 0;)
+ // if (newBytes[i] != oldBytes[i]) break notEqual;
+ // return false; // bytes are identical so skip them
+ // }
+ // }
+ // IPath location = file.getLocation();
+ // if (location == null) return false; // unable to determine location of
+ // this class file
+ // ClassFileReader reader = new ClassFileReader(oldBytes,
+ // location.toString().toCharArray());
+ // // ignore local types since they're only visible inside a single method
+ // if (!(reader.isLocal() || reader.isAnonymous()) &&
+ // reader.hasStructuralChanges(newBytes)) {
+ // if (JavaBuilder.DEBUG)
+ // System.out.println("Type has structural changes " + fileName);
+ // //$NON-NLS-1$
+ // addDependentsOf(new Path(fileName), true);
+ // }
+ // } catch (ClassFormatException e) {
+ // addDependentsOf(new Path(fileName), true);
+ // }
+ // return true;
+ //}
+ public String toString() {
+ return "incremental image builder for:\n\tnew state: " + newState; //$NON-NLS-1$
+ }
+ /*
+ * Debug helper
+ *
+ * static void dump(IResourceDelta delta) { StringBuffer buffer = new
+ * StringBuffer(); IPath path = delta.getFullPath(); for (int i =
+ * path.segmentCount(); --i > 0;) buffer.append(" "); switch
+ * (delta.getKind()) { case IResourceDelta.ADDED: buffer.append('+'); break;
+ * case IResourceDelta.REMOVED: buffer.append('-'); break; case
+ * IResourceDelta.CHANGED: '); break; case IResourceDelta.NO_CHANGE:
+ * buffer.append('='); break; default: buffer.append('?'); break; }
+ * buffer.append(path); System.out.println(buffer.toString());
+ * IResourceDelta[] children = delta.getAffectedChildren(); for (int i = 0, l =
+ * children.length; i < l; i++) dump(children[i]); }
+ */
}
* IBM Corporation - initial API and implementation
*******************************************************************************/
package net.sourceforge.phpdt.internal.core.builder;
-
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
-
import net.sourceforge.phpdt.core.IClasspathEntry;
import net.sourceforge.phpdt.core.IJavaModelMarker;
import net.sourceforge.phpdt.core.JavaModelException;
import net.sourceforge.phpdt.internal.core.JavaProject;
import net.sourceforge.phpdt.internal.core.Util;
import net.sourceforge.phpdt.internal.core.util.SimpleLookupTable;
+import net.sourceforge.phpdt.internal.ui.util.PHPFileUtil;
import net.sourceforge.phpeclipse.PHPCore;
-
+import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import net.sourceforge.phpeclipse.builder.IdentifierIndexManager;
+import net.sourceforge.phpeclipse.phpeditor.PHPParserAction;
+import net.sourceforge.phpeclipse.resourcesview.PHPProject;
+import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceChangeEvent;
import org.eclipse.core.resources.IResourceDelta;
+import org.eclipse.core.resources.IResourceVisitor;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.IncrementalProjectBuilder;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
-
+import org.eclipse.core.runtime.OperationCanceledException;
public class PHPBuilder extends IncrementalProjectBuilder {
-
IProject currentProject;
JavaProject javaProject;
IWorkspaceRoot workspaceRoot;
NameEnvironment nameEnvironment;
- SimpleLookupTable binaryLocationsPerProject; // maps a project to its binary resources (output folders, class folders, zip/jar files)
+ SimpleLookupTable binaryLocationsPerProject; // maps a project to its binary
+ // resources (output folders,
+ // class folders, zip/jar files)
State lastState;
BuildNotifier notifier;
char[][] extraResourceFileFilters;
String[] extraResourceFolderFilters;
-
public static final String CLASS_EXTENSION = "class"; //$NON-NLS-1$
-
public static boolean DEBUG = true;
-
/**
- * A list of project names that have been built.
- * This list is used to reset the JavaModel.existingExternalFiles cache when a build cycle begins
- * so that deleted external jars are discovered.
+ * A list of project names that have been built. This list is used to reset
+ * the JavaModel.existingExternalFiles cache when a build cycle begins so
+ * that deleted external jars are discovered.
*/
static ArrayList builtProjects = null;
-
public static IMarker[] getProblemsFor(IResource resource) {
try {
if (resource != null && resource.exists())
- return resource.findMarkers(IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER, false, IResource.DEPTH_INFINITE);
+ return resource.findMarkers(IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER,
+ false, IResource.DEPTH_INFINITE);
} catch (CoreException e) {
} // assume there are no problems
return new IMarker[0];
}
-
public static IMarker[] getTasksFor(IResource resource) {
try {
if (resource != null && resource.exists())
- return resource.findMarkers(IJavaModelMarker.TASK_MARKER, false, IResource.DEPTH_INFINITE);
+ return resource.findMarkers(IJavaModelMarker.TASK_MARKER, false,
+ IResource.DEPTH_INFINITE);
} catch (CoreException e) {
} // assume there are no tasks
return new IMarker[0];
}
-
public static void finishedBuilding(IResourceChangeEvent event) {
BuildNotifier.resetProblemCounters();
}
-
public static void removeProblemsFor(IResource resource) {
try {
if (resource != null && resource.exists())
- resource.deleteMarkers(IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER, false, IResource.DEPTH_INFINITE);
+ resource.deleteMarkers(IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER,
+ false, IResource.DEPTH_INFINITE);
} catch (CoreException e) {
} // assume there were no problems
}
-
public static void removeTasksFor(IResource resource) {
try {
if (resource != null && resource.exists())
- resource.deleteMarkers(IJavaModelMarker.TASK_MARKER, false, IResource.DEPTH_INFINITE);
+ resource.deleteMarkers(IJavaModelMarker.TASK_MARKER, false,
+ IResource.DEPTH_INFINITE);
} catch (CoreException e) {
} // assume there were no problems
}
-
public static void removeProblemsAndTasksFor(IResource resource) {
try {
if (resource != null && resource.exists()) {
- resource.deleteMarkers(IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER, false, IResource.DEPTH_INFINITE);
- resource.deleteMarkers(IJavaModelMarker.TASK_MARKER, false, IResource.DEPTH_INFINITE);
+ resource.deleteMarkers(IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER,
+ false, IResource.DEPTH_INFINITE);
+ resource.deleteMarkers(IJavaModelMarker.TASK_MARKER, false,
+ IResource.DEPTH_INFINITE);
}
} catch (CoreException e) {
} // assume there were no problems
}
-
- public static State readState(IProject project, DataInputStream in) throws IOException {
+ public static State readState(IProject project, DataInputStream in)
+ throws IOException {
return State.read(project, in);
}
-
- public static void writeState(Object state, DataOutputStream out) throws IOException {
+ public static void writeState(Object state, DataOutputStream out)
+ throws IOException {
((State) state).write(out);
}
-
public PHPBuilder() {
}
-
- protected IProject[] build(int kind, Map ignored, IProgressMonitor monitor) throws CoreException {
+ protected IProject[] build(int kind, Map ignored, IProgressMonitor monitor)
+ throws CoreException {
this.currentProject = getProject();
if (currentProject == null || !currentProject.isAccessible())
return new IProject[0];
-
if (DEBUG)
System.out.println("\nStarting build of " + currentProject.getName() //$NON-NLS-1$
- +" @ " + new Date(System.currentTimeMillis())); //$NON-NLS-1$
+ + " @ " + new Date(System.currentTimeMillis())); //$NON-NLS-1$
this.notifier = new BuildNotifier(monitor, currentProject);
notifier.begin();
boolean ok = false;
try {
notifier.checkCancel();
initializeBuilder();
-
if (isWorthBuilding()) {
if (kind == FULL_BUILD) {
+ processFullPHPIndex(currentProject, monitor);
buildAll();
} else {
if ((this.lastState = getLastState(currentProject)) == null) {
if (DEBUG)
- System.out.println("Performing full build since last saved state was not found"); //$NON-NLS-1$
- buildAll();
- } else if (hasClasspathChanged()) {
- // if the output location changes, do not delete the binary files from old location
- // the user may be trying something
+ System.out
+ .println("Performing full build since last saved state was not found"); //$NON-NLS-1$
+ processFullPHPIndex(currentProject, monitor);
buildAll();
+// } else if (hasClasspathChanged()) {
+// // if the output location changes, do not delete the binary files
+// // from old location
+// // the user may be trying something
+// buildAll();
} else if (nameEnvironment.sourceLocations.length > 0) {
- // if there is no source to compile & no classpath changes then we are done
+ // if there is no source to compile & no classpath changes then we
+ // are done
SimpleLookupTable deltas = findDeltas();
if (deltas == null)
buildAll();
else if (DEBUG)
System.out.println("Nothing to build since deltas were empty"); //$NON-NLS-1$
} else {
- if (hasStructuralDelta()) { // double check that a jar file didn't get replaced in a binary project
+ if (hasStructuralDelta()) { // double check that a jar file didn't
+ // get replaced in a binary project
+ processFullPHPIndex(currentProject, monitor);
buildAll();
} else {
if (DEBUG)
- System.out.println("Nothing to build since there are no source folders and no deltas"); //$NON-NLS-1$
+ System.out
+ .println("Nothing to build since there are no source folders and no deltas"); //$NON-NLS-1$
lastState.tagAsNoopBuild();
}
}
}
} catch (CoreException e) {
Util.log(e, "JavaBuilder handling CoreException"); //$NON-NLS-1$
- IMarker marker = currentProject.createMarker(IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER);
- marker.setAttribute(IMarker.MESSAGE, Util.bind("build.inconsistentProject", e.getLocalizedMessage())); //$NON-NLS-1$
+ IMarker marker = currentProject
+ .createMarker(IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER);
+ marker.setAttribute(IMarker.MESSAGE, Util.bind(
+ "build.inconsistentProject", e.getLocalizedMessage())); //$NON-NLS-1$
marker.setAttribute(IMarker.SEVERITY, IMarker.SEVERITY_ERROR);
} catch (ImageBuilderInternalException e) {
- Util.log(e.getThrowable(), "JavaBuilder handling ImageBuilderInternalException"); //$NON-NLS-1$
- IMarker marker = currentProject.createMarker(IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER);
- marker.setAttribute(IMarker.MESSAGE, Util.bind("build.inconsistentProject", e.coreException.getLocalizedMessage())); //$NON-NLS-1$
+ Util.log(e.getThrowable(),
+ "JavaBuilder handling ImageBuilderInternalException"); //$NON-NLS-1$
+ IMarker marker = currentProject
+ .createMarker(IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER);
+ marker.setAttribute(IMarker.MESSAGE, Util.bind(
+ "build.inconsistentProject", e.coreException.getLocalizedMessage())); //$NON-NLS-1$
marker.setAttribute(IMarker.SEVERITY, IMarker.SEVERITY_ERROR);
} catch (MissingClassFileException e) {
- // do not log this exception since its thrown to handle aborted compiles because of missing class files
+ // do not log this exception since its thrown to handle aborted compiles
+ // because of missing class files
if (DEBUG)
- System.out.println(Util.bind("build.incompleteClassPath", e.missingClassFile)); //$NON-NLS-1$
- IMarker marker = currentProject.createMarker(IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER);
- marker.setAttribute(IMarker.MESSAGE, Util.bind("build.incompleteClassPath", e.missingClassFile)); //$NON-NLS-1$
+ System.out.println(Util.bind("build.incompleteClassPath",
+ e.missingClassFile)); //$NON-NLS-1$
+ IMarker marker = currentProject
+ .createMarker(IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER);
+ marker.setAttribute(IMarker.MESSAGE, Util.bind(
+ "build.incompleteClassPath", e.missingClassFile)); //$NON-NLS-1$
marker.setAttribute(IMarker.SEVERITY, IMarker.SEVERITY_ERROR);
} catch (MissingSourceFileException e) {
- // do not log this exception since its thrown to handle aborted compiles because of missing source files
+ // do not log this exception since its thrown to handle aborted compiles
+ // because of missing source files
if (DEBUG)
- System.out.println(Util.bind("build.missingSourceFile", e.missingSourceFile)); //$NON-NLS-1$
- removeProblemsAndTasksFor(currentProject); // make this the only problem for this project
- IMarker marker = currentProject.createMarker(IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER);
- marker.setAttribute(IMarker.MESSAGE, Util.bind("build.missingSourceFile", e.missingSourceFile)); //$NON-NLS-1$
+ System.out.println(Util.bind("build.missingSourceFile",
+ e.missingSourceFile)); //$NON-NLS-1$
+ removeProblemsAndTasksFor(currentProject); // make this the only problem
+ // for this project
+ IMarker marker = currentProject
+ .createMarker(IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER);
+ marker.setAttribute(IMarker.MESSAGE, Util.bind("build.missingSourceFile",
+ e.missingSourceFile)); //$NON-NLS-1$
marker.setAttribute(IMarker.SEVERITY, IMarker.SEVERITY_ERROR);
} finally {
if (!ok)
- // If the build failed, clear the previously built state, forcing a full build next time.
+ // If the build failed, clear the previously built state, forcing a
+ // full build next time.
clearLastState();
notifier.done();
cleanup();
IProject[] requiredProjects = getRequiredProjects(true);
if (DEBUG)
System.out.println("Finished build of " + currentProject.getName() //$NON-NLS-1$
- +" @ " + new Date(System.currentTimeMillis())); //$NON-NLS-1$
+ + " @ " + new Date(System.currentTimeMillis())); //$NON-NLS-1$
return requiredProjects;
}
-
+ /**
+ * Performs a <code>FULL_BUILD</code> by visiting all nodes in the resource
+ * tree under the specified project.
+ *
+ * @param iProject
+ */
+ private void processFullPHPIndex(final IProject iProject,
+ final IProgressMonitor monitor) {
+ final IdentifierIndexManager indexManager = PHPeclipsePlugin.getDefault()
+ .getIndexManager(iProject);
+ // Create resource visitor logic
+ IResourceVisitor myVisitor = new IResourceVisitor() {
+ public boolean visit(IResource resource) throws CoreException {
+ if (resource.getType() == IResource.FILE) {
+ if (monitor.isCanceled()) {
+ throw new OperationCanceledException();
+ }
+ if ((resource.getFileExtension() != null)
+ && PHPFileUtil.isPHPFile((IFile) resource)) {
+ monitor.worked(1);
+ monitor.subTask("Parsing: " + resource.getFullPath());
+ // update indexfile for the project:
+// PHPProject nature = (PHPProject) iProject
+// .getNature(PHPeclipsePlugin.PHP_NATURE_ID);
+ indexManager.addFile((IFile) resource);
+ }
+ }
+ return true;
+ }
+ };
+ // Process the project using the visitor just created
+ try {
+ // if (iProject.hasNature(PHPeclipsePlugin.PHP_NATURE_ID)) {
+ // thePHPProject = new PHPProject();
+ // thePHPProject.setProject(iProject);
+ // }
+ indexManager.initialize();
+ iProject.accept(myVisitor);
+ indexManager.writeFile();
+ } catch (CoreException e) {
+ e.printStackTrace();
+ }
+ }
private void buildAll() {
notifier.checkCancel();
notifier.subTask(Util.bind("build.preparingBuild")); //$NON-NLS-1$
imageBuilder.build();
recordNewState(imageBuilder.newState);
}
-
private void buildDeltas(SimpleLookupTable deltas) {
notifier.checkCancel();
notifier.subTask(Util.bind("build.preparingBuild")); //$NON-NLS-1$
if (DEBUG && lastState != null)
System.out.println("Clearing last state : " + lastState); //$NON-NLS-1$
- clearLastState(); // clear the previously built state so if the build fails, a full build will occur next time
+ clearLastState(); // clear the previously built state so if the build
+ // fails, a full build will occur next time
IncrementalImageBuilder imageBuilder = new IncrementalImageBuilder(this);
if (imageBuilder.build(deltas))
recordNewState(imageBuilder.newState);
- else
+ else {
+ processFullPHPIndex(currentProject, notifier.monitor);
buildAll();
+ }
}
-
private void cleanup() {
this.nameEnvironment = null;
this.binaryLocationsPerProject = null;
this.extraResourceFileFilters = null;
this.extraResourceFolderFilters = null;
}
-
private void clearLastState() {
- JavaModelManager.getJavaModelManager().setLastBuiltState(currentProject, null);
+ JavaModelManager.getJavaModelManager().setLastBuiltState(currentProject,
+ null);
}
-
boolean filterExtraResource(IResource resource) {
if (extraResourceFileFilters != null) {
char[] name = resource.getName().toCharArray();
}
return false;
}
-
private SimpleLookupTable findDeltas() {
notifier.subTask(Util.bind("build.readingDelta", currentProject.getName())); //$NON-NLS-1$
IResourceDelta delta = getDelta(currentProject);
if (delta != null) {
if (delta.getKind() != IResourceDelta.NO_CHANGE) {
if (DEBUG)
- System.out.println("Found source delta for: " + currentProject.getName()); //$NON-NLS-1$
+ System.out.println("Found source delta for: "
+ + currentProject.getName()); //$NON-NLS-1$
deltas.put(currentProject, delta);
}
} else {
notifier.subTask(""); //$NON-NLS-1$
return null;
}
-
Object[] keyTable = binaryLocationsPerProject.keyTable;
Object[] valueTable = binaryLocationsPerProject.valueTable;
nextProject : for (int i = 0, l = keyTable.length; i < l; i++) {
IProject p = (IProject) keyTable[i];
if (p != null && p != currentProject) {
State s = getLastState(p);
- if (!lastState.wasStructurallyChanged(p, s)) { // see if we can skip its delta
+ if (!lastState.wasStructurallyChanged(p, s)) { // see if we can skip
+ // its delta
if (s.wasNoopBuild())
- continue nextProject; // project has no source folders and can be skipped
- // ClasspathLocation[] classFoldersAndJars = (ClasspathLocation[]) valueTable[i];
+ continue nextProject; // project has no source folders and can be
+ // skipped
+ // ClasspathLocation[] classFoldersAndJars = (ClasspathLocation[])
+ // valueTable[i];
boolean canSkip = true;
// for (int j = 0, m = classFoldersAndJars.length; j < m; j++) {
// if (classFoldersAndJars[j].isOutputFolder())
- // classFoldersAndJars[j] = null; // can ignore output folder since project was not structurally changed
+ // classFoldersAndJars[j] = null; // can ignore output folder since
+ // project was not structurally changed
// else
// canSkip = false;
// }
if (canSkip)
- continue nextProject; // project has no structural changes in its output folders
+ continue nextProject; // project has no structural changes in its
+ // output folders
}
-
notifier.subTask(Util.bind("build.readingDelta", p.getName())); //$NON-NLS-1$
delta = getDelta(p);
if (delta != null) {
notifier.subTask(""); //$NON-NLS-1$
return deltas;
}
-
private State getLastState(IProject project) {
- return (State) JavaModelManager.getJavaModelManager().getLastBuiltState(project, notifier.monitor);
+ return (State) JavaModelManager.getJavaModelManager().getLastBuiltState(
+ project, notifier.monitor);
}
-
- /* Return the list of projects for which it requires a resource delta. This builder's project
- * is implicitly included and need not be specified. Builders must re-specify the list
- * of interesting projects every time they are run as this is not carried forward
- * beyond the next build. Missing projects should be specified but will be ignored until
- * they are added to the workspace.
- */
+ /*
+ * Return the list of projects for which it requires a resource delta. This
+ * builder's project is implicitly included and need not be specified.
+ * Builders must re-specify the list of interesting projects every time they
+ * are run as this is not carried forward beyond the next build. Missing
+ * projects should be specified but will be ignored until they are added to
+ * the workspace.
+ */
private IProject[] getRequiredProjects(boolean includeBinaryPrerequisites) {
if (javaProject == null || workspaceRoot == null)
return new IProject[0];
-
ArrayList projects = new ArrayList();
try {
IClasspathEntry[] entries = javaProject.getExpandedClasspath(true);
IProject p = null;
switch (entry.getEntryKind()) {
case IClasspathEntry.CPE_PROJECT :
- p = workspaceRoot.getProject(path.lastSegment()); // missing projects are considered too
+ p = workspaceRoot.getProject(path.lastSegment()); // missing
+ // projects are
+ // considered too
break;
case IClasspathEntry.CPE_LIBRARY :
if (includeBinaryPrerequisites && path.segmentCount() > 1) {
- // some binary resources on the class path can come from projects that are not included in the project references
+ // some binary resources on the class path can come from projects
+ // that are not included in the project references
IResource resource = workspaceRoot.findMember(path.segment(0));
if (resource instanceof IProject)
p = (IProject) resource;
projects.toArray(result);
return result;
}
-
- private boolean hasClasspathChanged() {
- ClasspathMultiDirectory[] newSourceLocations = nameEnvironment.sourceLocations;
- ClasspathMultiDirectory[] oldSourceLocations = lastState.sourceLocations;
- int newLength = newSourceLocations.length;
- int oldLength = oldSourceLocations.length;
- int n, o;
- for (n = o = 0; n < newLength && o < oldLength; n++, o++) {
- if (newSourceLocations[n].equals(oldSourceLocations[o]))
- continue; // checks source & output folders
- try {
- if (newSourceLocations[n].sourceFolder.members().length == 0) { // added new empty source folder
- o--;
- continue;
- }
- } catch (CoreException ignore) {
- }
- if (DEBUG)
- System.out.println(newSourceLocations[n] + " != " + oldSourceLocations[o]); //$NON-NLS-1$
- return true;
- }
- while (n < newLength) {
- try {
- if (newSourceLocations[n].sourceFolder.members().length == 0) { // added new empty source folder
- n++;
- continue;
- }
- } catch (CoreException ignore) {
- }
- if (DEBUG)
- System.out.println("Added non-empty source folder"); //$NON-NLS-1$
- return true;
- }
- if (o < oldLength) {
- if (DEBUG)
- System.out.println("Removed source folder"); //$NON-NLS-1$
- return true;
- }
-
- // ClasspathLocation[] newBinaryLocations = nameEnvironment.binaryLocations;
- // ClasspathLocation[] oldBinaryLocations = lastState.binaryLocations;
- // newLength = newBinaryLocations.length;
- // oldLength = oldBinaryLocations.length;
- // for (n = o = 0; n < newLength && o < oldLength; n++, o++) {
- // if (newBinaryLocations[n].equals(oldBinaryLocations[o])) continue;
- // if (DEBUG)
- // System.out.println(newBinaryLocations[n] + " != " + oldBinaryLocations[o]); //$NON-NLS-1$
- // return true;
- // }
- // if (n < newLength || o < oldLength) {
- // if (DEBUG)
- // System.out.println("Number of binary folders/jar files has changed"); //$NON-NLS-1$
- // return true;
- // }
- return false;
- }
-
+// private boolean hasClasspathChanged() {
+// ClasspathMultiDirectory[] newSourceLocations = nameEnvironment.sourceLocations;
+// ClasspathMultiDirectory[] oldSourceLocations = lastState.sourceLocations;
+// int newLength = newSourceLocations.length;
+// int oldLength = oldSourceLocations.length;
+// int n, o;
+// for (n = o = 0; n < newLength && o < oldLength; n++, o++) {
+// if (newSourceLocations[n].equals(oldSourceLocations[o]))
+// continue; // checks source & output folders
+// try {
+// if (newSourceLocations[n].sourceFolder.members().length == 0) { // added
+// // new
+// // empty
+// // source
+// // folder
+// o--;
+// continue;
+// }
+// } catch (CoreException ignore) {
+// }
+// if (DEBUG)
+// System.out.println(newSourceLocations[n] + " != "
+// + oldSourceLocations[o]); //$NON-NLS-1$
+// return true;
+// }
+// while (n < newLength) {
+// try {
+// if (newSourceLocations[n].sourceFolder.members().length == 0) { // added
+// // new
+// // empty
+// // source
+// // folder
+// n++;
+// continue;
+// }
+// } catch (CoreException ignore) {
+// }
+// if (DEBUG)
+// System.out.println("Added non-empty source folder"); //$NON-NLS-1$
+// return true;
+// }
+// if (o < oldLength) {
+// if (DEBUG)
+// System.out.println("Removed source folder"); //$NON-NLS-1$
+// return true;
+// }
+// // ClasspathLocation[] newBinaryLocations =
+// // nameEnvironment.binaryLocations;
+// // ClasspathLocation[] oldBinaryLocations = lastState.binaryLocations;
+// // newLength = newBinaryLocations.length;
+// // oldLength = oldBinaryLocations.length;
+// // for (n = o = 0; n < newLength && o < oldLength; n++, o++) {
+// // if (newBinaryLocations[n].equals(oldBinaryLocations[o])) continue;
+// // if (DEBUG)
+// // System.out.println(newBinaryLocations[n] + " != " +
+// // oldBinaryLocations[o]); //$NON-NLS-1$
+// // return true;
+// // }
+// // if (n < newLength || o < oldLength) {
+// // if (DEBUG)
+// // System.out.println("Number of binary folders/jar files has changed");
+// // //$NON-NLS-1$
+// // return true;
+// // }
+// return false;
+// }
private boolean hasStructuralDelta() {
- // handle case when currentProject has only .class file folders and/or jar files... no source/output folders
+ // handle case when currentProject has only .class file folders and/or jar
+ // files... no source/output folders
IResourceDelta delta = getDelta(currentProject);
if (delta != null && delta.getKind() != IResourceDelta.NO_CHANGE) {
- // ClasspathLocation[] classFoldersAndJars = (ClasspathLocation[]) binaryLocationsPerProject.get(currentProject);
+ // ClasspathLocation[] classFoldersAndJars = (ClasspathLocation[])
+ // binaryLocationsPerProject.get(currentProject);
// if (classFoldersAndJars != null) {
// for (int i = 0, l = classFoldersAndJars.length; i < l; i++) {
- // ClasspathLocation classFolderOrJar = classFoldersAndJars[i]; // either a .class file folder or a zip/jar file
+ // ClasspathLocation classFolderOrJar = classFoldersAndJars[i]; // either
+ // a .class file folder or a zip/jar file
// if (classFolderOrJar != null) {
// IPath p = classFolderOrJar.getProjectRelativePath();
// if (p != null) {
// IResourceDelta binaryDelta = delta.findMember(p);
- // if (binaryDelta != null && binaryDelta.getKind() != IResourceDelta.NO_CHANGE)
+ // if (binaryDelta != null && binaryDelta.getKind() !=
+ // IResourceDelta.NO_CHANGE)
// return true;
// }
// }
}
return false;
}
-
private void initializeBuilder() throws CoreException {
this.javaProject = (JavaProject) PHPCore.create(currentProject);
this.workspaceRoot = currentProject.getWorkspace().getRoot();
-
- // Flush the existing external files cache if this is the beginning of a build cycle
+ // Flush the existing external files cache if this is the beginning of a
+ // build cycle
String projectName = currentProject.getName();
if (builtProjects == null || builtProjects.contains(projectName)) {
JavaModel.flushExternalFileCache();
builtProjects = new ArrayList();
}
builtProjects.add(projectName);
-
this.binaryLocationsPerProject = new SimpleLookupTable(3);
- this.nameEnvironment = new NameEnvironment(workspaceRoot, javaProject, binaryLocationsPerProject);
-
- String filterSequence = javaProject.getOption(PHPCore.CORE_JAVA_BUILD_RESOURCE_COPY_FILTER, true);
- char[][] filters = filterSequence != null && filterSequence.length() > 0 ? CharOperation.splitAndTrimOn(',', filterSequence.toCharArray()) : null;
+ this.nameEnvironment = new NameEnvironment(workspaceRoot, javaProject,
+ binaryLocationsPerProject);
+ String filterSequence = javaProject.getOption(
+ PHPCore.CORE_JAVA_BUILD_RESOURCE_COPY_FILTER, true);
+ char[][] filters = filterSequence != null && filterSequence.length() > 0
+ ? CharOperation.splitAndTrimOn(',', filterSequence.toCharArray())
+ : null;
if (filters == null) {
this.extraResourceFileFilters = null;
this.extraResourceFolderFilters = null;
if (f.length == 0)
continue;
if (f[f.length - 1] == '/')
- extraResourceFolderFilters[--folderCount] = new String(CharOperation.subarray(f, 0, f.length - 1));
+ extraResourceFolderFilters[--folderCount] = new String(CharOperation
+ .subarray(f, 0, f.length - 1));
else
extraResourceFileFilters[--fileCount] = f;
}
}
}
-
- private boolean isClasspathBroken(IClasspathEntry[] classpath, IProject p) throws CoreException {
- if (classpath == JavaProject.INVALID_CLASSPATH) // the .classpath file could not be read
+ private boolean isClasspathBroken(IClasspathEntry[] classpath, IProject p)
+ throws CoreException {
+ if (classpath == JavaProject.INVALID_CLASSPATH) // the .classpath file
+ // could not be read
return true;
-
- IMarker[] markers = p.findMarkers(IJavaModelMarker.BUILDPATH_PROBLEM_MARKER, false, IResource.DEPTH_ZERO);
+ IMarker[] markers = p.findMarkers(
+ IJavaModelMarker.BUILDPATH_PROBLEM_MARKER, false, IResource.DEPTH_ZERO);
for (int i = 0, l = markers.length; i < l; i++)
if (((Integer) markers[i].getAttribute(IMarker.SEVERITY)).intValue() == IMarker.SEVERITY_ERROR)
return true;
return false;
}
-
private boolean isWorthBuilding() throws CoreException {
- boolean abortBuilds = PHPCore.ABORT.equals(javaProject.getOption(PHPCore.CORE_JAVA_BUILD_INVALID_CLASSPATH, true));
+ boolean abortBuilds = PHPCore.ABORT.equals(javaProject.getOption(
+ PHPCore.CORE_JAVA_BUILD_INVALID_CLASSPATH, true));
if (!abortBuilds)
return true;
-
// Abort build only if there are classpath errors
-// if (isClasspathBroken(javaProject.getRawClasspath(), currentProject)) {
-// if (DEBUG)
-// System.out.println("Aborted build because project has classpath errors (incomplete or involved in cycle)"); //$NON-NLS-1$
-//
-// JavaModelManager.getJavaModelManager().deltaProcessor.addForRefresh(javaProject);
-//
-// removeProblemsAndTasksFor(currentProject); // remove all compilation problems
-//
-// IMarker marker = currentProject.createMarker(IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER);
-// marker.setAttribute(IMarker.MESSAGE, Util.bind("build.abortDueToClasspathProblems")); //$NON-NLS-1$
-// marker.setAttribute(IMarker.SEVERITY, IMarker.SEVERITY_ERROR);
-// return false;
-// }
-
- // make sure all prereq projects have valid build states... only when aborting builds since projects in cycles do not have build states
+ // if (isClasspathBroken(javaProject.getRawClasspath(), currentProject)) {
+ // if (DEBUG)
+ // System.out.println("Aborted build because project has classpath errors
+ // (incomplete or involved in cycle)"); //$NON-NLS-1$
+ //
+ // JavaModelManager.getJavaModelManager().deltaProcessor.addForRefresh(javaProject);
+ //
+ // removeProblemsAndTasksFor(currentProject); // remove all compilation
+ // problems
+ //
+ // IMarker marker =
+ // currentProject.createMarker(IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER);
+ // marker.setAttribute(IMarker.MESSAGE,
+ // Util.bind("build.abortDueToClasspathProblems")); //$NON-NLS-1$
+ // marker.setAttribute(IMarker.SEVERITY, IMarker.SEVERITY_ERROR);
+ // return false;
+ // }
+ // make sure all prereq projects have valid build states... only when
+ // aborting builds since projects in cycles do not have build states
// except for projects involved in a 'warning' cycle (see below)
IProject[] requiredProjects = getRequiredProjects(false);
next : for (int i = 0, l = requiredProjects.length; i < l; i++) {
IProject p = requiredProjects[i];
if (getLastState(p) == null) {
- // The prereq project has no build state: if this prereq project has a 'warning' cycle marker then allow build (see bug id 23357)
+ // The prereq project has no build state: if this prereq project has a
+ // 'warning' cycle marker then allow build (see bug id 23357)
JavaProject prereq = (JavaProject) PHPCore.create(p);
- if (prereq.hasCycleMarker() && PHPCore.WARNING.equals(javaProject.getOption(PHPCore.CORE_CIRCULAR_CLASSPATH, true)))
+ if (prereq.hasCycleMarker()
+ && PHPCore.WARNING.equals(javaProject.getOption(
+ PHPCore.CORE_CIRCULAR_CLASSPATH, true)))
continue;
if (DEBUG)
- System.out.println("Aborted build because prereq project " + p.getName() //$NON-NLS-1$
- +" was not built"); //$NON-NLS-1$
-
- removeProblemsAndTasksFor(currentProject); // make this the only problem for this project
- IMarker marker = currentProject.createMarker(IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER);
- marker.setAttribute(IMarker.MESSAGE, isClasspathBroken(prereq.getRawClasspath(), p) ? Util.bind("build.prereqProjectHasClasspathProblems", p.getName()) //$NON-NLS-1$
- : Util.bind("build.prereqProjectMustBeRebuilt", p.getName())); //$NON-NLS-1$
+ System.out.println("Aborted build because prereq project "
+ + p.getName() //$NON-NLS-1$
+ + " was not built"); //$NON-NLS-1$
+ removeProblemsAndTasksFor(currentProject); // make this the only
+ // problem for this project
+ IMarker marker = currentProject
+ .createMarker(IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER);
+ marker.setAttribute(IMarker.MESSAGE, isClasspathBroken(prereq
+ .getRawClasspath(), p) ? Util.bind(
+ "build.prereqProjectHasClasspathProblems", p.getName()) //$NON-NLS-1$
+ : Util.bind("build.prereqProjectMustBeRebuilt", p.getName())); //$NON-NLS-1$
marker.setAttribute(IMarker.SEVERITY, IMarker.SEVERITY_ERROR);
return false;
}
}
return true;
}
-
/*
* Instruct the build manager that this project is involved in a cycle and
* needs to propagate structural changes to the other projects in the cycle.
*/
void mustPropagateStructuralChanges() {
HashSet cycleParticipants = new HashSet(3);
- javaProject.updateCycleParticipants(null, new ArrayList(), cycleParticipants, workspaceRoot, new HashSet(3));
+ javaProject.updateCycleParticipants(null, new ArrayList(),
+ cycleParticipants, workspaceRoot, new HashSet(3));
IPath currentPath = javaProject.getPath();
Iterator i = cycleParticipants.iterator();
while (i.hasNext()) {
IPath participantPath = (IPath) i.next();
if (participantPath != currentPath) {
- IProject project = this.workspaceRoot.getProject(participantPath.segment(0));
+ IProject project = this.workspaceRoot.getProject(participantPath
+ .segment(0));
if (hasBeenBuilt(project)) {
if (DEBUG)
- System.out.println("Requesting another build iteration since cycle participant " + project.getName() //$NON-NLS-1$
- +" has not yet seen some structural changes"); //$NON-NLS-1$
+ System.out
+ .println("Requesting another build iteration since cycle participant "
+ + project.getName() //$NON-NLS-1$
+ + " has not yet seen some structural changes"); //$NON-NLS-1$
needRebuild();
return;
}
}
}
}
-
private void recordNewState(State state) {
Object[] keyTable = binaryLocationsPerProject.keyTable;
for (int i = 0, l = keyTable.length; i < l; i++) {
IProject prereqProject = (IProject) keyTable[i];
if (prereqProject != null && prereqProject != currentProject)
- state.recordStructuralDependency(prereqProject, getLastState(prereqProject));
+ state.recordStructuralDependency(prereqProject,
+ getLastState(prereqProject));
}
-
if (DEBUG)
System.out.println("Recording new state : " + state); //$NON-NLS-1$
// state.dump();
- JavaModelManager.getJavaModelManager().setLastBuiltState(currentProject, state);
+ JavaModelManager.getJavaModelManager().setLastBuiltState(currentProject,
+ state);
}
-
/**
* String representation for debugging purposes
*/
public String toString() {
return currentProject == null ? "JavaBuilder for unknown project" //$NON-NLS-1$
- : "JavaBuilder for " + currentProject.getName(); //$NON-NLS-1$
+ : "JavaBuilder for " + currentProject.getName(); //$NON-NLS-1$
}
}
package net.sourceforge.phpeclipse.builder;
-
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.util.SortedMap;
import java.util.StringTokenizer;
import java.util.TreeMap;
-
import net.sourceforge.phpdt.core.compiler.ITerminalSymbols;
import net.sourceforge.phpdt.core.compiler.InvalidInputException;
import net.sourceforge.phpdt.internal.compiler.parser.Scanner;
import net.sourceforge.phpdt.internal.compiler.parser.SyntaxError;
import net.sourceforge.phpdt.internal.compiler.util.Util;
import net.sourceforge.phpeclipse.obfuscator.PHPIdentifier;
-
import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.CoreException;
-
/**
* Manages the identifer index information for a specific project
- *
+ *
*/
public class IdentifierIndexManager {
-
public class LineCreator implements ITerminalSymbols {
-
private Scanner fScanner;
private int fToken;
-
public LineCreator() {
fScanner = new Scanner(true, false);
}
-
/**
* Add the information of the current identifier to the line
*
- * @param typeOfIdentifier the type of the identifier ('c'lass, 'd'efine, 'f'unction, 'm'ethod, 'v'ariable)
- * @param identifier current identifier
- * @param line Buffer for the current index line
- * @param phpdocOffset the offset of the PHPdoc comment if available
- * @param phpdocLength the length of the PHPdoc comment if available
+ * @param typeOfIdentifier
+ * the type of the identifier ('c'lass, 'd'efine, 'f'unction,
+ * 'm'ethod, 'v'ariable)
+ * @param identifier
+ * current identifier
+ * @param line
+ * Buffer for the current index line
+ * @param phpdocOffset
+ * the offset of the PHPdoc comment if available
+ * @param phpdocLength
+ * the length of the PHPdoc comment if available
*/
- private void addIdentifierInformation(
- char typeOfIdentifier,
- char[] identifier,
- StringBuffer line,
- int phpdocOffset,
- int phpdocLength) {
-
+ private void addIdentifierInformation(char typeOfIdentifier,
+ char[] identifier, StringBuffer line, int phpdocOffset, int phpdocLength) {
line.append('\t');
line.append(typeOfIdentifier);
line.append(identifier);
- line.append("\to"); // Offset
+ line.append("\to"); // Offset
line.append(fScanner.getCurrentTokenStartPosition());
if (phpdocOffset >= 0) {
line.append("\tp"); // phpdoc offset
line.append("\tl"); // phpdoc length
line.append(phpdocLength);
}
-
}
/**
* Get the next token from input
if (Scanner.DEBUG) {
int currentEndPosition = fScanner.getCurrentTokenEndPosition();
int currentStartPosition = fScanner.getCurrentTokenStartPosition();
-
- System.out.print(currentStartPosition + "," + currentEndPosition + ": ");
+ System.out.print(currentStartPosition + "," + currentEndPosition
+ + ": ");
System.out.println(fScanner.toStringAction(fToken));
}
return;
}
fToken = TokenNameERROR;
}
-
- private void parseDeclarations(char[] parent, StringBuffer buf, boolean goBack) {
+ private void parseDeclarations(char[] parent, StringBuffer buf,
+ boolean goBack) {
char[] ident;
char[] classVariable;
int counter = 0;
int phpdocOffset = -1;
int phpdocLength = -1;
-
try {
while (fToken != TokenNameEOF && fToken != TokenNameERROR) {
phpdocOffset = -1;
if (fToken == TokenNameCOMMENT_PHPDOC) {
phpdocOffset = fScanner.getCurrentTokenStartPosition();
- phpdocLength = fScanner.getCurrentTokenEndPosition() - fScanner.getCurrentTokenStartPosition() + 1;
+ phpdocLength = fScanner.getCurrentTokenEndPosition()
+ - fScanner.getCurrentTokenStartPosition() + 1;
getNextToken();
if (fToken == TokenNameEOF || fToken == TokenNameERROR) {
break;
}
}
- if (fToken == TokenNamevar) {
+ if (fToken == TokenNamevar || fToken == TokenNamepublic
+ || fToken == TokenNameprotected || fToken == TokenNameprivate) {
getNextToken();
if (fToken == TokenNameVariable) {
ident = fScanner.getCurrentIdentifierSource();
classVariable = new char[ident.length - 1];
System.arraycopy(ident, 1, classVariable, 0, ident.length - 1);
- addIdentifierInformation('v', classVariable, buf, phpdocOffset, phpdocLength);
+ addIdentifierInformation('v', classVariable, buf, phpdocOffset,
+ phpdocLength);
getNextToken();
}
} else if (fToken == TokenNamefunction) {
ident = fScanner.getCurrentIdentifierSource();
if (parent != null && equalCharArrays(parent, ident)) {
// constructor function
- addIdentifierInformation('k', ident, buf, phpdocOffset, phpdocLength);
+ addIdentifierInformation('k', ident, buf, phpdocOffset,
+ phpdocLength);
} else {
if (parent != null) {
// class method function
- addIdentifierInformation('m', ident, buf, phpdocOffset, phpdocLength);
+ addIdentifierInformation('m', ident, buf, phpdocOffset,
+ phpdocLength);
} else {
// nested function ?!
- addIdentifierInformation('f', ident, buf, phpdocOffset, phpdocLength);
+ addIdentifierInformation('f', ident, buf, phpdocOffset,
+ phpdocLength);
}
}
getNextToken();
getNextToken();
if (fToken == TokenNameIdentifier) {
ident = fScanner.getCurrentIdentifierSource();
- addIdentifierInformation('c', ident, buf, phpdocOffset, phpdocLength);
+ addIdentifierInformation('c', ident, buf, phpdocOffset,
+ phpdocLength);
getNextToken();
-
- //skip tokens for classname, extends and others until we have the opening '{'
- while (fToken != TokenNameLBRACE && fToken != TokenNameEOF && fToken != TokenNameERROR) {
+ //skip tokens for classname, extends and others until we have
+ // the opening '{'
+ while (fToken != TokenNameLBRACE && fToken != TokenNameEOF
+ && fToken != TokenNameERROR) {
getNextToken();
}
parseDeclarations(ident, buf, true);
}
- } else if (fToken == TokenNamedefine) {
+ } else if (fToken == TokenNameIdentifier) {
+ ident = fScanner.getCurrentIdentifierSource();
getNextToken();
- if (fToken == TokenNameLPAREN) {
- getNextToken();
- if (fToken == TokenNameStringLiteral) {
- ident = fScanner.getCurrentStringLiteralSource();
- addIdentifierInformation('d', ident, buf, phpdocOffset, phpdocLength);
+ if (ident.length==6 &&
+ ident[0]=='d' &&
+ ident[1]=='e' &&
+ ident[2]=='f' &&
+ ident[3]=='i' &&
+ ident[4]=='n' &&
+ ident[5]=='e') {
+ if (fToken == TokenNameLPAREN) {
getNextToken();
+ if (fToken == TokenNameStringLiteral) {
+ ident = fScanner.getCurrentStringLiteralSource();
+ addIdentifierInformation('d', ident, buf, phpdocOffset,
+ phpdocLength);
+ getNextToken();
+ }
}
}
- } else if ((fToken == TokenNameLBRACE) || (fToken == TokenNameDOLLAR_LBRACE)) {
+ } else if ((fToken == TokenNameLBRACE)
+ || (fToken == TokenNameDOLLAR_LBRACE)) {
getNextToken();
counter++;
} else if (fToken == TokenNameRBRACE) {
e.printStackTrace();
}
}
-
public void parseIdentifiers(char[] charArray, StringBuffer buf) {
char[] ident;
String identifier;
int counter = 0;
int phpdocOffset = -1;
int phpdocLength = -1;
-
fScanner.setSource(charArray);
fScanner.setPHPMode(false);
fToken = TokenNameEOF;
getNextToken();
-
try {
while (fToken != TokenNameEOF && fToken != TokenNameERROR) {
phpdocOffset = -1;
if (fToken == TokenNameCOMMENT_PHPDOC) {
phpdocOffset = fScanner.getCurrentTokenStartPosition();
- phpdocLength = fScanner.getCurrentTokenEndPosition() - fScanner.getCurrentTokenStartPosition() + 1;
+ phpdocLength = fScanner.getCurrentTokenEndPosition()
+ - fScanner.getCurrentTokenStartPosition() + 1;
getNextToken();
if (fToken == TokenNameEOF || fToken == TokenNameERROR) {
break;
}
if (fToken == TokenNameIdentifier) {
ident = fScanner.getCurrentIdentifierSource();
- addIdentifierInformation('f', ident, buf, phpdocOffset, phpdocLength);
+ addIdentifierInformation('f', ident, buf, phpdocOffset,
+ phpdocLength);
getNextToken();
parseDeclarations(null, buf, true);
}
getNextToken();
if (fToken == TokenNameIdentifier) {
ident = fScanner.getCurrentIdentifierSource();
- addIdentifierInformation('c', ident, buf, phpdocOffset, phpdocLength);
+ addIdentifierInformation('c', ident, buf, phpdocOffset,
+ phpdocLength);
getNextToken();
-
- //skip fTokens for classname, extends and others until we have the opening '{'
- while (fToken != TokenNameLBRACE && fToken != TokenNameEOF && fToken != TokenNameERROR) {
+ //skip fTokens for classname, extends and others until we have
+ // the opening '{'
+ while (fToken != TokenNameLBRACE && fToken != TokenNameEOF
+ && fToken != TokenNameERROR) {
getNextToken();
}
-
parseDeclarations(ident, buf, true);
-
}
- } else if (fToken == TokenNamedefine) {
+ } else if (fToken == TokenNameIdentifier) {
+ ident = fScanner.getCurrentIdentifierSource();
getNextToken();
- if (fToken == TokenNameLPAREN) {
- getNextToken();
- if (fToken == TokenNameStringLiteral) {
- ident = fScanner.getCurrentStringLiteralSource();
- addIdentifierInformation('d', ident, buf, phpdocOffset, phpdocLength);
+ if (ident.length==6 &&
+ ident[0]=='d' &&
+ ident[1]=='e' &&
+ ident[2]=='f' &&
+ ident[3]=='i' &&
+ ident[4]=='n' &&
+ ident[5]=='e') {
+ if (fToken == TokenNameLPAREN) {
getNextToken();
+ if (fToken == TokenNameStringLiteral) {
+ ident = fScanner.getCurrentStringLiteralSource();
+ addIdentifierInformation('d', ident, buf, phpdocOffset,
+ phpdocLength);
+ getNextToken();
+ }
}
}
} else {
}
}
}
-
class StringComparator implements Comparator {
public int compare(Object o1, Object o2) {
String s1 = (String) o1;
String s2 = (String) o2;
return s1.compareTo(s2);
- // return s1.toUpperCase().compareTo(s2.toUpperCase());
+ // return s1.toUpperCase().compareTo(s2.toUpperCase());
}
public boolean equals(Object o) {
String s = (String) o;
return compare(this, o) == 0;
}
}
-
private HashMap fFileMap;
private String fFilename;
private TreeMap fIndentifierMap;
-
public IdentifierIndexManager(String filename) {
fFilename = filename;
initialize();
readFile();
}
-
/**
* Check if 2 char arrays are equal
*
}
return true;
}
-
/**
* Add the information for a given IFile resource
- *
+ *
*/
public void addFile(IFile fileToParse) {
// InputStream iStream;
InputStream stream = null;
try {
stream = new BufferedInputStream(fileToParse.getContents());
-
StringBuffer lineBuffer = new StringBuffer();
lineBuffer.append(fileToParse.getFullPath().toString());
int lineLength = lineBuffer.length();
- // lineCreator.parseIdentifiers(buf.toString().toCharArray(), lineBuffer);
- lineCreator.parseIdentifiers(Util.getInputStreamAsCharArray(stream, -1, null), lineBuffer);
+ // lineCreator.parseIdentifiers(buf.toString().toCharArray(),
+ // lineBuffer);
+ lineCreator.parseIdentifiers(Util.getInputStreamAsCharArray(stream, -1,
+ null), lineBuffer);
if (lineLength != lineBuffer.length()) {
addLine(lineBuffer.toString());
}
e1.printStackTrace();
}
}
-
/**
- * Adds a line of the index file for function, class, class-method and class-variable names
+ * Adds a line of the index file for function, class, class-method and
+ * class-variable names
*
* @param line
*/
String offset = null;
PHPIdentifierLocation phpIdentifier = null;
boolean tokenExists = false;
-
tokenizer = new StringTokenizer(line, "\t");
// first token contains the filename:
if (tokenizer.hasMoreTokens()) {
token = tokenizer.nextToken();
//System.out.println(token);
switch (token.charAt(0)) {
- case 'c' : // class name
+ case 'c' :
+ // class name
identifier = token.substring(1);
classname = identifier;
- phpIdentifier = new PHPIdentifierLocation(identifier, PHPIdentifier.CLASS, phpFileName);
+ phpIdentifier = new PHPIdentifierLocation(identifier,
+ PHPIdentifier.CLASS, phpFileName);
break;
- case 'd' : // define
+ case 'd' :
+ // define
identifier = token.substring(1);
- phpIdentifier = new PHPIdentifierLocation(identifier, PHPIdentifier.DEFINE, phpFileName);
+ phpIdentifier = new PHPIdentifierLocation(identifier,
+ PHPIdentifier.DEFINE, phpFileName);
break;
- case 'f' : // function name
+ case 'f' :
+ // function name
identifier = token.substring(1);
- phpIdentifier = new PHPIdentifierLocation(identifier, PHPIdentifier.FUNCTION, phpFileName);
+ phpIdentifier = new PHPIdentifierLocation(identifier,
+ PHPIdentifier.FUNCTION, phpFileName);
break;
- case 'k' : // constructor function name
+ case 'k' :
+ // constructor function name
identifier = token.substring(1);
- phpIdentifier = new PHPIdentifierLocation(identifier, PHPIdentifier.CONSTRUCTOR, phpFileName);
+ phpIdentifier = new PHPIdentifierLocation(identifier,
+ PHPIdentifier.CONSTRUCTOR, phpFileName);
break;
- case 'm' : //method inside a class
+ case 'm' :
+ //method inside a class
identifier = token.substring(1);
- phpIdentifier = new PHPIdentifierLocation(identifier, PHPIdentifier.METHOD, phpFileName, classname);
+ phpIdentifier = new PHPIdentifierLocation(identifier,
+ PHPIdentifier.METHOD, phpFileName, classname);
break;
- case 'v' : // variable inside a class
+ case 'v' :
+ // variable inside a class
identifier = token.substring(1);
- phpIdentifier = new PHPIdentifierLocation(identifier, PHPIdentifier.VARIABLE, phpFileName, classname);
+ phpIdentifier = new PHPIdentifierLocation(identifier,
+ PHPIdentifier.VARIABLE, phpFileName, classname);
break;
- case 'o' : // offset information
+ case 'o' :
+ // offset information
identifier = null;
if (phpIdentifier != null) {
offset = token.substring(1);
phpIdentifier.setOffset(Integer.parseInt(offset));
}
break;
- case 'p' : // PHPdoc offset information
+ case 'p' :
+ // PHPdoc offset information
identifier = null;
if (phpIdentifier != null) {
offset = token.substring(1);
phpIdentifier.setPHPDocOffset(Integer.parseInt(offset));
}
break;
- case 'l' : // PHPdoc length information
+ case 'l' :
+ // PHPdoc length information
identifier = null;
if (phpIdentifier != null) {
offset = token.substring(1);
fFileMap.put(phpFileName, line);
}
}
-
/**
* Change the information for a given IFile resource
- *
+ *
*/
public void changeFile(IFile fileToParse) {
removeFile(fileToParse);
addFile(fileToParse);
}
-
/**
- * Get a list of all PHPIdentifierLocation object's associated with an identifier
+ * Get a list of all PHPIdentifierLocation object's associated with an
+ * identifier
*
* @param identifier
* @return
public List getLocations(String identifier) {
return (List) fIndentifierMap.get(identifier);
}
-
/**
* Initialize (i.e. clear) the current index information
- *
+ *
*/
public void initialize() {
fIndentifierMap = new TreeMap(new StringComparator());
fFileMap = new HashMap();
}
-
private void readFile() {
-
FileReader fileReader;
try {
fileReader = new FileReader(fFilename);
-
BufferedReader bufferedReader = new BufferedReader(fileReader);
-
String line;
while (bufferedReader.ready()) {
// all entries for one file are in a line
line = bufferedReader.readLine();
addLine(line);
}
-
fileReader.close();
} catch (FileNotFoundException e) {
// ignore this
// TODO Auto-generated catch block
e.printStackTrace();
}
-
}
-
/**
* Remove the information for a given IFile resource
- *
+ *
*/
public void removeFile(IFile fileToParse) {
- // String line = (String) fFileMap.get(fileToParse.getLocation().toString());
+ // String line = (String)
+ // fFileMap.get(fileToParse.getLocation().toString());
String line = (String) fFileMap.get(fileToParse.getFullPath().toString());
if (line != null) {
removeLine(line);
}
}
-
/**
- * Removes a line of the index file for function, class, class-method and class-variable names
+ * Removes a line of the index file for function, class, class-method and
+ * class-variable names
*
* @param line
*/
String classname = null;
PHPIdentifier phpIdentifier = null;
boolean tokenExists = false;
-
tokenizer = new StringTokenizer(line, "\t");
// first token contains the filename:
if (tokenizer.hasMoreTokens()) {
token = tokenizer.nextToken();
//System.out.println(token);
switch (token.charAt(0)) {
- case 'c' : // class name
+ case 'c' :
+ // class name
identifier = token.substring(1);
classname = identifier;
- phpIdentifier = new PHPIdentifierLocation(identifier, PHPIdentifier.CLASS, phpFileName);
+ phpIdentifier = new PHPIdentifierLocation(identifier,
+ PHPIdentifier.CLASS, phpFileName);
break;
- case 'd' : // define
+ case 'd' :
+ // define
identifier = token.substring(1);
- phpIdentifier = new PHPIdentifierLocation(identifier, PHPIdentifier.DEFINE, phpFileName);
+ phpIdentifier = new PHPIdentifierLocation(identifier,
+ PHPIdentifier.DEFINE, phpFileName);
break;
- case 'f' : // function name
+ case 'f' :
+ // function name
identifier = token.substring(1);
- phpIdentifier = new PHPIdentifierLocation(identifier, PHPIdentifier.FUNCTION, phpFileName);
+ phpIdentifier = new PHPIdentifierLocation(identifier,
+ PHPIdentifier.FUNCTION, phpFileName);
break;
- case 'k' : // constructor function name
+ case 'k' :
+ // constructor function name
identifier = token.substring(1);
- phpIdentifier = new PHPIdentifierLocation(identifier, PHPIdentifier.CONSTRUCTOR, phpFileName);
+ phpIdentifier = new PHPIdentifierLocation(identifier,
+ PHPIdentifier.CONSTRUCTOR, phpFileName);
break;
- case 'm' : //method inside a class
+ case 'm' :
+ //method inside a class
identifier = token.substring(1);
- phpIdentifier = new PHPIdentifierLocation(identifier, PHPIdentifier.METHOD, phpFileName, classname);
+ phpIdentifier = new PHPIdentifierLocation(identifier,
+ PHPIdentifier.METHOD, phpFileName, classname);
break;
- case 'v' : // variable inside a class
+ case 'v' :
+ // variable inside a class
identifier = token.substring(1);
- phpIdentifier = new PHPIdentifierLocation(identifier, PHPIdentifier.VARIABLE, phpFileName, classname);
+ phpIdentifier = new PHPIdentifierLocation(identifier,
+ PHPIdentifier.VARIABLE, phpFileName, classname);
break;
default :
identifier = null;
}
fFileMap.remove(phpFileName);
}
-
/**
* Save the current index information in the projects index file
- *
+ *
*/
public void writeFile() {
FileWriter fileWriter;
e.printStackTrace();
}
}
-
/**
* @param fromKey
* @param toKey
public SortedMap getIdentifierMap() {
return fIndentifierMap;
}
-
}
\ No newline at end of file