diff options
author | Martin Odersky <odersky@gmail.com> | 2013-03-13 14:11:44 +0100 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2013-03-13 14:11:44 +0100 |
commit | 3c7a8eada3630989b07bd3022797fd42a3b8cfcc (patch) | |
tree | 0036fee8aa025e3eea8502ea08f413f6baec3a56 /src/dotty/tools/dotc/core | |
parent | d1794c15f5a5743763adeb8f8e248f9ca5f53869 (diff) | |
download | dotty-3c7a8eada3630989b07bd3022797fd42a3b8cfcc.tar.gz dotty-3c7a8eada3630989b07bd3022797fd42a3b8cfcc.tar.bz2 dotty-3c7a8eada3630989b07bd3022797fd42a3b8cfcc.zip |
Various fixes to get past Definitions#init.
Diffstat (limited to 'src/dotty/tools/dotc/core')
-rw-r--r-- | src/dotty/tools/dotc/core/Contexts.scala | 3 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/Definitions.scala | 27 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/Flags.scala | 21 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/NameOps.scala | 2 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/Printers.scala | 6 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/SymDenotations.scala | 16 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/SymbolLoaders.scala | 39 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/Symbols.scala | 29 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/Trees.scala | 1 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/TypedTrees.scala | 4 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/pickling/ClassfileParser.scala | 2 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/pickling/PickleBuffer.scala | 60 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/pickling/UnPickler.scala | 85 |
13 files changed, 194 insertions, 101 deletions
diff --git a/src/dotty/tools/dotc/core/Contexts.scala b/src/dotty/tools/dotc/core/Contexts.scala index 4b730a4aa..fd2ce2251 100644 --- a/src/dotty/tools/dotc/core/Contexts.scala +++ b/src/dotty/tools/dotc/core/Contexts.scala @@ -16,6 +16,7 @@ import reporting._ import collection.mutable import collection.immutable.BitSet import config.{Settings, Platform, JavaPlatform} +import language.implicitConversions object Contexts { @@ -156,7 +157,6 @@ object Contexts { /** Is the verbose option set? */ def verbose: Boolean = base.settings.verbose.value - /** A condensed context containing essential information of this but * no outer contexts except the initial context. */ @@ -254,6 +254,7 @@ object Contexts { .withSetting(settings.verbose, true) // !!! for now .withSetting(settings.debug, true) .withSetting(settings.Ylogcp, true) + .withSetting(settings.printtypes, true) /** The symbol loaders */ val loaders = new SymbolLoaders diff --git a/src/dotty/tools/dotc/core/Definitions.scala b/src/dotty/tools/dotc/core/Definitions.scala index d8235b1e4..880182614 100644 --- a/src/dotty/tools/dotc/core/Definitions.scala +++ b/src/dotty/tools/dotc/core/Definitions.scala @@ -31,19 +31,22 @@ class Definitions(implicit ctx: Context) { scope.enter(tparam) } - private def specialPolyClass(name: TypeName, flags: FlagSet, parentConstrs: Type*): ClassSymbol = - ctx.newClassSymbolDenoting { cls => - val paramDecls = newScope - val typeParam = newSyntheticTypeParam(cls, paramDecls) - def instantiate(tpe: Type) = - if (tpe.typeParams.nonEmpty) tpe.appliedTo(typeParam.symbolicRef) - else tpe - val parents = parentConstrs.toList map instantiate - val parentRefs: List[TypeRef] = ctx.normalizeToRefs(parents, cls, paramDecls) - ctx.SymDenotation( - cls, ScalaPackageClass, name, flags, - ClassInfo(ScalaPackageClass.thisType, cls, parentRefs, paramDecls)) + private def specialPolyClass(name: TypeName, flags: FlagSet, parentConstrs: Type*): ClassSymbol = { + val completer = new LazyType { + def complete(denot: SymDenotation): Unit = { + val cls = denot.asClass.classSymbol + val paramDecls = newScope + val typeParam = newSyntheticTypeParam(cls, paramDecls) + def instantiate(tpe: Type) = + if (tpe.typeParams.nonEmpty) tpe.appliedTo(typeParam.symbolicRef) + else tpe + val parents = parentConstrs.toList map instantiate + val parentRefs: List[TypeRef] = ctx.normalizeToRefs(parents, cls, paramDecls) + denot.info = ClassInfo(ScalaPackageClass.thisType, cls, parentRefs, paramDecls) + } } + ctx.newClassSymbol(ScalaPackageClass, name, flags, completer) + } private def mkArityArray(name: String, arity: Int, countFrom: Int): Array[ClassSymbol] = { val arr = new Array[ClassSymbol](arity) diff --git a/src/dotty/tools/dotc/core/Flags.scala b/src/dotty/tools/dotc/core/Flags.scala index 14f31a16d..1a8ff3ea8 100644 --- a/src/dotty/tools/dotc/core/Flags.scala +++ b/src/dotty/tools/dotc/core/Flags.scala @@ -1,5 +1,7 @@ package dotty.tools.dotc.core +import language.implicitConversions + object Flags { /** A FlagSet represents a set of flags. Flags are encoded as follows: @@ -65,13 +67,13 @@ object Flags { def <= (that: FlagSet) = (bits & that.bits) == bits /** This flag set with all flags transposed to be type flags */ - def toTypeFlags = FlagSet(bits & ~KINDFLAGS | TYPES) + def toTypeFlags = if (bits == 0) this else FlagSet(bits & ~KINDFLAGS | TYPES) /** This flag set with all flags transposed to be term flags */ - def toTermFlags = FlagSet(bits & ~KINDFLAGS | TERMS) + def toTermFlags = if (bits == 0) this else FlagSet(bits & ~KINDFLAGS | TERMS) /** This flag set with all flags transposed to be common flags */ - def toCommonFlags = FlagSet(bits | KINDFLAGS) + def toCommonFlags = if (bits == 0) this else FlagSet(bits | KINDFLAGS) /** The number of non-kind flags in this set */ def numFlags: Int = java.lang.Long.bitCount(bits & ~KINDFLAGS) @@ -334,7 +336,8 @@ object Flags { final val ImplClass = typeFlag(54, "<implclass>") /** An existentially bound symbol (Scala 2.x only) */ - final val Scala2Existential = typeFlag(55, "<existential>") + final val Scala2ExistentialCommon = commonFlag(55, "<existential>") + final val Scala2Existential = Scala2ExistentialCommon.toTypeFlags /** An overloaded symbol (Scala 2.x only) */ final val Scala2Overloaded = termFlag(56, "<overloaded>") @@ -354,7 +357,7 @@ object Flags { /** Flags guaranteed to be set upon symbol creation */ final val FromStartFlags = - AccessFlags | Module | Package | Deferred + AccessFlags | Module | Package | Deferred | Param | Scala2ExistentialCommon /** Flags representing access rights */ final val AccessFlags = Private | Protected | Local @@ -367,10 +370,10 @@ object Flags { final val RetainedTypeArgFlags = Covariant | Contravariant | Protected | Local /** Modules always have these flags set */ - final val ModuleCreationFlags = Module + final val ModuleCreationFlags = ModuleVal /** Module classes always have these flags set */ - final val ModuleClassCreationFlags = Module | Final + final val ModuleClassCreationFlags = ModuleClass | Final /** The flags of a type parameter */ final val TypeParamCreationFlags = TypeParam | Protected | Local @@ -393,7 +396,9 @@ object Flags { InConstructor | ImplClass /** Packages and package classes always have these flags set */ - final val PackageCreationFlags = Module | Package | Final | JavaDefined | Static + final val PackageCreationFlags = + (Module | Package | Final | JavaDefined | Static).toTermFlags + final val PackageClassCreationFlags = PackageCreationFlags.toTypeFlags /** These flags are pickled */ final val PickledFlags = flagRange(FirstFlag, FirstNotPickledFlag) diff --git a/src/dotty/tools/dotc/core/NameOps.scala b/src/dotty/tools/dotc/core/NameOps.scala index 1099afb46..f50b44ac8 100644 --- a/src/dotty/tools/dotc/core/NameOps.scala +++ b/src/dotty/tools/dotc/core/NameOps.scala @@ -104,7 +104,7 @@ object NameOps { /** The expanded name of `name` relative to this class `base` with given `separator` */ def expandedName(base: Symbol, separator: Name = nme.EXPAND_SEPARATOR)(implicit ctx: Context): N = - name.fromName((base.fullName('$') ++ separator ++ name)).asInstanceOf[N] + name.fromName(base.fullName('$') ++ separator ++ name).asInstanceOf[N] def unexpandedName(separator: Name = nme.EXPAND_SEPARATOR): N = { val idx = name.lastIndexOfSlice(separator) diff --git a/src/dotty/tools/dotc/core/Printers.scala b/src/dotty/tools/dotc/core/Printers.scala index 0b1d951aa..6e89b2034 100644 --- a/src/dotty/tools/dotc/core/Printers.scala +++ b/src/dotty/tools/dotc/core/Printers.scala @@ -385,8 +385,10 @@ object Printers { val nodeName = node.productPrefix val elems = node.productIterator.map(showElem).mkString(", ") val tpSuffix = - if (ctx.settings.printtypes.value && tree.hasType) s" | ${tree.tpe}" - else "" + if (ctx.settings.printtypes.value && tree.hasType) + s" | ${tree.tpe.asInstanceOf[Type].show}" + else + "" s"$nodeName($elems$tpSuffix)" case _ => diff --git a/src/dotty/tools/dotc/core/SymDenotations.scala b/src/dotty/tools/dotc/core/SymDenotations.scala index 68aa2f0fa..1bbeb1009 100644 --- a/src/dotty/tools/dotc/core/SymDenotations.scala +++ b/src/dotty/tools/dotc/core/SymDenotations.scala @@ -51,6 +51,9 @@ object SymDenotations { private[this] var _privateWithin: Symbol = initPrivateWithin private[this] var _annotations: List[Annotation] = Nil + if (isType) assert(_flags.toTypeFlags == _flags, this.name + " " + _flags) + if (isTerm) assert(_flags.toTermFlags == _flags, this.name + " " + _flags) + /** The owner of the symbol */ def owner: Symbol = _owner @@ -58,8 +61,11 @@ object SymDenotations { final def flags: FlagSet = { ensureCompleted(); _flags } /** Update the flag set */ - private[core] final def flags_=(flags: FlagSet): Unit = + private[core] final def flags_=(flags: FlagSet): Unit = { _flags = flags + if (isType) assert(_flags.toTypeFlags == _flags, this.name) + if (isTerm) assert(_flags.toTermFlags == _flags, this.name) + } /** Set given flags(s) of this denotation */ final def setFlag(flags: FlagSet): Unit = { _flags |= flags } @@ -67,14 +73,15 @@ object SymDenotations { /** UnsSet given flags(s) of this denotation */ final def resetFlag(flags: FlagSet): Unit = { _flags &~= flags } - final def is(fs: FlagSet) = + final def is(fs: FlagSet) = { (if (fs <= FromStartFlags) _flags else flags) is fs + } final def is(fs: FlagSet, butNot: FlagSet) = - (if (fs <= FromStartFlags) _flags else flags) is (fs, butNot) + (if (fs <= FromStartFlags && butNot <= FromStartFlags) _flags else flags) is (fs, butNot) final def is(fs: FlagConjunction) = (if (fs <= FromStartFlags) _flags else flags) is fs final def is(fs: FlagConjunction, butNot: FlagSet) = - (if (fs <= FromStartFlags) _flags else flags) is (fs, butNot) + (if (fs <= FromStartFlags && butNot <= FromStartFlags) _flags else flags) is (fs, butNot) /** The type info. * The info is an instance of TypeType iff this is a type denotation @@ -88,6 +95,7 @@ object SymDenotations { private def completedInfo(completer: LazyType): Type = { if (_flags is CompletionStarted) throw new CyclicReference(this) _flags |= CompletionStarted + println("completing "+this.debugString+"/"+owner.id) // !!! DEBUG completer.complete(this) info } diff --git a/src/dotty/tools/dotc/core/SymbolLoaders.scala b/src/dotty/tools/dotc/core/SymbolLoaders.scala index 93e8ed64a..c3b3a944f 100644 --- a/src/dotty/tools/dotc/core/SymbolLoaders.scala +++ b/src/dotty/tools/dotc/core/SymbolLoaders.scala @@ -34,8 +34,10 @@ class SymbolLoaders { /** Enter module with given `name` into scope of `owner`. */ - def enterModule(owner: Symbol, name: PreName, completer: SymbolLoader, flags: FlagSet = EmptyFlags)(implicit ctx: Context): Symbol = { - val module = ctx.newModuleSymbol(owner, name.toTermName, flags, completer, assocFile = completer.sourceFileOrNull) + def enterModule(owner: Symbol, name: PreName, completer: SymbolLoader, modFlags: FlagSet = EmptyFlags, clsFlags: FlagSet = EmptyFlags)(implicit ctx: CondensedContext): Symbol = { + def moduleCompleterFn(modul: TermSymbol, cls: ClassSymbol): LazyType = + new ModuleClassCompleter(modul, completer) + val module = ctx.newModuleSymbol(owner, name.toTermName, modFlags, clsFlags, moduleCompleterFn, assocFile = completer.sourceFileOrNull) enterNew(owner, module, completer) } @@ -65,14 +67,14 @@ class SymbolLoaders { return NoSymbol } } - ctx.newModuleSymbol(owner, pname, PackageCreationFlags, + ctx.newModuleSymbol(owner, pname, PackageCreationFlags, PackageClassCreationFlags, (module, modcls) => new PackageLoader(module, pkg)).entered } /** Enter class and module with given `name` into scope of `owner` * and give them `completer` as type. */ - def enterClassAndModule(owner: Symbol, name: PreName, completer: SymbolLoader, flags: FlagSet = EmptyFlags)(implicit ctx: Context) { + def enterClassAndModule(owner: Symbol, name: PreName, completer: SymbolLoader, flags: FlagSet = EmptyFlags)(implicit ctx: CondensedContext) { val clazz = enterClass(owner, name, completer, flags) val module = enterModule(owner, name, completer, flags) /* @@ -90,7 +92,7 @@ class SymbolLoaders { * with source completer for given `src` as type. * (overridden in interactive.Global). */ - def enterToplevelsFromSource(owner: Symbol, name: PreName, src: AbstractFile)(implicit ctx: Context) { + def enterToplevelsFromSource(owner: Symbol, name: PreName, src: AbstractFile)(implicit ctx: CondensedContext) { enterClassAndModule(owner, name, new SourcefileLoader(src)(ctx.condensed)) } @@ -107,7 +109,7 @@ class SymbolLoaders { /** Initialize toplevel class and module symbols in `owner` from class path representation `classRep` */ - def initializeFromClassPath(owner: Symbol, classRep: ClassPath#ClassRep)(implicit ctx: Context) { + def initializeFromClassPath(owner: Symbol, classRep: ClassPath#ClassRep)(implicit ctx: CondensedContext) { ((classRep.binary, classRep.source): @unchecked) match { case (Some(bin), Some(src)) if needCompile(bin, src) && !binaryOnly(owner, classRep.name) => if (ctx.settings.verbose.value) ctx.inform("[symloader] picked up newer source file for " + src.path) @@ -127,9 +129,9 @@ class SymbolLoaders { */ class PackageLoader(module: TermSymbol, classpath: ClassPath)(implicit val cctx: CondensedContext) extends LazyModuleClassInfo(module) with SymbolLoader { - protected def description = "package loader " + classpath.name + def description = "package loader " + classpath.name - protected override def doComplete(root: SymDenotation) { + def doComplete(root: SymDenotation) { assert(root is PackageClass, root) val pre = root.owner.thisType root.info = ClassInfo(pre, root.symbol.asClass, Nil, newScope, TermRef(pre, module)) @@ -192,14 +194,14 @@ trait SymbolLoader extends LazyType { implicit val cctx: CondensedContext /** Load source or class file for `root`, return */ - protected def doComplete(root: SymDenotation): Unit + def doComplete(root: SymDenotation): Unit def sourceFileOrNull: AbstractFile = null /** Description of the resource (ClassPath, AbstractFile, MsilFile) * being processed by this loader */ - protected def description: String + def description: String override def complete(root: SymDenotation): Unit = { def signalError(ex: Exception) { @@ -235,7 +237,7 @@ class ClassfileLoader(val classfile: AbstractFile)(implicit val cctx: CondensedC override def sourceFileOrNull: AbstractFile = classfile - protected def description = "class file "+ classfile.toString + def description = "class file "+ classfile.toString def rootDenots(rootDenot: ClassDenotation): (ClassDenotation, ClassDenotation) = { val linkedDenot = rootDenot.linkedClass.denot match { @@ -246,14 +248,23 @@ class ClassfileLoader(val classfile: AbstractFile)(implicit val cctx: CondensedC else (rootDenot, linkedDenot) } - protected def doComplete(root: SymDenotation) { + def doComplete(root: SymDenotation) { val (classRoot, moduleRoot) = rootDenots(root.asClass) new ClassfileParser(classfile, classRoot, moduleRoot).run() } } class SourcefileLoader(val srcfile: AbstractFile)(implicit val cctx: CondensedContext) extends SymbolLoader { - protected def description = "source file "+ srcfile.toString + def description = "source file "+ srcfile.toString override def sourceFileOrNull = srcfile - protected def doComplete(root: SymDenotation): Unit = unsupported("doComplete") + def doComplete(root: SymDenotation): Unit = unsupported("doComplete") +} + +class ModuleClassCompleter(modul: TermSymbol, classCompleter: SymbolLoader)(implicit val cctx: CondensedContext) + extends LazyModuleClassInfo(modul) with SymbolLoader { + def description: String = classCompleter.description + override def sourceFileOrNull = classCompleter.sourceFileOrNull + def doComplete(root: SymDenotation): Unit = { + classCompleter.doComplete(root) + } } diff --git a/src/dotty/tools/dotc/core/Symbols.scala b/src/dotty/tools/dotc/core/Symbols.scala index 213ddb765..809265856 100644 --- a/src/dotty/tools/dotc/core/Symbols.scala +++ b/src/dotty/tools/dotc/core/Symbols.scala @@ -15,6 +15,7 @@ import Types._, Annotations._, Positions._, StdNames._, Trees._ import Denotations.{ Denotation, SingleDenotation, MultiDenotation } import collection.mutable import io.AbstractFile +import language.implicitConversions /** Creation methods for symbols */ trait Symbols { this: Context => @@ -101,13 +102,12 @@ trait Symbols { this: Context => /** Create a module symbol with associated module class * from its non-info fields and a function producing the info * of the module class (this info may be lazy). - * @param flags The combined flags of the module and the module class - * These are masked with RetainedModuleFlags/RetainedModuleClassFlags. */ def newModuleSymbol( owner: Symbol, name: TermName, - flags: FlagSet, + modFlags: FlagSet, + clsFlags: FlagSet, infoFn: (TermSymbol, ClassSymbol) => Type, privateWithin: Symbol = NoSymbol, coord: Coord = NoCoord, @@ -117,12 +117,10 @@ trait Symbols { this: Context => val module = newNakedSymbol[TermName](coord) val modcls = newNakedClassSymbol(coord, assocFile) val cdenot = SymDenotation( - modcls, owner, name.toTypeName, - flags & RetainedModuleClassFlags | ModuleClassCreationFlags, + modcls, owner, name.toTypeName, clsFlags, infoFn(module, modcls), privateWithin) val mdenot = SymDenotation( - module, owner, name, - flags & RetainedModuleValFlags | ModuleCreationFlags, + module, owner, name, modFlags, if (cdenot.isCompleted) TypeRef(owner.thisType, name.toTypeName, modcls) else new LazyModuleInfo(modcls)(condensed)) module.denot = mdenot @@ -138,14 +136,15 @@ trait Symbols { this: Context => def newCompleteModuleSymbol( owner: Symbol, name: TermName, - flags: FlagSet, + modFlags: FlagSet, + clsFlags: FlagSet, parents: List[TypeRef], decls: Scope, privateWithin: Symbol = NoSymbol, coord: Coord = NoCoord, assocFile: AbstractFile = null): TermSymbol = newModuleSymbol( - owner, name, flags, + owner, name, modFlags, clsFlags, (module, modcls) => ClassInfo( owner.thisType, modcls, parents, decls, TermRef(owner.thisType, name, module)), privateWithin, coord, assocFile) @@ -157,7 +156,7 @@ trait Symbols { this: Context => owner: Symbol, name: TermName, infoFn: (TermSymbol, ClassSymbol) => LazyType): TermSymbol = - newModuleSymbol(owner, name, PackageCreationFlags, infoFn) + newModuleSymbol(owner, name, PackageCreationFlags, PackageClassCreationFlags, infoFn) /** Create a package symbol with associated package class * from its non-info fields its member scope. @@ -165,9 +164,13 @@ trait Symbols { this: Context => def newCompletePackageSymbol( owner: Symbol, name: TermName, - flags: FlagSet = EmptyFlags, + modFlags: FlagSet = EmptyFlags, + clsFlags: FlagSet = EmptyFlags, decls: Scope = newScope): TermSymbol = - newCompleteModuleSymbol(owner, name, flags | PackageCreationFlags, Nil, decls) + newCompleteModuleSymbol( + owner, name, + modFlags | PackageCreationFlags, clsFlags | PackageClassCreationFlags, + Nil, decls) /** Create a stub symbol that will issue a missing reference error @@ -178,7 +181,7 @@ trait Symbols { this: Context => println(s"creating stub for $name") // !!! DEBUG name match { case name: TermName => - newModuleSymbol(owner, name, EmptyFlags, stub, assocFile = file) + newModuleSymbol(owner, name, EmptyFlags, EmptyFlags, stub, assocFile = file) case name: TypeName => newClassSymbol(owner, name, EmptyFlags, stub, assocFile = file) } diff --git a/src/dotty/tools/dotc/core/Trees.scala b/src/dotty/tools/dotc/core/Trees.scala index a2b134226..bc3d83aa1 100644 --- a/src/dotty/tools/dotc/core/Trees.scala +++ b/src/dotty/tools/dotc/core/Trees.scala @@ -3,6 +3,7 @@ package dotty.tools.dotc.core import Types._, Names._, Flags._, Positions._, Contexts._, Constants._, SymDenotations._, Symbols._ import Denotations._, StdNames._ import annotation.tailrec +import language.higherKinds object Trees { diff --git a/src/dotty/tools/dotc/core/TypedTrees.scala b/src/dotty/tools/dotc/core/TypedTrees.scala index d7179e9ac..bc85961dd 100644 --- a/src/dotty/tools/dotc/core/TypedTrees.scala +++ b/src/dotty/tools/dotc/core/TypedTrees.scala @@ -97,7 +97,7 @@ object TypedTrees { def Apply(fn: Tree, args: List[Tree])(implicit ctx: Context): Apply = { val owntype = fn.tpe.widen match { case fntpe @ MethodType(pnames, ptypes) => - check(sameLength(ptypes, args)) + check(sameLength(ptypes, args), s"${fn.show}: ${fntpe.show} to ${args.map(_.show).mkString(", ")}") fntpe.instantiate(args map (_.tpe)) case _ => check(false) @@ -400,7 +400,7 @@ object TypedTrees { import Trees._ - def check(p: Boolean)(implicit ctx: Context): Unit = assert(p) + def check(p: Boolean, msg: => String = "")(implicit ctx: Context): Unit = assert(p, msg) def checkTypeArg(arg: tpd.Tree, bounds: TypeBounds)(implicit ctx: Context): Unit = { check(arg.isValueType) diff --git a/src/dotty/tools/dotc/core/pickling/ClassfileParser.scala b/src/dotty/tools/dotc/core/pickling/ClassfileParser.scala index a5a09a4cd..8699033bd 100644 --- a/src/dotty/tools/dotc/core/pickling/ClassfileParser.scala +++ b/src/dotty/tools/dotc/core/pickling/ClassfileParser.scala @@ -222,7 +222,7 @@ class ClassfileParser( case BOOL_TAG => defn.BooleanType case 'L' => def processInner(tp: Type): Type = tp match { - case tp @ TypeRef(pre, name) if !tp.symbol.isStatic => + case tp @ TypeRef(pre, name) if !(tp.symbol.owner is Flags.ModuleClass) => TypeRef(pre.widen, name) case _ => tp diff --git a/src/dotty/tools/dotc/core/pickling/PickleBuffer.scala b/src/dotty/tools/dotc/core/pickling/PickleBuffer.scala index 74abf0ed8..ebda07f7f 100644 --- a/src/dotty/tools/dotc/core/pickling/PickleBuffer.scala +++ b/src/dotty/tools/dotc/core/pickling/PickleBuffer.scala @@ -173,19 +173,37 @@ class PickleBuffer(data: Array[Byte], from: Int, to: Int) { private val (scalaTermFlagMap, scalaTypeFlagMap) = { import scala.reflect.internal.Flags._ + + // The following vals are copy-pasted from reflect.internal.Flags. + // They are unfortunately private there, so we cannot get at them directly. + // Using the public method pickledToRawFlags instead looks unattractive + // because of performance. + val IMPLICIT_PKL = (1 << 0) + val FINAL_PKL = (1 << 1) + val PRIVATE_PKL = (1 << 2) + val PROTECTED_PKL = (1 << 3) + val SEALED_PKL = (1 << 4) + val OVERRIDE_PKL = (1 << 5) + val CASE_PKL = (1 << 6) + val ABSTRACT_PKL = (1 << 7) + val DEFERRED_PKL = (1 << 8) + val METHOD_PKL = (1 << 9) + val MODULE_PKL = (1 << 10) + val INTERFACE_PKL = (1 << 11) + val corr = Map( - PROTECTED -> Protected, - OVERRIDE -> Override, - PRIVATE -> Private, - ABSTRACT -> Abstract, - DEFERRED -> Deferred, - FINAL -> Final, - METHOD -> Method, - INTERFACE -> Interface, - MODULE -> Module, - IMPLICIT -> Implicit, - SEALED -> Sealed, - CASE -> Case, + PROTECTED_PKL -> Protected, + OVERRIDE_PKL -> Override, + PRIVATE_PKL -> Private, + ABSTRACT_PKL -> Abstract, + DEFERRED_PKL -> Deferred, + FINAL_PKL -> Final, + METHOD_PKL -> Method, + INTERFACE_PKL -> Interface, + MODULE_PKL -> Module, + IMPLICIT_PKL -> Implicit, + SEALED_PKL -> Sealed, + CASE_PKL -> Case, MUTABLE -> Mutable, PARAM -> Param, PACKAGE -> Package, @@ -243,6 +261,24 @@ class PickleBuffer(data: Array[Byte], from: Int, to: Int) { (chunkMap(termMap), chunkMap(typeMap)) } + /** Pickle = majorVersion_Nat minorVersion_Nat nbEntries_Nat {Entry} + * Entry = type_Nat length_Nat [actual entries] + * + * Assumes that the ..Version_Nat are already consumed. + * + * @return an array mapping entry numbers to locations in + * the byte array where the entries start. + */ + def createIndex: Array[Int] = { + val index = new Array[Int](readNat()) // nbEntries_Nat + for (i <- 0 until index.length) { + index(i) = readIndex + readByte() // skip type_Nat + readIndex = readNat() + readIndex // read length_Nat, jump to next entry + } + index + } + def unpickleScalaFlags(sflags: Long, isType: Boolean): FlagSet = { val map: FlagMap = if (isType) scalaTypeFlagMap else scalaTermFlagMap val shift = ChunkBits diff --git a/src/dotty/tools/dotc/core/pickling/UnPickler.scala b/src/dotty/tools/dotc/core/pickling/UnPickler.scala index db3370601..c26b33758 100644 --- a/src/dotty/tools/dotc/core/pickling/UnPickler.scala +++ b/src/dotty/tools/dotc/core/pickling/UnPickler.scala @@ -72,13 +72,25 @@ object UnPickler { * @param moduleroot the top-level module class which is unpickled, or NoSymbol if inapplicable * @param filename filename associated with bytearray, only used for error messages */ -class UnPickler(bytes: Array[Byte], classRoot: ClassDenotation, moduleRoot: ClassDenotation)(implicit cctx: CondensedContext) +class UnPickler(bytes: Array[Byte], classRoot: ClassDenotation, moduleClassRoot: ClassDenotation)(implicit cctx: CondensedContext) extends PickleBuffer(bytes, 0, -1) { + def showPickled() = { + atReadPos(0, () => { + println(s"classRoot = ${classRoot.debugString}, moduleClassRoot = ${moduleClassRoot.debugString}") + util.ShowPickled.printFile(this) + }) + } + + print("unpickling "); showPickled() // !!! DEBUG + import UnPickler._ import cctx.debug + val moduleRoot = moduleClassRoot.sourceModule.denot + println(s"moduleRoot = $moduleRoot, ${moduleRoot.isTerm}") // !!! DEBUG + checkVersion() private val loadingMirror = defn // was: mirrorThatLoaded(classRoot) @@ -116,6 +128,8 @@ class UnPickler(bytes: Array[Byte], classRoot: ClassDenotation, moduleRoot: Clas } i += 1 } + finishCompletion(classRoot) + finishCompletion(moduleClassRoot) // read children last, fix for #3951 i = 0 while (i < index.length) { @@ -138,12 +152,22 @@ class UnPickler(bytes: Array[Byte], classRoot: ClassDenotation, moduleRoot: Clas case ex: BadSignature => throw ex case ex: RuntimeException => + ex.printStackTrace() // !!! DEBUG errorBadSignature(s"a runtime exception occured: $ex $ex.getMessage()") } + def finishCompletion(root: SymDenotation) = { + if (!root.isCompleted) + root.completer match { + case completer: LocalUnpickler => + completer.complete(root) + case _ => + } + } + def source: AbstractFile = { val f = classRoot.symbol.associatedFile - if (f != null) f else moduleRoot.symbol.associatedFile + if (f != null) f else moduleClassRoot.symbol.associatedFile } private def checkVersion() { @@ -157,24 +181,6 @@ class UnPickler(bytes: Array[Byte], classRoot: ClassDenotation, moduleRoot: Clas " in " + source) } - /** Pickle = majorVersion_Nat minorVersion_Nat nbEntries_Nat {Entry} - * Entry = type_Nat length_Nat [actual entries] - * - * Assumes that the ..Version_Nat are already consumed. - * - * @return an array mapping entry numbers to locations in - * the byte array where the entries start. - */ - def createIndex: Array[Int] = { - val index = new Array[Int](readNat()) // nbEntries_Nat - for (i <- 0 until index.length) { - index(i) = readIndex - readByte() // skip type_Nat - readIndex = readNat() + readIndex // read length_Nat, jump to next entry - } - index - } - /** The `decls` scope associated with given symbol */ protected def symScope(sym: Symbol) = symScopes.getOrElseUpdate(sym, newScope) @@ -231,7 +237,7 @@ class UnPickler(bytes: Array[Byte], classRoot: ClassDenotation, moduleRoot: Clas protected def isUnpickleRoot(sym: Symbol) = { val d = sym.denot - d == moduleRoot || d == classRoot + d == moduleRoot || d == moduleClassRoot || d == classRoot } /** If entry at <code>i</code> is undefined, define it by performing @@ -344,11 +350,17 @@ class UnPickler(bytes: Array[Byte], classRoot: ClassDenotation, moduleRoot: Clas val owner = readSymbolRef() val flags = unpickleScalaFlags(readLongNat(), name.isTypeName) - def isClassRoot = (name == classRoot.name) && (owner == classRoot.owner) - def isModuleRoot = (name.toTermName == moduleRoot.name.toTermName) && (owner == moduleRoot.owner) + def isClassRoot = (name == classRoot.name) && (owner == classRoot.owner) && !(flags is ModuleClass) + def isModuleClassRoot = (name == moduleClassRoot.name) && (owner == moduleClassRoot.owner) && (flags is Module) + def isModuleRoot = (name == moduleClassRoot.name.toTermName) && (owner == moduleClassRoot.owner) && (flags is Module) + + if (isClassRoot) println(s"classRoot of $classRoot found at $readIndex, flags = $flags") // !!! DEBUG + if (isModuleRoot) println(s"moduleRoot of $moduleRoot found at $readIndex, flags = $flags") // !!! DEBUG + if (isModuleClassRoot) println(s"moduleClassRoot of $moduleClassRoot found at $readIndex, flags = $flags") // !!! DEBUG def completeRoot(denot: ClassDenotation): Symbol = { - atReadPos(start.toIndex, () => localUnpickler.parseToCompletion(denot)) + denot.setFlag(flags) + denot.info = new RootUnpickler(start) denot.symbol } @@ -372,11 +384,11 @@ class UnPickler(bytes: Array[Byte], classRoot: ClassDenotation, moduleRoot: Clas cctx.newSymbol(owner, name1, flags1, localUnpickler, coord = start) case CLASSsym => if (isClassRoot) completeRoot(classRoot) - else if (isModuleRoot) completeRoot(moduleRoot) + else if (isModuleClassRoot) completeRoot(moduleClassRoot) else cctx.newClassSymbol(owner, name.asTypeName, flags, localUnpickler, coord = start) case MODULEsym | VALsym => if (isModuleRoot) { - moduleRoot.flags = flags + moduleRoot setFlag flags moduleRoot.symbol } else cctx.newSymbol(owner, name.asTermName, flags, localUnpickler, coord = start) case _ => @@ -384,7 +396,7 @@ class UnPickler(bytes: Array[Byte], classRoot: ClassDenotation, moduleRoot: Clas }) } - val localUnpickler = new LazyType { + abstract class LocalUnpickler extends LazyType { def parseToCompletion(denot: SymDenotation) = { val tag = readByte() val end = readNat() + readIndex @@ -413,17 +425,25 @@ class UnPickler(bytes: Array[Byte], classRoot: ClassDenotation, moduleRoot: Clas assert(denot is (SuperAccessor | ParamAccessor), denot) def disambiguate(alt: Symbol) = denot.info =:= denot.owner.thisType.memberInfo(alt) - val aliasRef = readNat() - val alias = at(aliasRef, readDisambiguatedSymbol(disambiguate)).asTerm + val alias = readDisambiguatedSymbolRef(disambiguate).asTerm denot.addAnnotation(Annotation.makeAlias(alias)) } } } + def startCoord(denot: SymDenotation): Coord def complete(denot: SymDenotation): Unit = { - atReadPos(denot.symbol.coord.toIndex, () => parseToCompletion(denot)) + atReadPos(startCoord(denot).toIndex, () => parseToCompletion(denot)) } } + object localUnpickler extends LocalUnpickler { + def startCoord(denot: SymDenotation): Coord = denot.symbol.coord + } + + class RootUnpickler(start: Coord) extends LocalUnpickler { + def startCoord(denot: SymDenotation): Coord = start + } + /** Convert * tp { type name = sym } forSome { sym >: L <: H } * to @@ -485,7 +505,7 @@ class UnPickler(bytes: Array[Byte], classRoot: ClassDenotation, moduleRoot: Clas else ThisType(cls) case SINGLEtpe => val pre = readTypeRef() - val sym = readDisambiguatedSymbol(_.isParameterless) + val sym = readDisambiguatedSymbolRef(_.isParameterless) if (isLocal(sym)) TermRef(pre, sym.asTerm) else TermRef(pre, sym.name.asTermName, NotAMethod) case SUPERtpe => @@ -609,6 +629,9 @@ class UnPickler(bytes: Array[Byte], classRoot: ClassDenotation, moduleRoot: Clas r.asInstanceOf[Symbol] } + protected def readDisambiguatedSymbolRef(p: Symbol => Boolean): Symbol = + at(readNat(), readDisambiguatedSymbol(p)) + protected def readNameRef(): Name = at(readNat(), readName) protected def readTypeRef(): Type = at(readNat(), () => readType()) // after the NMT_TRANSITION period, we can leave off the () => ... () protected def readConstantRef(): Constant = at(readNat(), readConstant) |