Beispiel #1
0
  /**
   * Determine if a file is currently referenced by any part of any project in the workspace.
   *
   * @param fileSpecification An {@link IFileSpecification} that can be used to get the name of the
   *     file to check.
   * @return true if the specified file is referenced by any part of any project in the workspace,
   *     false otherwise.
   */
  @SuppressWarnings("unused")
  private boolean isKnownFile(IFileSpecification fileSpecification) {
    // make sure that nobody is calling isKnownFile outside of an assert
    if (!assertionsEnabled)
      throw new RuntimeException("isKnownFile() should only ever be called from an assert");

    // paths passed into this function need to have been normalized
    assert (fileSpecification
            .getPath()
            .equals(FilenameNormalization.normalize(fileSpecification.getPath())))
        : "Path not normalized";

    Collection<WeakReference<ICompilationUnit>> relatedCompilationUnits =
        pathToCompilationUnitMapping.get(fileSpecification.getPath());
    return (relatedCompilationUnits != null) && (relatedCompilationUnits.size() > 0);
  }
Beispiel #2
0
  private final void invalidate(
      IFileSpecification fileSpec,
      Collection<ICompilationUnit> compilationUnits,
      Map<ICompilerProject, Set<ICompilationUnit>> cusToUpdate) {
    mxmlDataManager.invalidate(fileSpec);
    // Tell the SWC manager the SWC file is invalid.
    getSWCManager().remove(new File(fileSpec.getPath()));

    if (compilationUnits.size() == 0) return;

    Set<ICompilationUnit> unitsToInvalidate = new HashSet<ICompilationUnit>();
    unitsToInvalidate.addAll(compilationUnits);
    Set<ICompilationUnit> unitsToClean =
        Sets.<ICompilationUnit>union(
            DependencyGraph.computeInvalidationSet(unitsToInvalidate),
            getCompilationUnitsDependingOnMissingDefinitions(unitsToInvalidate));

    notifyInvalidationListener(unitsToClean);

    // Do the actual invalidation
    Map<ICompilerProject, Set<File>> invalidatedSWCFiles =
        new HashMap<ICompilerProject, Set<File>>();
    for (ICompilationUnit compilationUnit : unitsToClean) {
      boolean clearCUFileScope = unitsToInvalidate.contains(compilationUnit);
      compilationUnit.clean(invalidatedSWCFiles, cusToUpdate, clearCUFileScope);
    }

    // invalidate any library files in the project
    for (Map.Entry<ICompilerProject, Set<File>> e : invalidatedSWCFiles.entrySet()) {
      if (e.getKey() instanceof IASProject)
        ((IASProject) e.getKey()).invalidateLibraries(e.getValue());
    }
  }
Beispiel #3
0
  private final Collection<ICompilationUnit> collectAssociatedCompilationUnits(
      IFileSpecification file) {
    String filename = file.getPath();
    Collection<WeakReference<ICompilationUnit>> relatedCompilationUnits =
        pathToCompilationUnitMapping.getVisibleAndInvisible(filename);

    // relatedCompilationUnits should never be null, but it is OK for it to be empty, as
    // we can be null, if someone passes us in a arbitrary file which has no compilation
    // units associated with it.
    assert (relatedCompilationUnits != null) : "relatedCompilationUnits should never be null";

    // add any compilation units which include the file, as they need to be recompiled also
    Collection<WeakReference<ICompilationUnit>> includingCompilationUnits =
        includeFilesToIncludingCompilationUnitMapping.get(filename);

    Collection<WeakReference<ICompilationUnit>> allRelatedCompilationUnits =
        new HashSet<WeakReference<ICompilationUnit>>();
    allRelatedCompilationUnits.addAll(relatedCompilationUnits);
    allRelatedCompilationUnits.addAll(includingCompilationUnits);

    HashSet<ICompilationUnit> associatedCompilationUnits = new HashSet<ICompilationUnit>();
    for (WeakReference<ICompilationUnit> relatedCURef : allRelatedCompilationUnits) {
      ICompilationUnit relatedCU = relatedCURef.get();
      if (relatedCU != null) {
        associatedCompilationUnits.add(relatedCU);
      }
    }

    final Set<ICompilationUnit> associatedCompilationUnitsAccountingForConflictingDefinitions =
        ASProjectScope.getCompilationUnitsWithConflictingDefinitions(
            this, associatedCompilationUnits);

    return associatedCompilationUnitsAccountingForConflictingDefinitions;
  }
Beispiel #4
0
  @Override
  public void fileRemoved(IFileSpecification removedFile) {
    // paths passed into this function need to have been normalized
    assert (removedFile.getPath().equals(FilenameNormalization.normalize(removedFile.getPath())))
        : "Path not normalized";
    final String path = removedFile.getPath();
    final Set<ASProject> affectedProjects = new HashSet<ASProject>();
    Map<ICompilerProject, Set<ICompilationUnit>> cusToUpdate =
        new HashMap<ICompilerProject, Set<ICompilationUnit>>();
    Collection<ICompilationUnit> relatedCompilationUnits = Collections.emptyList();

    startIdleState();
    try {
      relatedCompilationUnits = collectAssociatedCompilationUnits(removedFile);
      // collect the affected projects before invalidating the relatedCompilationUnits, as removed
      // compilation units will have their projects null'd out during invalidate, causing an NPE.
      for (ICompilationUnit compilationUnit : relatedCompilationUnits) {
        if (compilationUnit == null) continue;

        ICompilerProject containingProject = compilationUnit.getProject();
        assert (containingProject instanceof ASProject);
        affectedProjects.add((ASProject) containingProject);
      }

      invalidate(removedFile, relatedCompilationUnits, cusToUpdate);
    } finally {
      File f = new File(path);
      for (ASProject project : affectedProjects) {
        project.removeSourceFile(f);
      }

      // update the pathToCompilationUnitMapping CU by CU, rather than
      // just taking the whole path away, as we don't want to loose mappings
      // between SWC compilation units and the SWC path
      for (ICompilationUnit cu : relatedCompilationUnits) {
        if (cu.getCompilationUnitType() != UnitType.SWC_UNIT) {
          pathToCompilationUnitMapping.remove(path, cu);
          includeFilesToIncludingCompilationUnitMapping.remove(path, cu);
        }
      }

      pathToFileSpecMap.remove(path);

      endIdleState(cusToUpdate);
    }
  }
Beispiel #5
0
  @Override
  public void fileChanged(IFileSpecification changedFile) {
    // paths passed into this function need to have been normalized
    assert (changedFile.getPath().equals(FilenameNormalization.normalize(changedFile.getPath())))
        : "Path not normalized";
    Map<ICompilerProject, Set<ICompilationUnit>> cusToUpdate =
        new HashMap<ICompilerProject, Set<ICompilationUnit>>();
    startIdleState();
    try {
      Collection<ICompilationUnit> relatedCompilationUnits =
          collectAssociatedCompilationUnits(changedFile);
      HashSet<ICompilationUnit> compilationUnitsToInvalidate = new HashSet<ICompilationUnit>();
      compilationUnitsToInvalidate.addAll(relatedCompilationUnits);
      invalidate(changedFile, relatedCompilationUnits, cusToUpdate);

      pathToFileSpecMap.put(changedFile.getPath(), changedFile);
    } finally {
      endIdleState(cusToUpdate);
    }
  }
Beispiel #6
0
  @Override
  public void fileAdded(IFileSpecification addedFile) {
    // paths passed into this function need to have been normalized
    assert (addedFile.getPath().equals(FilenameNormalization.normalize(addedFile.getPath())))
        : "Path not normalized";
    Map<ICompilerProject, Set<ICompilationUnit>> cusToUpdate =
        new HashMap<ICompilerProject, Set<ICompilationUnit>>();

    startIdleState();
    try {
      // It would be nice to be able to assert that the file being added
      // is not a known file, but this is not currently possible.  When builder project
      // settings are changed in ways such as adding a new source path, there are two notifications,
      // 1) The project has changed and Configurator.applyToProject() is called which adds any new
      // files to the workspace.
      // 2) eclipse then sends file adds on a file which we know about because of 1).
      // Until the notification is straightened out, we can't have this assert.  This just means
      // that
      // we're potentially doing a slightly more costly invalidation when fileAdded() is called
      // instead
      // of fileChanged(), but as this only really happens when project settings are changed, it
      // shouldn't
      // be a real performance hit.
      // assert (!isKnownFile(addedFile));

      String path = addedFile.getPath();
      pathToFileSpecMap.put(path, addedFile);
      getSWCManager().remove(new File(path));

      File f = new File(path);
      CompilerProject[] projects = getProjects();
      boolean compilationUnitAdded = false;
      for (CompilerProject project : projects) {
        compilationUnitAdded = project.handleAddedFile(f) || compilationUnitAdded;
        if (project instanceof ASProject)
          compilationUnitAdded =
              ((ASProject) project).invalidateLibraries(Collections.singleton(f))
                  || compilationUnitAdded;
      }

      Set<ICompilationUnit> compilationUnitsToInvalidate = new HashSet<ICompilationUnit>();
      if (compilationUnitAdded) {
        // we now have compilation units from the newly added file, get it's
        // name, and see if there's either:
        // - any unresolved dependencies which could be resolved by this new name
        // - any compilation units which depend on the new name, and could now have
        //   an ambiguous reference
        Collection<ICompilationUnit> relatedCompilationUnits =
            collectAssociatedCompilationUnits(addedFile);
        compilationUnitsToInvalidate.addAll(relatedCompilationUnits);
        compilationUnitsToInvalidate.addAll(
            getCompilationUnitsDependingOnMissingDefinitions(relatedCompilationUnits));
      }

      // even if no compilation units were added, the added file may be a missing file which was
      // a source for an embed, so need to invalidate any CUs which have a dependency on the missing
      // filename
      for (CompilerProject project : projects) {
        compilationUnitsToInvalidate.addAll(
            project.getDependenciesOnUnfoundReferencedSourceFile(addedFile.getPath()));
      }

      invalidate(addedFile, compilationUnitsToInvalidate, cusToUpdate);
    } finally {
      endIdleState(cusToUpdate);
    }
  }