aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/core
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2013-08-20 11:55:56 +0200
committerMartin Odersky <odersky@gmail.com>2013-08-20 11:59:59 +0200
commitb048b321f5f700804ce4e3e67720eb65297eaf39 (patch)
tree56205d39392df6526089e82b83094320ea2ed27a /src/dotty/tools/dotc/core
parent9113c243875cd7f6c8ae6774834ea9a0a468acbc (diff)
downloaddotty-b048b321f5f700804ce4e3e67720eb65297eaf39.tar.gz
dotty-b048b321f5f700804ce4e3e67720eb65297eaf39.tar.bz2
dotty-b048b321f5f700804ce4e3e67720eb65297eaf39.zip
Refactored scheme for maintaining sourceModule, moduleClass and decls in lazy types.
New scheme is more composable.
Diffstat (limited to 'src/dotty/tools/dotc/core')
-rw-r--r--src/dotty/tools/dotc/core/SymDenotations.scala53
-rw-r--r--src/dotty/tools/dotc/core/SymbolLoaders.scala6
-rw-r--r--src/dotty/tools/dotc/core/pickling/ClassfileParser.scala4
-rw-r--r--src/dotty/tools/dotc/core/pickling/UnPickler.scala31
4 files changed, 42 insertions, 52 deletions
diff --git a/src/dotty/tools/dotc/core/SymDenotations.scala b/src/dotty/tools/dotc/core/SymDenotations.scala
index 789f320bb..f05712d78 100644
--- a/src/dotty/tools/dotc/core/SymDenotations.scala
+++ b/src/dotty/tools/dotc/core/SymDenotations.scala
@@ -157,8 +157,10 @@ object SymDenotations {
/** The symbols defined in this class.
*/
final def decls(implicit ctx: Context): Scope = myInfo match {
- case cinfo: ClassCompleterWithDecls => cinfo.decls
- case cinfo: LazyType => completeFrom(cinfo); decls // complete-once
+ case cinfo: LazyType =>
+ val knownDecls = cinfo.decls
+ if (knownDecls ne EmptyScope) knownDecls
+ else { completeFrom(cinfo); decls } // complete-once
case _ => info.decls
}
@@ -453,7 +455,7 @@ object SymDenotations {
myInfo match {
case info: TypeRefBySym => info.fixedSym
case ExprType(info: TypeRefBySym) => info.fixedSym // needed after uncurry, when module terms might be accessor defs
- case info: LazyTypeOfModule => info.moduleClass
+ case info: LazyType => info.moduleClass
case _ => println(s"missing module class for $name: $myInfo"); NoSymbol
}
else {
@@ -465,7 +467,7 @@ object SymDenotations {
final def sourceModule: Symbol = myInfo match {
case ClassInfo(_, _, _, _, selfType: TermRefBySym) if this is ModuleClass =>
selfType.fixedSym
- case info: LazyTypeOfModuleClass =>
+ case info: LazyType =>
info.sourceModule
case _ =>
NoSymbol
@@ -1050,39 +1052,36 @@ object SymDenotations {
*/
abstract class LazyType extends UncachedGroundType
with (Symbol => LazyType)
- with ((TermSymbol, ClassSymbol) => LazyType) {
+ with ((TermSymbol, ClassSymbol) => LazyType) { self =>
/** Sets all missing fields of given denotation */
def complete(denot: SymDenotation): Unit
def apply(sym: Symbol) = this
def apply(module: TermSymbol, modcls: ClassSymbol) = this
- }
- /** A base type for completers of module classes that knows about `sourceModule` */
- trait LazyTypeOfModuleClass extends LazyType {
- def sourceModule: Symbol
- }
+ private var myDecls: Scope = EmptyScope
+ private var mySourceModuleFn: () => Symbol = NoSymbolFn
+ private var myModuleClass: Symbol = NoSymbol
- trait LazyTypeOfModule extends LazyType {
- def moduleClass: Symbol
- }
+ def proxy: LazyType = new LazyType {
+ override def complete(denot: SymDenotation) = self.complete(denot)
+ }
- /** A lazy type for completing a class that already has a scope with all
- * declarations in the class.
- */
- class ClassCompleterWithDecls(val decls: Scope, underlying: LazyType = NoCompleter)
- extends LazyType {
- def complete(denot: SymDenotation): Unit = underlying.complete(denot)
+ def decls: Scope = myDecls
+ def sourceModule: Symbol = mySourceModuleFn()
+ def moduleClass: Symbol = myModuleClass
+
+ def withDecls(decls: Scope): this.type = { myDecls = decls; this }
+ def withSourceModule(sourceModule: => Symbol): this.type = { mySourceModuleFn = () => sourceModule; this }
+ def withModuleClass(moduleClass: Symbol): this.type = { myModuleClass = moduleClass; this }
}
- /** A lazy type for completing a class that already has a scope with all
- * declarations in the class.
- */
- class ModuleClassCompleterWithDecls(module: Symbol, decls: Scope, underlying: LazyType = NoCompleter)
- extends ClassCompleterWithDecls(decls, underlying) with LazyTypeOfModuleClass {
- override def sourceModule = module
- }
+ val NoSymbolFn = () => NoSymbol
+
+ class NoCompleter extends LazyType {
+ def complete(denot: SymDenotation): Unit = unsupported("complete")
+ }
/** A missing completer */
object NoCompleter extends LazyType {
@@ -1095,7 +1094,7 @@ object SymDenotations {
* module class, followed by copying the relevant fields to the module.
*/
class ModuleCompleter(override val moduleClass: ClassSymbol)(implicit cctx: CondensedContext)
- extends LazyTypeOfModule {
+ extends LazyType {
def complete(denot: SymDenotation): Unit = {
val from = denot.moduleClass.denot.asClass
denot.setFlag(from.flags.toTermFlags & RetainedModuleValFlags)
diff --git a/src/dotty/tools/dotc/core/SymbolLoaders.scala b/src/dotty/tools/dotc/core/SymbolLoaders.scala
index 791501ad5..097ab8e9e 100644
--- a/src/dotty/tools/dotc/core/SymbolLoaders.scala
+++ b/src/dotty/tools/dotc/core/SymbolLoaders.scala
@@ -49,7 +49,7 @@ class SymbolLoaders {
modFlags: FlagSet = EmptyFlags, clsFlags: FlagSet = EmptyFlags, scope: Scope = EmptyScope)(implicit ctx: CondensedContext): Symbol = {
val module = ctx.newModuleSymbol(
owner, name.toTermName, modFlags, clsFlags,
- (modul, _) => new ModuleClassCompleterWithDecls(modul, newScope, completer),
+ (modul, _) => completer.proxy withDecls newScope withSourceModule modul,
assocFile = completer.sourceFileOrNull)
enterNew(owner, module, completer, scope)
}
@@ -142,7 +142,7 @@ class SymbolLoaders {
/** Load contents of a package
*/
class PackageLoader(override val sourceModule: TermSymbol, classpath: ClassPath)(implicit val cctx: CondensedContext)
- extends SymbolLoader with LazyTypeOfModuleClass {
+ extends SymbolLoader {
def description = "package loader " + classpath.name
private[core] val preDecls: MutableScope = newScope
@@ -277,7 +277,7 @@ class ClassfileLoader(val classfile: AbstractFile)(implicit val cctx: CondensedC
else
cctx.newModuleSymbol(
rootDenot.owner, rootDenot.name.toTermName, Synthetic, Synthetic,
- (module, _) => new ModuleClassCompleterWithDecls(module, newScope))
+ (module, _) => new NoCompleter() withDecls newScope withSourceModule module)
.moduleClass.denot.asClass
}
if (rootDenot is ModuleClass) (linkedDenot, rootDenot)
diff --git a/src/dotty/tools/dotc/core/pickling/ClassfileParser.scala b/src/dotty/tools/dotc/core/pickling/ClassfileParser.scala
index e07f87b1d..ce26c604e 100644
--- a/src/dotty/tools/dotc/core/pickling/ClassfileParser.scala
+++ b/src/dotty/tools/dotc/core/pickling/ClassfileParser.scala
@@ -35,8 +35,8 @@ class ClassfileParser(
protected var currentClassName: Name = _ // JVM name of the current class
protected var classTParams = Map[Name,Symbol]()
- classRoot.info = new ClassCompleterWithDecls(instanceScope)
- moduleRoot.info = new ModuleClassCompleterWithDecls(staticModule, staticScope)
+ classRoot.info = (new NoCompleter).withDecls(instanceScope)
+ moduleRoot.info = (new NoCompleter).withDecls(staticScope).withSourceModule(staticModule)
private def currentIsTopLevel = classRoot.owner is Flags.PackageClass
diff --git a/src/dotty/tools/dotc/core/pickling/UnPickler.scala b/src/dotty/tools/dotc/core/pickling/UnPickler.scala
index 65b140edd..d99bc0278 100644
--- a/src/dotty/tools/dotc/core/pickling/UnPickler.scala
+++ b/src/dotty/tools/dotc/core/pickling/UnPickler.scala
@@ -452,14 +452,14 @@ class UnPickler(bytes: Array[Byte], classRoot: ClassDenotation, moduleClassRoot:
// create a type alias instead
cctx.newSymbol(owner, name, flags, localMemberUnpickler, coord = start)
else {
- def completer(cls: Symbol) =
+ def completer(cls: Symbol) = {
+ val unpickler = new LocalUnpickler() withDecls symScope(cls)
if (flags is ModuleClass)
- new LocalClassUnpickler(cls) with LazyTypeOfModuleClass {
- override def sourceModule =
- cls.owner.decls.lookup(cls.name.stripModuleClassSuffix.toTermName)
- .suchThat(_ is Module).symbol
- }
- else new LocalClassUnpickler(cls)
+ unpickler withSourceModule (
+ cls.owner.decls.lookup(cls.name.stripModuleClassSuffix.toTermName)
+ .suchThat(_ is Module).symbol)
+ else unpickler
+ }
cctx.newClassSymbol(owner, name.asTypeName, flags, completer, coord = start)
}
case MODULEsym | VALsym =>
@@ -472,7 +472,7 @@ class UnPickler(bytes: Array[Byte], classRoot: ClassDenotation, moduleClassRoot:
})
}
- abstract class LocalUnpickler extends LazyType {
+ class LocalUnpickler extends LazyType {
def parseToCompletion(denot: SymDenotation) = {
val tag = readByte()
val end = readNat() + readIndex
@@ -520,21 +520,12 @@ class UnPickler(bytes: Array[Byte], classRoot: ClassDenotation, moduleClassRoot:
}
}
- class AtStartUnpickler(start: Coord) extends LocalUnpickler {
- override def startCoord(denot: SymDenotation): Coord = start
- }
-
object localMemberUnpickler extends LocalUnpickler
- class LocalClassUnpickler(cls: Symbol)
- extends ClassCompleterWithDecls(symScope(cls), localMemberUnpickler)
-
def rootClassUnpickler(start: Coord, cls: Symbol, module: Symbol) =
- new ClassCompleterWithDecls(symScope(cls), new AtStartUnpickler(start))
- with LazyTypeOfModuleClass
- with SymbolLoaders.SecondCompleter {
- override def sourceModule = module
- }
+ (new LocalUnpickler with SymbolLoaders.SecondCompleter {
+ override def startCoord(denot: SymDenotation): Coord = start
+ }) withDecls symScope(cls) withSourceModule module
/** Convert
* tp { type name = sym } forSome { sym >: L <: H }