aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/core
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2013-03-13 14:11:44 +0100
committerMartin Odersky <odersky@gmail.com>2013-03-13 14:11:44 +0100
commit3c7a8eada3630989b07bd3022797fd42a3b8cfcc (patch)
tree0036fee8aa025e3eea8502ea08f413f6baec3a56 /src/dotty/tools/dotc/core
parentd1794c15f5a5743763adeb8f8e248f9ca5f53869 (diff)
downloaddotty-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.scala3
-rw-r--r--src/dotty/tools/dotc/core/Definitions.scala27
-rw-r--r--src/dotty/tools/dotc/core/Flags.scala21
-rw-r--r--src/dotty/tools/dotc/core/NameOps.scala2
-rw-r--r--src/dotty/tools/dotc/core/Printers.scala6
-rw-r--r--src/dotty/tools/dotc/core/SymDenotations.scala16
-rw-r--r--src/dotty/tools/dotc/core/SymbolLoaders.scala39
-rw-r--r--src/dotty/tools/dotc/core/Symbols.scala29
-rw-r--r--src/dotty/tools/dotc/core/Trees.scala1
-rw-r--r--src/dotty/tools/dotc/core/TypedTrees.scala4
-rw-r--r--src/dotty/tools/dotc/core/pickling/ClassfileParser.scala2
-rw-r--r--src/dotty/tools/dotc/core/pickling/PickleBuffer.scala60
-rw-r--r--src/dotty/tools/dotc/core/pickling/UnPickler.scala85
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)