summaryrefslogtreecommitdiff
path: root/sources
diff options
context:
space:
mode:
authorpaltherr <paltherr@epfl.ch>2004-03-10 02:29:56 +0000
committerpaltherr <paltherr@epfl.ch>2004-03-10 02:29:56 +0000
commit98bd45db839f0ec470d1fdbd42d5c748e428f4b5 (patch)
tree7cc9c1111515fa57b4a8917b87b61ae1cdf54282 /sources
parent70d535ae7b9e689b699a5327cdee747464874420 (diff)
downloadscala-98bd45db839f0ec470d1fdbd42d5c748e428f4b5.tar.gz
scala-98bd45db839f0ec470d1fdbd42d5c748e428f4b5.tar.bz2
scala-98bd45db839f0ec470d1fdbd42d5c748e428f4b5.zip
- Added new factory methods in class Symbol
- Removed hack from ClassSymbol.dualClass - Rewrote PackageParser and adapted other parsers and analyzer to use the new factory method - Replaced some unsound calls to Symbol.module by calls to Symbol.dualClass
Diffstat (limited to 'sources')
-rw-r--r--sources/scala/tools/scalac/typechecker/Analyzer.scala27
-rw-r--r--sources/scalac/symtab/Symbol.java80
-rw-r--r--sources/scalac/symtab/classfile/AttributeParser.java2
-rw-r--r--sources/scalac/symtab/classfile/CLRClassParser.java10
-rw-r--r--sources/scalac/symtab/classfile/CLRPackageParser.java13
-rw-r--r--sources/scalac/symtab/classfile/ClassfileParser.java8
-rw-r--r--sources/scalac/symtab/classfile/PackageParser.java218
-rw-r--r--sources/scalac/symtab/classfile/UnPickle.java4
8 files changed, 216 insertions, 146 deletions
diff --git a/sources/scala/tools/scalac/typechecker/Analyzer.scala b/sources/scala/tools/scalac/typechecker/Analyzer.scala
index e0a76fbf13..37ed261dd3 100644
--- a/sources/scala/tools/scalac/typechecker/Analyzer.scala
+++ b/sources/scala/tools/scalac/typechecker/Analyzer.scala
@@ -701,8 +701,7 @@ class Analyzer(global: scalac_Global, descr: AnalyzerPhase) extends Transformer(
def packageSymbol(pos: int, base: Symbol, name: Name): Symbol = {
var p: Symbol = base.members().lookup(name);
if (p.kind == NONE) {
- p = TermSymbol.newJavaPackageModule(name, base.moduleClass(), null);
- base.members().enter(p);
+ p = base.moduleClass().newPackage(name);
} else if (!p.isPackage()) {
error(pos, "package and class with same name");
p = Symbol.ERROR;
@@ -848,11 +847,27 @@ class Analyzer(global: scalac_Global, descr: AnalyzerPhase) extends Transformer(
enterSym(tree, clazz)
case Tree$ModuleDef(mods, name, _, _) =>
- val modul: TermSymbol = TermSymbol.define(
- tree.pos, name, owner, mods, context.scope).makeModule();
+ var modul: TermSymbol = TermSymbol.lookup(
+ tree.pos, name, owner, mods | MODUL | FINAL, context.scope);
+ if (modul == null) {
+ modul = new TermSymbol(tree.pos, name, owner, mods).makeModule();
+ } else {
+ // The symbol has already been created by some symbol
+ // loader. It must be a real module.
+ assert(modul.moduleClass() != modul, Debug.show(modul));
+ val clasz = modul.moduleClass();
+ clasz.flags = clasz.flags & (~JAVA);
+ clasz.pos = tree.pos;
+ val constr = clasz.primaryConstructor();
+ constr.flags = constr.flags & (~JAVA);
+ constr.pos = tree.pos;
+ }
val clazz: Symbol = modul.moduleClass();
- if (!clazz.isInitialized())
- clazz.setInfo(new LazyTreeType(tree));
+ if (!clazz.isInitialized()) {
+ val info = new LazyTreeType(tree);
+ clazz.setInfo(info);
+ modul.setInfo(info);
+ }
enterSym(tree, modul)
case Tree$ValDef(mods, name, _, _) =>
diff --git a/sources/scalac/symtab/Symbol.java b/sources/scalac/symtab/Symbol.java
index eacfdf0310..4f565e1fc2 100644
--- a/sources/scalac/symtab/Symbol.java
+++ b/sources/scalac/symtab/Symbol.java
@@ -87,6 +87,36 @@ public abstract class Symbol implements Modifiers, Kinds {
// Factories --------------------------------------------------------------
+ /** Creates a new module owned by this symbol. */
+ public final TermSymbol newModule(int pos, int flags, Name name) {
+ ClassSymbol clasz = newModuleClass(pos, flags, name.toTypeName());
+ return (TermSymbol)clasz.module();
+ }
+
+ /**
+ * Creates a new package owned by this symbol, initializes it with
+ * an empty scope and adds it to this symbol's members.
+ */
+ public final TermSymbol newPackage(Name name) {
+ TermSymbol peckage = newPackage(name, null);
+ members().enterNoHide(peckage);
+ return peckage;
+ }
+
+ /**
+ * Creates a new package owned by this symbol, initializes it with
+ * the loader and enters it in the scope if it's non-null.
+ */
+ public final TermSymbol newLoadedPackage(Name name, SymbolLoader loader,
+ Scope scope)
+ {
+ assert loader != null: Debug.show(this) + " - " + name;
+ TermSymbol peckage = newPackage(name, loader);
+ peckage.moduleClass().setInfo(loader);
+ if (scope != null) scope.enterNoHide(peckage);
+ return peckage;
+ }
+
/** Creates a new class owned by this symbol. */
public final ClassSymbol newClass(int pos, int flags, Name name) {
return newClass(pos, flags, name, 0, NONE);
@@ -97,6 +127,36 @@ public abstract class Symbol implements Modifiers, Kinds {
return newModuleClass(pos, flags, name, 0, NONE);
}
+ /**
+ * Creates a new class with a dual module class, both owned by
+ * this symbol, initializes them with the loader and enters the
+ * class and the module in the scope if it's non-null.
+ */
+ public final ClassSymbol newLoadedClass(int flags, Name name,
+ SymbolLoader loader, Scope scope)
+ {
+ assert isPackageClass(): Debug.show(this);
+ assert loader != null: Debug.show(this) + " - " + name;
+ ClassSymbol clasz = newClass(pos, flags, name, 0, null);
+ clasz.setInfo(loader);
+ clasz.allConstructors().setInfo(loader);
+ clasz.dualClass().setInfo(loader);
+ clasz.dualClass().module().setInfo(loader);
+ if (scope != null) scope.enterNoHide(clasz);
+ if (scope != null) scope.enterNoHide(clasz.dualClass().module());
+ return clasz;
+ }
+
+ /** Creates a new package owned by this symbol. */
+ final TermSymbol newPackage(Name name, Type info) {
+ assert isPackageClass(): Debug.show(this);
+ TermSymbol peckage = newModule(Position.NOPOS, JAVA | PACKAGE, name);
+ if (info == null) info = Type.compoundType(
+ Type.EMPTY_ARRAY, new Scope(), peckage.moduleClass());
+ peckage.moduleClass().setInfo(info);
+ return peckage;
+ }
+
/** Creates a new class owned by this symbol. */
final ClassSymbol newClass(int pos, int flags, Name name, int attrs,
Symbol dual)
@@ -104,7 +164,7 @@ public abstract class Symbol implements Modifiers, Kinds {
return new ClassSymbol(pos, name, this, flags, attrs, dual);
}
- /** Creates a new module-class owned by this symbol. */
+ /** Creates a new module class owned by this symbol. */
final ClassSymbol newModuleClass(int pos, int flags, Name name, int attrs,
Symbol dual)
{
@@ -116,7 +176,7 @@ public abstract class Symbol implements Modifiers, Kinds {
return clasz;
}
- /** Creates a new compound class. */
+ /** Creates a new compound class owned by this symbol. */
final ClassSymbol newCompoundClass(Type info) {
int pos = Position.FIRSTPOS;
Name name = Names.COMPOUND_NAME.toTypeName();
@@ -1359,6 +1419,12 @@ public class TermSymbol extends Symbol {
public static TermSymbol define(
int pos, Name name, Symbol owner, int flags, Scope scope) {
+ TermSymbol symbol = lookup(pos, name, owner, flags, scope);
+ if (symbol != null) return symbol;
+ return new TermSymbol(pos, name, owner, flags);
+ }
+ public static TermSymbol lookup(
+ int pos, Name name, Symbol owner, int flags, Scope scope) {
Scope.Entry e = scope.lookupEntry(name);
if (e.owner == scope && e.sym.isExternal() && e.sym.kind == VAL) {
TermSymbol sym = (TermSymbol) e.sym;
@@ -1381,7 +1447,7 @@ public class TermSymbol extends Symbol {
sym.update(pos, flags);
return sym;
} else {
- return new TermSymbol(pos, name, owner, flags);
+ return null;
}
}
@@ -1865,13 +1931,7 @@ public class ClassSymbol extends TypeSymbol {
/** Get dual class */
public Symbol dualClass() {
- // !!! temporary hack, replace all this by: "return dual;"
- if (isModuleClass()) {
- Symbol symbol = owner().lookup(name.toTypeName());
- return symbol.isClassType() ? symbol : NONE;
- } else {
- return module.isNone() ? NONE : module.moduleClass();
- }
+ return dual;
}
/** Set module; only used internally from TermSymbol
diff --git a/sources/scalac/symtab/classfile/AttributeParser.java b/sources/scalac/symtab/classfile/AttributeParser.java
index 183e96785b..9205291748 100644
--- a/sources/scalac/symtab/classfile/AttributeParser.java
+++ b/sources/scalac/symtab/classfile/AttributeParser.java
@@ -122,7 +122,7 @@ public class AttributeParser implements ClassfileConstants {
((flags & 0x0009) == 0) ||
((flags & 0x0001) == 0) ||
!outer.isModule() ||
- (outer != sym.module()))
+ (outer != sym.dualClass().module()))
continue;
AliasTypeSymbol alias =
new AliasTypeSymbol(Position.NOPOS, name.toTypeName(), outer, 0);
diff --git a/sources/scalac/symtab/classfile/CLRClassParser.java b/sources/scalac/symtab/classfile/CLRClassParser.java
index 026755a73f..7136b1f90f 100644
--- a/sources/scalac/symtab/classfile/CLRClassParser.java
+++ b/sources/scalac/symtab/classfile/CLRClassParser.java
@@ -70,12 +70,12 @@ public class CLRClassParser extends SymbolLoader {
scalac.symtab.Type classType =
scalac.symtab.Type.compoundType(baseTypes, members, clazz);
clazz.setInfo(classType);
- Symbol staticsClass = clazz.module().moduleClass();
+ Symbol staticsClass = clazz.dualClass();
if (staticsClass.isModuleClass()) {
scalac.symtab.Type staticsInfo = scalac.symtab.Type.compoundType
(scalac.symtab.Type.EMPTY_ARRAY, statics, staticsClass);
staticsClass.setInfo(staticsInfo);
- clazz.module().setInfo(scalac.symtab.Type.typeRef
+ staticsClass.module().setInfo(scalac.symtab.Type.typeRef
(staticsClass.owner().thisType(),
staticsClass, scalac.symtab.Type.EMPTY_ARRAY));
}
@@ -94,14 +94,12 @@ public class CLRClassParser extends SymbolLoader {
Name classname = Name.fromString(n).toTypeName();
Name aliasname = Name.fromString(ntype.Name).toTypeName();
// put the class at the level of its outermost class
- ClassSymbol nclazz = new ClassSymbol(classname, clazz.owner(), this);
+ Symbol nclazz = clazz.owner().newLoadedClass(JAVA, classname, this, null);
importer.map(nclazz, ntype);
// create an alias in the module of the outer class
AliasTypeSymbol alias =
- new AliasTypeSymbol(Position.NOPOS, aliasname, clazz.module(),
+ new AliasTypeSymbol(Position.NOPOS, aliasname, staticsClass,
translateAttributes(ntype));
- nclazz.allConstructors().setInfo(this);
- nclazz.module().setInfo(this);
//
alias.setInfo(make.classType(nclazz));
alias.allConstructors()
diff --git a/sources/scalac/symtab/classfile/CLRPackageParser.java b/sources/scalac/symtab/classfile/CLRPackageParser.java
index 3d626e0f28..310ea7a2fd 100644
--- a/sources/scalac/symtab/classfile/CLRPackageParser.java
+++ b/sources/scalac/symtab/classfile/CLRPackageParser.java
@@ -260,14 +260,7 @@ public class CLRPackageParser extends SymbolLoader {
Name n = Name.fromString(name);
if (k < 0) {
// it's a class
- ClassSymbol clazz = new ClassSymbol(n.toTypeName(), p, completer);
- clazz.allConstructors().setInfo(completer);
- clazz.module().setInfo(completer);
- members.enter(clazz);
- Scope.Entry e = members.lookupEntry(clazz.module().name);
- if (e != Scope.Entry.NONE)
- members.unlink(e);
- members.enter(clazz.module());
+ Symbol clazz = p.newLoadedClass(JAVA, n.toTypeName(), completer, members);
map(clazz, types[i]);
} else {
importCLRNamespace(name, p, members, pp);
@@ -283,9 +276,7 @@ public class CLRPackageParser extends SymbolLoader {
Name n = Name.fromString(namespace);
if (members.lookup(n) == Symbol.NONE) {
//System.out.println("importing namespace " + namespace);
- TermSymbol module = TermSymbol.newJavaPackageModule(n, p, pp);
- members.enter(module);
- members.enter(module.moduleClass());
+ p.newLoadedPackage(n, pp, members);
}
}
diff --git a/sources/scalac/symtab/classfile/ClassfileParser.java b/sources/scalac/symtab/classfile/ClassfileParser.java
index f966d331a2..3ee3f61b1e 100644
--- a/sources/scalac/symtab/classfile/ClassfileParser.java
+++ b/sources/scalac/symtab/classfile/ClassfileParser.java
@@ -102,11 +102,11 @@ public class ClassfileParser implements ClassfileConstants {
Type classType = Type.compoundType(basetpes, locals, c);
c.setInfo(classType);
// set type of statics
- Symbol staticsClass = c.module().moduleClass();
+ Symbol staticsClass = c.dualClass();
if (staticsClass.isModuleClass()) {
Type staticsInfo = Type.compoundType(Type.EMPTY_ARRAY, statics, staticsClass);
staticsClass.setInfo(staticsInfo);
- c.module().setInfo(Type.typeRef(staticsClass.owner().thisType(),
+ staticsClass.module().setInfo(Type.typeRef(staticsClass.owner().thisType(),
staticsClass, Type.EMPTY_ARRAY));
}
basetpes[0] = supertpe;
@@ -193,7 +193,7 @@ public class ClassfileParser implements ClassfileConstants {
mods |= Modifiers.MUTABLE;
Symbol owner = c;
if ((flags & JAVA_ACC_STATIC) != 0)
- owner = c.module().moduleClass();
+ owner = c.dualClass();
Symbol s = new TermSymbol(Position.NOPOS, name, owner, mods);
s.setInfo(type);
attrib.readAttributes(s, type, FIELD_ATTR);
@@ -236,7 +236,7 @@ public class ClassfileParser implements ClassfileConstants {
} else {
Symbol s = new TermSymbol(
Position.NOPOS, name,
- ((flags & JAVA_ACC_STATIC) != 0) ? c.module().moduleClass() : c,
+ ((flags & JAVA_ACC_STATIC) != 0) ? c.dualClass() : c,
sflags);
setParamOwners(type, s);
s.setInfo(type);
diff --git a/sources/scalac/symtab/classfile/PackageParser.java b/sources/scalac/symtab/classfile/PackageParser.java
index 00e4ae1da9..a805f0c1c2 100644
--- a/sources/scalac/symtab/classfile/PackageParser.java
+++ b/sources/scalac/symtab/classfile/PackageParser.java
@@ -2,135 +2,141 @@
** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala **
** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL **
** /_____/\____/\___/\____/____/ **
-** **
-** $Id$
\* */
+// $Id$
+
package scalac.symtab.classfile;
-import ch.epfl.lamp.util.*;
-import scalac.*;
-import scalac.symtab.*;
-import scalac.util.*;
-import java.io.*;
+import java.io.IOException;
+import java.util.Iterator;
import java.util.HashMap;
+import java.util.HashSet;
+
+import ch.epfl.lamp.util.Position;
+import scalac.Global;
+import scalac.symtab.Scope;
+import scalac.symtab.SourceCompleter;
+import scalac.symtab.Symbol;
+import scalac.symtab.SymbolLoader;
+import scalac.symtab.Type;
+import scalac.util.AbstractFile;
+import scalac.util.Name;
+import scalac.util.SourceRepresentation;
+
+/**
+ * This class implements a package member loader. It can be used to
+ * complete package class symbols.
+ */
public class PackageParser extends SymbolLoader {
- /** the class parser
- */
- public ClassParser classCompletion;
- public SymblParser symblCompletion; // provisional
+ //########################################################################
+ // Private Fields
+
+ /** The JVM class file parser */
+ private final ClassParser classCompletion;
- protected final CLRPackageParser importer;
+ /** The CLR package parser */
+ private final CLRPackageParser importer;
+ //########################################################################
+ // Public Constructors
+
+ /** Initializes this instance. */
public PackageParser(Global global) {
super(global);
this.classCompletion = new ClassParser(global);
- this.symblCompletion = new SymblParser(global); // provisional
- if (global.reporter.verbose)
- System.out.println("classpath = " + global.classPath);//debug
- importer = (global.target == global.TARGET_MSIL)
+ this.importer = (global.target == global.TARGET_MSIL)
? CLRPackageParser.create(global) : null;
+ if (global.reporter.verbose)
+ global.reporter.inform("classpath = " + global.classPath);
}
- /** complete package type symbol p by loading all package members
- */
- protected String doComplete(Symbol p) {
- Scope members = new Scope();
- String dirname = null;
- HashMap/*<Symbol, AbstractFile>*/ symFile = new HashMap();
- if (!p.isRoot()) {
- dirname = SourceRepresentation.externalizeFileName(p, "/");
- }
- String[] base = global.classPath.components();
- for (int i = 0; i < base.length; i++) {
- includeMembers(
- AbstractFile.open(base[i], dirname),
- p, members, symFile);
- }
- if (global.target == global.TARGET_MSIL)
- importer.importCLRTypes(p, members, this);
- p.setInfo(Type.compoundType(Type.EMPTY_ARRAY, members, p));
- return dirname == null ? "anonymous package" : "package '"+dirname+"'";
- }
+ //########################################################################
+ // Protected Methods
- private boolean isMostRecent(AbstractFile f, Symbol previous, HashMap symFile) {
- if (previous == Symbol.NONE || previous.isPackage()) return true;
- if (previous.pos != Position.NOPOS) return false;
- AbstractFile pf = (AbstractFile) symFile.get(previous);
- if (f.getName().endsWith(".scala")) {
- if (pf.getName().endsWith(".scala")) return false;
- if (!global.separate) return true;
- }
- if (f.getName().endsWith(".class")) {
- if (pf.getName().endsWith(".class")) return false;
- if (!global.separate) return false;
- }
- return f.lastModified() > pf.lastModified();
- }
+ /** Completes the package symbol by loading all its members. */
+ protected String doComplete(Symbol peckage) {
+ boolean isRoot = peckage.isRoot();
+ String dirname = isRoot ? null
+ : SourceRepresentation.externalizeFileName(peckage, "/");
- /** read directory of a classpath directory and include members
- * in package/module scope
- */
- protected void includeMembers(AbstractFile dir, Symbol p, Scope locals,
- HashMap symFile) {
- if (dir == null)
- return;
- boolean inclClasses = p != global.definitions.ROOT_CLASS;
- String[] filenames = null;
- try {
- if ((filenames = dir.list()) == null)
- return;
- for (int j = 0; j < filenames.length; j++) {
- String fname = filenames[j];
- AbstractFile f = dir.open(fname);
- if (inclClasses && fname.endsWith(".class")) {
- Name n = Name.fromString(fname.substring(0, fname.length() - 6))
- .toTypeName();
- if (isMostRecent(f, locals.lookup(n), symFile)) {
- ClassSymbol clazz = new ClassSymbol(n, p, classCompletion);
- // todo: needed?
- clazz.allConstructors().setInfo(classCompletion);
- clazz.module().setInfo(classCompletion);
- // enter class
- locals.enter(clazz);
- // enter module
- Scope.Entry e = locals.lookupEntry(clazz.module().name);
- if (e != Scope.Entry.NONE) {
- // we already have a package of the same name; delete it
- locals.unlink(e);
- }
- locals.enter(clazz.module());
- symFile.put(clazz, f);
+ // collect JVM and source members
+ HashMap sources = new HashMap();
+ HashMap classes = new HashMap();
+ HashSet packages = new HashSet();
+ String[] base = global.classPath.components();
+ for (int i = 0; i < base.length; i++) {
+ AbstractFile dir = AbstractFile.open(base[i], dirname);
+ if (dir == null) continue;
+ try {
+ String[] filenames = dir.list();
+ if (filenames == null) continue;
+ for (int j = 0; j < filenames.length; j++) {
+ String fname = filenames[j];
+ if (fname.endsWith("/") && !fname.equals("META-INF/")) {
+ String name = fname.substring(0, fname.length() - 1);
+ packages.add(name);
+ continue;
+ }
+ if (!isRoot && fname.endsWith(".class")) {
+ String name = fname.substring(0, fname.length() - 6);
+ if (!classes.containsKey(name))
+ classes.put(name, dir.open(fname));
+ continue;
}
- } else if (inclClasses && fname.endsWith(".scala")) {
- Name n = Name.fromString(fname.substring(0, fname.length() - 6))
- .toTypeName();
- if (isMostRecent(f, locals.lookup(n), symFile)) {
- SourceCompleter completer = new SourceCompleter(global);
- ClassSymbol clazz = new ClassSymbol(n, p, completer);
- //todo: needed?
- clazz.allConstructors().setInfo(completer);
- clazz.module().setInfo(completer);
- // enter class
- locals.enter(clazz);
- locals.enter(clazz.module());
- symFile.put(clazz, f);
+ if (!isRoot && fname.endsWith(".scala")) {
+ String name = fname.substring(0, fname.length() - 6);
+ if (!sources.containsKey(name))
+ sources.put(name, dir.open(fname));
+ continue;
}
- } else if (fname.endsWith("/") && !fname.equals("META-INF/")) {
- Name n = Name.fromString(fname.substring(0, fname.length() - 1));
- if (locals.lookup(n) == Symbol.NONE) {
- TermSymbol module = TermSymbol.newJavaPackageModule(n, p, this);
- locals.enter(module);
- //todo: moduleClass needs to be entered?
- locals.enter(module.moduleClass());
- }
}
+ } catch (IOException exception) {
+ if (global.debug) exception.printStackTrace();
+ continue;
}
- } catch (IOException e) {
+ }
+
+ // 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();
+ 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();
+ SourceCompleter completer = new SourceCompleter(global);
+ peckage.newLoadedClass(0, classname, completer, members);
+ }
+ for (Iterator i = classes.entrySet().iterator(); i.hasNext(); ) {
+ HashMap.Entry entry = (HashMap.Entry)i.next();
+ String name = (String)entry.getKey();
+ AbstractFile cfile = (AbstractFile)entry.getValue();
+ packages.remove(name);
+ Name classname = Name.fromString(name).toTypeName();
+ peckage.newLoadedClass(JAVA, classname, classCompletion, members);
+ }
+ for (Iterator i = packages.iterator(); i.hasNext(); ) {
+ String name = (String)i.next();
+ peckage.newLoadedPackage(Name.fromString(name), this, members);
}
- }
+ // collect and create CLR members
+ if (importer != null) importer.importCLRTypes(peckage, members, this);
+
+ // initialize package
+ peckage.setInfo(Type.compoundType(Type.EMPTY_ARRAY, members, peckage));
+ return dirname == null ? "anonymous package" : "package '"+dirname+"'";
+ }
+ //########################################################################
}
diff --git a/sources/scalac/symtab/classfile/UnPickle.java b/sources/scalac/symtab/classfile/UnPickle.java
index 7efb9c318f..f87a411f47 100644
--- a/sources/scalac/symtab/classfile/UnPickle.java
+++ b/sources/scalac/symtab/classfile/UnPickle.java
@@ -39,10 +39,10 @@ public class UnPickle implements Kinds, Modifiers, EntryTags, TypeTags {
global = Global.instance;
if (root.isConstructor()) {
this.classroot = root.constructorClass();
- this.moduleroot = classroot.module();
+ this.moduleroot = classroot.dualClass().module();
} else if (root.isType()) {
this.classroot = root;
- this.moduleroot = classroot.module();
+ this.moduleroot = classroot.dualClass().module();
} else {
this.moduleroot = root;
this.classroot = root.owner().lookup(root.name.toTypeName());