///*
// * Copyright Red Hat Inc. and/or its affiliates and other contributors
// * as indicated by the authors tag. All rights reserved.
// *
// * This copyrighted material is made available to anyone wishing to use,
// * modify, copy, or redistribute it subject to the terms and conditions
// * of the GNU General Public License version 2.
// *
// * This particular file is subject to the "Classpath" exception as provided in the
// * LICENSE file that accompanied this code.
// *
// * This program is distributed in the hope that it will be useful, but WITHOUT A
// * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
// * PARTICULAR PURPOSE. See the GNU General Public License for more details.
// * You should have received a copy of the GNU General Public License,
// * along with this distribution; if not, write to the Free Software
// * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
// * MA 02110-1301, USA.
// */
//
//package com.redhat.ceylon.eclipse.core.model;
//
//import static com.redhat.ceylon.eclipse.core.model.modelJ2C.ceylonModel;
//
//import java.io.File;
//import java.io.IOException;
//import java.lang.ref.SoftReference;
//import java.lang.ref.WeakReference;
//import java.util.ArrayList;
//import java.util.Arrays;
//import java.util.Collections;
//import java.util.Enumeration;
//import java.util.HashMap;
//import java.util.HashSet;
//import java.util.LinkedHashSet;
//import java.util.List;
//import java.util.Map;
//import java.util.Map.Entry;
//import java.util.Properties;
//import java.util.Set;
//import java.util.TreeSet;
//import java.util.zip.ZipEntry;
//import java.util.zip.ZipFile;
//
//import net.lingala.zip4j.exception.ZipException;
//
//import org.antlr.runtime.CommonToken;
//import org.antlr.runtime.CommonTokenStream;
//import org.eclipse.core.resources.IProject;
//import org.eclipse.core.runtime.CoreException;
//import org.eclipse.core.runtime.IPath;
//import org.eclipse.core.runtime.IStatus;
//import org.eclipse.core.runtime.Path;
//import org.eclipse.core.runtime.Status;
//import org.eclipse.jdt.core.IClasspathEntry;
//import org.eclipse.jdt.core.IJavaElement;
//import org.eclipse.jdt.core.IJavaProject;
//import org.eclipse.jdt.core.IPackageFragment;
//import org.eclipse.jdt.core.IPackageFragmentRoot;
//import org.eclipse.jdt.core.IParent;
//import org.eclipse.jdt.core.JavaCore;
//import org.eclipse.jdt.core.JavaModelException;
//import org.eclipse.jdt.internal.core.JarPackageFragmentRoot;
//import org.eclipse.jdt.internal.core.JavaModelManager;
//import org.eclipse.jdt.internal.core.PackageFragment;
//
//import com.redhat.ceylon.cmr.api.ArtifactContext;
//import com.redhat.ceylon.cmr.api.RepositoryManager;
//import com.redhat.ceylon.common.Backend;
//import com.redhat.ceylon.common.Backends;
//import com.redhat.ceylon.compiler.typechecker.context.PhasedUnit;
//import com.redhat.ceylon.compiler.typechecker.context.PhasedUnitMap;
//import com.redhat.ceylon.compiler.typechecker.io.ClosableVirtualFile;
//import com.redhat.ceylon.compiler.typechecker.io.VirtualFile;
//import com.redhat.ceylon.compiler.typechecker.parser.CeylonLexer;
//import com.redhat.ceylon.compiler.typechecker.parser.CeylonParser;
//import com.redhat.ceylon.compiler.typechecker.tree.Tree;
//import com.redhat.ceylon.compiler.typechecker.util.NewlineFixingStringStream;
//import com.redhat.ceylon.eclipse.core.builder.CeylonBuilder;
//import com.redhat.ceylon.eclipse.core.classpath.CeylonLanguageModuleContainer;
//import com.redhat.ceylon.eclipse.core.classpath.CeylonProjectModulesContainer;
//import com.redhat.ceylon.eclipse.core.model.JDTModuleSourceMapper.ExternalModulePhasedUnits;
//import com.redhat.ceylon.ide.common.model.ModuleDependencies.TraversalAction;
//import com.redhat.ceylon.eclipse.core.typechecker.CrossProjectPhasedUnit;
//import com.redhat.ceylon.eclipse.core.typechecker.ExternalPhasedUnit;
//import com.redhat.ceylon.eclipse.core.typechecker.IdePhasedUnit;
//import com.redhat.ceylon.eclipse.ui.CeylonPlugin;
//import com.redhat.ceylon.eclipse.util.CarUtils;
//import com.redhat.ceylon.eclipse.util.SingleSourceUnitPackage;
//import com.redhat.ceylon.ide.common.model.CeylonProject;
//import com.redhat.ceylon.ide.common.model.ModuleDependencies;
//import com.redhat.ceylon.model.cmr.ArtifactResult;
//import com.redhat.ceylon.model.cmr.ArtifactResultType;
//import com.redhat.ceylon.model.cmr.ImportType;
//import com.redhat.ceylon.model.cmr.JDKUtils;
//import com.redhat.ceylon.model.cmr.PathFilter;
//import com.redhat.ceylon.model.cmr.Repository;
//import com.redhat.ceylon.model.cmr.RepositoryException;
//import com.redhat.ceylon.model.cmr.VisibilityType;
//import com.redhat.ceylon.model.loader.model.LazyModule;
//import com.redhat.ceylon.model.typechecker.model.Declaration;
//import com.redhat.ceylon.model.typechecker.model.Module;
//import com.redhat.ceylon.model.typechecker.model.ModuleImport;
//import com.redhat.ceylon.model.typechecker.model.Modules;
//import com.redhat.ceylon.model.typechecker.model.Package;
//import com.redhat.ceylon.model.typechecker.model.TypeDeclaration;
//import com.redhat.ceylon.model.typechecker.model.Unit;
//import com.redhat.ceylon.model.typechecker.model.ModelUtil;
//
//public class JDTModule extends LazyModule {
// private JDTModuleManager moduleManager;
// private JDTModuleSourceMapper moduleSourceMapper;
// private List<IPackageFragmentRoot> packageFragmentRoots;
// private File artifact;
// private String repositoryDisplayString = "";
// private WeakReference<ExternalModulePhasedUnits> sourceModulePhasedUnits; // Here we have a weak ref on the PhasedUnits because there are already stored as strong references in the TypeChecker phasedUnitsOfDependencies list.
// // But in the future we might remove the strong reference in the typeChecker and use strong references here, which would be
// // much more modular (think of several versions of a module imported in a non-shared way in the same projet).
// private PhasedUnitMap<ExternalPhasedUnit, SoftReference<ExternalPhasedUnit>> binaryModulePhasedUnits;
// private List<String> sourceRelativePaths = new ArrayList<>();
// private Properties classesToSources = new Properties();
// private Map<String, String> javaImplFilesToCeylonDeclFiles = new HashMap<String, String>();
// private String sourceArchivePath = null;
// private IProject originalProject = null;
// private JDTModule originalModule = null;
// private Set<String> originalUnitsToRemove = new LinkedHashSet<>();
// private Set<String> originalUnitsToAdd = new LinkedHashSet<>();
// private ArtifactResultType artifactType = ArtifactResultType.OTHER;
// private Exception resolutionException = null;
//
// public JDTModule(JDTModuleManager jdtModuleManager, JDTModuleSourceMapper jdtModuleSourceMapper, List<IPackageFragmentRoot> packageFragmentRoots) {
// this.moduleManager = jdtModuleManager;
// this.moduleSourceMapper = jdtModuleSourceMapper;
// this.packageFragmentRoots = packageFragmentRoots;
// }
//
// private File returnCarFile() {
// if (isCeylonBinaryArchive()) {
// return artifact;
// }
// if (isSourceArchive()) {
// return new File(sourceArchivePath.substring(0, sourceArchivePath.length()-ArtifactContext.SRC.length()) + ArtifactContext.CAR);
// }
// return null;
// }
//
// private class BinaryPhasedUnits extends PhasedUnitMap<ExternalPhasedUnit, SoftReference<ExternalPhasedUnit>> {
// Set<String> sourceCannotBeResolved = new HashSet<String>();
// final String fullPathPrefix = sourceArchivePath + "!/";
//
// public BinaryPhasedUnits() {
// for (String sourceRelativePath : sourceRelativePaths) {
// if (sourceRelativePath.endsWith(".java")) {
// String ceylonRelativePath = javaImplFilesToCeylonDeclFiles.get(sourceRelativePath);
// if (ceylonRelativePath != null) {
// sourceRelativePath = ceylonRelativePath;
// }
// }
// putRelativePath(sourceRelativePath);
// }
// }
//
// public void putRelativePath(String sourceRelativePath) {
// String path = fullPathPrefix + sourceRelativePath;
// phasedUnitPerPath.put(path, new SoftReference<ExternalPhasedUnit>(null));
// relativePathToPath.put(sourceRelativePath, path);
// }
//
// @Override
// public ExternalPhasedUnit getPhasedUnit(String path) {
// if (! phasedUnitPerPath.containsKey(path)) {
// if (path.endsWith(".java")) {
// // Case of a Ceylon file with a Java implementation, the classesToSources key is the Java source file.
// String ceylonFileRelativePath = getCeylonDeclarationFile(path.replace(sourceArchivePath + "!/", ""));
// if (ceylonFileRelativePath != null) {
// return super.getPhasedUnit(sourceArchivePath + "!/" + ceylonFileRelativePath);
// }
// }
// return null;
// }
// return super.getPhasedUnit(path);
// }
//
// @Override
// public ExternalPhasedUnit getPhasedUnitFromRelativePath(String relativePath) {
// if (relativePath.startsWith("/")) {
// relativePath = relativePath.substring(1);
// }
// if (! relativePathToPath.containsKey(relativePath)) {
// if (relativePath.endsWith(".java")) {
// // Case of a Ceylon file with a Java implementation, the classesToSources key is the Java source file.
// String ceylonFileRelativePath = getCeylonDeclarationFile(relativePath);
// if (ceylonFileRelativePath != null) {
// return super.getPhasedUnitFromRelativePath(ceylonFileRelativePath);
// }
// }
// return null;
// }
// return super.getPhasedUnitFromRelativePath(relativePath);
// }
//
// @Override
// protected ExternalPhasedUnit fromStoredType(SoftReference<ExternalPhasedUnit> storedValue, String path) {
// ExternalPhasedUnit result = storedValue.get();
// if (result == null) {
// if (!sourceCannotBeResolved.contains(path)) {
// result = buildPhasedUnitForBinaryUnit(path);
// if (result != null) {
// phasedUnitPerPath.put(path, toStoredType(result));
// } else {
// sourceCannotBeResolved.add(path);
// }
// }
// }
// return result;
// }
//
// @Override
// protected void addInReturnedList(List<ExternalPhasedUnit> list,
// ExternalPhasedUnit phasedUnit) {
// if (phasedUnit != null) {
// list.add(phasedUnit);
// }
// }
//
// @Override
// protected SoftReference<ExternalPhasedUnit> toStoredType(ExternalPhasedUnit phasedUnit) {
// return new SoftReference<ExternalPhasedUnit>(phasedUnit);
// }
//
// @Override
// public void removePhasedUnitForRelativePath(String relativePath) {
// // Don't clean the Package since we are in the binary case
// String path = relativePathToPath.get(relativePath);
// relativePathToPath.remove(relativePath);
// phasedUnitPerPath.remove(path);
// }
//
//
// };
//
// private void fillSourceRelativePaths() throws ZipException {
// classesToSources = CarUtils.retrieveMappingFile(returnCarFile());
// sourceRelativePaths.clear();
// File sourceArchiveFile = new File( sourceArchivePath);
// boolean sourcePathsFilled = false;
// if (sourceArchiveFile.exists()) {
// ZipFile sourceArchive;
// try {
// sourceArchive = new ZipFile(sourceArchiveFile);
// try {
// Enumeration<? extends ZipEntry> entries = sourceArchive.entries();
// while(entries.hasMoreElements()) {
// ZipEntry entry = entries.nextElement();
// sourceRelativePaths.add(entry.getName());
// }
// sourcePathsFilled = true;
// } finally {
// sourceArchive.close();
// }
// } catch (IOException e) {
// e.printStackTrace();
// sourceRelativePaths.clear();
// }
// }
// if (!sourcePathsFilled) {
// for (Object value : classesToSources.values()) {
// sourceRelativePaths.add((String)value);
// }
// }
//
// javaImplFilesToCeylonDeclFiles = CarUtils.searchCeylonFilesForJavaImplementations(classesToSources, new File(sourceArchivePath));
// }
//
// synchronized void setArtifact(ArtifactResult artifactResult) {
// artifact = artifactResult.artifact();
// repositoryDisplayString = artifactResult.repositoryDisplayString();
//
// if (artifact.getName().endsWith(ArtifactContext.SRC)) {
// moduleType = ModuleType.CEYLON_SOURCE_ARCHIVE;
// } else if(artifact.getName().endsWith(ArtifactContext.CAR)) {
// moduleType = ModuleType.CEYLON_BINARY_ARCHIVE;
// } else if(artifact.getName().endsWith(ArtifactContext.JAR)) {
// moduleType = ModuleType.JAVA_BINARY_ARCHIVE;
// }
//
// artifactType = artifactResult.type();
// if (isCeylonBinaryArchive()){
// String carPath = artifact.getPath();
// sourceArchivePath = carPath.substring(0, carPath.length()-ArtifactContext.CAR.length()) + ArtifactContext.SRC;
// try {
// fillSourceRelativePaths();
// } catch (Exception e) {
// CeylonPlugin.getInstance().getLog().log(new Status(IStatus.WARNING, CeylonPlugin.PLUGIN_ID, "Cannot find the source archive for the Ceylon binary module " + getSignature(), e));
// }
// binaryModulePhasedUnits = new BinaryPhasedUnits();
// }
//
// if (isSourceArchive()) {
// sourceArchivePath = artifact.getPath();
// try {
// fillSourceRelativePaths();
// } catch (Exception e) {
// e.printStackTrace();
// }
// sourceModulePhasedUnits = new WeakReference<ExternalModulePhasedUnits>(null);
// }
//
// try {
// IJavaProject javaProject = moduleManager.getJavaProject();
// if (javaProject != null) {
// for (IProject refProject : javaProject.getProject().getReferencedProjects()) {
// CeylonProject<IProject> ceylonProject = ceylonModel().getProject(refProject);
// if (refProject.isAccessible() && ceylonProject != null) {
// if (artifact.getAbsolutePath().contains(CeylonBuilder.getCeylonModulesOutputDirectory(refProject).getAbsolutePath())) {
// originalProject = refProject;
// }
// }
// }
// }
// } catch (CoreException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
//
// if (isJavaBinaryArchive()){
// String carPath = artifact.getPath();
// sourceArchivePath = carPath.substring(0, carPath.length()-ArtifactContext.JAR.length())
// + (artifactResult.type().equals(ArtifactResultType.MAVEN) ? ArtifactContext.LEGACY_SRC : ArtifactContext.SRC);
// }
// }
//
// public String getRepositoryDisplayString() {
// if (isJDKModule()) {
// return "Java SE Modules";
// }
// return repositoryDisplayString;
// }
//
// synchronized void setSourcePhasedUnits(final ExternalModulePhasedUnits modulePhasedUnits) {
// sourceModulePhasedUnits = new WeakReference<ExternalModulePhasedUnits>(modulePhasedUnits);
// }
//
// public File getArtifact() {
// return artifact;
// }
//
// public ArtifactResultType getArtifactType() {
// return artifactType;
// }
//
// private Properties getClassesToSources() {
// if (classesToSources.isEmpty() && getNameAsString().equals("java.base")) {
// for (Map.Entry<Object, Object> entry : ((JDTModule)getLanguageModule()).getClassesToSources().entrySet()) {
// if (entry.getKey().toString().startsWith("com/redhat/ceylon/compiler/java/language/")) {
// classesToSources.put(entry.getKey().toString().replace("com/redhat/ceylon/compiler/java/language/", "java/lang/"),
// entry.getValue().toString());
// }
// }
// }
// return classesToSources;
// }
//
// public boolean containsJavaImplementations() {
// for (String className : classesToSources.stringPropertyNames()) {
// String sourceFile = classesToSources.getProperty(className);
// if (sourceFile != null && sourceFile.endsWith(".java")) {
// return true;
// }
// }
// return false;
// }
//
// public String toSourceUnitRelativePath(String binaryUnitRelativePath) {
// return getClassesToSources().getProperty(binaryUnitRelativePath);
// }
//
// public String getJavaImplementationFile(String ceylonFileRelativePath) {
// String javaFileRelativePath = null;
// for (Entry<String, String> entry : javaImplFilesToCeylonDeclFiles.entrySet()) {
// if (entry.getValue().equals(ceylonFileRelativePath)) {
// javaFileRelativePath = entry.getKey();
// }
// }
// return javaFileRelativePath;
// }
//
// public String getCeylonDeclarationFile(String sourceUnitRelativePath) {
// if (sourceUnitRelativePath==null||sourceUnitRelativePath.endsWith(".ceylon")) {
// return sourceUnitRelativePath;
// }
// return javaImplFilesToCeylonDeclFiles.get(sourceUnitRelativePath);
// }
//
// public List<String> toBinaryUnitRelativePaths(String sourceUnitRelativePath) {
// if (sourceUnitRelativePath == null) {
// return Collections.emptyList();
// }
//
// List<String> result = new ArrayList<String>();
// for (Entry<Object, Object> entry : classesToSources.entrySet()) {
// if (sourceUnitRelativePath.equals(entry.getValue())) {
// result.add((String) entry.getKey());
// }
// }
// return result;
// }
//
// public List<IPackageFragmentRoot> getPackageFragmentRoots() {
// synchronized (packageFragmentRoots) {
// if (packageFragmentRoots.isEmpty() &&
// ! moduleManager.isExternalModuleLoadedFromSource(getNameAsString())) {
// IJavaProject javaProject = moduleManager.getJavaProject();
// if (javaProject != null) {
// if (this.equals(getLanguageModule())) {
// IClasspathEntry runtimeClasspathEntry = null;
//
// try {
// for (IClasspathEntry entry : javaProject.getRawClasspath()) {
// if (entry.getEntryKind() == IClasspathEntry.CPE_CONTAINER &&
// entry.getPath().segment(0).equals(CeylonLanguageModuleContainer.CONTAINER_ID)) {
// runtimeClasspathEntry = entry;
// break;
// }
// }
//
// if (runtimeClasspathEntry != null) {
// for (IPackageFragmentRoot root : javaProject.getPackageFragmentRoots()) {
// if (root.exists() &&
// javaProject.isOnClasspath(root) &&
// root.getRawClasspathEntry().equals(runtimeClasspathEntry)) {
// packageFragmentRoots.add(root);
// }
// }
// }
// } catch (JavaModelException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
// }
// else {
// File jarToSearch = null;
// try {
// jarToSearch = returnCarFile();
// if (jarToSearch == null) {
// RepositoryManager repoMgr = CeylonBuilder.getProjectRepositoryManager(javaProject.getProject());
// if (repoMgr != null) {
// jarToSearch = CeylonProjectModulesContainer.getModuleArtifact(repoMgr, this);
// }
// }
//
// if (jarToSearch != null) {
// IPackageFragmentRoot root = moduleManager.getJavaProject().getPackageFragmentRoot(jarToSearch.toString());
// if (root instanceof JarPackageFragmentRoot) {
// JarPackageFragmentRoot jarRoot = (JarPackageFragmentRoot) root;
// if (jarRoot.getJar().getName().equals(jarToSearch.getPath())) {
// packageFragmentRoots.add(root);
// }
// }
// }
// } catch (CoreException e) {
// if (jarToSearch != null) {
// System.err.println("Exception trying to get Jar file '" + jarToSearch + "' :");
// }
// e.printStackTrace();
// }
// }
// }
// }
// }
// return packageFragmentRoots;
// }
//
// @Override
// protected JDTModelLoader getModelLoader() {
// return moduleManager.getModelLoader();
// }
//
// public JDTModuleManager getModuleManager() {
// return moduleManager;
// }
//
// public JDTModuleSourceMapper getModuleSourceMapper() {
// return moduleSourceMapper;
// }
//
// @Override
// public List<Package> getAllVisiblePackages() {
// synchronized (getModelLoader()) {
// // force-load every package from the module if we can
// loadAllPackages(new HashSet<String>());
//
// // now delegate
// return super.getAllVisiblePackages();
// }
// }
//
// @Override
// public List<Package> getAllReachablePackages() {
// synchronized (getModelLoader()) {
// // force-load every package from the module if we can
// loadAllPackages(new HashSet<String>());
//
// // now delegate
// return super.getAllReachablePackages();
// }
// }
//
// private void loadAllPackages(Set<String> alreadyScannedModules) {
// Set<String> packageList = listPackages();
// for (String packageName : packageList) {
// getPackage(packageName);
// }
//
// // now force-load other modules
// for (ModuleImport mi: getImports()) {
// Module importedModule = mi.getModule();
// if(importedModule instanceof JDTModule &&
// alreadyScannedModules.add(importedModule.getNameAsString())){
// ((JDTModule)importedModule).loadAllPackages(alreadyScannedModules);
// }
// }
// }
//
// private Set<String> listPackages() {
// Set<String> packageList = new TreeSet<String>();
// String name = getNameAsString();
// if(JDKUtils.isJDKModule(name)){
// packageList.addAll(JDKUtils.getJDKPackagesByModule(name));
// }else if(JDKUtils.isOracleJDKModule(name)){
// packageList.addAll(JDKUtils.getOracleJDKPackagesByModule(name));
// } else if(isJava() || true){
// for(IPackageFragmentRoot fragmentRoot : getPackageFragmentRoots()){
// if(!fragmentRoot.exists())
// continue;
// IParent parent = fragmentRoot;
// listPackages(packageList, parent);
// }
// }
// return packageList;
// }
//
// private void listPackages(Set<String> packageList, IParent parent) {
// try {
// for (IJavaElement child : parent.getChildren()) {
// if (child instanceof PackageFragment) {
// packageList.add(child.getElementName());
// listPackages(packageList, (IPackageFragment) child);
// }
// }
// } catch (JavaModelException e) {
// e.printStackTrace();
// }
// }
//
// @Override
// public void loadPackageList(ArtifactResult artifact) {
// try {
// super.loadPackageList(artifact);
// } catch(Exception e) {
// CeylonPlugin.getInstance().getLog().log(new Status(IStatus.ERROR, CeylonPlugin.PLUGIN_ID, "Failed loading the package list of module " + getSignature(), e));
// }
// JDTModelLoader modelLoader = getModelLoader();
// if (modelLoader != null) {
// synchronized(modelLoader){
// String name = getNameAsString();
// for(String pkg : jarPackages){
// if(name.equals("ceylon.language") && ! pkg.startsWith("ceylon.language")) {
// // special case for the language module to hide stuff
// continue;
// }
// modelLoader.findOrCreatePackage(this, pkg);
// }
// }
// }
// }
//
// private ModuleType moduleType;
//
// private enum ModuleType {
// PROJECT_MODULE,
// CEYLON_SOURCE_ARCHIVE,
// CEYLON_BINARY_ARCHIVE,
// JAVA_BINARY_ARCHIVE,
// SDK_MODULE,
// UNKNOWN
// }
//
// public void setProjectModule() {
// moduleType = ModuleType.PROJECT_MODULE;
// }
//
// public boolean isCeylonArchive() {
// return isCeylonBinaryArchive() || isSourceArchive();
// }
//
// public boolean isDefaultModule() {
// return this.equals(moduleManager.getModules().getDefaultModule());
// }
//
// public boolean isProjectModule() {
// return ModuleType.PROJECT_MODULE.equals(moduleType);
// }
//
// public boolean isJDKModule() {
// synchronized (this) {
// if (moduleType == null) {
// if (JDKUtils.isJDKModule(getNameAsString()) ||
// JDKUtils.isOracleJDKModule(getNameAsString())) {
// moduleType = ModuleType.SDK_MODULE;
// }
// }
// }
// return ModuleType.SDK_MODULE.equals(moduleType);
// }
//
// public boolean isUnresolved() {
// return artifact == null && ! isAvailable();
// }
//
// public boolean isJavaBinaryArchive() {
// return ModuleType.JAVA_BINARY_ARCHIVE.equals(moduleType);
// }
//
// public boolean isCeylonBinaryArchive() {
// return ModuleType.CEYLON_BINARY_ARCHIVE.equals(moduleType);
// }
//
// public boolean isSourceArchive() {
// return ModuleType.CEYLON_SOURCE_ARCHIVE.equals(moduleType);
// }
//
// public List<? extends PhasedUnit> getPhasedUnits() {
// PhasedUnitMap<? extends PhasedUnit, ?> phasedUnitMap = null;
// if (isCeylonBinaryArchive()) {
// phasedUnitMap = binaryModulePhasedUnits;
// }
// if (isSourceArchive()) {
// phasedUnitMap = sourceModulePhasedUnits.get();
// }
// if (phasedUnitMap != null) {
// synchronized (phasedUnitMap) {
// return phasedUnitMap.getPhasedUnits();
// }
// }
// return Collections.emptyList();
// }
//
// public ExternalPhasedUnit getPhasedUnit(IPath path) {
// PhasedUnitMap<? extends PhasedUnit, ?> phasedUnitMap = null;
// if (isCeylonBinaryArchive()) {
// phasedUnitMap = binaryModulePhasedUnits;
// }
// if (isSourceArchive()) {
// phasedUnitMap = sourceModulePhasedUnits.get();
// }
// if (phasedUnitMap != null) {
// IPath sourceArchiveIPath = new Path(sourceArchivePath+"!");
// synchronized (phasedUnitMap) {
// return (ExternalPhasedUnit) phasedUnitMap.getPhasedUnitFromRelativePath(path.makeRelativeTo(sourceArchiveIPath).toString());
// }
// }
// return null;
// }
//
// public ExternalPhasedUnit getPhasedUnit(String path) {
// PhasedUnitMap<? extends PhasedUnit, ?> phasedUnitMap = null;
// if (isCeylonBinaryArchive()) {
// phasedUnitMap = binaryModulePhasedUnits;
// }
// if (isSourceArchive()) {
// phasedUnitMap = sourceModulePhasedUnits.get();
// }
// if (phasedUnitMap != null) {
// synchronized (phasedUnitMap) {
// return (ExternalPhasedUnit) phasedUnitMap.getPhasedUnit(path);
// }
// }
// return null;
// }
//
// public ExternalPhasedUnit getPhasedUnit(VirtualFile file) {
// PhasedUnitMap<? extends PhasedUnit, ?> phasedUnitMap = null;
// if (isCeylonBinaryArchive()) {
// phasedUnitMap = binaryModulePhasedUnits;
// }
// if (isSourceArchive()) {
// phasedUnitMap = sourceModulePhasedUnits.get();
// }
// if (phasedUnitMap != null) {
// synchronized (phasedUnitMap) {
// return (ExternalPhasedUnit) phasedUnitMap.getPhasedUnit(file);
// }
// }
// return null;
// }
//
// public ExternalPhasedUnit getPhasedUnitFromRelativePath(String relativePathToSource) {
// PhasedUnitMap<? extends PhasedUnit, ?> phasedUnitMap = null;
// if (isCeylonBinaryArchive()) {
// phasedUnitMap = binaryModulePhasedUnits;
// }
// if (isSourceArchive()) {
// phasedUnitMap = sourceModulePhasedUnits.get();
// }
// if (phasedUnitMap != null) {
// synchronized (phasedUnitMap) {
// return (ExternalPhasedUnit) phasedUnitMap.getPhasedUnitFromRelativePath(relativePathToSource);
// }
// }
// return null;
// }
//
// public void removedOriginalUnit(String relativePathToSource) {
// if (isProjectModule()) {
// return;
// }
// originalUnitsToRemove.add(relativePathToSource);
//
// try {
// if (isCeylonBinaryArchive() || JavaCore.isJavaLikeFileName(relativePathToSource)) {
// List<String> unitPathsToSearch = new ArrayList<>();
// unitPathsToSearch.add(relativePathToSource);
// unitPathsToSearch.addAll(toBinaryUnitRelativePaths(relativePathToSource));
// for (String relativePathOfUnitToRemove : unitPathsToSearch) {
// Package p = getPackageFromRelativePath(relativePathOfUnitToRemove);
// if (p != null) {
// Set<Unit> units = new HashSet<>();
// try {
// for(Declaration d : p.getMembers()) {
// Unit u = d.getUnit();
// if (u.getRelativePath().equals(relativePathOfUnitToRemove)) {
// units.add(u);
// }
// }
// } catch(Exception e) {
// e.printStackTrace();
// }
//
// for (Unit u : units) {
// try {
// for (Declaration d : u.getDeclarations()) {
// d.getMembers();
// // Just to fully load the declaration before
// // the corresponding class is removed (so that
// // the real removing from the model loader
// // will not require reading the bindings.
// }
// } catch(Exception e) {
// e.printStackTrace();
// }
// }
// }
// }
// }
// } catch(Exception e) {
// e.printStackTrace();
// }
// }
//
// public void addedOriginalUnit(String relativePathToSource) {
// if (isProjectModule()) {
// return;
// }
// originalUnitsToAdd.add(relativePathToSource);
// }
//
// public void refresh() {
// if (originalUnitsToAdd.size() + originalUnitsToRemove.size() == 0) {
// // Nothing to refresh
// return;
// }
//
// try {
// PhasedUnitMap<? extends PhasedUnit, ?> phasedUnitMap = null;
// if (isCeylonBinaryArchive()) {
// JavaModelManager.getJavaModelManager().resetClasspathListCache();
// JavaModelManager.getJavaModelManager().getJavaModel().refreshExternalArchives(getPackageFragmentRoots().toArray(new IPackageFragmentRoot[0]), null);
// phasedUnitMap = binaryModulePhasedUnits;
// }
// if (isSourceArchive()) {
// phasedUnitMap = sourceModulePhasedUnits.get();
// }
// if (phasedUnitMap != null) {
// synchronized (phasedUnitMap) {
// for (String relativePathToRemove : originalUnitsToRemove) {
// if (isCeylonBinaryArchive() || JavaCore.isJavaLikeFileName(relativePathToRemove)) {
// List<String> unitPathsToSearch = new ArrayList<>();
// unitPathsToSearch.add(relativePathToRemove);
// unitPathsToSearch.addAll(toBinaryUnitRelativePaths(relativePathToRemove));
// for (String relativePathOfUnitToRemove : unitPathsToSearch) {
// Package p = getPackageFromRelativePath(relativePathOfUnitToRemove);
// if (p != null) {
// Set<Unit> units = new HashSet<>();
// for(Declaration d : p.getMembers()) {
// Unit u = d.getUnit();
// if (u.getRelativePath().equals(relativePathOfUnitToRemove)) {
// units.add(u);
// }
// }
// for (Unit u : units) {
// try {
// p.removeUnit(u);
// // In the future, when we are sure that we cannot add several unit objects with the
// // same relative path, we can add a break.
// } catch(Exception e) {
// e.printStackTrace();
// }
// }
// } else {
// System.out.println("WARNING : The package of the following binary unit (" + relativePathOfUnitToRemove + ") "
// + "cannot be found in module " + getNameAsString() +
// artifact != null ? " (artifact=" + artifact.getAbsolutePath() + ")" : "");
// }
// }
// }
// phasedUnitMap.removePhasedUnitForRelativePath(relativePathToRemove);
// }
//
// if (isSourceArchive()) {
// ClosableVirtualFile sourceArchive = null;
// try {
// sourceArchive = moduleSourceMapper.getContext().getVfs().getFromZipFile(new File(sourceArchivePath));
// for (String relativePathToAdd : originalUnitsToAdd) {
// VirtualFile archiveEntry = null;
// archiveEntry = searchInSourceArchive(
// relativePathToAdd, sourceArchive);
//
// if (archiveEntry != null) {
// Package pkg = getPackageFromRelativePath(relativePathToAdd);
// ((ExternalModulePhasedUnits)phasedUnitMap).parseFile(archiveEntry, sourceArchive, pkg);
// }
// }
// } catch (Exception e) {
// StringBuilder error = new StringBuilder("Unable to read source artifact from ");
// error.append(sourceArchive);
// error.append( "\ndue to connection error: ").append(e.getMessage());
// throw e;
// } finally {
// if (sourceArchive != null) {
// sourceArchive.close();
// }
// }
// } else if (isCeylonBinaryArchive() && binaryModulePhasedUnits != null){
// for (String relativePathToAdd : originalUnitsToAdd) {
// ((BinaryPhasedUnits) binaryModulePhasedUnits).putRelativePath(relativePathToAdd);
// }
// }
//
// fillSourceRelativePaths();
//
// originalUnitsToRemove.clear();
// originalUnitsToAdd.clear();
// }
// }
// if (isCeylonBinaryArchive() || isJavaBinaryArchive()) {
// jarPackages.clear();
// loadPackageList(new ArtifactResult() {
// @Override
// public VisibilityType visibilityType() {
// return null;
// }
// @Override
// public String version() {
// return null;
// }
// @Override
// public ArtifactResultType type() {
// return null;
// }
// @Override
// public String name() {
// return null;
// }
// @Override
// public ImportType importType() {
// return null;
// }
// @Override
// public List<ArtifactResult> dependencies() throws RepositoryException {
// return null;
// }
// @Override
// public File artifact() throws RepositoryException {
// return artifact;
// }
// @Override
// public String repositoryDisplayString() {
// return "";
// }
// @Override
// public PathFilter filter() {
// return null;
// }
// @Override
// public Repository repository() {
// return null;
// }
// });
// }
// } catch (Exception e) {
// e.printStackTrace();
// }
// }
//
// private Package getPackageFromRelativePath(
// String relativePathOfClassToRemove) {
// List<String> pathElements = Arrays.asList(relativePathOfClassToRemove.split("/"));
// String packageName = ModelUtil.formatPath(pathElements.subList(0, pathElements.size()-1));
// Package p = findPackageNoLazyLoading(packageName);
// return p;
// }
//
// @SuppressWarnings("unchecked")
// private ExternalPhasedUnit buildPhasedUnitForBinaryUnit(String sourceUnitFullPath) {
// if (sourceArchivePath == null || sourceUnitFullPath == null) {
// return null;
// }
//
// if (! sourceUnitFullPath.startsWith(sourceArchivePath)) {
// return null;
// }
//
// File sourceArchiveFile = new File(sourceArchivePath);
// if (! sourceArchiveFile.exists()) {
// return null;
// }
//
// ExternalPhasedUnit phasedUnit = null;
// String sourceUnitRelativePath = sourceUnitFullPath.replace(sourceArchivePath + "!/", "");
// Package pkg = getPackageFromRelativePath(sourceUnitRelativePath);
// if (pkg != null) {
// try {
// JDTModuleManager moduleManager = getModuleManager();
// JDTModuleSourceMapper moduleSourceMapper = getModuleSourceMapper();
// ClosableVirtualFile sourceArchive = null;
// try {
// sourceArchive = moduleSourceMapper.getContext().getVfs().getFromZipFile(sourceArchiveFile);
//
// String ceylonSourceUnitRelativePath = getCeylonDeclarationFile(sourceUnitRelativePath);
// if (ceylonSourceUnitRelativePath !=null) {
// String ceylonSourceUnitFullPath = sourceArchivePath + "!/" + ceylonSourceUnitRelativePath;
// VirtualFile archiveEntry = searchInSourceArchive(
// ceylonSourceUnitRelativePath, sourceArchive);
// if (archiveEntry != null) {
// IProject project = moduleManager.getJavaProject().getProject();
// CeylonLexer lexer = new CeylonLexer(NewlineFixingStringStream.fromStream(archiveEntry.getInputStream(), project.getDefaultCharset()));
// CommonTokenStream tokenStream = new CommonTokenStream(lexer);
// CeylonParser parser = new CeylonParser(tokenStream);
// Tree.CompilationUnit cu = parser.compilationUnit();
// List<CommonToken> tokens = new ArrayList<CommonToken>(tokenStream.getTokens().size());
// tokens.addAll(tokenStream.getTokens());
// SingleSourceUnitPackage proxyPackage = new SingleSourceUnitPackage(pkg, ceylonSourceUnitFullPath);
// if(originalProject == null) {
// phasedUnit = new ExternalPhasedUnit(archiveEntry, sourceArchive, cu,
// proxyPackage, moduleManager, moduleSourceMapper, CeylonBuilder.getProjectTypeChecker(project), tokens) {
// @Override
// protected boolean isAllowedToChangeModel(Declaration declaration) {
// return !IdePhasedUnit.isCentralModelDeclaration(declaration);
// }
// };
// } else {
// phasedUnit = new CrossProjectPhasedUnit(archiveEntry, sourceArchive, cu,
// proxyPackage, moduleManager, moduleSourceMapper, CeylonBuilder.getProjectTypeChecker(project), tokens, originalProject) {
// @Override
// protected boolean isAllowedToChangeModel(Declaration declaration) {
// return !IdePhasedUnit.isCentralModelDeclaration(declaration);
// }
// };
// }
// }
// }
// } catch (Exception e) {
// StringBuilder error = new StringBuilder("Unable to read source artifact from ");
// error.append(sourceArchive);
// error.append( "\ndue to connection error: ").append(e.getMessage());
// System.err.println(error);
// } finally {
// if (sourceArchive != null) {
// sourceArchive.close();
// }
// }
// if (phasedUnit != null) {
// phasedUnit.validateTree();
// phasedUnit.visitSrcModulePhase();
// phasedUnit.visitRemainingModulePhase();
// phasedUnit.scanDeclarations();
// phasedUnit.scanTypeDeclarations();
// phasedUnit.validateRefinement();
// }
// } catch (Exception e) {
// e.printStackTrace();
// phasedUnit = null;
// }
// }
// return phasedUnit;
// }
//
// private VirtualFile searchInSourceArchive(String sourceUnitRelativePath,
// ClosableVirtualFile sourceArchive) {
// VirtualFile archiveEntry;
// archiveEntry = sourceArchive;
// for (String part : sourceUnitRelativePath.split("/")) {
// boolean found = false;
// for (VirtualFile vf : archiveEntry.getChildren()) {
// if (part.equals(vf.getName().replace("/", ""))) {
// archiveEntry = vf;
// found = true;
// break;
// }
// }
// if (!found) {
// archiveEntry = null;
// break;
// }
// }
// return archiveEntry;
// }
//
// public String getSourceArchivePath() {
// return sourceArchivePath;
// }
//
//
// public IProject getOriginalProject() {
// return originalProject;
// }
//
// public JDTModule getOriginalModule() {
// if (originalProject != null) {
// if (originalModule == null) {
// Modules modules = CeylonBuilder.getProjectModules(originalProject);
// if (modules != null) {
// for (Module m : modules.getListOfModules()) {
// // TODO : in the future : manage version ?? in case we reference 2 identical projects with different version in the workspace
// if (m.getNameAsString().equals(getNameAsString())) {
// assert(m instanceof JDTModule);
// if (((JDTModule) m).isProjectModule()) {
// originalModule = (JDTModule) m;
// break;
// }
// }
// }
// }
// }
// return originalModule;
// }
// return null;
// }
//
// public boolean containsClass(String className) {
// return className != null &&
// (classesToSources != null ? classesToSources.containsKey(className) : false);
// }
//
// @Override
// public List<Package> getPackages() {
// return super.getPackages();
// }
//
// @Override
// public void clearCache(final TypeDeclaration declaration) {
// clearCacheLocally(declaration);
// if (getProjectModuleDependencies() != null) {
// getProjectModuleDependencies().doWithReferencingModules(this, new TraversalAction<Module>() {
// @Override
// public void applyOn(Module module) {
// assert(module instanceof JDTModule);
// if (module instanceof JDTModule) {
// ((JDTModule) module).clearCacheLocally(declaration);
// }
// }
// });
// getProjectModuleDependencies().doWithTransitiveDependencies(this, new TraversalAction<Module>() {
// @Override
// public void applyOn(Module module) {
// assert(module instanceof JDTModule);
// if (module instanceof JDTModule) {
// ((JDTModule) module).clearCacheLocally(declaration);
// }
// }
// });
// ((JDTModule)getLanguageModule()).clearCacheLocally(declaration);
// }
// }
//
// private void clearCacheLocally(final TypeDeclaration declaration) {
// super.clearCache(declaration);
// }
//
// private ModuleDependencies projectModuleDependencies = null;
// private ModuleDependencies getProjectModuleDependencies() {
// if (projectModuleDependencies == null) {
// IJavaProject javaProject = moduleManager.getJavaProject();
// if (javaProject != null) {
// projectModuleDependencies = CeylonBuilder.getModuleDependenciesForProject(javaProject.getProject());
// }
// }
// return projectModuleDependencies;
// }
//
// public Iterable<Module> getReferencingModules() {
// if (getProjectModuleDependencies() != null) {
// return getProjectModuleDependencies().getReferencingModules(this);
// }
// return Collections.emptyList();
// }
//
// public Iterable<Module> getTransitiveDependencies() {
// if (getProjectModuleDependencies() != null) {
// return getProjectModuleDependencies().getTransitiveDependencies(this);
// }
// return Collections.emptyList();
// }
//
// public boolean resolutionFailed() {
// return resolutionException != null;
// }
//
// public void setResolutionException(Exception resolutionException) {
// if (resolutionException instanceof RuntimeException)
// this.resolutionException = resolutionException;
// }
//
// public List<JDTModule> getModuleInReferencingProjects() {
// if (! isProjectModule()) {
// return Collections.emptyList();
// }
// IProject project = moduleManager.getJavaProject().getProject();
// IProject[] referencingProjects = project.getReferencingProjects();
// if (referencingProjects.length == 0) {
// return Collections.emptyList();
// }
//
// List<JDTModule> result = new ArrayList<>();
// for(IProject referencingProject : referencingProjects) {
// JDTModule referencingModule = null;
// Modules referencingProjectModules = CeylonBuilder.getProjectModules(referencingProject);
// if (referencingProjectModules != null) {
// for (Module m : referencingProjectModules.getListOfModules()) {
// if (m.getSignature().equals(getSignature())) {
// assert(m instanceof JDTModule);
// referencingModule = (JDTModule) m;
// break;
// }
// }
// }
// if (referencingModule != null) {
// result.add(referencingModule);
// }
// }
// return result;
// }
//
//}
//