diff options
author | paltherr <paltherr@epfl.ch> | 2004-12-02 09:21:07 +0000 |
---|---|---|
committer | paltherr <paltherr@epfl.ch> | 2004-12-02 09:21:07 +0000 |
commit | e3198c669cce304ea1f86fd7f6cf919d0e54177a (patch) | |
tree | 91cf49e1e006ae2f4327ae8b66b935a1d8b15600 /sources/scalac/symtab | |
parent | 23f795a322eeca5f44a8f5e297ec38f475bfa2ac (diff) | |
download | scala-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.java | 137 | ||||
-rw-r--r-- | sources/scalac/symtab/classfile/CLRTypes.java | 34 | ||||
-rw-r--r-- | sources/scalac/symtab/classfile/PackageParser.java | 107 |
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 + "'"; } |