summaryrefslogtreecommitdiff
path: root/sources/scalac/symtab
diff options
context:
space:
mode:
authorpaltherr <paltherr@epfl.ch>2004-12-02 09:21:07 +0000
committerpaltherr <paltherr@epfl.ch>2004-12-02 09:21:07 +0000
commite3198c669cce304ea1f86fd7f6cf919d0e54177a (patch)
tree91cf49e1e006ae2f4327ae8b66b935a1d8b15600 /sources/scalac/symtab
parent23f795a322eeca5f44a8f5e297ec38f475bfa2ac (diff)
downloadscala-e3198c669cce304ea1f86fd7f6cf919d0e54177a.tar.gz
scala-e3198c669cce304ea1f86fd7f6cf919d0e54177a.tar.bz2
scala-e3198c669cce304ea1f86fd7f6cf919d0e54177a.zip
- In [CLR]PackageParser split doComplete/preIni...
- In [CLR]PackageParser split doComplete/preInitialize into four methods
Diffstat (limited to 'sources/scalac/symtab')
-rw-r--r--sources/scalac/symtab/classfile/CLRPackageParser.java137
-rw-r--r--sources/scalac/symtab/classfile/CLRTypes.java34
-rw-r--r--sources/scalac/symtab/classfile/PackageParser.java107
3 files changed, 146 insertions, 132 deletions
diff --git a/sources/scalac/symtab/classfile/CLRPackageParser.java b/sources/scalac/symtab/classfile/CLRPackageParser.java
index e50e1518b6..4ad89311c2 100644
--- a/sources/scalac/symtab/classfile/CLRPackageParser.java
+++ b/sources/scalac/symtab/classfile/CLRPackageParser.java
@@ -9,22 +9,19 @@
package scalac.symtab.classfile;
import java.util.Iterator;
-import java.util.Map;
import java.util.HashMap;
-import java.util.Set;
+import java.util.HashSet;
import scala.tools.util.AbstractFile;
import scala.tools.util.ByteArrayFile;
+import scala.tools.util.VirtualDirectory;
import scalac.Global;
import scalac.util.Debug;
import scalac.util.Name;
import scalac.symtab.Scope;
import scalac.symtab.Symbol;
-import scalac.symtab.Modifiers;
import scalac.symtab.SymbolLoader;
-import scalac.symtab.SourceCompleter;
-import scalac.symtab.SymbolNameWriter;
import ch.epfl.lamp.compiler.msil.Type;
import ch.epfl.lamp.compiler.msil.Attribute;
@@ -34,63 +31,89 @@ import ch.epfl.lamp.compiler.msil.Attribute;
*/
public final class CLRPackageParser extends PackageParser {
- //##########################################################################
+ //########################################################################
+ // Private Constants
+
+ /** An empty directory */
+ private static final AbstractFile EMPTY = new VirtualDirectory("<empty>");
+
+ //########################################################################
+ // Protected Fields
+
+ /** A table to collect types */
+ protected final HashMap types = new HashMap();
+
+ //########################################################################
+ // Public Constructors
public CLRPackageParser(Global global, AbstractFile directory) {
super(global, directory);
}
- private final SymbolNameWriter snw = new SymbolNameWriter();
+ //########################################################################
+ // Protected Methods
- 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);
+ protected PackageParser newPackageParser(AbstractFile directory) {
+ return new CLRPackageParser(global, directory);
+ }
- final CLRTypes clrTypes = CLRTypes.instance();
- java.util.Map types = clrTypes.getTypes(peckage);
- Set namespaces = clrTypes.getNamespaces(peckage);
+ protected void collectAllMembers(Symbol clasz) {
+ super.collectAllMembers(clasz);
+ HashSet namespaces = new HashSet();
+ CLRTypes.instance().collectMembers(clasz, types, namespaces);
+ for (Iterator i = namespaces.iterator(); i.hasNext(); ) {
+ String namespace = (String)i.next();
+ if (!packages.containsKey(namespace))
+ packages.put(namespace, EMPTY);
+ }
+ }
- // create JVM and source members
- Scope members = new Scope();
+ protected void removeHiddenMembers(Symbol clasz) {
+ // Ignore all ".class" files.
+ classes.clear();
+ super.removeHiddenMembers(clasz);
+ // Classes/Objects in the root package are hidden.
+ if (clasz.isRoot()) { types.clear(); }
+ // Source versions hide compiled versions except if separate
+ // compilation is enabled and the compiled version is more
+ // recent. In that case the compiled version hides the source
+ // version.
+ boolean separate = global.separate;
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);
- }
+ Type type = (Type)types.get(name);
+ boolean hidden = false;
+ if (type != null)
+ if (separate /* !!! && type.Assembly().getFile().lastModified() > sfile.lastModified() */)
+ hidden = true;
+ else
+ types.remove(name);
+ if (hidden) i.remove();
}
+ // Packages are hidden by classes/objects with the same name.
+ packages.keySet().removeAll(types.keySet());
+ }
+
+ protected Scope createMemberSymbols(Symbol clasz) {
+ CLRTypes clrTypes = CLRTypes.instance();
+ String namespace = clrTypes.getNameSpaceOf(clasz);
+ Scope members = super.createMemberSymbols(clasz);
// 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;
+ assert namespace.equals(type.Namespace)
+ : Debug.show(clasz, namespace) + " << " + 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();
+ assert a.GetType() == clrTypes.SCALA_SYMTAB_ATTR : a.toString();
byte[] symtab = (byte[])a.getConstructorArguments()[0];
symfile = new ByteArrayFile
(type.FullName, "[" + type.Assembly().GetName() + "]",
@@ -101,40 +124,22 @@ public final class CLRPackageParser extends PackageParser {
: new CLRClassParser(Global.instance, type);
Name classname = Name.fromString(type.Name).toTypeName();
- Symbol clazz = peckage.newLoadedClass
- (Modifiers.JAVA, classname, loader, members);
+ Symbol clazz = clasz.newLoadedClass
+ (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));
- }
- }
+ return members;
+ }
- // initialize package
- peckage.setInfo(scalac.symtab.Type.compoundType
- (scalac.symtab.Type.EMPTY_ARRAY, members, peckage));
- return "namespace '" + snw.toString(peckage) + "'";
+ protected String doComplete(Symbol root) {
+ String base = super.doComplete(root);
+ base = directory == EMPTY ? "" : base + " and ";
+ String namespace = CLRTypes.instance().getNameSpaceOf(root);
+ return base + "namespace '" + namespace + "'";
}
- //##########################################################################
+ //########################################################################
} // CLRPackageParser
diff --git a/sources/scalac/symtab/classfile/CLRTypes.java b/sources/scalac/symtab/classfile/CLRTypes.java
index 71a4112a10..945261ab47 100644
--- a/sources/scalac/symtab/classfile/CLRTypes.java
+++ b/sources/scalac/symtab/classfile/CLRTypes.java
@@ -244,10 +244,6 @@ public final class CLRTypes {
//##########################################################################
// 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
@@ -265,14 +261,10 @@ public final class CLRTypes {
/** 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 = getNameSpaceOf(pakage);
+ void collectMembers(Symbol pakage, Map/*<String,Type>*/ typesMap,
+ Set/*<String>*/ namespacesSet)
+ {
+ String namespace = pakage.isRoot() ? "" : snw.toString(pakage) + ".";
int nl = namespace.length();
for (int i = findFirst(namespace);
i < types.length && types[i].FullName.startsWith(namespace);
@@ -292,26 +284,10 @@ public final class CLRTypes {
}
}
- /** 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;
- }
-
/** Returns the namespace of the given package */
String getNameSpaceOf(Symbol pakage) {
assert pakage.hasPackageFlag() || pakage.isRoot(): Debug.show(pakage);
- return pakage.isRoot() ? "" : snw.toString(pakage) + ".";
+ return pakage.isRoot() ? "" : snw.toString(pakage);
}
//##########################################################################
diff --git a/sources/scalac/symtab/classfile/PackageParser.java b/sources/scalac/symtab/classfile/PackageParser.java
index 415ee7a3b4..86b62fa6c8 100644
--- a/sources/scalac/symtab/classfile/PackageParser.java
+++ b/sources/scalac/symtab/classfile/PackageParser.java
@@ -9,11 +9,9 @@
package scalac.symtab.classfile;
import java.util.Iterator;
-import java.util.Map;
import java.util.HashMap;
import scala.tools.util.AbstractFile;
-import scala.tools.util.Position;
import scalac.Global;
import scalac.symtab.Scope;
@@ -24,8 +22,6 @@ import scalac.symtab.Type;
import scalac.util.Name;
import scalac.util.Debug;
-import scalac.symtab.SymbolNameWriter;
-
/**
* This class implements a package member loader. It can be used to
* complete package class symbols.
@@ -33,11 +29,18 @@ import scalac.symtab.SymbolNameWriter;
public class PackageParser extends SymbolLoader {
//########################################################################
- // Private Fields
+ // Protected Fields
/** The directory to read */
protected final AbstractFile directory;
+ /** A table to collect .scala files */
+ protected final HashMap/*<String,AbstractFile>*/ sources = new HashMap();
+ /** A table to collect .class files */
+ protected final HashMap/*<String,AbstractFile>*/ classes = new HashMap();
+ /** A table to collect subdirectories */
+ protected final HashMap/*<String,AbstractFile>*/ packages = new HashMap();
+
//########################################################################
// Public Constructors
@@ -45,18 +48,22 @@ public class PackageParser extends SymbolLoader {
public PackageParser(Global global, AbstractFile directory) {
super(global);
this.directory = directory;
+ assert directory != null;
}
//########################################################################
// Protected Methods
- protected java.util.Map sources = new HashMap();
- protected java.util.Map classes = new HashMap();
- protected java.util.Map packages = new HashMap();
+ /** Returns a new package parser for the given directory. */
+ protected PackageParser newPackageParser(AbstractFile directory) {
+ return new PackageParser(global, directory);
+ }
- // collect JVM and source members
- protected void preInitialize(Symbol root, boolean loadClassfiles) {
- boolean isRoot = root.isRoot();
+ /**
+ * Collects all members of the package. This method is invoked by
+ * method "doComplete". It should not be invoked otherwise.
+ */
+ protected void collectAllMembers(Symbol clasz) {
for (Iterator i = directory.list(); i.hasNext(); ) {
AbstractFile file = (AbstractFile)i.next();
String filename = file.getName();
@@ -65,12 +72,12 @@ public class PackageParser extends SymbolLoader {
packages.put(filename, file);
continue;
}
- if (!isRoot && loadClassfiles && filename.endsWith(".class")) {
+ if (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")) {
+ if (filename.endsWith(".scala")) {
String name = filename.substring(0, filename.length() - 6);
if (!sources.containsKey(name)) sources.put(name, file);
continue;
@@ -78,52 +85,78 @@ public class PackageParser extends SymbolLoader {
}
}
- /** 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);
+ /**
+ * Removes from the members collected by "collectAllMembers" all
+ * those that are hidden. This method is invoked by method
+ * "doComplete". It should not be invoked otherwise.
+ */
+ protected void removeHiddenMembers(Symbol clasz) {
+ // Classes/Objects in the root package are hidden.
+ if (clasz.isRoot()) { sources.clear(); classes.clear(); }
+ // Source versions hide compiled versions except if separate
+ // compilation is enabled and the compiled version is more
+ // recent. In that case the compiled version hides the source
+ // version.
+ boolean separate = global.separate;
+ 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();
+ AbstractFile cfile = (AbstractFile)classes.get(name);
+ boolean hidden = false;
+ if (cfile != null)
+ if (separate && cfile.lastModified() > sfile.lastModified())
+ hidden = true;
+ else
+ classes.remove(name);
+ if (hidden) i.remove();
+ }
+ // Packages are hidden by classes/objects with the same name.
+ packages.keySet().removeAll(sources.keySet());
+ packages.keySet().removeAll(classes.keySet());
+ }
- // create JVM and source members
+ /**
+ * Creates symbols for all members left by method
+ * "removeHiddenMembers". This method is invoked by method
+ * "doComplete". It should not be invoked otherwise.
+ */
+ protected Scope createMemberSymbols(Symbol clasz) {
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();
- AbstractFile cfile = (AbstractFile)classes.remove(name);
- if (global.separate && cfile != null) {
- if (cfile.lastModified() > sfile.lastModified()) {
- classes.put(name, cfile);
- continue;
- }
- }
- packages.remove(name);
Name classname = Name.fromString(name).toTypeName();
SymbolLoader loader = new SourceCompleter(global, sfile);
- peckage.newLoadedClass(0, classname, loader, members);
+ clasz.newLoadedClass(0, classname, loader, members);
}
-
for (Iterator i = classes.entrySet().iterator(); i.hasNext(); ) {
HashMap.Entry entry = (HashMap.Entry)i.next();
String name = (String)entry.getKey();
- //assert !types.containsKey(name) : types.get(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);
+ clasz.newLoadedClass(JAVA, classname, loader, 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);
+ SymbolLoader loader = newPackageParser(dfile);
+ clasz.newLoadedPackage(Name.fromString(name), loader, members);
}
+ return members;
+ }
- // initialize package
- peckage.setInfo(Type.compoundType(Type.EMPTY_ARRAY, members, peckage));
+ /** Completes the package symbol by loading all its members. */
+ protected String doComplete(Symbol root) {
+ assert root.isRoot() || root.isPackage(): Debug.show(root);
+ Symbol clasz = root.isRoot() ? root : root.moduleClass();
+ collectAllMembers(clasz);
+ removeHiddenMembers(clasz);
+ Scope members = createMemberSymbols(clasz);
+ clasz.setInfo(Type.compoundType(Type.EMPTY_ARRAY, members, clasz));
return "directory path '" + directory + "'";
}