diff options
author | paltherr <paltherr@epfl.ch> | 2004-03-23 02:36:24 +0000 |
---|---|---|
committer | paltherr <paltherr@epfl.ch> | 2004-03-23 02:36:24 +0000 |
commit | a70044860bbd402c4191038615160fb7168572f7 (patch) | |
tree | 4644374257c1a4d50d6ffe12d433b1732407d5ab | |
parent | 71ac5a4ad27fd6d3ab4da4d551fefa6ae508ff2e (diff) | |
download | scala-a70044860bbd402c4191038615160fb7168572f7.tar.gz scala-a70044860bbd402c4191038615160fb7168572f7.tar.bz2 scala-a70044860bbd402c4191038615160fb7168572f7.zip |
- Split scala.tools.util.AbstractFile into seve...
- Split scala.tools.util.AbstractFile into several files Added
- scala.tools.util.DirectoryPath Added scala.tools.util.VirtualDirectory
- Changed interface of scala.tools.util.AbstractFile Rewrote
- scala.tools.util.ZipArchive (merged ZipArchive and JarArchive) Moved
- ClassPath to scala.tools.util Changed ClassPath and PackageParser to
- rely on DirectoryPath for file lookups
-rw-r--r-- | config/list/compiler.lst | 1 | ||||
-rw-r--r-- | config/list/util.lst | 7 | ||||
-rw-r--r-- | sources/scala/tools/scaladoc/HTMLGeneratorCommand.java | 3 | ||||
-rw-r--r-- | sources/scala/tools/scalai/Compiler.java | 2 | ||||
-rw-r--r-- | sources/scala/tools/scalai/PathClassLoader.java | 13 | ||||
-rw-r--r-- | sources/scala/tools/util/AbstractFile.java | 747 | ||||
-rw-r--r-- | sources/scala/tools/util/CharArrayFile.java | 53 | ||||
-rw-r--r-- | sources/scala/tools/util/ClassPath.java (renamed from sources/scalac/util/ClassPath.java) | 57 | ||||
-rw-r--r-- | sources/scala/tools/util/DirectoryPath.java | 222 | ||||
-rw-r--r-- | sources/scala/tools/util/PlainFile.java | 130 | ||||
-rw-r--r-- | sources/scala/tools/util/VirtualDirectory.java | 39 | ||||
-rw-r--r-- | sources/scala/tools/util/VirtualFile.java | 97 | ||||
-rw-r--r-- | sources/scala/tools/util/ZipArchive.java | 229 | ||||
-rw-r--r-- | sources/scalac/CompilerCommand.java | 3 | ||||
-rw-r--r-- | sources/scalac/Global.java | 11 | ||||
-rw-r--r-- | sources/scalac/symtab/classfile/CLRPackageParser.java | 2 | ||||
-rw-r--r-- | sources/scalac/symtab/classfile/PackageParser.java | 72 |
17 files changed, 928 insertions, 760 deletions
diff --git a/config/list/compiler.lst b/config/list/compiler.lst index 998d153c7c..e8652d4d74 100644 --- a/config/list/compiler.lst +++ b/config/list/compiler.lst @@ -151,7 +151,6 @@ typechecker/RefCheckPhase.java util/AbstractFileReader.java util/ArrayApply.java -util/ClassPath.java util/Debug.java util/EmptyPhase.java util/FreshNameCreator.java diff --git a/config/list/util.lst b/config/list/util.lst index 65397167dc..fdfb555d07 100644 --- a/config/list/util.lst +++ b/config/list/util.lst @@ -4,9 +4,16 @@ # $Id$ AbstractFile.java +CharArrayFile.java +ClassPath.java +DirectoryPath.java EmptyIterator.java +PlainFile.java Position.java SourceFile.java SourceReader.java +VirtualFile.java +VirtualDirectory.java +ZipArchive.java ############################################################################## diff --git a/sources/scala/tools/scaladoc/HTMLGeneratorCommand.java b/sources/scala/tools/scaladoc/HTMLGeneratorCommand.java index 6aef1f195c..dfdc81d18c 100644 --- a/sources/scala/tools/scaladoc/HTMLGeneratorCommand.java +++ b/sources/scala/tools/scaladoc/HTMLGeneratorCommand.java @@ -14,9 +14,10 @@ import java.util.List; import ch.epfl.lamp.util.HTMLPrinter; import ch.epfl.lamp.util.HTMLRepresentation; +import scala.tools.util.ClassPath; + import scalac.CompilerCommand; import scalac.util.BooleanOptionParser; -import scalac.util.ClassPath; import scalac.util.OptionParser; import scalac.util.Reporter; import scalac.util.StringOptionParser; diff --git a/sources/scala/tools/scalai/Compiler.java b/sources/scala/tools/scalai/Compiler.java index 97e0c6cb29..a52e002dea 100644 --- a/sources/scala/tools/scalai/Compiler.java +++ b/sources/scala/tools/scalai/Compiler.java @@ -54,7 +54,7 @@ public class Compiler { this.global = global; this.definitions = global.definitions; this.constants = new Constants(); - this.loader = new PathClassLoader(global.classPath); + this.loader = new PathClassLoader(global.classPath.getRoot()); scala.runtime.RunTime.setClassLoader(loader); JavaMirror mirror = new JavaMirror(definitions, loader); this.environment = new Environment(this, mirror); diff --git a/sources/scala/tools/scalai/PathClassLoader.java b/sources/scala/tools/scalai/PathClassLoader.java index fb975d4452..251b79661f 100644 --- a/sources/scala/tools/scalai/PathClassLoader.java +++ b/sources/scala/tools/scalai/PathClassLoader.java @@ -9,24 +9,23 @@ package scala.tools.scalai; +import java.io.File; import java.io.IOException; import scala.tools.util.AbstractFile; -import scalac.util.ClassPath; - public class PathClassLoader extends ClassLoader { //######################################################################## // PathClassLoader state - private final ClassPath classpath; + private final AbstractFile root; //######################################################################## // PathClassLoader constructors - public PathClassLoader(ClassPath classpath) { - this.classpath = classpath; + public PathClassLoader(AbstractFile root) { + this.root = root; } //######################################################################## @@ -34,8 +33,8 @@ public class PathClassLoader extends ClassLoader { public Class findClass(String name) throws ClassNotFoundException { try { - String filename = name.replace('.', '/') + ".class"; - AbstractFile file = classpath.openFile(filename); + String filename = name.replace('.', File.separatorChar) + ".class"; + AbstractFile file = root.lookupPath(filename, false); byte[] bytes = file.read(); return defineClass(name, bytes, 0, bytes.length); } catch (IOException exception) { diff --git a/sources/scala/tools/util/AbstractFile.java b/sources/scala/tools/util/AbstractFile.java index ab4705d085..723d983a4a 100644 --- a/sources/scala/tools/util/AbstractFile.java +++ b/sources/scala/tools/util/AbstractFile.java @@ -8,686 +8,121 @@ package scala.tools.util; -import java.io.*; -import java.util.*; -import java.util.zip.*; -import java.util.jar.*; - +import java.io.File; +import java.io.IOException; +import java.util.Iterator; +import java.util.jar.JarFile; +import java.util.zip.ZipFile; + +/** + * This class implements an abstract representation of files and + * directories. These files and directories may have some real counter + * part within the file system but that is not necessarily true. For + * example, there exist abstract files that represent files within a + * zip archive or files that exist only in memory. + * + * Every abstract file has a path (i.e. a full name) and a name + * (i.e. a short name) and may be backed by some real File. There are + * two different kinds of abstract files: regular files and + * directories. Regular files may be read and have a last modification + * time. Directories may list their content and look for subfiles with + * a specified name or path and of a specified kind. + */ public abstract class AbstractFile { - /** separator - */ - protected char separator = File.separatorChar; - - /** table of all opened jar-files - */ - protected static Hashtable opened = new Hashtable(); - - /** get name of the file - */ - public abstract String getName(); - - /** get path of the file - */ - public abstract String getPath(); - - /** does the file exist? - */ - public abstract boolean exists(); + //######################################################################## + // Public Factories - /** is the file a directory? - */ - public abstract boolean isDirectory(); - - /** date file was last modified - */ - public abstract long lastModified(); - - /** read content of the file into a byte[] buffer - */ - public abstract byte[] read() throws IOException; - - /** list contents of a directory - */ - public abstract String[] list() throws IOException; - - /** open a new file - */ - public abstract AbstractFile open(String name); - - /** return an input stream for the file - */ - public InputStream getInputStream() throws IOException { - return new ByteArrayInputStream(read()); + /** Returns "getFile(new File(path))". */ + public static AbstractFile getFile(String path) { + return getFile(new File(path)); } - /** Returns the path of this file. */ - public String toString() { - return getPath(); - } - - /** open file 'name' in directory 'dirname' + /** + * If the specified File exists and is a regular file, returns an + * abstract regular file backed by it. Otherwise, returns null. */ - public static AbstractFile open(String dirname, String name) { - AbstractFile res; - if (dirname == null) - res = new PlainFile(new File(name)); - else if (dirname.endsWith(".zip")) { - AbstractFile dir = (AbstractFile)opened.get(dirname); - if (dir == null) { - dir = new ZipDir(new File(dirname)); - if (dir.isDirectory()) - opened.put(dirname, dir); - } - res = (name == null) ? dir : dir.open(name); - } else if (dirname.endsWith(".jar")) { - AbstractFile dir = (AbstractFile)opened.get(dirname); - if (dir == null) { - dir = new JarArchive(new File(dirname)); - if (dir.isDirectory()) - opened.put(dirname, dir); - } - res = (name == null) ? dir : dir.open(name); - } else if (name == null) - res = new PlainFile(new File(dirname)); - else - res = new PlainFile(new File(dirname, name)); - if (!res.exists()) - res = null; - return res; - } - - /** create file given by a fully qualified name from root directory `outdir'; - * create intermediate directories if they do not exist already - */ - public static File create(File outdir, String name, - String suffix) throws IOException { - int start = 0; - int end = name.indexOf('.'); - while (end >= start) { - outdir = new File(outdir, name.substring(start, end)); - if (!outdir.exists()) - outdir.mkdir(); - start = end + 1; - end = name.indexOf('.', start); - } - return new File(outdir, name.substring(start) + suffix); - } -} - -class PlainFile extends AbstractFile { - File f; - - PlainFile(File f) { - this.f = f; - } - - public String getName() { - return f.getName(); - } - - public String getPath() { - return f.getPath(); - } - - public boolean exists() { - return f.exists(); - } - - public boolean isDirectory() { - return f.isDirectory(); - } - - public long lastModified() { - return f.lastModified(); - } - - public byte[] read() throws IOException { - FileInputStream in = new FileInputStream(f); - int rest = (int)f.length(); - byte[] buf = new byte[rest]; - do { - int res = in.read(buf, buf.length - rest, rest); - if (res == -1) - throw new IOException("read error"); - rest -= res; - } while (rest > 0); - in.close(); - return buf; - } - - public String[] list() throws IOException { - File[] fs = f.listFiles(); - if (fs == null) - return new String[0]; - String[] res = new String[fs.length]; - for (int i = 0; i < fs.length; i++) { - res[i] = fs[i].getName(); - if (fs[i].isDirectory() && - !res[i].endsWith("/")) - res[i] = res[i] + "/"; - } - return res; - } - - public AbstractFile open(String name) { - return new PlainFile(new File(f, name)); - } -} - -class ZippedFile extends AbstractFile { - ZipDir dir; - ZipEntry zipEntry; - - { - separator = '/'; - } - - ZippedFile(ZipDir dir, String name) { - this.dir = dir; - if (dir.zipFile != null) { - name = name.replace(File.separatorChar, separator); - zipEntry = this.dir.zipFile.getEntry(name); - if (zipEntry == null) - zipEntry = this.dir.zipFile.getEntry(name + separator); - } + public static AbstractFile getFile(File file) { + return file.isFile() ? new PlainFile(file) : null; } - public String getName() { - return zipEntry.getName(); - } - - public String getPath() { - return dir.getPath() + "(" + zipEntry.getName() + ")"; - } - - public boolean exists() { - return (zipEntry != null); - } - - public boolean isDirectory() { - return zipEntry.isDirectory(); - } - - public long lastModified() { - return zipEntry.getTime(); - } - - public byte[] read() throws IOException { - InputStream in = dir.zipFile.getInputStream(zipEntry); - int rest = (int)zipEntry.getSize(); - byte[] buf = new byte[rest]; - do { - int res = in.read(buf, buf.length - rest, rest); - if (res == -1) - throw new IOException("read error"); - rest -= res; - } while (rest > 0); - in.close(); - return buf; - } - - public String[] list() throws IOException { - if (!isDirectory()) - throw new IOException("not a directory"); - return dir.list(zipEntry.getName()); - } - - public AbstractFile open(String name) { - String pathname = zipEntry.getName(); - return new ZippedFile(dir, pathname + name); - } -} - -class ZipDir extends AbstractFile { - File f; - ZipFile zipFile; - - { - separator = '/'; - } - - ZipDir(File f) { - this.f = f; - try { - zipFile = new ZipFile(f); - } catch (ZipException e) { - } catch (IOException e) {} - } - - public String getName() { - return f.getName(); - } - - public String getPath() { - return f.getPath(); - } - - public boolean exists() { - return (zipFile != null); - } - - public boolean isDirectory() { - return (zipFile != null); - } - - public long lastModified() { - return -1; - } - public byte[] read() throws IOException { - throw new IOException("cannot read directory"); - } - - public String[] list(String prefix) { - int n = 0; - for (Enumeration enum = zipFile.entries(); enum.hasMoreElements();) { - ZipEntry e = (ZipEntry)enum.nextElement(); - if (e.getName().startsWith(prefix)) { - String candidate = e.getName().substring(prefix.length()); - if (candidate.indexOf(separator) < 0) - n++; - } - } - String[] filenames = new String[n]; - n = 0; - for (Enumeration enum = zipFile.entries(); enum.hasMoreElements();) { - ZipEntry e = (ZipEntry)enum.nextElement(); - if (e.getName().startsWith(prefix)) { - String candidate = e.getName().substring(prefix.length()); - if (candidate.indexOf(separator) < 0) - filenames[n++] = candidate; - } - } - return filenames; - } - - public String[] list() throws IOException { - return list(""); - } - - public AbstractFile open(String name) { - return new ZippedFile(this, name); - } -} - -final class JarArchive extends AbstractFile { - File f; - JarFile jarFile; - HashMap entries; - - public final static String[] EMPTY = new String[0]; - - - JarArchive(File f) { - try { - jarFile = new JarFile(this.f = f); - } - catch (ZipException e) {} - catch (IOException e) {} - } - - public String getName() { - return f.getName(); - } - - public String getPath() { - return f.getPath(); - } - - public boolean exists() { - return jarFile != null; - } - - public boolean isDirectory() { - return jarFile != null; - } - - public long lastModified() { - return -1; - } - - public byte[] read() throws IOException { - throw new IOException("cannot read archive"); - } - - private void load() { - entries = new HashMap(); - if (jarFile == null) - return; - Enumeration enum = jarFile.entries(); - while (enum.hasMoreElements()) { - String candidate = ((JarEntry)enum.nextElement()).getName(); - int i = candidate.indexOf('/'); - int j = 0; - HashMap files = entries; - while (i >= 0) { - String dirname = candidate.substring(j, j = (i + 1)); - JarDirEntry dir = (JarDirEntry)files.get(dirname); - if (dir == null) - files.put(dirname, dir = new JarDirEntry( - candidate.substring(0, j))); - files = dir.entries; - i = candidate.indexOf('/', j); - } - if (j < (candidate.length() - 1)) { - String filename = candidate.substring(j); - JarFileEntry file = (JarFileEntry)files.get(filename); - if (file == null) - files.put(filename, new JarFileEntry(candidate)); - } - } + /** Returns "getDirectory(new File(path))". */ + public static AbstractFile getDirectory(String path) { + return getDirectory(new File(path)); } - public String[] list(String prefix) { - prefix = prefix.replace(File.separatorChar, '/'); - if (entries == null) - load(); - int i = prefix.indexOf('/'); - int j = 0; - HashMap files = entries; - while (i >= 0) { - String dirname = prefix.substring(j, j = (i + 1)); - JarDirEntry dir = (JarDirEntry)files.get(dirname); - if (dir == null) - return EMPTY; - files = dir.entries; - i = prefix.indexOf('/', j); - } - if (j < (prefix.length() - 1)) { - String filename = prefix.substring(j); - return (files.get(filename) != null) ? new String[]{prefix} - : EMPTY; - } else - return (String[])files.keySet().toArray(new String[files.size()]); - } - - public String[] list() throws IOException { - return list(""); - } - - public AbstractFile open(String name) { - if (entries == null) - load(); - name = name.replace(File.separatorChar, '/'); - int i = name.indexOf('/'); - int j = 0; - int namelen = name.length(); - HashMap files = entries; - while (i >= 0) { - String dirname = name.substring(j, j = (i + 1)); - if (files != null) { - JarDirEntry dir = (JarDirEntry)files.get(dirname); - if (dir == null) - files = null; - else if (j == namelen) - return dir; - else - files = dir.entries; - } - i = name.indexOf('/', j); - } - if (j < (namelen - 1)) { - String filename = name.substring(j); - if (files == null) - return new NoJarFileEntry(name); - JarFileEntry file = (JarFileEntry)files.get(filename); - if (file == null) - return new NoJarFileEntry(name); - else - return file; - } else - return new NoJarDirEntry(name); - } - - static class NoJarDirEntry extends AbstractFile { - String name; - - NoJarDirEntry(String name) { - this.name = name; - } - - public String getName() { - return name.substring( - name.lastIndexOf('/', name.length() - 2) + 1); - } - - public String getPath() { - return name; - } - - public String getFullName() { - return name; - } - - public boolean exists() { - return false; - } - - public boolean isDirectory() { - return true; - } - - public long lastModified() { - return -1; - } - - public String[] list() throws IOException { - throw new IOException("not a directory"); - } - - public byte[] read() throws IOException { - throw new IOException("cannot read archive"); - } - - public AbstractFile open(String fname) { - throw new Error("cannot open archive entry"); - } - } - - final class JarDirEntry extends NoJarDirEntry { - HashMap entries; - - JarDirEntry(String name) { - super(name); - this.entries = new HashMap(); - } - - public String getPath() { - return JarArchive.this.getPath() + "(" + name + ")"; - } - - public boolean exists() { - return true; - } - - public String[] list() throws IOException { - return JarArchive.this.list(name); - } - - public AbstractFile open(String fname) { - fname = fname.replace(File.separatorChar, '/'); - return JarArchive.this.open(name + fname); - } - } - - static class NoJarFileEntry extends AbstractFile { - String name; - - NoJarFileEntry(String name) { - this.name = name; - } - - public String getName() { - return name.substring( - name.lastIndexOf('/', name.length() - 1) + 1); - } - - public String getFullName() { - return name; - } - - public String getPath() { - return name; - } - - public boolean exists() { - return false; - } - - public boolean isDirectory() { - return false; - } - - public long lastModified() { - return -1; - } - - public String[] list() throws IOException { - throw new IOException("not a directory"); - } - - public byte[] read() throws IOException { - throw new IOException("cannot read archive"); - } - - public AbstractFile open(String fname) { - throw new Error("not a directory"); - } - } - - final class JarFileEntry extends NoJarFileEntry { - - JarFileEntry(String name) { - super(name); - } - - public String getPath() { - return JarArchive.this.getPath() + "(" + name + ")"; - } - - public boolean exists() { - return true; - } - - public long lastModified() { - return jarFile.getJarEntry(name).getTime(); - } - - public byte[] read() throws IOException { - JarEntry jarEntry = jarFile.getJarEntry(name); - if (jarEntry == null) - throw new IOException("unable to read " + name); - InputStream in = jarFile.getInputStream(jarEntry); - int rest = (int)jarEntry.getSize(); - byte[] buf = new byte[rest]; - do { - int res = in.read(buf, buf.length - rest, rest); - if (res == -1) - throw new IOException("read error"); - rest -= res; - } while (rest > 0); - in.close(); - return buf; + /** + * if the specified File exists and is either a directory or a + * readable zip or jar archive, returns an abstract directory + * backed by it. Otherwise, returns null. + */ + public static AbstractFile getDirectory(File file) { + if (file.isDirectory()) return new PlainFile(file); + if (file.isFile()) { + String path = file.getPath(); + if (path.endsWith(".jar") || path.endsWith(".zip")) + return ZipArchive.fromFile(file); } - } -} - - -public class VirtualFile extends AbstractFile { - - /** The file name */ - private final String name; - - /** The file path */ - private final String path; - - public VirtualFile(String name) { - this(name, name); - } - - public VirtualFile(String name, String path) { - this.name = name; - this.path = path; - } - - public String getName() { - return name; - } - - public String getPath() { - return path; - } - - public boolean exists() { - return false; - } - - public boolean isDirectory() { - return false; - } - - public long lastModified() { - return Long.MIN_VALUE; - } - - public byte[] read() { - return new byte[0]; - } - - public String[] list() { - return new String[0]; - } - - public AbstractFile open(String name) { return null; } -} - -public class ByteArrayFile extends VirtualFile { - - private final byte[] bytes; - - public ByteArrayFile(String name, byte[] bytes) { - this(name, name, bytes); - } - - public ByteArrayFile(String name, String path, byte[] bytes) { - super(name, path); - this.bytes = bytes; - } - - public boolean exists() { - return true; - } + //######################################################################## + // Public Methods - public byte[] read() { - return bytes; - } + /** Returns the name of this abstract file. */ + public abstract String getName(); -} + /** Returns the path of this abstract file. */ + public abstract String getPath(); + /** Returns the underlying File if any and null otherwise. */ + public abstract File getFile(); -public class CharArrayFile extends VirtualFile { + /** Is this abstract file a directory? */ + public abstract boolean isDirectory(); - private final char[] chars; + /** Returns the time that this abstract file was last modified. */ + public abstract long lastModified(); - public CharArrayFile(String name, char[] chars) { - this(name, name, chars); - } + /** Reads the content of this abstract file into a byte array. */ + public abstract byte[] read() throws IOException; - public CharArrayFile(String name, String path, char[] chars) { - super(name, path); - this.chars = chars; - } + /** Returns all abstract subfiles of this abstract directory. */ + public abstract Iterator/*<AbstractFile>*/ list(); - public boolean exists() { - return true; - } + /** + * Returns the abstract file in this abstract directory with the + * specified name. If there is no such file, returns null. The + * argument "directory" tells whether to look for a directory or + * or a regular file. + */ + public abstract AbstractFile lookupName(String name, boolean directory); - public byte[] read() { - return new String(chars).getBytes(); // !!! + /** + * Returns the abstract file in this abstract directory with the + * specified path relative to it, If there is no such file, + * returns null. The argument "directory" tells whether to look + * for a directory or or a regular file. + */ + public final AbstractFile lookupPath(String path, boolean directory) { + final int length = path.length(); + final char separator = File.separatorChar; + assert 0 < length && path.lastIndexOf(separator) < length - 1: path; + AbstractFile file = this; + for (int start = 0, index; true; start = index + 1) { + index = path.indexOf(separator, start); + assert index < 0 || start < index: path+" - "+start+" - "+index; + String name = path.substring(start, index < 0 ? length : index); + file = file.lookupName(name, index < 0 ? directory : true); + if (file == null || index < 0) return file; + } + } + + /** Returns the path of this abstract file. */ + public final String toString() { + return getPath(); } + //######################################################################## } diff --git a/sources/scala/tools/util/CharArrayFile.java b/sources/scala/tools/util/CharArrayFile.java new file mode 100644 index 0000000000..55c8f4a19d --- /dev/null +++ b/sources/scala/tools/util/CharArrayFile.java @@ -0,0 +1,53 @@ +/* ____ ____ ____ ____ ______ *\ +** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** +** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** +** /_____/\____/\___/\____/____/ ** +\* */ + +// $Id$ + +package scala.tools.util; + +/** + * This class implements an abstract regular file backed by a + * character array. + */ +public class CharArrayFile extends VirtualFile { + + //######################################################################## + // Private Fields + + /** The character array */ + private final char[] chars; + + //######################################################################## + // Public Constructors + + /** + * Initializes this instance with the specified name, an identical + * path and the specified character array. + */ + public CharArrayFile(String name, char[] chars) { + this(name, name, chars); + } + + /** + * Initializes this instance with the specified name, path and + * character array. + */ + public CharArrayFile(String name, String path, char[] chars) { + super(name, path); + this.chars = chars; + } + + //######################################################################## + // Public Methods + + /** Reads the content of this abstract file into a byte array. */ + public byte[] read() { + assert false: "!!! not yet implemented"; + return new String(chars).getBytes(); // !!! + } + + //######################################################################## +} diff --git a/sources/scalac/util/ClassPath.java b/sources/scala/tools/util/ClassPath.java index 036af2240e..fee5ca435c 100644 --- a/sources/scalac/util/ClassPath.java +++ b/sources/scala/tools/util/ClassPath.java @@ -6,18 +6,14 @@ // $Id$ -package scalac.util; +package scala.tools.util; import java.io.File; -import java.io.FileNotFoundException; import java.util.ArrayList; import java.util.Iterator; import java.util.LinkedHashSet; import java.util.Set; -import scala.tools.util.AbstractFile; - - /** This class represents a Java/Scala class path. */ public class ClassPath { @@ -100,14 +96,11 @@ public class ClassPath { return scala == null ? java : java + PATH_SEPARATOR + scala; } - /** the various class path roots - */ - protected String[] root; - - /** print searches in the class path - */ - public boolean printSearch; + //######################################################################## + // Private Fields + /** The abstract directory represented by this class path */ + private final AbstractFile root; //######################################################################## // Public Constructors @@ -125,7 +118,6 @@ public class ClassPath { this(classpath, SOURCEPATH, BOOTCLASSPATH, EXTDIRS); } - /** Initializes this instance with the specified paths. */ public ClassPath(String classpath, String sourcepath, String bootclasspath, String extdirs) @@ -146,47 +138,24 @@ public class ClassPath { addFilesInPath(files, sourcepath); ArrayList dirs = new ArrayList(files.size()); for (Iterator i = files.iterator(); i.hasNext(); ) { - File file = (File)i.next(); - if (file.exists()) dirs.add(file.getPath()); + AbstractFile dir = AbstractFile.getDirectory((File)i.next()); + if (dir != null) dirs.add(dir); } - this.root = (String[])dirs.toArray(new String[dirs.size()]); + Object[] array = dirs.toArray(new AbstractFile[dirs.size()]); + this.root = DirectoryPath.fromArray("<root>", (AbstractFile[])array); } //######################################################################## // Public Methods - /** find file with given name in class path and return an abstract - * file representation - */ - public AbstractFile openFile(String name) throws FileNotFoundException { - if (printSearch) - System.out.println("looking for " + name); - for (int i = 0; i < root.length; i++) { - if (printSearch) - System.out.println(" in " + root[i]); - AbstractFile f = AbstractFile.open(root[i], name); - if (f != null) - return f; - } - throw new FileNotFoundException("file '" + name + - "' not found in classpath"); - } - - public String[] components() { + /** Returns the root of this class path. */ + public AbstractFile getRoot() { return root; } - /** return a textual representation of this class path - */ + /** Returns a string representation of this class path. */ public String toString() { - if (root.length == 0) - return ""; - else if (root.length == 1) - return root[0]; - String path = root[0]; - for (int i = 1; i < root.length; i++) - path += PATH_SEPARATOR + root[i]; - return path; + return root.toString(); } //######################################################################## diff --git a/sources/scala/tools/util/DirectoryPath.java b/sources/scala/tools/util/DirectoryPath.java new file mode 100644 index 0000000000..2b114f8efe --- /dev/null +++ b/sources/scala/tools/util/DirectoryPath.java @@ -0,0 +1,222 @@ +/* ____ ____ ____ ____ ______ *\ +** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** +** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** +** /_____/\____/\___/\____/____/ ** +\* */ + +// $Id$ + +package scala.tools.util; + +import java.io.File; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Map.Entry; +import java.util.NoSuchElementException; + +/** + * This class implements an abstract directory backed by a list of + * abstract directories. The content of the directories are merged + * together. If a subfile occurs in several directories, then the + * first occurrence hides the next ones. If a subdirectory occurs in + * several directories then the content of the different occurrences + * are merged together in the same way. + */ +public class DirectoryPath extends VirtualDirectory { + + //######################################################################## + // Public Factories + + /** + * Returns an abstract directory with the specified name and + * backed by the specified array of abstract directories. + */ + public static AbstractFile fromArray(String name, AbstractFile[] dirs) { + if (dirs.length == 0) return new VirtualDirectory(name, ""); + if (dirs.length == 1 && dirs[0].getName().equals(name)) return dirs[1]; + return new DirectoryPath(name, dirs); + } + + //######################################################################## + // Private Fields + + /** The directories composing this directory path */ + private final AbstractFile[] dirs; + + //######################################################################## + // Protected Constructor + + /** Initializes this instance with given name and directories. */ + protected DirectoryPath(String name, AbstractFile[] dirs) { + super(name); + this.dirs = dirs; + for (int i = 0; i < dirs.length; i++) + assert dirs[i].isDirectory(): dirs[i]; + } + + //######################################################################## + // Public Methods + + /** Returns the path of this abstract file. */ + public String getPath() { + StringBuffer buffer = new StringBuffer(); + for (int i = 0; i < dirs.length; i++) { + if (i > 0) buffer.append(File.pathSeparator); + buffer.append(dirs[i]); + } + return buffer.toString(); + } + + /** Returns all abstract subfiles of this abstract directory. */ + public Iterator/*<AbstractFile>*/ list() { + return new ListIterator(); + } + + /** + * Returns the abstract file in this abstract directory with the + * specified name. If there is no such file, returns null. The + * argument "directory" tells whether to look for a directory or + * or a regular file. + */ + public AbstractFile lookupName(String name, boolean directory) { + if (directory) { + AbstractFile first = null; + AbstractFile[] subdirs = null; + int count = 0; + for (int i = 0; i < dirs.length; i++) { + AbstractFile subdir = dirs[i].lookupName(name, directory); + if (subdir == null) continue; + if (count == 0) { + first = subdir; + count++; + } else { + if (count == 1) { + subdirs = new AbstractFile[dirs.length]; + subdirs[0] = first; + } + subdirs[count++] = subdir; + } + } + if (count == 0) return null; + if (count == 1) return first; + if (count != subdirs.length) { + AbstractFile[] array = new AbstractFile[count]; + for (int i = 0; i < array.length; i++) array[i] = subdirs[i]; + subdirs = array; + } + return new DirectoryPath(name, subdirs); + } else { + for (int i = 0; i < dirs.length; i++) { + AbstractFile file = dirs[i].lookupName(name, directory); + if (file != null) return file; + } + return null; + } + } + + //######################################################################## + // Private Class - ListIterator + + /** An iterator over the files contained in this directory. */ + private class ListIterator implements Iterator { + + /** The type of the values in the subdirectory table */ + // type SubDirs = AbstractFile | ArrayList<AbstractFile> + + /** A table to collect subdirectories */ + private final HashMap/*<String,SubDirs>*/ subdirs = new HashMap(); + + /** A table to track already returned regular subfiles */ + private final HashSet/*<String>*/ subfiles = new HashSet(); + + /** The current iterator */ + private Iterator iterator; + + /** The index of the current directory */ + private int index; + + /** The next iteration value or null if no more */ + private Object next; + + /** Initializes this instance. */ + public ListIterator() { + this.next = getNextValue(); + } + + /** Does this iteration have more elements? */ + public boolean hasNext() { + return next != null; + } + + /** Returns the next element in this iteration. */ + public Object next() { + if (next == null) throw new NoSuchElementException(); + Object value = next; + next = getNextValue(); + return value; + } + + /** Throws UnsupportedOperationException. */ + public void remove() { + throw new UnsupportedOperationException(); + } + + /** Returns the next iteration value or null if no more. */ + private AbstractFile getNextValue() { + for (; index < dirs.length; iterator = null, index++) { + // iterate over the files of directory "index" + if (iterator == null) iterator = dirs[index].list(); + while (iterator.hasNext()) { + AbstractFile subfile = (AbstractFile)iterator.next(); + String name = subfile.getName(); + if (subfile.isDirectory()) { + addSubDir(name, subfile); + } else if (!subfiles.contains(name)) { + subfiles.add(name); + return subfile; + } + } + } + // iterate over the collected subdirectories + if (iterator == null) iterator = subdirs.entrySet().iterator(); + if (iterator.hasNext()) return getSubDir((Entry)iterator.next()); + return null; + } + + /** Adds given subdirectory to the subdirectory table. */ + private void addSubDir(String name, AbstractFile subdir) { + Object value = subdirs.get(name); + if (value == null) { + subdirs.put(name, subdir); + } else { + ArrayList list; + if (value instanceof ArrayList) { + list = (ArrayList)value; + } else { + list = new ArrayList(); + subdirs.put(name, list); + list.add(value); + } + list.add(subdir); + } + } + + /** Turns given entry into an abstract directory. */ + private AbstractFile getSubDir(Entry/*<String,SubDirs>*/ entry) { + Object value = entry.getValue(); + if (value instanceof ArrayList) { + ArrayList list = (ArrayList)value; + AbstractFile[] array = new AbstractFile[list.size()]; + list.toArray(array); + return new DirectoryPath((String)entry.getKey(), array); + } else { + return (AbstractFile)value; + } + } + + } + + //######################################################################## +} diff --git a/sources/scala/tools/util/PlainFile.java b/sources/scala/tools/util/PlainFile.java new file mode 100644 index 0000000000..6684774038 --- /dev/null +++ b/sources/scala/tools/util/PlainFile.java @@ -0,0 +1,130 @@ +/* ____ ____ ____ ____ ______ *\ +** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** +** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** +** /_____/\____/\___/\____/____/ ** +\* */ + +// $Id$ + +package scala.tools.util; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.util.Iterator; +import java.util.NoSuchElementException; + +/** This class implements an abstract file backed by a File. */ +public class PlainFile extends AbstractFile { + + //######################################################################## + // Public Factories + + /** Returns "fromFile(new File(path))". */ + public static AbstractFile fromPath(String path) { + return fromFile(new File(path)); + } + + /** + * If the specified File exists, returns an abstract file backed + * by it. Otherwise, returns null. + */ + public static AbstractFile fromFile(File file) { + return file.exists() ? new PlainFile(file) : null; + } + + //######################################################################## + // Private Fields + + /** The underlying File */ + private final File file; + + //######################################################################## + // Protected Constructors + + /** Initializes this instance with the specified File. */ + protected PlainFile(File file) { + this.file = file; + assert file != null; + } + + //######################################################################## + // Public Methods + + /** Returns the name of this abstract file. */ + public String getName() { + return file.getName(); + } + + /** Returns the path of this abstract file. */ + public String getPath() { + return file.getPath(); + } + + /** Returns the underlying File if any and null otherwise. */ + public File getFile() { + return file; + } + + /** Is this abstract file a directory? */ + public boolean isDirectory() { + return file.isDirectory(); + } + + /** Returns the time that this abstract file was last modified. */ + public long lastModified() { + return file.lastModified(); + } + + /** Reads the content of this abstract file into a byte array. */ + public byte[] read() throws IOException { + assert !isDirectory(): "cannot read directory '" + this + "'"; + FileInputStream in = new FileInputStream(file); + int rest = (int)file.length(); + byte[] buf = new byte[rest]; + do { + int res = in.read(buf, buf.length - rest, rest); + if (res == -1) + throw new IOException("read error"); + rest -= res; + } while (rest > 0); + in.close(); + return buf; + } + + /** Returns all abstract subfiles of this abstract directory. */ + public Iterator/*<AbstractFile>*/ list() { + assert isDirectory(): "not a directory '" + this + "'"; + final String[] names = file.list(); + if (names == null || names.length == 0) return EmptyIterator.object; + class ListIterator implements Iterator { + private int i; + public boolean hasNext() { + return i < names.length; + } + public Object next() { + if (i == names.length) throw new NoSuchElementException(); + return new PlainFile(new File(file, names[i++])); + } + public void remove() { + throw new UnsupportedOperationException(); + } + } + return new ListIterator(); + } + + /** + * Returns the abstract file in this abstract directory with the + * specified name. If there is no such file, returns null. The + * argument "directory" tells whether to look for a directory or + * or a regular file. + */ + public AbstractFile lookupName(String name, boolean directory) { + assert isDirectory(): "not a directory '" + this + "'"; + File child = new File(file, name); + if (directory ? !child.isDirectory() : !child.isFile()) return null; + return new PlainFile(child); + } + + //######################################################################## +} diff --git a/sources/scala/tools/util/VirtualDirectory.java b/sources/scala/tools/util/VirtualDirectory.java new file mode 100644 index 0000000000..597f52d14b --- /dev/null +++ b/sources/scala/tools/util/VirtualDirectory.java @@ -0,0 +1,39 @@ +/* ____ ____ ____ ____ ______ *\ +** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** +** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** +** /_____/\____/\___/\____/____/ ** +\* */ + +// $Id$ + +package scala.tools.util; + +/** This class implements an empty abstract directory. */ +public class VirtualDirectory extends VirtualFile { + + //######################################################################## + // Public Constructors + + /** + * Initializes this instance with the specified name and an + * identical path. + */ + public VirtualDirectory(String name) { + this(name, name); + } + + /** Initializes this instance with the specified name and path. */ + public VirtualDirectory(String name, String path) { + super(name, path); + } + + //######################################################################## + // Public Methods + + /** Is this abstract file a directory? */ + public boolean isDirectory() { + return true; + } + + //######################################################################## +} diff --git a/sources/scala/tools/util/VirtualFile.java b/sources/scala/tools/util/VirtualFile.java new file mode 100644 index 0000000000..b0e6e2a897 --- /dev/null +++ b/sources/scala/tools/util/VirtualFile.java @@ -0,0 +1,97 @@ +/* ____ ____ ____ ____ ______ *\ +** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** +** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** +** /_____/\____/\___/\____/____/ ** +\* */ + +// $Id$ + +package scala.tools.util; + +import java.io.File; +import java.io.IOException; +import java.util.Iterator; + +/** This class implements an empty abstract regular file. */ +public class VirtualFile extends AbstractFile { + + //######################################################################## + // Private Fields + + /** The file name */ + private final String name; + + /** The file path */ + private final String path; + + //######################################################################## + // Public Constructors + + /** + * Initializes this instance with the specified name and an + * identical path. + */ + public VirtualFile(String name) { + this(name, name); + } + + /** Initializes this instance with the specified name and path. */ + public VirtualFile(String name, String path) { + this.name = name; + this.path = path; + assert name != null && path != null: name + " - " + path; + } + + //######################################################################## + // Public Methods + + /** Returns the name of this abstract file. */ + public String getName() { + return name; + } + + /** Returns the path of this abstract file. */ + public String getPath() { + return path; + } + + /** Returns null. */ + public final File getFile() { + return null; + } + + /** Is this abstract file a directory? */ + public boolean isDirectory() { + return false; + } + + /** Returns the time that this abstract file was last modified. */ + public long lastModified() { + return Long.MIN_VALUE; + } + + /** Reads the content of this abstract file into a byte array. */ + public byte[] read() throws IOException { + assert !isDirectory(): "cannot read directory '" + this + "'"; + return new byte[0]; + } + + /** Returns all abstract subfiles of this abstract directory. */ + public Iterator/*<AbstractFile>*/ list() { + assert isDirectory(): "not a directory '" + this + "'"; + return EmptyIterator.object; + } + + /** + * Returns the abstract file in this abstract directory with the + * specified name. If there is no such file, returns null. The + * argument "directory" tells whether to look for a directory or + * or a regular file. + */ + public AbstractFile lookupName(String name, boolean directory) { + assert isDirectory(): "not a directory '" + this + "'"; + return null; + } + + //######################################################################## +} diff --git a/sources/scala/tools/util/ZipArchive.java b/sources/scala/tools/util/ZipArchive.java new file mode 100644 index 0000000000..c0525a0bcd --- /dev/null +++ b/sources/scala/tools/util/ZipArchive.java @@ -0,0 +1,229 @@ +/* ____ ____ ____ ____ ______ *\ +** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** +** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** +** /_____/\____/\___/\____/____/ ** +\* */ + +// $Id$ + +package scala.tools.util; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.Iterator; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; + +/** + * This class implements an abstract directory backed by a zip + * archive. + */ +public final class ZipArchive extends PlainFile { + + //######################################################################## + // Public Factories + + /** Returns "fromFile(new File(path))". */ + public static AbstractFile fromPath(String path) { + return fromFile(new File(path)); + } + + /** + * If the specified File exists and is a readable zip archive, + * returns an abstract file backed by it. Otherwise, returns null. + */ + public static AbstractFile fromFile(File file) { + try { + return new ZipArchive(file, new ZipFile(file)); + } catch (IOException exception) { + return null; + } + } + + /** + * Returns an abstract directory backed by the specified archive. + */ + public static AbstractFile fromArchive(ZipFile archive) { + return new ZipArchive(new File(archive.getName()), archive); + } + + //######################################################################## + // Private Fields + + /** The zip archive */ + private final ZipFile archive; + + /** The root directory or null if not yet initialized */ + private DirEntry root; + + //######################################################################## + // Protected Constructors + + /** + * Initializes this instance with the specified File and ZipFile. + */ + protected ZipArchive(File file, ZipFile archive) { + super(file); + this.archive = archive; + assert archive != null; + } + + //######################################################################## + // Public Methods + + /** Returns true. */ + public boolean isDirectory() { + return true; + } + + /** Returns all abstract subfiles of this abstract directory. */ + public Iterator/*<AbstractFile>*/ list() { + if (root == null) load(); + return root.list(); + } + + /** + * Returns the abstract file in this abstract directory with the + * specified name. If there is no such file, returns null. The + * argument "directory" tells whether to look for a directory or + * or a regular file. + */ + public AbstractFile lookupName(String name, boolean directory) { + if (root == null) load(); + return root.lookupName(name, directory); + } + + //######################################################################## + // Private Methods + + /** Loads the archive and creates the root directory. */ + private void load() { + this.root = new DirEntry("<root>", "/"); + // A path to DirEntry map + HashMap/*<String,DirEntry>*/ dirs = new HashMap(); + dirs.put("/", root); + for (Enumeration e = archive.entries(); e.hasMoreElements(); ) { + ZipEntry entry = (ZipEntry)e.nextElement(); + String path = entry.getName(); + assert entry.isDirectory() == path.endsWith("/"): this +"-"+ path; + if (entry.isDirectory()) { + DirEntry dir = getDir(dirs, path); + assert dir.entry == null: this + " - " + path; + dir.entry = entry; + } else { + int index = path.lastIndexOf('/'); + String name = index < 0 ? path : path.substring(index + 1); + String home = index < 0 ? "/" : path.substring(0, index + 1); + DirEntry parent = getDir(dirs, home); + assert !parent.entries.containsKey(path): this + " - " + path; + parent.entries.put(path, new FileEntry(name, path, entry)); + } + } + } + + /** + * Lookups the specified table for a DirEntry with the specified + * path. If successful, returns the found DirEntry. Otherwise + * creates a new DirEntry, enters it into the table and in the + * table of its parent ZipDir and returns it. + */ + private DirEntry getDir(HashMap/*<String,DirEntry>*/ dirs, String path) { + DirEntry dir = (DirEntry)dirs.get(path); + if (dir == null) { + int index = path.lastIndexOf('/', path.length() - 2); + String name = index < 0 ? path : path.substring(index + 1); + String home = index < 0 ? "/" : path.substring(0, index + 1); + DirEntry parent = getDir(dirs, home); + dir = new DirEntry(name.substring(0, name.length() - 1), path); + parent.entries.put(name, dir); + dirs.put(path, dir); + } + return dir; + } + + //######################################################################## + // Private Class - Entry + + /** Superclass of archive entries */ + private abstract class Entry extends VirtualFile { + + public Entry(String name, String path) { + super(name, path); + } + + public final String getPath() { + return ZipArchive.this + "(" + super.getPath() + ")"; + } + + } + + //######################################################################## + // Private Class - DirEntry + + /** A directory archive entry */ + private final class DirEntry extends Entry { + + public final HashMap/*<String,Entry>*/ entries; + public ZipEntry entry; + + public DirEntry(String name, String path) { + super(name, path); + this.entries = new HashMap(); + } + + public boolean isDirectory() { + return true; + } + + public long lastModified() { + return entry != null ? entry.getTime() : super.lastModified(); + } + + public Iterator/*<AbstractFile>*/ list() { + return entries.values().iterator(); + } + + public AbstractFile lookupName(String name, boolean directory) { + return (AbstractFile)entries.get(directory ? name + "/" : name); + } + + } + + //######################################################################## + // Private Class - FileEntry + + /** A regular file archive entry */ + private final class FileEntry extends Entry { + + public final ZipEntry entry; + + public FileEntry(String name, String path, ZipEntry entry) { + super(name, path); + this.entry = entry; + } + + public long lastModified() { + return entry.getTime(); + } + + public byte[] read() throws IOException { + InputStream in = archive.getInputStream(entry); + int rest = (int)entry.getSize(); + byte[] buf = new byte[rest]; + do { + int res = in.read(buf, buf.length - rest, rest); + if (res == -1) + throw new IOException("read error"); + rest -= res; + } while (rest > 0); + in.close(); + return buf; + } + + } + + //######################################################################## +} diff --git a/sources/scalac/CompilerCommand.java b/sources/scalac/CompilerCommand.java index 80e60e4245..f1d4fa8605 100644 --- a/sources/scalac/CompilerCommand.java +++ b/sources/scalac/CompilerCommand.java @@ -12,7 +12,8 @@ import java.io.File; import java.util.ArrayList; import java.util.List; -import scalac.util.ClassPath; +import scala.tools.util.ClassPath; + import scalac.util.Reporter; import scalac.util.CommandParser; import scalac.util.ArgumentParser; diff --git a/sources/scalac/Global.java b/sources/scalac/Global.java index 30d385c016..d2d0df060d 100644 --- a/sources/scalac/Global.java +++ b/sources/scalac/Global.java @@ -23,6 +23,7 @@ import java.nio.charset.UnsupportedCharsetException; import java.util.*; import scala.tools.util.AbstractFile; +import scala.tools.util.ClassPath; import scala.tools.util.Position; import scala.tools.util.SourceFile; import scala.tools.util.SourceReader; @@ -299,7 +300,7 @@ public abstract class Global { /** Reads and returns the source file in file with given name. */ public SourceFile getSourceFile(String filename) throws IOException { - AbstractFile file = AbstractFile.open(null, filename); + AbstractFile file = AbstractFile.getFile(filename); if (file == null) throw new FileNotFoundException( "source file '" + filename + "' could not be found"); return getSourceFile(file); @@ -307,16 +308,14 @@ public abstract class Global { /** Reads and returns the source file in given abstract file. */ public SourceFile getSourceFile(AbstractFile file) throws IOException { - if (!file.exists()) throw new FileNotFoundException( - "source file '" + file + "' could not be found"); return new SourceFile(file, reader.read(file)); } /** Reads and returns the source file of given clasz. */ public SourceFile getSourceFile(Symbol clasz) throws IOException { assert clasz.isClass() && clasz.isStatic(): Debug.show(clasz); - AbstractFile file = classPath.openFile( - SourceRepresentation.externalizeFileName(clasz, ".scala")); + AbstractFile file = classPath.getRoot().lookupPath( + SourceRepresentation.externalizeFileName(clasz, ".scala"), false); if (file == null) throw new FileNotFoundException( "source file for " + clasz + " could not be found"); return getSourceFile(file); @@ -324,7 +323,7 @@ public abstract class Global { /** Returns the root symbol loader. */ public SymbolLoader getRootLoader() { - return new PackageParser(this); + return new PackageParser(this, classPath.getRoot()); } /** the top-level compilation process diff --git a/sources/scalac/symtab/classfile/CLRPackageParser.java b/sources/scalac/symtab/classfile/CLRPackageParser.java index decce98a26..51ba33edf6 100644 --- a/sources/scalac/symtab/classfile/CLRPackageParser.java +++ b/sources/scalac/symtab/classfile/CLRPackageParser.java @@ -75,7 +75,7 @@ public class CLRPackageParser extends SymbolLoader { private boolean initialized = false; public void init() { if (initialized) return; - scalac.util.ClassPath.addFilesInPath( + scala.tools.util.ClassPath.addFilesInPath( assemrefs, global.args.assemrefs.value); Assembly mscorlib = findAssembly("mscorlib.dll"); Type.initMSCORLIB(mscorlib); diff --git a/sources/scalac/symtab/classfile/PackageParser.java b/sources/scalac/symtab/classfile/PackageParser.java index c28a11f443..13882f7714 100644 --- a/sources/scalac/symtab/classfile/PackageParser.java +++ b/sources/scalac/symtab/classfile/PackageParser.java @@ -8,10 +8,8 @@ package scalac.symtab.classfile; -import java.io.IOException; import java.util.Iterator; import java.util.HashMap; -import java.util.HashSet; import scala.tools.util.AbstractFile; import scala.tools.util.Position; @@ -23,7 +21,6 @@ import scalac.symtab.Symbol; import scalac.symtab.SymbolLoader; import scalac.symtab.Type; import scalac.util.Name; -import scalac.util.SourceRepresentation; /** * This class implements a package member loader. It can be used to @@ -34,12 +31,16 @@ public class PackageParser extends SymbolLoader { //######################################################################## // Private Fields + /** The directory to read */ + private final AbstractFile directory; + //######################################################################## // Public Constructors /** Initializes this instance. */ - public PackageParser(Global global) { + public PackageParser(Global global, AbstractFile directory) { super(global); + this.directory = directory; } //######################################################################## @@ -47,43 +48,27 @@ public class PackageParser extends SymbolLoader { /** Completes the package symbol by loading all its members. */ protected String doComplete(Symbol peckage) { - boolean isRoot = peckage.isRoot(); - String dirname = isRoot ? null - : SourceRepresentation.externalizeFileName(peckage, "/"); - // collect JVM and source members + boolean isRoot = peckage.isRoot(); HashMap sources = new HashMap(); HashMap classes = new HashMap(); - HashSet packages = new HashSet(); - String[] base = global.classPath.components(); - for (int i = 0; i < base.length; i++) { - AbstractFile dir = AbstractFile.open(base[i], dirname); - if (dir == null) continue; - try { - String[] filenames = dir.list(); - if (filenames == null) continue; - for (int j = 0; j < filenames.length; j++) { - String fname = filenames[j]; - if (fname.endsWith("/") && !fname.equals("META-INF/")) { - String name = fname.substring(0, fname.length() - 1); - packages.add(name); - continue; - } - if (!isRoot && fname.endsWith(".class")) { - String name = fname.substring(0, fname.length() - 6); - if (!classes.containsKey(name)) - classes.put(name, dir.open(fname)); - continue; - } - if (!isRoot && fname.endsWith(".scala")) { - String name = fname.substring(0, fname.length() - 6); - if (!sources.containsKey(name)) - sources.put(name, dir.open(fname)); - continue; - } - } - } catch (IOException exception) { - if (global.debug) exception.printStackTrace(); + HashMap packages = new HashMap(); + for (Iterator i = directory.list(); i.hasNext(); ) { + AbstractFile file = (AbstractFile)i.next(); + String filename = file.getName(); + if (file.isDirectory()) { + if (filename.equals("META-INF")) continue; + packages.put(filename, file); + continue; + } + if (!isRoot && filename.endsWith(".class")) { + String name = filename.substring(0, filename.length() - 6); + if (!classes.containsKey(name)) classes.put(name, file); + continue; + } + if (!isRoot && filename.endsWith(".scala")) { + String name = filename.substring(0, filename.length() - 6); + if (!sources.containsKey(name)) sources.put(name, file); continue; } } @@ -115,9 +100,12 @@ public class PackageParser extends SymbolLoader { SymbolLoader loader = new ClassParser(global, cfile); peckage.newLoadedClass(JAVA, classname, loader, members); } - for (Iterator i = packages.iterator(); i.hasNext(); ) { - String name = (String)i.next(); - peckage.newLoadedPackage(Name.fromString(name), this, members); + for (Iterator i = packages.entrySet().iterator(); i.hasNext(); ) { + HashMap.Entry entry = (HashMap.Entry)i.next(); + String name = (String)entry.getKey(); + AbstractFile dfile = (AbstractFile)entry.getValue(); + SymbolLoader loader = new PackageParser(global, dfile); + peckage.newLoadedPackage(Name.fromString(name), loader, members); } // collect and create CLR members @@ -126,7 +114,7 @@ public class PackageParser extends SymbolLoader { // initialize package peckage.setInfo(Type.compoundType(Type.EMPTY_ARRAY, members, peckage)); - return dirname == null ? "anonymous package" : "package '"+dirname+"'"; + return "directory path '" + directory + "'"; } //######################################################################## |