示例#1
0
  protected void clean(IProgressMonitor monitor) throws CoreException {
    this.currentProject = getProject();
    if (this.currentProject == null || !this.currentProject.isAccessible()) return;

    if (DEBUG)
      System.out.println(
          "\nJavaBuilder: Cleaning "
              + this.currentProject.getName() // $NON-NLS-1$
              + " @ "
              + new Date(System.currentTimeMillis())); // $NON-NLS-1$
    this.notifier = new BuildNotifier(monitor, this.currentProject);
    this.notifier.begin();
    try {
      this.notifier.checkCancel();

      initializeBuilder(CLEAN_BUILD, true);
      if (DEBUG)
        System.out.println(
            "JavaBuilder: Clearing last state as part of clean : " + this.lastState); // $NON-NLS-1$
      clearLastState();
      removeProblemsAndTasksFor(this.currentProject);
      new BatchImageBuilder(this, false).cleanOutputFolders(false);
    } catch (CoreException e) {
      Util.log(
          e,
          "JavaBuilder handling CoreException while cleaning: "
              + this.currentProject.getName()); // $NON-NLS-1$
      createInconsistentBuildMarker(e);
    } finally {
      this.notifier.done();
      cleanup();
    }
    if (DEBUG)
      System.out.println(
          "JavaBuilder: Finished cleaning "
              + this.currentProject.getName() // $NON-NLS-1$
              + " @ "
              + new Date(System.currentTimeMillis())); // $NON-NLS-1$
  }
  public void build() {
    if (JavaBuilder.DEBUG) System.out.println("FULL build"); // $NON-NLS-1$

    try {
      this.notifier.subTask(
          Messages.bind(Messages.build_cleaningOutput, this.javaBuilder.currentProject.getName()));
      JavaBuilder.removeProblemsAndTasksFor(this.javaBuilder.currentProject);
      cleanOutputFolders(true);
      this.notifier.updateProgressDelta(0.05f);

      this.notifier.subTask(Messages.build_analyzingSources);
      ArrayList sourceFiles = new ArrayList(33);
      addAllSourceFiles(sourceFiles);
      this.notifier.updateProgressDelta(0.10f);

      if (sourceFiles.size() > 0) {
        SourceFile[] allSourceFiles = new SourceFile[sourceFiles.size()];
        sourceFiles.toArray(allSourceFiles);

        this.notifier.setProgressPerCompilationUnit(0.75f / allSourceFiles.length);
        this.workQueue.addAll(allSourceFiles);
        compile(allSourceFiles);

        if (this.typeLocatorsWithUndefinedTypes != null)
          if (this.secondaryTypes != null && !this.secondaryTypes.isEmpty())
            rebuildTypesAffectedBySecondaryTypes();
        if (this.incrementalBuilder != null) this.incrementalBuilder.buildAfterBatchBuild();
      }

      if (this.javaBuilder.javaProject.hasCycleMarker())
        this.javaBuilder.mustPropagateStructuralChanges();
    } catch (CoreException e) {
      throw internalException(e);
    } finally {
      if (JavaBuilder.SHOW_STATS) printStats();
      cleanUp();
    }
  }
  protected boolean 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();
    // remember that if inclusion & exclusion patterns change then a full build is done
    boolean isExcluded =
        (md.exclusionPatterns != null || md.inclusionPatterns != null)
            && Util.isExcluded(resource, md.inclusionPatterns, md.exclusionPatterns);
    switch (resource.getType()) {
      case IResource.FOLDER:
        if (isExcluded && md.inclusionPatterns == null)
          return true; // no need to go further with this delta since its children cannot be
        // included

        switch (sourceDelta.getKind()) {
          case IResourceDelta.ADDED:
            if (!isExcluded) {
              IPath addedPackagePath = resource.getFullPath().removeFirstSegments(segmentCount);
              createFolder(
                  addedPackagePath, md.binaryFolder); // ensure package exists in the output folder
              // see if any known source file is from the same package... classpath already includes
              // new package
              if (this.sourceLocations.length > 1
                  && this.newState.isKnownPackage(addedPackagePath.toString())) {
                if (JavaBuilder.DEBUG)
                  System.out.println(
                      "Skipped dependents of added package " + addedPackagePath); // $NON-NLS-1$
              } else {
                if (JavaBuilder.DEBUG)
                  System.out.println("Found added package " + addedPackagePath); // $NON-NLS-1$
                addDependentsOf(addedPackagePath, true);
              }
            }
            // $FALL-THROUGH$ collect all the source files
          case IResourceDelta.CHANGED:
            IResourceDelta[] children = sourceDelta.getAffectedChildren();
            for (int i = 0, l = children.length; i < l; i++)
              if (!findSourceFiles(children[i], md, segmentCount)) return false;
            return true;
          case IResourceDelta.REMOVED:
            if (isExcluded) {
              // since this folder is excluded then there is nothing to delete (from this md), but
              // must walk any included subfolders
              children = sourceDelta.getAffectedChildren();
              for (int i = 0, l = children.length; i < l; i++)
                if (!findSourceFiles(children[i], md, segmentCount)) return false;
              return true;
            }
            IPath removedPackagePath = resource.getFullPath().removeFirstSegments(segmentCount);
            if (this.sourceLocations.length > 1) {
              for (int i = 0, l = this.sourceLocations.length; i < l; i++) {
                if (this.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++)
                    if (!findSourceFiles(removedChildren[j], md, segmentCount)) return false;
                  return true;
                }
              }
            }
            if ((sourceDelta.getFlags() & IResourceDelta.MOVED_TO) != 0) {
              // same idea as moving a source file
              // see bug 163200
              IResource movedFolder =
                  this.javaBuilder.workspaceRoot.getFolder(sourceDelta.getMovedToPath());
              JavaBuilder.removeProblemsAndTasksFor(movedFolder);
            }
            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 (JavaBuilder.DEBUG)
              System.out.println("Found removed package " + removedPackagePath); // $NON-NLS-1$
            addDependentsOf(removedPackagePath, true);
            this.newState.removePackage(sourceDelta);
        }
        return true;
      case IResource.FILE:
        if (isExcluded) return true;

        String resourceName = resource.getName();
        // GROOVY start
        // determine if this is a Groovy project
        final boolean isInterestingProject =
            LanguageSupportFactory.isInterestingProject(this.javaBuilder.getProject());
        // GROOVY end

        // GROOVY start
        /* old {
        if (org.eclipse.jdt.internal.core.util.Util.isJavaLikeFileName(resourceName)) {
        } new */
        // GRECLIPSE-404 must call 'isJavaLikeFile' directly in order to make the Scala-Eclipse
        // plugin's weaving happy
        if ((!isInterestingProject
                && org.eclipse.jdt.internal.core.util.Util.isJavaLikeFileName(resourceName)
                && !LanguageSupportFactory.isInterestingSourceFile(resourceName))
            || (isInterestingProject
                && LanguageSupportFactory.isSourceFile(resourceName, isInterestingProject))) {
          // GROOVY end
          IPath typePath =
              resource.getFullPath().removeFirstSegments(segmentCount).removeFileExtension();
          String typeLocator = resource.getProjectRelativePath().toString();
          switch (sourceDelta.getKind()) {
            case IResourceDelta.ADDED:
              if (JavaBuilder.DEBUG)
                System.out.println("Compile this added source file " + typeLocator); // $NON-NLS-1$
              this.sourceFiles.add(new SourceFile((IFile) resource, md, true));
              String typeName = typePath.toString();
              if (!this.newState.isDuplicateLocator(
                  typeName, typeLocator)) { // adding dependents results in 2 duplicate errors
                if (JavaBuilder.DEBUG)
                  System.out.println("Found added source file " + typeName); // $NON-NLS-1$
                addDependentsOf(typePath, true);
              }
              return true;
            case IResourceDelta.REMOVED:
              char[][] definedTypeNames = this.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 =
                      this.javaBuilder.workspaceRoot.getFile(sourceDelta.getMovedToPath());
                  JavaBuilder.removeProblemsAndTasksFor(movedFile);
                }
              } else {
                if (JavaBuilder.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);
                }
              }
              this.newState.removeLocator(typeLocator);
              return true;
            case IResourceDelta.CHANGED:
              if ((sourceDelta.getFlags() & IResourceDelta.CONTENT) == 0
                  && (sourceDelta.getFlags() & IResourceDelta.ENCODING) == 0)
                return true; // skip it since it really isn't changed
              if (JavaBuilder.DEBUG)
                System.out.println(
                    "Compile this changed source file " + typeLocator); // $NON-NLS-1$
              this.sourceFiles.add(new SourceFile((IFile) resource, md, true));
          }
          return true;
        } else if (org.eclipse.jdt.internal.compiler.util.Util.isClassFileName(resourceName)) {
          // perform full build if a managed class file has been changed
          if (this.makeOutputFolderConsistent) {
            IPath typePath =
                resource.getFullPath().removeFirstSegments(segmentCount).removeFileExtension();
            if (this.newState.isKnownType(typePath.toString())) {
              if (JavaBuilder.DEBUG)
                System.out.println(
                    "MUST DO FULL BUILD. Found change to class file " + typePath); // $NON-NLS-1$
              return false;
            }
          }
          return true;
        } else if (md.hasIndependentOutputFolder) {
          if (this.javaBuilder.filterExtraResource(resource)) return true;

          // 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 (JavaBuilder.DEBUG)
                  System.out.println("Deleting existing file " + resourcePath); // $NON-NLS-1$
                outputFile.delete(IResource.FORCE, null);
              }
              if (JavaBuilder.DEBUG)
                System.out.println("Copying added file " + resourcePath); // $NON-NLS-1$
              createFolder(
                  resourcePath.removeLastSegments(1),
                  md.binaryFolder); // ensure package exists in the output folder
              copyResource(resource, outputFile);
              return true;
            case IResourceDelta.REMOVED:
              if (outputFile.exists()) {
                if (JavaBuilder.DEBUG)
                  System.out.println("Deleting removed file " + resourcePath); // $NON-NLS-1$
                outputFile.delete(IResource.FORCE, null);
              }
              return true;
            case IResourceDelta.CHANGED:
              if ((sourceDelta.getFlags() & IResourceDelta.CONTENT) == 0
                  && (sourceDelta.getFlags() & IResourceDelta.ENCODING) == 0)
                return true; // skip it since it really isn't changed
              if (outputFile.exists()) {
                if (JavaBuilder.DEBUG)
                  System.out.println("Deleting existing file " + resourcePath); // $NON-NLS-1$
                outputFile.delete(IResource.FORCE, null);
              }
              if (JavaBuilder.DEBUG)
                System.out.println("Copying changed file " + resourcePath); // $NON-NLS-1$
              createFolder(
                  resourcePath.removeLastSegments(1),
                  md.binaryFolder); // ensure package exists in the output folder
              copyResource(resource, outputFile);
          }
          return true;
        }
    }
    return true;
  }
示例#4
0
  private boolean isWorthBuilding() throws CoreException {
    boolean abortBuilds =
        JavaCore.ABORT.equals(
            this.javaProject.getOption(JavaCore.CORE_JAVA_BUILD_INVALID_CLASSPATH, true));
    if (!abortBuilds) {
      if (DEBUG) System.out.println("JavaBuilder: Ignoring invalid classpath"); // $NON-NLS-1$
      return true;
    }

    // Abort build only if there are classpath errors
    if (isClasspathBroken(this.javaProject, true)) {
      if (DEBUG)
        System.out.println(
            "JavaBuilder: Aborted build because project has classpath errors (incomplete or involved in cycle)"); //$NON-NLS-1$

      removeProblemsAndTasksFor(this.currentProject); // remove all compilation problems

      IMarker marker = this.currentProject.createMarker(IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER);
      marker.setAttributes(
          new String[] {
            IMarker.MESSAGE, IMarker.SEVERITY, IJavaModelMarker.CATEGORY_ID, IMarker.SOURCE_ID
          },
          new Object[] {
            Messages.build_abortDueToClasspathProblems,
            new Integer(IMarker.SEVERITY_ERROR),
            new Integer(CategorizedProblem.CAT_BUILDPATH),
            JavaBuilder.SOURCE_ID
          });
      return false;
    }

    if (JavaCore.WARNING.equals(
        this.javaProject.getOption(JavaCore.CORE_INCOMPLETE_CLASSPATH, true))) return true;

    // 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);
    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)
        JavaProject prereq = (JavaProject) JavaCore.create(p);
        if (prereq.hasCycleMarker()
            && JavaCore.WARNING.equals(
                this.javaProject.getOption(JavaCore.CORE_CIRCULAR_CLASSPATH, true))) {
          if (DEBUG)
            System.out.println(
                "JavaBuilder: Continued to build even though prereq project "
                    + p.getName() // $NON-NLS-1$
                    + " was not built since its part of a cycle"); //$NON-NLS-1$
          continue;
        }
        if (!hasJavaBuilder(p)) {
          if (DEBUG)
            System.out.println(
                "JavaBuilder: Continued to build even though prereq project "
                    + p.getName() // $NON-NLS-1$
                    + " is not built by JavaBuilder"); //$NON-NLS-1$
          continue;
        }
        if (DEBUG)
          System.out.println(
              "JavaBuilder: Aborted build because prereq project "
                  + p.getName() // $NON-NLS-1$
                  + " was not built"); //$NON-NLS-1$

        removeProblemsAndTasksFor(
            this.currentProject); // make this the only problem for this project
        IMarker marker =
            this.currentProject.createMarker(IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER);
        marker.setAttributes(
            new String[] {
              IMarker.MESSAGE, IMarker.SEVERITY, IJavaModelMarker.CATEGORY_ID, IMarker.SOURCE_ID
            },
            new Object[] {
              isClasspathBroken(prereq, true)
                  ? Messages.bind(Messages.build_prereqProjectHasClasspathProblems, p.getName())
                  : Messages.bind(Messages.build_prereqProjectMustBeRebuilt, p.getName()),
              new Integer(IMarker.SEVERITY_ERROR),
              new Integer(CategorizedProblem.CAT_BUILDPATH),
              JavaBuilder.SOURCE_ID
            });
        return false;
      }
    }
    return true;
  }
示例#5
0
  protected IProject[] build(int kind, Map ignored, IProgressMonitor monitor) throws CoreException {
    this.currentProject = getProject();
    if (this.currentProject == null || !this.currentProject.isAccessible()) return new IProject[0];

    if (DEBUG)
      System.out.println(
          "\nJavaBuilder: Starting build of "
              + this.currentProject.getName() // $NON-NLS-1$
              + " @ "
              + new Date(System.currentTimeMillis())); // $NON-NLS-1$
    this.notifier = new BuildNotifier(monitor, this.currentProject);
    this.notifier.begin();
    boolean ok = false;
    try {
      this.notifier.checkCancel();
      kind = initializeBuilder(kind, true);

      if (isWorthBuilding()) {
        if (kind == FULL_BUILD) {
          if (DEBUG)
            System.out.println("JavaBuilder: Performing full build as requested"); // $NON-NLS-1$
          buildAll();
        } else {
          if ((this.lastState = getLastState(this.currentProject)) == null) {
            if (DEBUG)
              System.out.println(
                  "JavaBuilder: 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
            if (DEBUG)
              System.out.println(
                  "JavaBuilder: Performing full build since classpath has changed"); //$NON-NLS-1$
            buildAll();
          } else if (this.nameEnvironment.sourceLocations.length > 0) {
            // if there is no source to compile & no classpath changes then we are done
            SimpleLookupTable deltas = findDeltas();
            if (deltas == null) {
              if (DEBUG)
                System.out.println(
                    "JavaBuilder: Performing full build since deltas are missing after incremental request"); //$NON-NLS-1$
              buildAll();
            } else if (deltas.elementSize > 0) {
              buildDeltas(deltas);
            } else if (DEBUG) {
              System.out.println(
                  "JavaBuilder: 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 (DEBUG)
                System.out.println(
                    "JavaBuilder: Performing full build since there are structural deltas"); //$NON-NLS-1$
              buildAll();
            } else {
              if (DEBUG)
                System.out.println(
                    "JavaBuilder: Nothing to build since there are no source folders and no deltas"); //$NON-NLS-1$
              this.lastState.tagAsNoopBuild();
            }
          }
        }
        ok = true;
      }
    } catch (CoreException e) {
      Util.log(
          e,
          "JavaBuilder handling CoreException while building: "
              + this.currentProject.getName()); // $NON-NLS-1$
      createInconsistentBuildMarker(e);
    } catch (ImageBuilderInternalException e) {
      Util.log(
          e.getThrowable(),
          "JavaBuilder handling ImageBuilderInternalException while building: "
              + this.currentProject.getName()); // $NON-NLS-1$
      createInconsistentBuildMarker(e.coreException);
    } catch (MissingSourceFileException e) {
      // do not log this exception since its thrown to handle aborted compiles because of missing
      // source files
      if (DEBUG)
        System.out.println(Messages.bind(Messages.build_missingSourceFile, e.missingSourceFile));
      removeProblemsAndTasksFor(this.currentProject); // make this the only problem for this project
      IMarker marker = this.currentProject.createMarker(IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER);
      marker.setAttributes(
          new String[] {IMarker.MESSAGE, IMarker.SEVERITY, IMarker.SOURCE_ID},
          new Object[] {
            Messages.bind(Messages.build_missingSourceFile, e.missingSourceFile),
            new Integer(IMarker.SEVERITY_ERROR),
            JavaBuilder.SOURCE_ID
          });
    } finally {
      for (int i = 0, l = this.participants == null ? 0 : this.participants.length; i < l; i++)
        this.participants[i].buildFinished(this.javaProject);
      if (!ok)
        // If the build failed, clear the previously built state, forcing a full build next time.
        clearLastState();
      this.notifier.done();
      cleanup();
    }
    IProject[] requiredProjects = getRequiredProjects(true);
    if (DEBUG)
      System.out.println(
          "JavaBuilder: Finished build of "
              + this.currentProject.getName() // $NON-NLS-1$
              + " @ "
              + new Date(System.currentTimeMillis())
              + "\n"); //$NON-NLS-1$ //$NON-NLS-2$
    return requiredProjects;
  }