summaryrefslogtreecommitdiff
path: root/sources
diff options
context:
space:
mode:
authormihaylov <mihaylov@epfl.ch>2004-09-09 16:11:30 +0000
committermihaylov <mihaylov@epfl.ch>2004-09-09 16:11:30 +0000
commitbb58768c2cd856127b31ccb98cb64a6d8b922487 (patch)
treeed8113e2f5881e7dbd9e1983cacac3a42f724936 /sources
parentea60f460774aa5878128a385f4bb1bb54cf4ee75 (diff)
downloadscala-bb58768c2cd856127b31ccb98cb64a6d8b922487.tar.gz
scala-bb58768c2cd856127b31ccb98cb64a6d8b922487.tar.bz2
scala-bb58768c2cd856127b31ccb98cb64a6d8b922487.zip
- Separated the JVM package parser from the CLR...
- Separated the JVM package parser from the CLR package parser
Diffstat (limited to 'sources')
-rw-r--r--sources/scalac/symtab/classfile/CLRPackageParser.java440
-rw-r--r--sources/scalac/symtab/classfile/CLRTypes.java312
-rw-r--r--sources/scalac/symtab/classfile/PackageParser.java86
3 files changed, 436 insertions, 402 deletions
diff --git a/sources/scalac/symtab/classfile/CLRPackageParser.java b/sources/scalac/symtab/classfile/CLRPackageParser.java
index 7ea2ab5d70..e50e1518b6 100644
--- a/sources/scalac/symtab/classfile/CLRPackageParser.java
+++ b/sources/scalac/symtab/classfile/CLRPackageParser.java
@@ -8,369 +8,133 @@
package scalac.symtab.classfile;
-import java.util.List;
import java.util.Iterator;
-import java.util.LinkedList;
import java.util.Map;
import java.util.HashMap;
import java.util.Set;
-import java.util.HashSet;
-import java.util.LinkedHashSet;
-import java.util.Arrays;
-import java.util.Comparator;
-
-import java.io.File;
import scala.tools.util.AbstractFile;
import scala.tools.util.ByteArrayFile;
import scalac.Global;
-import scalac.CompilerCommand;
import scalac.util.Debug;
import scalac.util.Name;
-import scalac.util.NameTransformer;
-import scalac.symtab.Modifiers;
+import scalac.symtab.Scope;
import scalac.symtab.Symbol;
+import scalac.symtab.Modifiers;
import scalac.symtab.SymbolLoader;
-import scalac.symtab.Scope;
+import scalac.symtab.SourceCompleter;
import scalac.symtab.SymbolNameWriter;
-import ch.epfl.lamp.compiler.msil.*;
+import ch.epfl.lamp.compiler.msil.Type;
+import ch.epfl.lamp.compiler.msil.Attribute;
/**
- * Collects all types from all reference assemblies.
+ * Package/namespace member loader for the CLR.
*/
-public final class CLRPackageParser {
+public final class CLRPackageParser extends PackageParser {
//##########################################################################
- private static CLRPackageParser instance;
-
- /** Return the unique instance of the CLRPackageParser class */
- public static CLRPackageParser instance() {
- assert instance != null;
- return instance;
- }
-
- /** Initialize the CLRPackageParser */
- public static void init(CompilerCommand args) {
- instance = new CLRPackageParser(args);
+ public CLRPackageParser(Global global, AbstractFile directory) {
+ super(global, directory);
}
- //##########################################################################
-
- public final Type BYTE;
- public final Type UBYTE;
- public final Type CHAR;
- public final Type SHORT;
- public final Type USHORT;
- public final Type INT;
- public final Type UINT;
- public final Type LONG;
- public final Type ULONG;
- public final Type FLOAT;
- public final Type DOUBLE;
- public final Type BOOLEAN;
- public final Type VOID;
- public final Type ENUM;
-
- public final Type OBJECT;
- public final Type STRING;
- public final Type STRING_ARRAY;
-
- public final Type SCALA_SYMTAB_ATTR;
-
private final SymbolNameWriter snw = new SymbolNameWriter();
- private final Type[] types;
-
- private final CompilerCommand args;
-
- private CLRPackageParser(CompilerCommand args) {
- this.args = args;
- scala.tools.util.ClassPath.addFilesInPath(
- assemrefs, args.assemrefs.value);
- Assembly mscorlib = findAssembly("mscorlib.dll");
- Type.initMSCORLIB(mscorlib);
- findAssembly("vjscor.dll");
- findAssembly("vjslib.dll");
- findAssembly("scala.dll");
- findAllAssemblies();
-
- BYTE = getType("System.SByte");
- UBYTE = getType("System.Byte");
- CHAR = getType("System.Char");
- SHORT = getType("System.Int16");
- USHORT = getType("System.UInt16");
- INT = getType("System.Int32");
- UINT = getType("System.UInt32");
- LONG = getType("System.Int64");
- ULONG = getType("System.UInt64");
- FLOAT = getType("System.Single");
- DOUBLE = getType("System.Double");
- BOOLEAN = getType("System.Boolean");
- VOID = getType("System.Void");
- ENUM = getType("System.Enum");
-
- OBJECT = getType("System.Object");
- STRING = getType("System.String");
- STRING_ARRAY = getType("System.String[]");
-
- SCALA_SYMTAB_ATTR = Type.GetType("scala.support.SymtabAttribute");
-
- Type[] types = Type.EmptyTypes;
- Iterator as = assemblies.iterator();
- while (as.hasNext()) {
- Type[] atypes = ((Assembly)as.next()).GetTypes();
- int j = 0;
- for (int i = 0; i < atypes.length; i++)
- // skip nested types
- if (atypes[i].DeclaringType == null)
- atypes[j++] = atypes[i];
- Type[] btypes = new Type[types.length + j];
- System.arraycopy(types, 0, btypes, 0, types.length);
- System.arraycopy(atypes, 0, btypes, types.length, j);
- types = btypes;
- }
- Comparator typeNameComparator = new Comparator() {
- public int compare(Object o1, Object o2) {
- Type t1 = (Type)o1;
- Type t2 = (Type)o2;
- return t1.FullName.compareTo(t2.FullName);
- }
- };
-
- Arrays.sort(types, typeNameComparator);
- this.types = types;
- }
-
- //##########################################################################
-
- private final Map syms2members = new HashMap();
- private final Map members2syms = new HashMap();
-
- public Type[] getTypes() { return types; }
-
- public void map(Symbol sym, MemberInfo m) {
- syms2members.put(sym, m);
- members2syms.put(m, sym);
- }
-
- public MemberInfo getMember(Symbol sym) {
- return (MemberInfo)syms2members.get(sym);
- }
-
- public Symbol getSymbol(MemberInfo m) {
- return (Symbol)members2syms.get(m);
- }
-
- public Type getType(String name) {
- Type t = Type.GetType(name);
- //assert t != null : name;
- return t;
- }
-
- public Type mkArrayType(Type elemType) {
- return getType(elemType.FullName + "[]");
- }
-
- //##########################################################################
- // assembly loading methods
-
- // a list of all loaded assemblies
- private final List assemblies = new LinkedList();
-
- // a set of all directories and assembly files
- private final Set/*<File>*/ assemrefs = new LinkedHashSet();
-
- /** Load the assembly with the given name
- */
- private Assembly findAssembly(String name) {
- // see if the assembly is referenced directly
- for (Iterator assems = assemrefs.iterator(); assems.hasNext();) {
- File file = (File)assems.next();
- if (!file.getName().equals(name))
- continue;
- Assembly assem = Assembly.LoadFrom(file.getPath());
- if (assem != null) {
- assems.remove();
- assemblies.add(assem);
- return assem;
- }
- }
- // look in directories specified with the '-r' option
- for (Iterator assems = assemrefs.iterator(); assems.hasNext();) {
- File d = (File)assems.next();
- if (!d.isDirectory())
- continue;
- File file = new File(d, name);
- if (file.exists()) {
- Assembly assem = Assembly.LoadFrom(file.getPath());
- if (assem != null) {
- assemblies.add(assem);
- return assem;
- }
- }
- }
- // try in the current directory
- File file = new File(".", name);
- if (file.exists()) {
- Assembly assem = Assembly.LoadFrom(file.getPath());
- if (assem != null) {
- assemblies.add(assem);
- return assem;
- }
- }
- //the Global instance is not yet constructed; use the Reporter from args
- args.reporter().error(null, "cannot find assembly " + name +
- "; use the -r option to specify its location");
- throw Debug.abort();
- }
-
- /** Load the rest of the assemblies specified with the '-r' option
- */
- private void findAllAssemblies() {
- for (Iterator assems = assemrefs.iterator(); assems.hasNext();) {
- File f = (File)assems.next();
- if (f.isFile()) {
- Assembly assem = Assembly.LoadFrom(f.getPath());
- if (assem != null) {
- assemblies.add(assem);
- }
- }
- assems.remove();
- }
- assert assemrefs.isEmpty();
- }
-
- //##########################################################################
- // collect the members contained in a given namespace
-
- private Symbol pakage;
- private HashMap/*<String,Type>*/ typesMap;
- private Set/*<String>*/ namespacesSet;
-
- private static final String[] BANNED = new String[] {
- "scala.AnyVal", "scala.Array", "scala.Boolean", "scala.Byte",
- "scala.Char", "scala.Double", "scala.Float", "scala.Function0",
- "scala.Function1", "scala.Function2", "scala.Function3",
- "scala.Function4", "scala.Function5", "scala.Function6",
- "scala.Function7", "scala.Function8", "scala.Function9", "scala.Int",
- "scala.Long", "scala.MatchError", "scala.Ref", "scala.ScalaObject",
- "scala.Short", "scala.Type", "scala.Unit", "scala.runtime.NativeLoop",
- "scala.runtime.ResultOrException", "scala.runtime.RunTime",
- "java.lang.CharSequence", "java.lang.StringBuffer", "java.lang.Byte",
- "java.lang.Float", "java.lang.Double", "java.lang.Cloneable"
- };
- private static final Set BANNED_TYPES = new HashSet();
- static {
- for (int i = 0; i < BANNED.length; i++) {
- BANNED_TYPES.add(BANNED[i]);
- }
- }
-
- /** Find the position of the first type whose name starts with
- * the given prefix; return the length of the types array if no match
- * is found so the result can be used to terminate loop conditions
- */
- private int findFirst(String prefix) {
- int m = 0, n = types.length - 1;
- while (m < n) {
- int l = (m + n) / 2;
- int res = types[l].FullName.compareTo(prefix);
- if (res < 0) m = l + 1;
- else n = l;
- }
- return types[m].FullName.startsWith(prefix) ? m : types.length;
- }
-
- /** Collects the members contained in the given Scala package (namespace)
- */
- private void enumerateMembers(Symbol pakage) {
- if (this.pakage == pakage)
- return;
- this.pakage = pakage;
- typesMap = new HashMap();
- namespacesSet = new LinkedHashSet();
-
- String namespace = pakage.isRoot() ? "" : snw.toString(pakage) + ".";
- int nl = namespace.length();
- for (int i = findFirst(namespace);
- i < types.length && types[i].FullName.startsWith(namespace);
- i++)
- {
- Type type = types[i];
- if (BANNED_TYPES.contains(type.FullName)
- || type.FullName.equals("java.lang.Object")
- || type.FullName.equals("java.lang.String")) {
- continue;
- }
- int k = type.FullName.indexOf(".", nl);
- if (k < 0) {
- typesMap.put(type.Name, type);
- } else {
- namespacesSet.add(type.Namespace.substring(nl, k));
- }
- }
- }
-
- /** return a mapping from type names to types contained
- * in the given Scala package (namespace)
- */
- HashMap getTypes(Symbol pakage) {
- enumerateMembers(pakage);
- return typesMap;
- }
-
- /** Returns a set of the namespaces contained
- * in the given Scala package (namespace)
- */
- Set getNamespaces(Symbol pakage) {
- enumerateMembers(pakage);
- return namespacesSet;
- }
-
- boolean shouldLoadClassfile(Symbol pakage, String name) {
- String fullname = snw.toString(pakage) + "." + name;
- return BANNED_TYPES.contains(fullname);
- }
-
- boolean shouldLoadClassfile(Symbol sym) {
- return BANNED_TYPES.contains(snw.toString(sym));
- }
-
- /** Imports a CLR type in a scala package (only called from PackageParser)
- */
- void importType(Type type, Symbol pakage, Scope members) {
- // discard top level types
- if (type.Namespace.equals("")) {
- return;
- }
-
- assert snw.toString(pakage).equals(type.Namespace)
- : Debug.show(pakage) + " << " + type.FullName;
- Object[] symtab_attr=type.GetCustomAttributes(SCALA_SYMTAB_ATTR, false);
- AbstractFile symtab = null;
- for (int l = 0; l < symtab_attr.length; l++) {
- MemberInfo.Attribute a = (MemberInfo.Attribute)symtab_attr[l];
- if (a.GetType() == SCALA_SYMTAB_ATTR) {
- symtab = new ByteArrayFile
- (type.FullName, "[" + type.Assembly.GetName() + "]",
- a.getValue());
- break;
- }
- }
- SymbolLoader loader = symtab != null
- ? new SymblParser(Global.instance, symtab)
- : new CLRClassParser(Global.instance, type);
-
- Name classname = Name.fromString(type.Name).toTypeName();
- Symbol clazz =
- pakage.newLoadedClass(Modifiers.JAVA, classname, loader, members);
- Type moduleType = getType(type.FullName + "$");
- map(clazz, type);
-// map(clazz, moduleType != null ? moduleType : type);
+ protected String doComplete(Symbol root) {
+ assert root.isRoot() || root.isPackage(): Debug.show(root);
+ Symbol peckage = root.isRoot() ? root : root.moduleClass();
+ if (directory != null)
+ preInitialize(peckage, false);
+
+ final CLRTypes clrTypes = CLRTypes.instance();
+ java.util.Map types = clrTypes.getTypes(peckage);
+ Set namespaces = clrTypes.getNamespaces(peckage);
+
+ // create JVM and source members
+ Scope members = new Scope();
+ for (Iterator i = sources.entrySet().iterator(); i.hasNext(); ) {
+ HashMap.Entry entry = (HashMap.Entry)i.next();
+ String name = (String)entry.getKey();
+ AbstractFile sfile = (AbstractFile)entry.getValue();
+ Type type = (Type)types.remove(name);
+ if (global.separate && type != null
+ /*&& type.Assembly().getFile().lastModified() > sfile.lastModified()*/
+ )
+ {
+ types.put(name, type);
+ } else {
+ packages.remove(name);
+ Name classname = Name.fromString(name).toTypeName();
+ SymbolLoader loader = new SourceCompleter(global, sfile);
+ peckage.newLoadedClass(0, classname, loader, members);
+ }
+ }
+
+ // import the CLR types contained in the package (namespace)
+ for (Iterator i = types.values().iterator(); i.hasNext(); ) {
+ Type type = (Type)i.next();
+
+ // discard top level types
+ if (type.Namespace.equals("")) {
+ Global.instance.operation("Ignoring top-level type " + type);
+ continue;
+ }
+
+ assert snw.toString(peckage).equals(type.Namespace)
+ : Debug.show(peckage) + " << " + type.FullName;
+ AbstractFile symfile = null;
+ if (type.IsDefined(clrTypes.SCALA_SYMTAB_ATTR, false)) {
+ Object[] attrs = type.GetCustomAttributes
+ (clrTypes.SCALA_SYMTAB_ATTR, false);
+ assert attrs.length == 1 : attrs.length;
+ Attribute a = (Attribute)attrs[0];
+ assert a.GetType() == clrTypes.SCALA_SYMTAB_ATTR : a.toString();
+ byte[] symtab = (byte[])a.getConstructorArguments()[0];
+ symfile = new ByteArrayFile
+ (type.FullName, "[" + type.Assembly().GetName() + "]",
+ symtab);
+ }
+ SymbolLoader loader = symfile != null
+ ? new SymblParser(Global.instance, symfile)
+ : new CLRClassParser(Global.instance, type);
+
+ Name classname = Name.fromString(type.Name).toTypeName();
+ Symbol clazz = peckage.newLoadedClass
+ (Modifiers.JAVA, classname, loader, members);
+ clrTypes.map(clazz, type);
+ //Type moduleType = getType(type.FullName + "$");
+ //map(clazz, moduleType != null ? moduleType : type);
+ }
+
+ 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 CLRPackageParser(global, dfile);
+ peckage.newLoadedPackage(Name.fromString(name), loader, members);
+ namespaces.remove(name);
+ }
+
+ // import the CLR namespaces contained in the package (namespace)
+ for (Iterator i = namespaces.iterator(); i.hasNext(); ) {
+ String namespace = (String)i.next();
+ Name name = Name.fromString(namespace);
+ Symbol p = members.lookup(name);
+ if (p == Symbol.NONE) {
+ SymbolLoader loader = new CLRPackageParser(global, null);
+ peckage.newLoadedPackage(name, this, members);
+ } else {
+ System.out.println("package already in scope: " + Debug.show(p));
+ }
+ }
+
+ // initialize package
+ peckage.setInfo(scalac.symtab.Type.compoundType
+ (scalac.symtab.Type.EMPTY_ARRAY, members, peckage));
+ return "namespace '" + snw.toString(peckage) + "'";
}
//##########################################################################
-} // CLRPackageParser
+} // CLRPackageParser
diff --git a/sources/scalac/symtab/classfile/CLRTypes.java b/sources/scalac/symtab/classfile/CLRTypes.java
new file mode 100644
index 0000000000..11ff2a11d7
--- /dev/null
+++ b/sources/scalac/symtab/classfile/CLRTypes.java
@@ -0,0 +1,312 @@
+/* ____ ____ ____ ____ ______ *\
+** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala **
+** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL **
+** /_____/\____/\___/\____/____/ **
+\* */
+
+// $Id$
+
+package scalac.symtab.classfile;
+
+import java.util.List;
+import java.util.LinkedList;
+import java.util.Map;
+import java.util.HashMap;
+import java.util.Set;
+import java.util.LinkedHashSet;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.Comparator;
+
+import java.io.File;
+
+import scalac.Global;
+import scalac.CompilerCommand;
+import scalac.util.Debug;
+import scalac.util.Name;
+import scalac.symtab.Symbol;
+import scalac.symtab.SymbolNameWriter;
+
+import ch.epfl.lamp.compiler.msil.*;
+
+/**
+ * Collects all types from all reference assemblies.
+ */
+public final class CLRTypes {
+
+ //##########################################################################
+
+ private static CLRTypes instance;
+
+ /** Return the unique instance of the CLRTypes class */
+ public static CLRTypes instance() {
+ assert instance != null;
+ return instance;
+ }
+
+ /** Initialize the CLRTypes */
+ public static void init(CompilerCommand args) {
+ instance = new CLRTypes(args);
+ }
+
+ //##########################################################################
+
+ public final Type BYTE;
+ public final Type UBYTE;
+ public final Type CHAR;
+ public final Type SHORT;
+ public final Type USHORT;
+ public final Type INT;
+ public final Type UINT;
+ public final Type LONG;
+ public final Type ULONG;
+ public final Type FLOAT;
+ public final Type DOUBLE;
+ public final Type BOOLEAN;
+ public final Type VOID;
+ public final Type ENUM;
+
+ public final Type OBJECT;
+ public final Type STRING;
+ public final Type STRING_ARRAY;
+
+ public final Type SCALA_SYMTAB_ATTR;
+
+ public final Type PICO_META_ATTR;
+
+ private final SymbolNameWriter snw = new SymbolNameWriter();
+
+ private Type[] types;
+
+ private final CompilerCommand args;
+
+ private CLRTypes(CompilerCommand args) {
+ this.args = args;
+ scala.tools.util.ClassPath.addFilesInPath(
+ assemrefs, args.assemrefs.value);
+ Assembly mscorlib = findAssembly("mscorlib.dll");
+ Type.initMSCORLIB(mscorlib);
+ findAssembly("vjscor.dll");
+ findAssembly("vjslib.dll");
+ findAssembly("scala.dll");
+ findAllAssemblies();
+
+ BYTE = getType("System.SByte");
+ UBYTE = getType("System.Byte");
+ CHAR = getType("System.Char");
+ SHORT = getType("System.Int16");
+ USHORT = getType("System.UInt16");
+ INT = getType("System.Int32");
+ UINT = getType("System.UInt32");
+ LONG = getType("System.Int64");
+ ULONG = getType("System.UInt64");
+ FLOAT = getType("System.Single");
+ DOUBLE = getType("System.Double");
+ BOOLEAN = getType("System.Boolean");
+ VOID = getType("System.Void");
+ ENUM = getType("System.Enum");
+
+ OBJECT = getType("System.Object");
+ STRING = getType("System.String");
+ STRING_ARRAY = getType("System.String[]");
+
+ SCALA_SYMTAB_ATTR = Type.GetType("scala.runtime.SymtabAttribute");
+ PICO_META_ATTR = Type.GetType("scala.runtime.MetaAttribute");
+
+ assert PICO_META_ATTR != null;
+
+ Type[] types = Type.EmptyTypes;
+ Iterator as = assemblies.iterator();
+ while (as.hasNext()) {
+ Type[] atypes = ((Assembly)as.next()).GetTypes();
+ int j = 0;
+ for (int i = 0; i < atypes.length; i++)
+ // skip nested types
+ if (atypes[i].DeclaringType == null)
+ atypes[j++] = atypes[i];
+ Type[] btypes = new Type[types.length + j];
+ System.arraycopy(types, 0, btypes, 0, types.length);
+ System.arraycopy(atypes, 0, btypes, types.length, j);
+ types = btypes;
+ }
+
+ Comparator typeNameComparator =
+ new Comparator() {
+ public int compare(Object o1, Object o2) {
+ Type t1 = (Type)o1;
+ Type t2 = (Type)o2;
+ return t1.FullName.compareTo(t2.FullName);
+ }
+ };
+
+ Arrays.sort(types, typeNameComparator);
+ this.types = types;
+ }
+
+ //##########################################################################
+ // type mapping and lookup
+
+ private final Map syms2members = new HashMap();
+ private final Map members2syms = new HashMap();
+
+ public void map(Symbol sym, MemberInfo m) {
+ syms2members.put(sym, m);
+ members2syms.put(m, sym);
+ }
+
+ public MemberInfo getMember(Symbol sym) {
+ return (MemberInfo)syms2members.get(sym);
+ }
+
+ public Symbol getSymbol(MemberInfo m) {
+ return (Symbol)members2syms.get(m);
+ }
+
+ public Type getType(String name) {
+ Type t = Type.GetType(name);
+ //assert t != null : name;
+ return t;
+ }
+
+ public Type mkArrayType(Type elemType) {
+ return getType(elemType.FullName + "[]");
+ }
+
+ //##########################################################################
+ // assembly loading methods
+
+ // a list of all loaded assemblies
+ private final List assemblies = new LinkedList();
+
+ // a set of all directories and assembly files
+ private final Set/*<File>*/ assemrefs = new LinkedHashSet();
+
+ /** Load the assembly with the given name
+ */
+ private Assembly findAssembly(String name) {
+ // see if the assembly is referenced directly
+ for (Iterator assems = assemrefs.iterator(); assems.hasNext();) {
+ File file = (File)assems.next();
+ if (!file.getName().equals(name))
+ continue;
+ Assembly assem = Assembly.LoadFrom(file.getPath());
+ if (assem != null) {
+ assems.remove();
+ assemblies.add(assem);
+ return assem;
+ }
+ }
+ // look in directories specified with the '-r' option
+ for (Iterator assems = assemrefs.iterator(); assems.hasNext();) {
+ File d = (File)assems.next();
+ if (!d.isDirectory())
+ continue;
+ File file = new File(d, name);
+ if (file.exists()) {
+ Assembly assem = Assembly.LoadFrom(file.getPath());
+ if (assem != null) {
+ assemblies.add(assem);
+ return assem;
+ }
+ }
+ }
+ // try in the current directory
+ File file = new File(".", name);
+ if (file.exists()) {
+ Assembly assem = Assembly.LoadFrom(file.getPath());
+ if (assem != null) {
+ assemblies.add(assem);
+ return assem;
+ }
+ }
+ //the Global instance is not yet constructed; use the Reporter from args
+ args.reporter().error(null, "cannot find assembly " + name +
+ "; use the -r option to specify its location");
+ throw Debug.abort();
+ }
+
+ /** Load the rest of the assemblies specified with the '-r' option
+ */
+ private void findAllAssemblies() {
+ for (Iterator assems = assemrefs.iterator(); assems.hasNext();) {
+ File f = (File)assems.next();
+ if (f.isFile()) {
+ Assembly assem = Assembly.LoadFrom(f.getPath());
+ if (assem != null) {
+ assemblies.add(assem);
+ }
+ }
+ assems.remove();
+ }
+ assert assemrefs.isEmpty();
+ }
+
+ //##########################################################################
+ // collect the members contained in a given namespace
+
+ private Symbol pakage;
+ private Map/*<String,Type>*/ typesMap;
+ private Set/*<String>*/ namespacesSet;
+
+ /** Find the position of the first type whose name starts with
+ * the given prefix; return the length of the types array if no match
+ * is found so the result can be used to terminate loop conditions
+ */
+ private int findFirst(String prefix) {
+ int m = 0, n = types.length - 1;
+ while (m < n) {
+ int l = (m + n) / 2;
+ int res = types[l].FullName.compareTo(prefix);
+ if (res < 0) m = l + 1;
+ else n = l;
+ }
+ return types[m].FullName.startsWith(prefix) ? m : types.length;
+ }
+
+ /** Collects the members contained in the given Scala package (namespace)
+ */
+ private void enumerateMembers(Symbol pakage) {
+ if (this.pakage == pakage)
+ return;
+ this.pakage = pakage;
+ typesMap = new HashMap();
+ namespacesSet = new LinkedHashSet();
+
+ String namespace = pakage.isRoot() ? "" : snw.toString(pakage) + ".";
+ int nl = namespace.length();
+ for (int i = findFirst(namespace);
+ i < types.length && types[i].FullName.startsWith(namespace);
+ i++)
+ {
+ Type type = types[i];
+ if (type.FullName.equals("java.lang.Object")
+ || type.FullName.equals("java.lang.String")) {
+ continue;
+ }
+ int k = type.FullName.indexOf(".", nl);
+ if (k < 0) {
+ typesMap.put(type.Name, type);
+ } else {
+ namespacesSet.add(type.Namespace.substring(nl, k));
+ }
+ }
+ }
+
+ /** return a mapping from type names to types contained
+ * in the given Scala package (namespace)
+ */
+ Map getTypes(Symbol pakage) {
+ enumerateMembers(pakage);
+ return typesMap;
+ }
+
+ /** Returns a set of the namespaces contained
+ * in the given Scala package (namespace)
+ */
+ Set getNamespaces(Symbol pakage) {
+ enumerateMembers(pakage);
+ return namespacesSet;
+ }
+
+ //##########################################################################
+} // CLRTypes
diff --git a/sources/scalac/symtab/classfile/PackageParser.java b/sources/scalac/symtab/classfile/PackageParser.java
index 710c16ea48..415ee7a3b4 100644
--- a/sources/scalac/symtab/classfile/PackageParser.java
+++ b/sources/scalac/symtab/classfile/PackageParser.java
@@ -9,8 +9,8 @@
package scalac.symtab.classfile;
import java.util.Iterator;
+import java.util.Map;
import java.util.HashMap;
-import java.util.Set;
import scala.tools.util.AbstractFile;
import scala.tools.util.Position;
@@ -36,12 +36,7 @@ public class PackageParser extends SymbolLoader {
// Private Fields
/** The directory to read */
- private final AbstractFile directory;
-
- /** Are we targeting the MSIL? */
- private boolean forMSIL;
-
- private final CLRPackageParser clrParser;
+ protected final AbstractFile directory;
//########################################################################
// Public Constructors
@@ -50,22 +45,18 @@ public class PackageParser extends SymbolLoader {
public PackageParser(Global global, AbstractFile directory) {
super(global);
this.directory = directory;
- this.forMSIL = global.target == global.TARGET_MSIL;
- this.clrParser = forMSIL ? CLRPackageParser.instance() : null;
}
//########################################################################
// Protected Methods
- /** Completes the package symbol by loading all its members. */
- protected String doComplete(Symbol root) {
- assert root.isRoot() || root.isPackage(): Debug.show(root);
- Symbol peckage = root.isRoot() ? root : root.moduleClass();
- // collect JVM and source members
- boolean isRoot = peckage.isRoot();
- HashMap sources = new HashMap();
- HashMap classes = new HashMap();
- HashMap packages = new HashMap();
+ protected java.util.Map sources = new HashMap();
+ protected java.util.Map classes = new HashMap();
+ protected java.util.Map packages = new HashMap();
+
+ // collect JVM and source members
+ protected void preInitialize(Symbol root, boolean loadClassfiles) {
+ boolean isRoot = root.isRoot();
for (Iterator i = directory.list(); i.hasNext(); ) {
AbstractFile file = (AbstractFile)i.next();
String filename = file.getName();
@@ -74,7 +65,7 @@ public class PackageParser extends SymbolLoader {
packages.put(filename, file);
continue;
}
- if (!isRoot && filename.endsWith(".class")) {
+ if (!isRoot && loadClassfiles && filename.endsWith(".class")) {
String name = filename.substring(0, filename.length() - 6);
if (!classes.containsKey(name)) classes.put(name, file);
continue;
@@ -85,14 +76,13 @@ public class PackageParser extends SymbolLoader {
continue;
}
}
+ }
- HashMap types = null;
- Set namespaces = null;
- ch.epfl.lamp.compiler.msil.Type type = null;
- if (forMSIL) {
- types = clrParser.getTypes(peckage);
- namespaces = clrParser.getNamespaces(peckage);
- }
+ /** Completes the package symbol by loading all its members. */
+ protected String doComplete(Symbol root) {
+ assert root.isRoot() || root.isPackage(): Debug.show(root);
+ Symbol peckage = root.isRoot() ? root : root.moduleClass();
+ preInitialize(peckage, true);
// create JVM and source members
Scope members = new Scope();
@@ -101,16 +91,7 @@ public class PackageParser extends SymbolLoader {
String name = (String)entry.getKey();
AbstractFile sfile = (AbstractFile)entry.getValue();
AbstractFile cfile = (AbstractFile)classes.remove(name);
- if (forMSIL) {
- type = (ch.epfl.lamp.compiler.msil.Type)types.remove(name);
- if (global.separate && forMSIL && type != null) {
-// if (type.Assembly.getFile().lastModified()
-// > sfile.lastModified()) {
- types.put(name, type);
- continue;
-// }
- }
- } else if (global.separate && cfile != null) {
+ if (global.separate && cfile != null) {
if (cfile.lastModified() > sfile.lastModified()) {
classes.put(name, cfile);
continue;
@@ -126,44 +107,21 @@ public class PackageParser extends SymbolLoader {
HashMap.Entry entry = (HashMap.Entry)i.next();
String name = (String)entry.getKey();
//assert !types.containsKey(name) : types.get(name);
- if (!forMSIL || clrParser.shouldLoadClassfile(peckage, name)) {
- AbstractFile cfile = (AbstractFile)entry.getValue();
- packages.remove(name);
- Name classname = Name.fromString(name).toTypeName();
- SymbolLoader loader = new ClassParser(global, cfile);
- peckage.newLoadedClass(JAVA, classname, loader, members);
- }
+ AbstractFile cfile = (AbstractFile)entry.getValue();
+ packages.remove(name);
+ Name classname = Name.fromString(name).toTypeName();
+ SymbolLoader loader = new ClassParser(global, cfile);
+ peckage.newLoadedClass(JAVA, classname, loader, members);
}
- if (forMSIL) {
- // import the CLR types contained in the package (namespace)
- for (Iterator i = types.values().iterator(); i.hasNext(); ) {
- type = (ch.epfl.lamp.compiler.msil.Type)i.next();
- clrParser.importType(type, peckage, 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);
- if (forMSIL)
- namespaces.remove(name);
}
- if (forMSIL) {
- // import the CLR namespaces contained in the package (namespace)
- for (Iterator i = namespaces.iterator(); i.hasNext(); ) {
- String namespace = (String)i.next();
- Name name = Name.fromString(namespace);
- if (members.lookup(name) == Symbol.NONE) {
- peckage.newLoadedPackage(name, this, members);
- }
- }
- }
-
// initialize package
peckage.setInfo(Type.compoundType(Type.EMPTY_ARRAY, members, peckage));
return "directory path '" + directory + "'";