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; }
/** * 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); } }
/** * 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); }
@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); } }
/** * 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); }
/** * 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); }
private static Collection<ICompilationUnit> getCompilationUnits( final StringToCompilationUnitMap compilationUnitMap, final String sortKey, ICompilerProject project) { Collection<WeakReference<ICompilationUnit>> compilationUnitRefs = compilationUnitMap.get(sortKey, project); ArrayList<ICompilationUnit> compilationUnits = new ArrayList<ICompilationUnit>(compilationUnitRefs.size()); for (WeakReference<ICompilationUnit> cuRef : compilationUnitRefs) { final ICompilationUnit cu = cuRef.get(); // The get method pathToCompilationUnitMapping will filter out compilation units // that have been removed from the project, so at this point // we can assert the weak references will always return non-null. assert cu != null : "ICompilerProject's dependency graph should be pinning all the compilation units in the collection."; compilationUnits.add(cu); } return compilationUnits; }
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; }
/** * Get all invisible compilation units from the filename across all projects * * @param path String to source filename */ public Collection<WeakReference<ICompilationUnit>> getInvisibleCompilationUnits(String path) { // paths passed into this function need to have been normalized assert (path.equals(FilenameNormalization.normalize(path))) : "Path not normalized"; return pathToCompilationUnitMapping.getInvisible(path); }
/** * Remove any references to the compilation unit to the collection of include files it includes. * * @param includingCompilationUnit {@link ICompilationUnit} that contains include statements that * reference the specified list of files. * @param includedFiles The included files. */ public void removeIncludedFilesToCompilationUnit( ICompilationUnit includingCompilationUnit, Collection<String> includedFiles) { for (String includedFile : includedFiles) { includeFilesToIncludingCompilationUnitMapping.remove(includedFile, includingCompilationUnit); } }
/** * Specifies that the specified compilation unit includes the specified list of files. Called by * {@link ICompilationUnit}'s when they discover included files. * * @param includingCompilationUnit {@link ICompilationUnit} that contains include statements that * reference the specified list of files. * @param includedFiles The included files. */ public void addIncludedFilesToCompilationUnit( ICompilationUnit includingCompilationUnit, Collection<String> includedFiles) { includeFilesToIncludingCompilationUnitMapping.add( includedFiles.toArray(new String[includedFiles.size()]), includingCompilationUnit); }