summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpaltherr <paltherr@epfl.ch>2004-04-14 13:31:35 +0000
committerpaltherr <paltherr@epfl.ch>2004-04-14 13:31:35 +0000
commit3ec2af254866c60389b3fd304c14d1137b9cf4c8 (patch)
treec4cb09396b20ca0a2412930c891cee3566c7a2c6
parentfbd9b93cc4f10e90da94d963f3e052803e93acfd (diff)
downloadscala-3ec2af254866c60389b3fd304c14d1137b9cf4c8.tar.gz
scala-3ec2af254866c60389b3fd304c14d1137b9cf4c8.tar.bz2
scala-3ec2af254866c60389b3fd304c14d1137b9cf4c8.zip
- Replaced Symbol.module by Symbol.sourceModule
- Made Symbol.linkedModule and Symbol.linkedClass a bit less ambiguous - Added documentation to Symbol.sourceModule and Symbol.linkedModule - Added classes ConstructorSymbol, ModuleSymbol ModuleClassSymbol - Added classes LinkedModuleSymbol and LinkedClassSymbol - Changed the argument order in symbol constructors to be the same as in the symbol factories - Changed Pickle to use sourceModule instead of HashTable - Replaced notion of main class by notion of root symbol in SymbolLoader - Fixed UnPickle to work with any root symbol
-rw-r--r--sources/scala/tools/scalac/typechecker/Analyzer.scala3
-rw-r--r--sources/scala/tools/scaladoc/HTMLGenerator.java4
-rw-r--r--sources/scala/tools/scaladoc/ScalaSearch.java2
-rw-r--r--sources/scalac/symtab/SourceCompleter.java2
-rw-r--r--sources/scalac/symtab/Symbol.java363
-rw-r--r--sources/scalac/symtab/SymbolLoader.java113
-rw-r--r--sources/scalac/symtab/SymbolTablePrinter.java5
-rw-r--r--sources/scalac/symtab/classfile/CLRClassParser.java10
-rw-r--r--sources/scalac/symtab/classfile/CLRPackageParser.java4
-rw-r--r--sources/scalac/symtab/classfile/ClassParser.java6
-rw-r--r--sources/scalac/symtab/classfile/PackageParser.java5
-rw-r--r--sources/scalac/symtab/classfile/Pickle.java15
-rw-r--r--sources/scalac/symtab/classfile/SymblParser.java4
-rw-r--r--sources/scalac/symtab/classfile/UnPickle.java30
14 files changed, 347 insertions, 219 deletions
diff --git a/sources/scala/tools/scalac/typechecker/Analyzer.scala b/sources/scala/tools/scalac/typechecker/Analyzer.scala
index 3c0d37861c..68594cbb81 100644
--- a/sources/scala/tools/scalac/typechecker/Analyzer.scala
+++ b/sources/scala/tools/scalac/typechecker/Analyzer.scala
@@ -677,9 +677,6 @@ class Analyzer(global: scalac_Global, descr: AnalyzerPhase) extends Transformer(
def moduleSymbol(pos: int, name: Name, owner: Symbol, flags: int, scope: Scope): Symbol = {
val symbol = termSymbolOrNone(scope, pos, name, flags | MODUL | FINAL);
if (symbol.isNone()) owner.newModule(pos, flags, name) else {
- // The symbol has already been created by some symbol
- // loader. It must be a real module (or package).
- assert(symbol.moduleClass() != symbol, Debug.show(symbol));
val clasz = symbol.moduleClass();
updateFlagsAndPos(clasz, pos, clasz.flags & ~(JAVA | PACKAGE));
val constr = clasz.primaryConstructor();
diff --git a/sources/scala/tools/scaladoc/HTMLGenerator.java b/sources/scala/tools/scaladoc/HTMLGenerator.java
index 3ff44c6939..6978ba92a0 100644
--- a/sources/scala/tools/scaladoc/HTMLGenerator.java
+++ b/sources/scala/tools/scaladoc/HTMLGenerator.java
@@ -978,7 +978,7 @@ public abstract class HTMLGenerator {
Symbol[] owners = (Symbol[]) grouped.fst;
Map/*<Symbol, Symbol[]>*/ group = (Map) grouped.snd;
for (int i = 0; i < owners.length; i++) {
- if (owners[i] != sym.moduleClass()) {
+ if (owners[i] != (sym.isModule() ? sym.moduleClass() : sym)) {
page.printlnOTag("table", ATTRS_MEMBER).indent();
// owner
@@ -1053,7 +1053,7 @@ public abstract class HTMLGenerator {
}
// parents
- Type[] parts = symbol.moduleClass().parents();
+ Type[] parts = (symbol.isModule() ? symbol.moduleClass() : symbol).parents();
page.printlnCTag("dt");
for (int i = 0; i < parts.length; i++) {
page.printOTag("dd");
diff --git a/sources/scala/tools/scaladoc/ScalaSearch.java b/sources/scala/tools/scaladoc/ScalaSearch.java
index b697e9c862..96f3d5e174 100644
--- a/sources/scala/tools/scaladoc/ScalaSearch.java
+++ b/sources/scala/tools/scaladoc/ScalaSearch.java
@@ -376,7 +376,7 @@ public class ScalaSearch {
final Map subs = new HashMap();
foreach(root, new SymFun() { public void apply(Symbol sym) {
if (sym.isClass() || sym.isModule()) {
- Type[] parents = sym.moduleClass().parents();
+ Type[] parents = (sym.isModule() ? sym.moduleClass(): sym).parents();
for (int i = 0; i < parents.length; i++) {
Symbol parentSymbol = parents[i].symbol();
List subList = (List) subs.get(parentSymbol);
diff --git a/sources/scalac/symtab/SourceCompleter.java b/sources/scalac/symtab/SourceCompleter.java
index fa6157ea14..73596724bd 100644
--- a/sources/scalac/symtab/SourceCompleter.java
+++ b/sources/scalac/symtab/SourceCompleter.java
@@ -37,7 +37,7 @@ public class SourceCompleter extends SymbolLoader {
// Protected Methods
/** Completes the specified symbol by reading the source file. */
- protected String doComplete(Symbol clasz) throws IOException {
+ protected String doComplete(Symbol root) throws IOException {
global.compileLate(global.getSourceFile(file), false);
return "source file '" + file + "'";
}
diff --git a/sources/scalac/symtab/Symbol.java b/sources/scalac/symtab/Symbol.java
index defa4b18af..1b32899c69 100644
--- a/sources/scalac/symtab/Symbol.java
+++ b/sources/scalac/symtab/Symbol.java
@@ -78,7 +78,7 @@ public abstract class Symbol implements Modifiers, Kinds {
// Constructors -----------------------------------------------------------
/** Generic symbol constructor */
- public Symbol(int kind, int pos, Name name, Symbol owner, int flags, int attrs) {
+ public Symbol(int kind, Symbol owner, int pos, int flags, Name name, int attrs) {
this.kind = kind;
this.pos = pos;
this.name = name;
@@ -98,7 +98,7 @@ public abstract class Symbol implements Modifiers, Kinds {
/** Creates a new constructor of this symbol. */
public final Symbol newConstructor(int pos, int flags) {
assert isType(): Debug.show(this);
- return new TermSymbol(pos, Names.CONSTRUCTOR, owner(), flags, 0, this);
+ return new ConstructorSymbol(this, pos, flags);
}
/** Creates a new method owned by this symbol. */
@@ -184,7 +184,7 @@ public abstract class Symbol implements Modifiers, Kinds {
/** Creates a new module owned by this symbol. */
public final Symbol newModule(int pos, int flags, Name name) {
- return newTerm(pos, flags | MODUL | FINAL | STABLE, name, 0);
+ return new ModuleSymbol(this, pos, flags, name);
}
/**
@@ -220,12 +220,12 @@ public abstract class Symbol implements Modifiers, Kinds {
/** Creates a new type alias owned by this symbol. */
public final Symbol newTypeAlias(int pos, int flags, Name name) {
- return new AliasTypeSymbol(pos, name, this, flags, 0);
+ return new AliasTypeSymbol(this, pos, flags, name, 0);
}
/** Creates a new abstract type owned by this symbol. */
public final Symbol newAbstractType(int pos, int flags, Name name) {
- return new AbsTypeSymbol(pos, name, this, flags, 0);
+ return new AbsTypeSymbol(this, pos, flags, name, 0);
}
/** Creates a new type parameter owned by this symbol. */
@@ -276,7 +276,7 @@ public abstract class Symbol implements Modifiers, Kinds {
{
assert isPackageClass(): Debug.show(this);
assert loader != null: Debug.show(this) + " - " + name;
- ClassSymbol clasz = new LinkedClassSymbol(name, this, flags);
+ ClassSymbol clasz = new LinkedClassSymbol(this, flags, name);
clasz.setInfo(loader);
clasz.allConstructors().setInfo(loader);
clasz.linkedModule().setInfo(loader);
@@ -300,7 +300,7 @@ public abstract class Symbol implements Modifiers, Kinds {
/** Creates a new term owned by this symbol. */
final Symbol newTerm(int pos, int flags, Name name, int attrs) {
- return new TermSymbol(pos, name, this, flags, attrs, null);
+ return new TermSymbol(this, pos, flags, name, attrs);
}
/** Creates a new package owned by this symbol. */
@@ -315,7 +315,7 @@ public abstract class Symbol implements Modifiers, Kinds {
/** Creates a new class owned by this symbol. */
final ClassSymbol newClass(int pos, int flags, Name name, int attrs) {
- return new ClassSymbol(pos, name, this, flags, attrs);
+ return new ClassSymbol(this, pos, flags, name, attrs);
}
/** Creates a new compound class owned by this symbol. */
@@ -434,7 +434,6 @@ public abstract class Symbol implements Modifiers, Kinds {
|| info instanceof Type.OverloadedType
|| info instanceof Type.PolyType
: "illegal type for " + this + ": " + info;
- // !!! if (phase.prev != null) phase = phase.prev;
infos = new TypeIntervalList(null, info, phase);
if (info instanceof Type.LazyType) flags &= ~INITIALIZED;
else flags |= INITIALIZED;
@@ -447,7 +446,7 @@ public abstract class Symbol implements Modifiers, Kinds {
* "nextInfo". It will not be transformed by the current phase.
*/
public final Symbol updateInfo(Type info) {
- return updateInfoAt_(info, Global.instance.currentPhase.next);
+ return updateInfoAt(info, Global.instance.currentPhase.next);
}
/**
@@ -456,7 +455,7 @@ public abstract class Symbol implements Modifiers, Kinds {
* which is also the first phase that will transform this
* information.
*/
- private final Symbol updateInfoAt_(Type info, Phase phase) {
+ private final Symbol updateInfoAt(Type info, Phase phase) {
assert info != null: Debug.show(this);
assert phase != null: Debug.show(this);
assert infos != null: Debug.show(this);
@@ -889,23 +888,64 @@ public abstract class Symbol implements Modifiers, Kinds {
return NONE;
}
- /** Get module associated with class */
- public Symbol module() {
- return NONE;
- }
-
/**
- * Returns the linked class if there is one and NONE otherwise.
+ * Returns the class linked to this module or null if there is no
+ * such class. The returned value remains the same for the whole
+ * life of the symbol.
+ *
+ * See method "linkedModule" to learn more about linked modules
+ * and classes.
*/
- public Symbol linkedClass() {
- return NONE;
+ public ClassSymbol linkedClass() {
+ assert isModule(): "not a module: " + Debug.show(this);
+ return null;
}
/**
- * Returns the linked module if there is one and NONE otherwise.
- */
- public Symbol linkedModule() {
- return NONE;
+ * Returns the module linked to this class or null if there is no
+ * such module. The returned value remains the same for the whole
+ * life of the symbol.
+ *
+ * Linked modules and classes are intended to be used by the
+ * symbol table loader. They are needed because it is impossible
+ * to know from the name of a class or source file if it defines a
+ * class or a module. For that reason a class and a module (each
+ * linked to the other) are created for each of those files. Once
+ * the file is read the class, the module or both are initialized
+ * depending on what the file defines.
+ *
+ * It is guaranteed that if a class "c" has a linked module then
+ * "c.linkedModule().linkedClasss() == c" and that if a module "m"
+ * has a linked class then "m.linkedClasss().linkedModule() == m".
+ *
+ * The linked module of a Java class, is the module that contains
+ * the static members of that class. A Java class has always a
+ * linked module.
+ *
+ * The linked module of a Scala class, is the module with the same
+ * name declared in the same scope. A Scala class may or may not
+ * have a linked module. However, this does not depend on the
+ * presence or absence of a module with the same name but on how
+ * the class is created. Therefore a Scala class may have no
+ * linked module even though there exists a module with the same
+ * name in the same scope. A Scala class may also have a linked
+ * module even though there exists no module with the same name in
+ * the same scope. In the latter case, the linked would be
+ * initialized to NoType (which prevents accesses to it).
+ *
+ * There is a last catch about linked modules. It may happen that
+ * the symbol returned by "linkedModule" is not a module (and that
+ * method "linkedClass" works on a non-module symbol). At creation
+ * time, linked modules are always modules, but at initialization
+ * time, it may be discovered that the module is in fact a case
+ * class factory method. In that case, the module is downgraded to
+ * a non-module term. This implies that from then on calls to its
+ * method "moduleClass" will fail, but the links defined by the
+ * methods "linkedModule" and "linkedClass" remain unchanged.
+ */
+ public ModuleSymbol linkedModule() {
+ assert isClassType(): "not a class: " + Debug.show(this);
+ return null;
}
/** Get owner */
@@ -957,11 +997,50 @@ public abstract class Symbol implements Modifiers, Kinds {
return this;
}
- /* If this is a module, return its class.
- * Otherwise return the symbol itself.
+ /**
+ * Returns the class of this module. This method may be invoked
+ * only on module symbols. It returns always a non-null module
+ * class symbol whose identity never changes.
*/
- public Symbol moduleClass() {
- return this;
+ public ModuleClassSymbol moduleClass() {
+ throw Debug.abort("not a module", this);
+ }
+
+ /**
+ * Returns the source module of this module class. This method may
+ * be invoked only on module class symbols. It returns always a
+ * non-null module symbol whose identity never changes.
+ *
+ * This method should be used with great care. If possible, one
+ * should always use moduleClass instead. For example, one should
+ * write "m.moduleClass()==c" rather than "m==c.sourceModule()".
+ *
+ * This method is problematic because the module - module-class
+ * relation is not a one - one relation. There might be more than
+ * one module that share the same module class. In that case, the
+ * source module of the module class is the module that created
+ * the class. This implies that "m.moduleClass().sourceModule()"
+ * may be different of "m". However, its is guaranteed that
+ * "c.sourceModule().moduleClass()" always returns "c".
+ *
+ * Phases like "AddInterfaces" and "ExpandMixins" are two examples
+ * of phases that create additional modules referring the same
+ * module class.
+ *
+ * Even if a module class is related to only one module, the use
+ * of this method may still be dangerous. The problem is that
+ * modules and module classes are not always as related as one
+ * might expect. For example, modules declared in a function are
+ * lifted out of the function by phase "LambdaLift". During this
+ * process, the module value is transformed into a module method
+ * with a "Ref" argument. If the "sourceModule" method is used to
+ * replace references to module classes by references to their
+ * source modules and this is done it naively with the class of a
+ * lifted module, it will yield wrong code because the the "Ref"
+ * argument will be missing.
+ */
+ public ModuleSymbol sourceModule() {
+ throw Debug.abort("not a module class", this);
}
/** if type is a (possibly lazy) overloaded type, return its alternatves
@@ -1138,7 +1217,6 @@ public abstract class Symbol implements Modifiers, Kinds {
return infos.info;
} else {
TypeIntervalList infos = this.infos;
- // !!! && infos.prev != null
while (phase.id < infos.start.id && infos.prev != null)
infos = infos.prev;
return infos.info;
@@ -1262,7 +1340,9 @@ public abstract class Symbol implements Modifiers, Kinds {
if (global.PHASE.EXPLICITOUTER.id() < global.currentPhase.id)
return Type.NoPrefix;
if (isRoot()) return thisType();
- return Type.singleType(owner.staticPrefix(), module());
+ assert sourceModule().owner() == owner(): Debug.show(this);
+ assert sourceModule().type().isObjectType(): Debug.show(this);
+ return Type.singleType(owner.staticPrefix(), sourceModule());
}
/** The type constructor of a symbol is:
@@ -1396,8 +1476,10 @@ public abstract class Symbol implements Modifiers, Kinds {
if (owner.kind == CLASS &&
!owner.isAnonymousClass() && !owner.isCompoundSym() ||
Global.instance.debug)
- return " in " +
+ return " in " + owner;
+ /*
(owner.isModuleClass() ? ((ClassSymbol) owner).module() : owner);
+ */
else
return "";
}
@@ -1563,34 +1645,14 @@ public abstract class Symbol implements Modifiers, Kinds {
*/
class TermSymbol extends Symbol {
- /**
- * The module class if this is a module, the constructed class if
- * this is a constructor and null otherwise
- */
- private final Symbol clasz;
-
/** Constructor */
- TermSymbol(int pos, Name name, Symbol owner, int flags, int attrs, Symbol clasz) {
- super(VAL, pos, name, owner, flags, attrs);
- this.clasz = clasz == null && isModule() ? newModuleClass() : clasz;
- if (isModule()) setType(this.clasz.typeConstructor());
+ TermSymbol(Symbol owner, int pos, int flags, Name name, int attrs) {
+ super(VAL, owner, pos, flags, name, attrs);
assert name.isTermName(): Debug.show(this);
- assert (isModule() || isConstructor()) == (this.clasz != null): this;
}
- /** Creates the module class associated to this module. */
- ClassSymbol newModuleClass() {
- return new ClassSymbol(this);
- }
-
- /** Is this symbol an instance initializer? */
public boolean isInitializer() {
- return clasz == null && name == Names.INITIALIZER;
- }
-
- /** Is this symbol a constructor? */
- public boolean isConstructor() {
- return clasz != null && name == Names.CONSTRUCTOR;
+ return name == Names.INITIALIZER;
}
public Symbol[] typeParams() {
@@ -1601,45 +1663,97 @@ class TermSymbol extends Symbol {
return type().valueParams();
}
+ protected Symbol cloneSymbolImpl(Symbol owner, int attrs) {
+ return new TermSymbol(owner, pos, flags, name, attrs);
+ }
+
+}
+
+/** A class for constructor symbols */
+final class ConstructorSymbol extends TermSymbol {
+
+ /** The constructed class */
+ private final Symbol clasz;
+
+ /** Initializes this instance. */
+ ConstructorSymbol(Symbol clasz, int pos, int flags) {
+ super(clasz.owner(), pos, flags, Names.CONSTRUCTOR, 0);
+ this.clasz = clasz;
+ }
+
+ public boolean isInitializer() {
+ return false;
+ }
+
+ public boolean isConstructor() {
+ return true;
+ }
+
public Symbol constructorClass() {
- return isConstructor() ? clasz : this;
+ return clasz;
+ }
+
+ protected final Symbol cloneSymbolImpl(Symbol owner, int attrs) {
+ throw Debug.abort("illegal clone of constructor", this);
}
- public Symbol moduleClass() {
- return isModule() ? clasz : this;
+}
+
+/** A class for module symbols */
+public class ModuleSymbol extends TermSymbol {
+
+ /** The module class */
+ private final ModuleClassSymbol clasz;
+
+ /** Initializes this instance. */
+ private ModuleSymbol(Symbol owner, int pos, int flags, Name name,
+ int attrs, ModuleClassSymbol clasz)
+ {
+ super(owner, pos, flags | MODUL | FINAL | STABLE, name, attrs);
+ this.clasz = clasz != null ? clasz : new ModuleClassSymbol(this);
+ setType(Type.typeRef(owner().thisType(), this.clasz,Type.EMPTY_ARRAY));
+ }
+
+ /** Initializes this instance. */
+ ModuleSymbol(Symbol owner, int pos, int flags, Name name) {
+ this(owner, pos, flags, name, 0, null);
+ }
+
+ public ModuleClassSymbol moduleClass() {
+ // test may fail because loaded modules may be downgraded to
+ // case class factory methods (see Symbol#linkedModule())
+
+ assert isModule(): Debug.show(this);
+ return clasz;
}
protected final Symbol cloneSymbolImpl(Symbol owner, int attrs) {
- assert !isPrimaryConstructor() : Debug.show(this);
- return new TermSymbol(pos, name, owner, flags, attrs, clasz);
+ return new ModuleSymbol(owner, pos, flags, name, attrs, clasz);
}
}
-final class LinkedModuleSymbol extends TermSymbol {
+/**
+ * A class for linked module symbols
+ *
+ * @see Symbol#linkedModule()
+ */
+final class LinkedModuleSymbol extends ModuleSymbol {
/** The linked class */
private final LinkedClassSymbol clasz;
- /** Inistializes this instance. */
+ /** Initializes this instance. */
LinkedModuleSymbol(LinkedClassSymbol clasz) {
- super(clasz.pos, clasz.name.toTermName(), clasz.owner(),
- (clasz.flags & JAVA) | MODUL | FINAL | STABLE, 0, null);
+ super(clasz.owner(), clasz.pos, clasz.flags & JAVA,
+ clasz.name.toTermName());
this.clasz = clasz;
}
- final ClassSymbol newModuleClass() {
- return new LinkedModuleClassSymbol(this);
- }
-
- public Symbol linkedClass() {
+ public ClassSymbol linkedClass() {
return clasz;
}
- public Symbol linkedModule() {
- return this;
- }
-
}
/** A base class for all type symbols.
@@ -1658,8 +1772,8 @@ abstract class TypeSymbol extends Symbol {
private Symbol constructor;
/** Constructor */
- public TypeSymbol(int kind, int pos, Name name, Symbol owner, int flags, int attrs) {
- super(kind, pos, name, owner, flags, attrs);
+ public TypeSymbol(int kind, Symbol owner, int pos, int flags, Name name, int attrs) {
+ super(kind, owner, pos, flags, name, attrs);
this.closures = new ClosureHistory();
assert name.isTypeName() : this;
this.constructor = newConstructor(pos, flags & CONSTRFLAGS);
@@ -1785,12 +1899,12 @@ abstract class TypeSymbol extends Symbol {
final class AliasTypeSymbol extends TypeSymbol {
/** Initializes this instance. */
- AliasTypeSymbol(int pos, Name name, Symbol owner, int flags, int attrs) {
- super(ALIAS, pos, name, owner, flags, attrs);
+ AliasTypeSymbol(Symbol owner, int pos, int flags, Name name, int attrs) {
+ super(ALIAS, owner, pos, flags, name, attrs);
}
protected TypeSymbol cloneTypeSymbolImpl(Symbol owner, int attrs) {
- return new AliasTypeSymbol(pos, name, owner, flags, attrs);
+ return new AliasTypeSymbol(owner, pos, flags, name, attrs);
}
}
@@ -1801,8 +1915,8 @@ final class AbsTypeSymbol extends TypeSymbol {
private Type vubound = null;
/** Initializes this instance. */
- AbsTypeSymbol(int pos, Name name, Symbol owner, int flags, int attrs) {
- super(TYPE, pos, name, owner, flags, attrs);
+ AbsTypeSymbol(Symbol owner, int pos, int flags, Name name, int attrs) {
+ super(TYPE, owner, pos, flags, name, attrs);
allConstructors().setInfo(Type.MethodType(EMPTY_ARRAY, Type.typeRef(owner.thisType(), this, Type.EMPTY_ARRAY)));
}
@@ -1828,7 +1942,7 @@ final class AbsTypeSymbol extends TypeSymbol {
}
protected TypeSymbol cloneTypeSymbolImpl(Symbol owner, int attrs) {
- TypeSymbol clone = new AbsTypeSymbol(pos, name, owner, flags, attrs);
+ TypeSymbol clone = new AbsTypeSymbol(owner, pos, flags, name, attrs);
clone.setLoBound(loBound());
clone.setVuBound(vuBound());
return clone;
@@ -1839,9 +1953,6 @@ final class AbsTypeSymbol extends TypeSymbol {
/** A class for class symbols. */
public class ClassSymbol extends TypeSymbol {
- /** The module belonging to the class or NONE. */
- private final Symbol module;
-
/** The given type of self, or NoType, if no explicit type was given.
*/
private Symbol thisSym = this;
@@ -1855,29 +1966,12 @@ public class ClassSymbol extends TypeSymbol {
private final Symbol rebindSym;
/** Initializes this instance. */
- private ClassSymbol(int pos, Name name, Symbol owner, int flags, int attrs, Symbol module) {
- super(CLASS, pos, name, owner, flags, attrs);
+ ClassSymbol(Symbol owner, int pos, int flags, Name name, int attrs) {
+ super(CLASS, owner, pos, flags, name, attrs);
this.rebindSym = owner.newTypeAlias(pos, 0, Names.ALIAS(this));
Type rebindType = new ClassAliasLazyType();
this.rebindSym.setInfo(rebindType);
this.rebindSym.primaryConstructor().setInfo(rebindType);
- this.module = module;
- assert isModuleClass() == !module.isNone(): Debug.show(this);
- }
-
- /** Initializes this instance. */
- ClassSymbol(int pos, Name name, Symbol owner, int flags, int attrs) {
- this(pos, name, owner, flags, attrs, Symbol.NONE);
- }
-
- /** Initializes this instance. */
- ClassSymbol(TermSymbol module) {
- this(module.pos, module.name.toTypeName(), module.owner(),
- (module.flags & MODULE2CLASSFLAGS) | MODUL | FINAL, 0,
- module);
- primaryConstructor().flags |= PRIVATE;
- primaryConstructor().setInfo(
- Type.MethodType(Symbol.EMPTY_ARRAY, typeConstructor()));
}
private class ClassAliasLazyType extends Type.LazyType {
@@ -1902,7 +1996,7 @@ public class ClassSymbol extends TypeSymbol {
Symbol owner = Symbol.NONE;
int flags = JAVA | PACKAGE | FINAL;
int attrs = IS_ROOT;
- Symbol clasz = new ClassSymbol(pos, name, owner, flags, attrs, NONE);
+ Symbol clasz = new ClassSymbol(owner, pos, flags, name, attrs);
clasz.setInfo(global.getRootLoader());
clasz.primaryConstructor().setInfo(
Type.MethodType(Symbol.EMPTY_ARRAY, clasz.typeConstructor()));
@@ -1915,12 +2009,6 @@ public class ClassSymbol extends TypeSymbol {
return newTerm(pos, SYNTHETIC, Names.this_, IS_THISTYPE);
}
- /** Get module */
- public Symbol module() {
- assert !isRoot(): this + ".module()";
- return module;
- }
-
public Type thisType() {
Global global = Global.instance;
if (global.currentPhase.id > global.PHASE.ERASURE.id()) return type();
@@ -1973,65 +2061,74 @@ public class ClassSymbol extends TypeSymbol {
public void reset(Type completer) {
super.reset(completer);
- module().reset(completer);
thisSym = this;
}
- protected TypeSymbol cloneTypeSymbolImpl(Symbol owner, int attrs) {
+ protected final TypeSymbol cloneTypeSymbolImpl(Symbol owner, int attrs) {
assert !isModuleClass(): Debug.show(this);
- ClassSymbol clone = new ClassSymbol(pos, name, owner,flags,attrs,NONE);
+ ClassSymbol clone = new ClassSymbol(owner, pos, flags, name, attrs);
if (thisSym != this) clone.setTypeOfThis(typeOfThis());
return clone;
}
}
-final class LinkedClassSymbol extends ClassSymbol {
+/**
+ * A class for module class symbols
+ *
+ * @see Symbol#sourceModule()
+ */
+public final class ModuleClassSymbol extends ClassSymbol {
- /** The linked module */
- private final LinkedModuleSymbol module;
+ /** The source module */
+ private final ModuleSymbol module;
/** Initializes this instance. */
- LinkedClassSymbol(Name name, Symbol owner, int flags) {
- super(Position.NOPOS, name, owner, flags, 0);
- this.module = new LinkedModuleSymbol(this);
- }
-
- public Symbol linkedClass() {
- return this;
+ ModuleClassSymbol(ModuleSymbol module) {
+ super(module.owner(), module.pos,
+ (module.flags & MODULE2CLASSFLAGS) | MODUL | FINAL,
+ module.name.toTypeName(), 0);
+ primaryConstructor().flags |= PRIVATE;
+ primaryConstructor().setInfo(
+ Type.MethodType(Symbol.EMPTY_ARRAY, typeConstructor()));
+ this.module = module;
}
- public Symbol linkedModule() {
+ public ModuleSymbol sourceModule() {
return module;
}
}
-final class LinkedModuleClassSymbol extends ClassSymbol {
+/**
+ * A class for linked class symbols
+ *
+ * @see Symbol#linkedModule()
+ */
+final class LinkedClassSymbol extends ClassSymbol {
- /** Initializes this instance. */
- LinkedModuleClassSymbol(LinkedModuleSymbol module) {
- super(module);
- }
+ /** The linked module */
+ private final LinkedModuleSymbol module;
- public Symbol linkedClass() {
- return linkedModule().linkedClass();
+ /** Initializes this instance. */
+ LinkedClassSymbol(Symbol owner, int flags, Name name) {
+ super(owner, Position.NOPOS, flags, name, 0);
+ this.module = new LinkedModuleSymbol(this);
}
- public Symbol linkedModule() {
- return module();
+ public ModuleSymbol linkedModule() {
+ return module;
}
}
-
/** The class of Symbol.NONE
*/
final class NoSymbol extends Symbol {
/** Constructor */
public NoSymbol() {
- super(Kinds.NONE, Position.NOPOS, Names.NOSYMBOL, null, 0, 0);
+ super(Kinds.NONE, null, Position.NOPOS, 0, Names.NOSYMBOL, 0);
super.setInfo(Type.NoType);
}
diff --git a/sources/scalac/symtab/SymbolLoader.java b/sources/scalac/symtab/SymbolLoader.java
index 3a4c1464eb..d02829f191 100644
--- a/sources/scalac/symtab/SymbolLoader.java
+++ b/sources/scalac/symtab/SymbolLoader.java
@@ -40,36 +40,37 @@ public abstract class SymbolLoader extends Type.LazyType {
// Public Methods
/**
- * Completes the symbol. More precisely, it completes all related
- * symbols of the main class of the symbol. It is guaranteed that
- * after this method call all these symbols are initialized (or at
- * least that their info does not contain this lazy type).
+ * Completes the specified symbol. More precisely, it completes
+ * all symbols related to the root symbol of the specified
+ * symbol. It is guaranteed that after this method call all these
+ * symbols are initialized (or at least that their info does no
+ * longer contain this lazy type).
*
- * The main class of a symbol is:
- * - the main class of the constructed class, if it's a
+ * The root symbol of a symbol is:
+ * - the root symbol of the constructed class, if it's a
* constructor,
- * - the main class of the module class, if it's a module,
- * - the linked class, if it's a linked module class,
- * - itself if it's a non-linked class or a non-module class,
+ * - the root symbol of the source module, if it's a module class,
+ * - the linked class, if it's a module with a linked class,
+ * - itself if it's a class or a module with no linked class,
* - undefined otherwise.
*
- * The related symbols of a class include:
- * - the class itself,
- * - its constructor (symbol returned by allConstructors()),
- * - its linked module, if it has one,
- * - the related symbols of its linked module class, if it has one
+ * The symbols related to a symbol include:
+ * - the symbol itself,
+ * - its constructor (allConstructors()), if it's a class,
+ * - the symbols related to its linked module, if there is one.
+ * - the symbols related to its module class, if it's a module,
*/
public final void complete(Symbol symbol) {
- Symbol clasz = getMainClass(symbol);
+ Symbol root = getRootSymbol(symbol);
try {
long start = System.currentTimeMillis();
Phase phase = global.currentPhase;
global.currentPhase = global.PHASE.ANALYZER.phase();
- String source = doComplete(clasz);
+ String source = doComplete(root);
global.currentPhase = phase;
long end = System.currentTimeMillis();
global.operation("loaded " + source + " in " + (end-start) + "ms");
- checkValidity(clasz, source);
+ checkValidity(root, source);
} catch (IOException exception) {
if (global.debug) exception.printStackTrace();
String error = "error while loading " + symbol;
@@ -77,7 +78,7 @@ public abstract class SymbolLoader extends Type.LazyType {
error = message != null ? error + ", " + message : "i/o " + error;
global.error(error);
}
- initializeAll(clasz);
+ initializeRoot(root);
}
//########################################################################
@@ -86,56 +87,78 @@ public abstract class SymbolLoader extends Type.LazyType {
/**
* Performs the actual loading and returns the name of the
* external source. It is guaranteed that the argument of this
- * method is always a main class (see also method complete).
+ * method is always a root symbol
+ *
+ * @see complete(Symbol)
*/
- protected abstract String doComplete(Symbol clasz) throws IOException;
+ protected abstract String doComplete(Symbol root) throws IOException;
//########################################################################
// Private Methods
- /** Returns the main class of the symbol (see method complete). */
- private Symbol getMainClass(Symbol symbol) {
+ /**
+ * Returns the root symbol of the specified symbol.
+ *
+ * @see complete(Symbol)
+ */
+ private Symbol getRootSymbol(Symbol symbol) {
if (symbol.isConstructor())
- return getMainClass(symbol.constructorClass());
- if (symbol.isModule())
- return getMainClass(symbol.moduleClass());
- if (symbol.isModuleClass() && !symbol.linkedClass().isNone())
+ return getRootSymbol(symbol.constructorClass());
+ if (symbol.isModuleClass())
+ return getRootSymbol(symbol.sourceModule());
+ if (symbol.isModule() && symbol.linkedClass() != null)
return symbol.linkedClass();
- assert symbol.isClassType(): Debug.show(symbol);
+ assert symbol.isClassType() || symbol.isModule(): Debug.show(symbol);
return symbol;
}
/**
- * Checks that at least the class or its dual class have been
- * initialized and signals an error otherwise.
+ * Checks that at least the specified root symbol or its linked
+ * module, if any, has been initialized and signals an error
+ * otherwise.
+ *
+ * @see complete(Symbol)
*/
- private void checkValidity(Symbol clasz, String source) {
- if (clasz.rawInfo() != this) return;
+ private void checkValidity(Symbol root, String source) {
+ if (root.rawInfo() != this) return;
String what;
- if (clasz.linkedClass().isNone()) {
- what = "does not define " + clasz.linkedModule();
+ if (!root.isClassType() || root.linkedModule() == null) {
+ what = "does not define " + root;
} else {
- if (clasz.linkedModule().moduleClass().rawInfo() != this) return;
- what = "defines neither " + clasz + " nor " + clasz.linkedModule();
+ if (root.linkedModule().moduleClass().rawInfo() != this) return;
+ what = "defines neither " + root + " nor " + root.linkedModule();
}
global.error(source + " " + what);
}
/**
- * Initializes all related symbols of the class whose info is this
- * instance (see also method complete).
+ * Initializes all symbols related to the specified root symbol
+ * and whose info is this instance.
+ *
+ * @see complete(Symbol)
+ */
+ private void initializeRoot(Symbol root) {
+ if (root.isClassType()) {
+ initializeClass(root);
+ if (root.linkedModule() != null)
+ initializeRoot(root.linkedModule());
+ } else {
+ initializeSymbol(root);
+ if (root.isModule()) initializeClass(root.moduleClass());
+ }
+ }
+
+ /**
+ * Initializes the specified class and its constructor if their
+ * info is this instance.
*/
- private void initializeAll(Symbol clasz) {
- initializeOne(clasz);
- initializeOne(clasz.allConstructors());
- if (clasz.isModuleClass()) initializeOne(clasz.linkedModule());
- Symbol module = clasz.linkedModule();
- if (!module.isNone() && module.moduleClass() != clasz)
- initializeAll(module.moduleClass());
+ private void initializeClass(Symbol clasz) {
+ initializeSymbol(clasz);
+ initializeSymbol(clasz.allConstructors());
}
/** Initializes the symbol if its info is this instance. */
- private void initializeOne(Symbol symbol) {
+ private void initializeSymbol(Symbol symbol) {
if (symbol.rawInfo() != this) return;
symbol.setInfo(symbol.isModule() ? Type.NoType : Type.ErrorType);
if (symbol.isConstructor()) symbol.flags |= Modifiers.PRIVATE;
diff --git a/sources/scalac/symtab/SymbolTablePrinter.java b/sources/scalac/symtab/SymbolTablePrinter.java
index d70d62d3c2..89fe42d869 100644
--- a/sources/scalac/symtab/SymbolTablePrinter.java
+++ b/sources/scalac/symtab/SymbolTablePrinter.java
@@ -407,7 +407,10 @@ public class SymbolTablePrinter {
case ThisType(Symbol clasz):
if (global.debug || !clasz.isModuleClass()) return type;
Type prefix = getTypeToPrintForType(clasz.owner().thisType());
- return Type.singleType(prefix, clasz.module());
+ Symbol module = clasz.sourceModule();
+ if (module.owner() != clasz.owner()) return type;
+ if (!module.type().isObjectType()) return type;
+ return Type.singleType(prefix, module);
case SingleType(_, Symbol sym):
if (global.debug) return type;
if (sym.isSynthetic()) return type.widen();
diff --git a/sources/scalac/symtab/classfile/CLRClassParser.java b/sources/scalac/symtab/classfile/CLRClassParser.java
index 7c7f2f1376..9de9d17629 100644
--- a/sources/scalac/symtab/classfile/CLRClassParser.java
+++ b/sources/scalac/symtab/classfile/CLRClassParser.java
@@ -39,10 +39,14 @@ public class CLRClassParser extends SymbolLoader {
private static Name[] ENUM_BIT_LOG_NAMES = new Name[]
{ Names.OR, Names.AND, Names.XOR };
- protected String doComplete(Symbol clazz) {
- try { return doComplete0(clazz); }
+ protected String doComplete(Symbol root) {
+ assert root.isClassType(): Debug.show(root);
+ try { return doComplete0(root); }
catch (Throwable e) {
- System.err.println("\nWhile processing " + Debug.show(clazz));
+ // !!! doComplete may throw an IOException which is then
+ // caught by SymbolLoader and reported to the user as
+ // normal error message
+ System.err.println("\nWhile processing " + Debug.show(root));
e.printStackTrace();
System.exit(1);
return null; // !!!
diff --git a/sources/scalac/symtab/classfile/CLRPackageParser.java b/sources/scalac/symtab/classfile/CLRPackageParser.java
index 10e6d4acd6..90fd0fcc47 100644
--- a/sources/scalac/symtab/classfile/CLRPackageParser.java
+++ b/sources/scalac/symtab/classfile/CLRPackageParser.java
@@ -221,7 +221,9 @@ public class CLRPackageParser extends SymbolLoader {
//##########################################################################
// main functionality
- protected String doComplete(Symbol p) {
+ protected String doComplete(Symbol root) {
+ assert root.isRoot() || root.isPackage(): Debug.show(root);
+ Symbol p = root.isRoot() ? root : root.moduleClass();
Scope members = new Scope();
importCLRTypes(p, members);
p.setInfo(scalac.symtab.Type.compoundType
diff --git a/sources/scalac/symtab/classfile/ClassParser.java b/sources/scalac/symtab/classfile/ClassParser.java
index f920a5ef79..5284d9cfed 100644
--- a/sources/scalac/symtab/classfile/ClassParser.java
+++ b/sources/scalac/symtab/classfile/ClassParser.java
@@ -15,6 +15,7 @@ import scala.tools.util.AbstractFile;
import scalac.Global;
import scalac.symtab.Symbol;
import scalac.symtab.SymbolLoader;
+import scalac.util.Debug;
/** This class implements a SymbolLoader that reads a class file. */
public class ClassParser extends SymbolLoader {
@@ -38,8 +39,9 @@ public class ClassParser extends SymbolLoader {
// Protected Methods
/** Completes the specified symbol by reading the class file. */
- protected String doComplete(Symbol clasz) throws IOException {
- ClassfileParser.parse(global, file, clasz);
+ protected String doComplete(Symbol root) throws IOException {
+ assert root.isClassType(): Debug.show(root);
+ ClassfileParser.parse(global, file, root);
return "class file '" + file + "'";
}
diff --git a/sources/scalac/symtab/classfile/PackageParser.java b/sources/scalac/symtab/classfile/PackageParser.java
index 13882f7714..07d196312c 100644
--- a/sources/scalac/symtab/classfile/PackageParser.java
+++ b/sources/scalac/symtab/classfile/PackageParser.java
@@ -21,6 +21,7 @@ import scalac.symtab.Symbol;
import scalac.symtab.SymbolLoader;
import scalac.symtab.Type;
import scalac.util.Name;
+import scalac.util.Debug;
/**
* This class implements a package member loader. It can be used to
@@ -47,7 +48,9 @@ public class PackageParser extends SymbolLoader {
// Protected Methods
/** Completes the package symbol by loading all its members. */
- protected String doComplete(Symbol peckage) {
+ 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();
diff --git a/sources/scalac/symtab/classfile/Pickle.java b/sources/scalac/symtab/classfile/Pickle.java
index bd2f1f0ef2..6891093e75 100644
--- a/sources/scalac/symtab/classfile/Pickle.java
+++ b/sources/scalac/symtab/classfile/Pickle.java
@@ -34,7 +34,6 @@ public class Pickle implements Kinds, Modifiers, EntryTags {
private HashMap index;
private Object[] entries;
private int ep;
- private final HashMap modules; // maps module-classes to modules
/** Write symbol table info for root.
* root must be either a module or a class.
@@ -43,7 +42,6 @@ public class Pickle implements Kinds, Modifiers, EntryTags {
index = new HashMap();
entries = new Object[256];
ep = 0;
- modules = new HashMap();
}
/** Pickle all symbols descending from `root'.
@@ -132,6 +130,7 @@ public class Pickle implements Kinds, Modifiers, EntryTags {
break;
case CLASS:
putType(sym.info());
+ if (sym.isModuleClass()) putSymbol(sym.sourceModule());
putType(sym.typeOfThis());
putSymbol(sym.allConstructors());
for (Scope.SymbolIterator it = sym.members().iterator();
@@ -143,12 +142,8 @@ public class Pickle implements Kinds, Modifiers, EntryTags {
if (sym.isConstructor() &&
sym == sym.constructorClass().allConstructors())
putSymbol(sym.constructorClass());
- else if (sym.isModule()) {
- Symbol clasz = sym.moduleClass();
+ else if (sym.isModule())
putSymbol(sym.moduleClass());
- assert !modules.containsKey(clasz): Debug.show(sym);
- modules.put(clasz, sym);
- }
break;
default:
throw new ApplicationError();
@@ -358,11 +353,7 @@ public class Pickle implements Kinds, Modifiers, EntryTags {
break;
case CLASS:
writeRef(sym.info());
- if (sym.isModuleClass()) {
- Symbol module = (Symbol)modules.remove(sym);
- assert module != null: Debug.show(sym);
- writeRef(module);
- }
+ if (sym.isModuleClass()) writeRef(sym.sourceModule());
writeRef(sym.typeOfThis());
writeRef(sym.allConstructors());
break;
diff --git a/sources/scalac/symtab/classfile/SymblParser.java b/sources/scalac/symtab/classfile/SymblParser.java
index 56873215e8..5c948d9176 100644
--- a/sources/scalac/symtab/classfile/SymblParser.java
+++ b/sources/scalac/symtab/classfile/SymblParser.java
@@ -38,8 +38,8 @@ public class SymblParser extends SymbolLoader {
// Protected Methods
/** Completes the specified symbol by reading the symbol file. */
- public String doComplete(Symbol clasz) throws IOException {
- UnPickle.parse(global, file, clasz);
+ public String doComplete(Symbol root) throws IOException {
+ UnPickle.parse(global, file, root);
return "symbol file '" + file + "'";
}
diff --git a/sources/scalac/symtab/classfile/UnPickle.java b/sources/scalac/symtab/classfile/UnPickle.java
index 61c62dc63f..9579458394 100644
--- a/sources/scalac/symtab/classfile/UnPickle.java
+++ b/sources/scalac/symtab/classfile/UnPickle.java
@@ -38,6 +38,11 @@ public class UnPickle implements Kinds, Modifiers, EntryTags, TypeTags {
}
}
+ /**
+ * The root symbol must be either a module or a non-module
+ * class. The unpickler initializes it. If it has a linked module
+ * or class, it will also be initialized.
+ */
public static void parse(Global global, byte[] data, Symbol root)
throws BadSignature
{
@@ -55,17 +60,16 @@ public class UnPickle implements Kinds, Modifiers, EntryTags, TypeTags {
private UnPickle(Global global, byte[] data, Symbol root) {
this.global = global;
- this.classroot = root.linkedClass();
- this.moduleroot = root.linkedModule();
- assert !classroot.isNone(): Debug.show(root);
- assert !moduleroot.isNone(): Debug.show(root);
- if (root != moduleroot && moduleroot.isModule()) {
+ this.classroot = root.isModule() ? root.linkedClass() : root;
+ this.moduleroot = root.isClassType() ? root.linkedModule() : root;
+ assert classroot == null || classroot.isClassType(): Debug.show(root);
+ assert moduleroot == null || moduleroot.isModule(): Debug.show(root);
+ if (root != moduleroot && moduleroot != null) {
moduleroot.moduleClass().setInfo(Type.NoType);
}
- if (global.debug)
- global.log(
- "unpickle " + root + " " + classroot + " " + moduleroot + " " +
- moduleroot.moduleClass() + " " + moduleroot.moduleClass().primaryConstructor());
+ if (global.debug) global.log(
+ "unpickle " + root + " " + classroot + " " + moduleroot
+ + (moduleroot != null ? " " + moduleroot.moduleClass() : ""));
this.bytes = data;
this.bp = 0;
index = new int[readNat()];
@@ -84,7 +88,9 @@ public class UnPickle implements Kinds, Modifiers, EntryTags, TypeTags {
if (global.debug) global.log("unpickled " + root + ":" + root.rawInfo());//debug
if (!root.isInitialized())
throw new BadSignature(this, "it does not define " + root);
- if (moduleroot.isModule() && moduleroot.moduleClass().type() == Type.NoType) {
+ // the isModule test is needed because moduleroot may become
+ // the case class factory method of classroot
+ if (moduleroot != null && moduleroot.isModule() && moduleroot.moduleClass().type() == Type.NoType) {
moduleroot.setInfo(Type.NoType);
}
}
@@ -259,7 +265,7 @@ public class UnPickle implements Kinds, Modifiers, EntryTags, TypeTags {
Symbol modulesym = readSymbolRef();
entries[n] = sym = modulesym.moduleClass();
sym.flags = flags;
- } else if (name == classroot.name && owner == classroot.owner()) {
+ } else if (classroot != null && name == classroot.name && owner == classroot.owner()) {
if (global.debug)
global.log("overwriting " + classroot);
entries[n] = sym = classroot;
@@ -275,7 +281,7 @@ public class UnPickle implements Kinds, Modifiers, EntryTags, TypeTags {
break;
case VALsym:
- if (name == moduleroot.name && owner == moduleroot.owner()) {
+ if (moduleroot != null && name == moduleroot.name && owner == moduleroot.owner()) {
if (global.debug)
global.log("overwriting " + moduleroot);
entries[n] = sym = moduleroot;