public void parse() { String bundlePath = null; if (bundle.getBundleFile() != null) bundlePath = FilenameNormalization.normalize(bundle.getBundleFile().getAbsolutePath()); try { while (reader.hasNext()) { final int next = reader.next(); if (next != XMLStreamConstants.START_ELEMENT) continue; final String tagName = reader.getName().getLocalPart(); if (tagName.equals(TAG_LIBRARY)) { if (reader.isStartElement()) { library = new BundleLibrary(reader.getAttributeValue(null, "name")); bundle.addLibrary(library); } else if (reader.isEndElement()) { library = null; } } else if (library != null) { final String containerType = tagName; final String categoryType = reader.getAttributeValue(null, "type"); BundleContainer container = (BundleContainer) library.getContainer(IBundleContainer.Type.toType(containerType)); if (container == null) { container = (BundleContainer) library.addContainer(IBundleContainer.Type.toType(containerType)); } IBundleCategory category = container.addCategory(IBundleCategory.Type.toType(categoryType)); category.addFile(bundlePath, reader.getAttributeValue(null, "path")); } else if (tagName.equals("versions")) { version = (BundleVersion) bundle.getVersion(); } else if (tagName.equals("bundle")) { version.setBundleVersion(reader.getAttributeValue(null, "version")); } else if (tagName.equals("randori")) { version.setRandoriVersion(reader.getAttributeValue(null, "version")); version.setRandoriBuild(reader.getAttributeValue(null, "build")); version.setRandoriMinSupportedVersion( reader.getAttributeValue(null, "minimumSupportedVersion")); } else if (tagName.equals("compiler")) { version.setCompilerName(reader.getAttributeValue(null, "name")); version.setCompilerVersion(reader.getAttributeValue(null, "version")); } else if (tagName.equals("version")) { } } } catch (XMLStreamException e) { File bundleFile = bundle.getBundleFile(); final String file = (bundleFile != null) ? FilenameNormalization.normalize(bundleFile.getAbsolutePath()) : ""; bundle.addProblem( new FileInLibraryIOProblem(BundleReader.MANIFEST_XML, file, e.getLocalizedMessage())); } }
/** * Get all compilation units from which the filename is included related to the specified project * * @param path String to source filename * @param project containing project */ public Collection<ICompilationUnit> getIncludingCompilationUnits( String path, ICompilerProject project) { // paths passed into this function need to have been normalized assert (path.equals(FilenameNormalization.normalize(path))) : "Path not normalized"; return getCompilationUnits(includeFilesToIncludingCompilationUnitMapping, path, project); }
@Override public Iterable<ICompilationUnit> getInvisibleAndVisibleCompilationUnits( final String path, final ICompilerProject project) { // paths passed into this function need to have been normalized assert (path.equals(FilenameNormalization.normalize(path))) : "Path not normalized"; return getInvisibleAndVisibleCompilationUnits(pathToCompilationUnitMapping, path, project); }
/** * 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); }
/** * 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); }
/** * Returns the most recent {@link IFileSpecification} given to the workspace for a specified path. * If the workspace has not seen the specified path before a new {@link FileSpecification} is * returned. * * @param path Path for which a {@link IFileSpecification} should be returned. * @return The most recent {@link IFileSpecification} given to the workspace for a specified path. */ @Override public synchronized IFileSpecification getFileSpecification(String path) { assert (path.equals(FilenameNormalization.normalize(path))) : "Path not normalized"; IFileSpecification fileSpec = pathToFileSpecMap.get(path); if (fileSpec == null) { fileSpec = new FileSpecification(path); pathToFileSpecMap.put(path, fileSpec); } return fileSpec; }
/** * Get the source path for this node. * * @return The source path for this node */ @Override public final String getSourcePath() { // null means the source is unknown. // "" means the source is a buffer that hasn't yet been saved to a file. // Something like "framework.swc:defaults.css" means the source is a file inside a SWC. // TODO Shouldn't the part before the colon be normalized? // Anything else should be a normalized path to a source file. assert sourcePath == null || sourcePath.isEmpty() || sourcePath.contains(".swc:") || FilenameNormalization.isNormalized(sourcePath) : "Invalid value for sourcePath: " + sourcePath; return sourcePath; }
/** * 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); } }
/** * 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); }
@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); } }
@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); } }
/** * 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); }
@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); } }