Пример #1
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());
    }
  }
Пример #2
0
  /**
   * Maintain a mapping between filenames and compilation units. Needed for incremental compilation.
   */
  public void addCompilationUnit(ICompilationUnit compilationUnit) {
    String path = compilationUnit.getAbsoluteFilename();
    // paths passed into this function need to have been normalized
    assert (path.equals(FilenameNormalization.normalize(path))) : "Path not normalized";

    pathToCompilationUnitMapping.add(path, compilationUnit);
  }
Пример #3
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);
    }
  }
Пример #4
0
  /**
   * Gets the {@link IFileSpecification} for the root source file of the specified {@link
   * ICompilationUnit}.
   *
   * @param compilationUnit A compilation unit.
   * @return Tthe {@link IFileSpecification} for the root source file of the specified {@link
   *     ICompilationUnit}
   */
  public IFileSpecification getFileSpecificationForCompilationUnit(
      ICompilationUnit compilationUnit) {
    String path = compilationUnit.getAbsoluteFilename();
    // paths passed into this function need to have been normalized
    assert (path.equals(FilenameNormalization.normalize(path))) : "Path not normalized";

    // Make sure that we seen this path associated with a compilation unit before.
    assert pathToCompilationUnitMapping.get(path) != null;

    return getFileSpecification(path);
  }
Пример #5
0
  private static Collection<ICompilationUnit> getInvisibleCompilationUnits(
      final StringToCompilationUnitMap compilationUnitMap,
      final String sortKey,
      ICompilerProject project) {
    Collection<WeakReference<ICompilationUnit>> compilationUnitRefs =
        compilationUnitMap.getInvisible(sortKey, project);
    ArrayList<ICompilationUnit> compilationUnits =
        new ArrayList<ICompilationUnit>(compilationUnitRefs.size());
    for (WeakReference<ICompilationUnit> cuRef : compilationUnitRefs) {
      final ICompilationUnit cu = cuRef.get();

      // Nothing in the compiler pins the invisible compilation units
      // so we have to check that the weak reference is still good.
      if (cu != null) {
        assert cu.isInvisible()
            : "StringToCompilationUnitMap.getInvisible returned a visible compilation unit.";
        compilationUnits.add(cu);
      }
    }
    return compilationUnits;
  }
Пример #6
0
  private Set<ICompilationUnit> getCompilationUnitsDependingOnMissingDefinitions(
      Collection<ICompilationUnit> addedUnits) {
    Set<ICompilationUnit> compilationUnitsToInvalidate = new HashSet<ICompilationUnit>();

    for (ICompilationUnit addedCompilationUnit : addedUnits) {
      try {
        CompilerProject project = (CompilerProject) addedCompilationUnit.getProject();
        List<String> newIdentifierNames = addedCompilationUnit.getShortNames();
        for (String newIdentifierName : newIdentifierNames) {
          compilationUnitsToInvalidate.addAll(
              project.getDependenciesOnUnfoundDefinition(newIdentifierName));
          compilationUnitsToInvalidate.addAll(
              project.getDependenciesOnDefinition(newIdentifierName));
        }
      } catch (InterruptedException e) {
        // should never happen, as all threads should be stopped
        e.printStackTrace();
      }
    }

    return compilationUnitsToInvalidate;
  }
Пример #7
0
  /**
   * Remove a compilation unit from the filename to compilation unit map
   *
   * @param compilationUnit The compilation unit to be removed.
   */
  public void removeCompilationUnit(ICompilationUnit compilationUnit) {
    String path = compilationUnit.getAbsoluteFilename();
    // paths passed into this function need to have been normalized
    assert (path.equals(FilenameNormalization.normalize(path))) : "Path not normalized";

    pathToCompilationUnitMapping.remove(path, compilationUnit);
    ((CompilationUnitBase) compilationUnit).clearIncludedFilesFromWorkspace();

    // only remove the file spec if there are no more remaining CUs tied
    // to that path
    if (pathToCompilationUnitMapping.get(path).isEmpty()
        && includeFilesToIncludingCompilationUnitMapping.get(path).isEmpty()) {
      pathToFileSpecMap.remove(path);
    }
  }
Пример #8
0
  /**
   * When an ISWC has changed in memory, invalidate any compilation units which depend on the units
   * which depend on the SWC
   *
   * @param unitsRemoved The collection of compilation units to be removed.
   * @param unitsAdded The collection compilation units to be added.
   */
  public void swcChanged(
      Collection<ICompilationUnit> unitsRemoved,
      Collection<ICompilationUnit> unitsAdded,
      Runnable runWhileIdle) {
    final Map<ICompilerProject, Set<ICompilationUnit>> cusToUpdate =
        new HashMap<ICompilerProject, Set<ICompilationUnit>>();
    final Set<ICompilationUnit> unitsRemoveSet = ImmutableSet.copyOf(unitsRemoved);
    startIdleState();
    try {
      // Find all the compilation units reference a definition with the same base
      // name as a definition defined by any of the compilation units in the SWC that is
      // changing.
      final Collection<ICompilationUnit> unitsDependingOnMissingDefinitions =
          getCompilationUnitsDependingOnMissingDefinitions(unitsAdded);

      // Compute the set of compilation units to invalidate by starting with the union of
      // the unitsDependingOnMissingDefinitions and the list of
      // compilation units we are removing.
      Set<ICompilationUnit> unitsToInvalidate =
          DependencyGraph.computeInvalidationSet(
              Iterables.concat(unitsRemoved, unitsDependingOnMissingDefinitions));
      notifyInvalidationListener(unitsToInvalidate);

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

      runWhileIdle.run();
    } finally {
      endIdleState(cusToUpdate);
    }
  }
Пример #9
0
  private void notifyInvalidationListener(Collection<ICompilationUnit> unitsToClean) {
    if (invalidationListeners.isEmpty()) return;

    Map<ICompilerProject, Collection<InvalidatedDefinition>> invalidationMap =
        new HashMap<ICompilerProject, Collection<InvalidatedDefinition>>();

    for (ICompilationUnit compilationUnit : unitsToClean) {
      // Collect all definitions associated with the compilation unit
      Collection<IDefinition> definitions = compilationUnit.getDefinitionPromises();
      if (definitions.size() == 0) {
        // no definition promises, so getting the file scope should be cheap.
        try {
          IFileScopeRequestResult fsr = compilationUnit.getFileScopeRequest().get();
          definitions = fsr.getExternallyVisibleDefinitions();
        } catch (InterruptedException e1) {
          assert false : "Since this is a single threaded method, we should never be interrupted";
        }
      }

      // for all the found definition, build up a map of projects to a list of
      // InvalidatedDefinitions
      // and pass this map onto the registered invalidation listener to do with what it will
      if (definitions.size() > 0) {
        Collection<InvalidatedDefinition> invalidatedDefinitions =
            invalidationMap.get(compilationUnit.getProject());
        if (invalidatedDefinitions == null) {
          invalidatedDefinitions = new LinkedList<InvalidatedDefinition>();
          invalidationMap.put(compilationUnit.getProject(), invalidatedDefinitions);
        }

        String filename = compilationUnit.getAbsoluteFilename();
        for (IDefinition definition : definitions) {
          String qName = definition.getQualifiedName();
          InvalidatedDefinition invalidatedDefinition = new InvalidatedDefinition(qName, filename);
          invalidatedDefinitions.add(invalidatedDefinition);
        }
      }
    }
    for (IInvalidationListener listener : invalidationListeners)
      listener.definitionsChanged(invalidationMap);
  }