aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/core/pickling/UnPickler.scala
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2013-02-15 16:07:36 +0100
committerMartin Odersky <odersky@gmail.com>2013-02-15 16:07:36 +0100
commit5e219c1d8426da4fba6c4604e24f4bceb3573392 (patch)
treec62cccb5b0c31e3bab8c5b5e77a5911a5a8c6bbd /src/dotty/tools/dotc/core/pickling/UnPickler.scala
parent11c5251de18aab187646e3f58612b457349ebe6a (diff)
downloaddotty-5e219c1d8426da4fba6c4604e24f4bceb3573392.tar.gz
dotty-5e219c1d8426da4fba6c4604e24f4bceb3573392.tar.bz2
dotty-5e219c1d8426da4fba6c4604e24f4bceb3573392.zip
Almost completed code for unpickling and classfile loading.
Still remains: Unpicklign trees, dealing with sourcefile attributes.
Diffstat (limited to 'src/dotty/tools/dotc/core/pickling/UnPickler.scala')
-rw-r--r--src/dotty/tools/dotc/core/pickling/UnPickler.scala1149
1 files changed, 591 insertions, 558 deletions
diff --git a/src/dotty/tools/dotc/core/pickling/UnPickler.scala b/src/dotty/tools/dotc/core/pickling/UnPickler.scala
index 0183718e4..6a4dff9e2 100644
--- a/src/dotty/tools/dotc/core/pickling/UnPickler.scala
+++ b/src/dotty/tools/dotc/core/pickling/UnPickler.scala
@@ -9,66 +9,97 @@ import java.lang.Double.longBitsToDouble
import Contexts._, Symbols._, Types._, Scopes._, SymDenotations._, Names._
import StdNames._, Denotations._, NameOps._, Flags._, Constants._, Annotations._
-import Trees._
+import Trees._, Positions._
+import io.AbstractFile
import scala.reflect.internal.pickling.PickleFormat._
import scala.collection.{ mutable, immutable }
import scala.collection.mutable.ListBuffer
import scala.annotation.switch
-/** @author Martin Odersky
- * @version 1.0
- */
-abstract class UnPickler {
-
- /** Unpickle symbol table information descending from a class and/or module root
- * from an array of bytes.
- * @param bytes bytearray from which we unpickle
- * @param offset offset from which unpickling starts
- * @param classroot the top-level class which is unpickled, or NoSymbol if inapplicable
- * @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
+object UnPickler {
+
+ case class TempPolyType(tparams: List[Symbol], tpe: Type) extends UncachedGroundType
+
+ /** Temporary type for classinfos, will be decomposed on completion of the class */
+ case class TempClassInfoType(parentTypes: List[Type], decls: Scope, clazz: Symbol) extends UncachedGroundType
+
+ def depoly(tp: Type)(implicit ctx: Context): Type = tp match {
+ case TempPolyType(tparams, restpe) => PolyType.fromSymbols(tparams, restpe)
+ case tp => tp
+ }
+
+ /** Convert array parameters denoting a repeated parameter of a Java method
+ * to `JavaRepeatedParamClass` types.
*/
- def unpickle(bytes: Array[Byte], offset: Int, classRoot: Symbol, moduleRoot: Symbol, filename: String)(implicit ctx: Context) {
- try {
- new Scan(bytes, offset, classRoot, moduleRoot, filename).run()
- } catch {
- case ex: IOException =>
- throw ex
- case ex: MissingRequirementError =>
- throw ex
- case ex: Throwable =>
- /*if (settings.debug.value)*/ ex.printStackTrace()
- throw new RuntimeException("error reading Scala signature of "+filename+": "+ex.getMessage())
+ def arrayToRepeated(tp: Type)(implicit ctx: Context): Type = tp match {
+ case tp @ MethodType(paramNames, paramTypes) =>
+ val (tycon, elemtp0 :: Nil) = paramTypes.last.splitArgs
+ assert(tycon.typeSymbol == defn.ArrayClass, tp)
+ val elemtp = elemtp0 match {
+ case AndType(t1, t2) if t1.typeSymbol.isAbstractType && t2.typeSymbol == defn.ObjectClass =>
+ t1 // drop intersection with Object for abstract types in varargs. UnCurry can handle them.
+ case _ =>
+ elemtp0
+ }
+ tp.derivedMethodType(
+ paramNames,
+ paramTypes.init :+ defn.JavaRepeatedParamType.appliedTo(elemtp),
+ tp.resultType)
+ case tp @ PolyType(paramNames) =>
+ tp.derivedPolyType(paramNames, tp.paramBounds, arrayToRepeated(tp.resultType))
+ }
+
+ def assignClassFields(denot: LazyClassDenotation, info: Type, selfType: Type)(implicit ctx: Context): Unit = {
+ val cls = denot.symbol
+ val (tparams, TempClassInfoType(parents, decls, clazz)) = info match {
+ case TempPolyType(tps, cinfo) => (tps, cinfo)
+ case cinfo => (Nil, cinfo)
}
+ tparams foreach decls.enter
+ denot.parents = ctx.normalizeToRefs(parents, cls, decls)
+ denot.selfType = selfType
+ denot.decls = decls
}
+}
+
+/** Unpickle symbol table information descending from a class and/or module root
+ * from an array of bytes.
+ * @param bytes bytearray from which we unpickle
+ * @param offset offset from which unpickling starts
+ * @param classroot the top-level class which is unpickled, or NoSymbol if inapplicable
+ * @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: LazyClassDenotation, moduleRoot: LazyClassDenotation)(implicit cctx: CondensedContext)
+ extends PickleBuffer(bytes, 0, -1) {
- class Scan(_bytes: Array[Byte], offset: Int, classRoot: Symbol, moduleRoot: Symbol, filename: String)(implicit ctx: Context) extends PickleBuffer(_bytes, offset, -1) {
- //println("unpickle " + classRoot + " and " + moduleRoot)//debug
+ import UnPickler._
- protected def debug = ctx.settings.debug.value
+ protected def debug = cctx.settings.debug.value
- checkVersion()
+ checkVersion()
- private val loadingMirror = defn // was: mirrorThatLoaded(classRoot)
+ private val loadingMirror = defn // was: mirrorThatLoaded(classRoot)
- /** A map from entry numbers to array offsets */
- private val index = createIndex
+ /** A map from entry numbers to array offsets */
+ private val index = createIndex
- /** A map from entry numbers to symbols, types, or annotations */
- private val entries = new Array[AnyRef](index.length)
+ /** A map from entry numbers to symbols, types, or annotations */
+ private val entries = new Array[AnyRef](index.length)
- /** A map from symbols to their associated `decls` scopes */
- private val symScopes = mutable.HashMap[Symbol, Scope]()
+ /** A map from symbols to their associated `decls` scopes */
+ private val symScopes = mutable.HashMap[Symbol, Scope]()
- /** A map from refinement classes to their associated refinement types */
- private val refinementTypes = mutable.HashMap[Symbol, RefinedType]()
+ /** A map from refinement classes to their associated refinement types */
+ private val refinementTypes = mutable.HashMap[Symbol, RefinedType]()
- private val mk = makeTypedTree
+ private val mk = makeTypedTree
- //println("unpickled " + classRoot + ":" + classRoot.rawInfo + ", " + moduleRoot + ":" + moduleRoot.rawInfo);//debug
+ //println("unpickled " + classRoot + ":" + classRoot.rawInfo + ", " + moduleRoot + ":" + moduleRoot.rawInfo);//debug
- // Laboriously unrolled for performance.
- def run() {
+ // Laboriously unrolled for performance.
+ def run() =
+ try {
var i = 0
while (i < index.length) {
if (entries(i) == null && isSymbolEntry(i)) {
@@ -88,8 +119,7 @@ abstract class UnPickler {
readIndex = index(i)
readSymbolAnnotation()
readIndex = savedIndex
- }
- else if (isChildrenEntry(i)) {
+ } else if (isChildrenEntry(i)) {
val savedIndex = readIndex
readIndex = index(i)
readChildren()
@@ -98,533 +128,582 @@ abstract class UnPickler {
}
i += 1
}
+ } catch {
+ case ex: IOException =>
+ throw ex
+ case ex: MissingRequirementError =>
+ throw ex
+ case ex: Throwable =>
+ /*if (settings.debug.value)*/ ex.printStackTrace()
+ throw new RuntimeException("error reading Scala signature of " + source + ": " + ex.getMessage())
}
- private def checkVersion() {
- val major = readNat()
- val minor = readNat()
- if (major != MajorVersion || minor > MinorVersion)
- throw new IOException("Scala signature " + classRoot.fullName.decode +
- " has wrong version\n expected: " +
- MajorVersion + "." + MinorVersion +
- "\n found: " + major + "." + minor +
- " in "+filename)
- }
-
- /** The `decls` scope associated with given symbol */
- protected def symScope(sym: Symbol) = symScopes.getOrElseUpdate(sym, newScope)
+ def source: AbstractFile = {
+ val f = classRoot.associatedFile
+ if (f != null) f else moduleRoot.associatedFile
+ }
- /** Does entry represent an (internal) symbol */
- protected def isSymbolEntry(i: Int): Boolean = {
- val tag = bytes(index(i)).toInt
- (firstSymTag <= tag && tag <= lastSymTag &&
- (tag != CLASSsym || !isRefinementSymbolEntry(i)))
- }
+ private def checkVersion() {
+ val major = readNat()
+ val minor = readNat()
+ if (major != MajorVersion || minor > MinorVersion)
+ throw new IOException("Scala signature " + classRoot.fullName.decode +
+ " has wrong version\n expected: " +
+ MajorVersion + "." + MinorVersion +
+ "\n found: " + major + "." + minor +
+ " in " + source)
+ }
- /** Does entry represent an (internal or external) symbol */
- protected def isSymbolRef(i: Int): Boolean = {
- val tag = bytes(index(i))
- (firstSymTag <= tag && tag <= lastExtSymTag)
+ /** 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
+ }
- /** Does entry represent a name? */
- protected def isNameEntry(i: Int): Boolean = {
- val tag = bytes(index(i)).toInt
- tag == TERMname || tag == TYPEname
- }
+ /** The `decls` scope associated with given symbol */
+ protected def symScope(sym: Symbol) = symScopes.getOrElseUpdate(sym, newScope)
- /** Does entry represent a symbol annotation? */
- protected def isSymbolAnnotationEntry(i: Int): Boolean = {
- val tag = bytes(index(i)).toInt
- tag == SYMANNOT
- }
+ /** Does entry represent an (internal) symbol */
+ protected def isSymbolEntry(i: Int): Boolean = {
+ val tag = bytes(index(i)).toInt
+ (firstSymTag <= tag && tag <= lastSymTag &&
+ (tag != CLASSsym || !isRefinementSymbolEntry(i)))
+ }
- /** Does the entry represent children of a symbol? */
- protected def isChildrenEntry(i: Int): Boolean = {
- val tag = bytes(index(i)).toInt
- tag == CHILDREN
- }
+ /** Does entry represent an (internal or external) symbol */
+ protected def isSymbolRef(i: Int): Boolean = {
+ val tag = bytes(index(i))
+ (firstSymTag <= tag && tag <= lastExtSymTag)
+ }
- /** Does entry represent a refinement symbol?
- * pre: Entry is a class symbol
- */
- protected def isRefinementSymbolEntry(i: Int): Boolean = {
- val savedIndex = readIndex
- readIndex = index(i)
- val tag = readByte().toInt
- assert(tag == CLASSsym)
+ /** Does entry represent a name? */
+ protected def isNameEntry(i: Int): Boolean = {
+ val tag = bytes(index(i)).toInt
+ tag == TERMname || tag == TYPEname
+ }
- readNat(); // read length
- val result = readNameRef() == tpnme.REFINE_CLASS
- readIndex = savedIndex
- result
- }
+ /** Does entry represent a symbol annotation? */
+ protected def isSymbolAnnotationEntry(i: Int): Boolean = {
+ val tag = bytes(index(i)).toInt
+ tag == SYMANNOT
+ }
- protected def isRefinementClass(sym: Symbol): Boolean =
- sym.name == tpnme.REFINE_CLASS
+ /** Does the entry represent children of a symbol? */
+ protected def isChildrenEntry(i: Int): Boolean = {
+ val tag = bytes(index(i)).toInt
+ tag == CHILDREN
+ }
- protected def isLocal(sym: Symbol) = {
- val root = sym.topLevelClass
- sym == moduleRoot || sym == classRoot
- }
+ /** Does entry represent a refinement symbol?
+ * pre: Entry is a class symbol
+ */
+ protected def isRefinementSymbolEntry(i: Int): Boolean = {
+ val savedIndex = readIndex
+ readIndex = index(i)
+ val tag = readByte().toInt
+ assert(tag == CLASSsym)
+
+ readNat(); // read length
+ val result = readNameRef() == tpnme.REFINE_CLASS
+ readIndex = savedIndex
+ result
+ }
- /** If entry at <code>i</code> is undefined, define it by performing
- * operation <code>op</code> with <code>readIndex at start of i'th
- * entry. Restore <code>readIndex</code> afterwards.
- */
- protected def at[T <: AnyRef](i: Int, op: () => T): T = {
- var r = entries(i)
- if (r eq null) {
- val savedIndex = readIndex
- readIndex = index(i)
- r = op()
- assert(entries(i) eq null, entries(i))
- entries(i) = r
- readIndex = savedIndex
- }
- r.asInstanceOf[T]
- }
+ protected def isRefinementClass(sym: Symbol): Boolean =
+ sym.name == tpnme.REFINE_CLASS
- /** Read a name */
- protected def readName(): Name = {
- val tag = readByte()
- val len = readNat()
- tag match {
- case TERMname => termName(bytes, readIndex, len)
- case TYPEname => typeName(bytes, readIndex, len)
- case _ => errorBadSignature("bad name tag: " + tag)
- }
- }
- protected def readTermName(): TermName = readName().toTermName
- protected def readTypeName(): TypeName = readName().toTypeName
+ protected def isLocal(sym: Symbol) = isUnpickleRoot(sym.topLevelClass)
- /** Read a symbol */
- protected def readSymbol(): Symbol = readDisambiguatedSymbol(Function.const(true))()
+ protected def isUnpickleRoot(sym: Symbol) = {
+ val d = sym.denot
+ d == moduleRoot || d == classRoot
+ }
- /** Read a symbol, with possible disambiguation */
- protected def readDisambiguatedSymbol(disambiguate: Symbol => Boolean)(): Symbol = {
- val tag = readByte()
- val end = readNat() + readIndex
- def atEnd = readIndex == end
+ /** If entry at <code>i</code> is undefined, define it by performing
+ * operation <code>op</code> with <code>readIndex at start of i'th
+ * entry. Restore <code>readIndex</code> afterwards.
+ */
+ protected def at[T <: AnyRef](i: Int, op: () => T): T = {
+ var r = entries(i)
+ if (r eq null) {
+ r = atReadPos(index(i), op)
+ assert(entries(i) eq null, entries(i))
+ entries(i) = r
+ }
+ r.asInstanceOf[T]
+ }
- def readExtSymbol(): Symbol = {
- val name = readNameRef()
- val owner = if (atEnd) loadingMirror.RootClass else readSymbolRef()
+ protected def atReadPos[T](start: Int, op: () => T): T = {
+ val savedIndex = readIndex
+ readIndex = start
+ try op()
+ finally readIndex = savedIndex
+ }
- def adjust(denot: Denotation) = {
- val denot1 = if (denot.isOverloaded) denot filter disambiguate else denot
- if (denot1.isOverloaded)
- throw new TypeError(s"failure to disambiguate overloaded reference $denot1")
- val sym = denot1.symbol
- if (tag == EXTref) sym else sym.moduleClass
- }
+ /** Read a name */
+ protected def readName(): Name = {
+ val tag = readByte()
+ val len = readNat()
+ tag match {
+ case TERMname => termName(bytes, readIndex, len)
+ case TYPEname => typeName(bytes, readIndex, len)
+ case _ => errorBadSignature("bad name tag: " + tag)
+ }
+ }
+ protected def readTermName(): TermName = readName().toTermName
+ protected def readTypeName(): TypeName = readName().toTypeName
+
+ /** Read a symbol */
+ protected def readSymbol(): Symbol = readDisambiguatedSymbol(Function.const(true))()
+
+ /** Read a symbol, with possible disambiguation */
+ protected def readDisambiguatedSymbol(p: Symbol => Boolean)(): Symbol = {
+ val start = new Offset(readIndex)
+ val tag = readByte()
+ val end = readNat() + readIndex
+ def atEnd = readIndex == end
+
+ def readExtSymbol(): Symbol = {
+ val name = readNameRef()
+ val owner = if (atEnd) loadingMirror.RootClass else readSymbolRef()
+
+ def adjust(denot: Denotation) = {
+ val denot1 = denot.disambiguate(p)
+ val sym = denot1.symbol
+ if (tag == EXTref) sym else sym.moduleClass
+ }
- def fromName(name: Name): Symbol = name.toTermName match {
- case nme.ROOT => loadingMirror.RootClass
- case nme.ROOTPKG => loadingMirror.RootPackage
- case _ => adjust(owner.info.decl(name))
- }
+ def fromName(name: Name): Symbol = name.toTermName match {
+ case nme.ROOT => loadingMirror.RootClass
+ case nme.ROOTPKG => loadingMirror.RootPackage
+ case _ => adjust(owner.info.decl(name))
+ }
- def nestedObjectSymbol: Symbol = {
- // If the owner is overloaded (i.e. a method), it's not possible to select the
- // right member, so return NoSymbol. This can only happen when unpickling a tree.
- // the "case Apply" in readTree() takes care of selecting the correct alternative
- // after parsing the arguments.
- //if (owner.isOverloaded)
- // return NoSymbol
-
- if (tag == EXTMODCLASSref) {
- ???
-/*
+ def nestedObjectSymbol: Symbol = {
+ // If the owner is overloaded (i.e. a method), it's not possible to select the
+ // right member, so return NoSymbol. This can only happen when unpickling a tree.
+ // the "case Apply" in readTree() takes care of selecting the correct alternative
+ // after parsing the arguments.
+ //if (owner.isOverloaded)
+ // return NoSymbol
+
+ if (tag == EXTMODCLASSref) {
+ ???
+ /*
val moduleVar = owner.info.decl(name.toTermName.moduleVarName).symbol
if (moduleVar.isLazyAccessor)
return moduleVar.lazyAccessor.lazyAccessor
*/
- }
- NoSymbol
}
+ NoSymbol
+ }
- // (1) Try name.
- fromName(name) orElse {
- // (2) Try with expanded name. Can happen if references to private
- // symbols are read from outside: for instance when checking the children
- // of a class. See #1722.
- fromName(name.toTermName.expandedName(owner)) orElse {
- // (3) Try as a nested object symbol.
- nestedObjectSymbol orElse {
-// // (4) Call the mirror's "missing" hook.
-// adjust(mirrorThatLoaded(owner).missingHook(owner, name)) orElse {
-// }
- // (5) Create a stub symbol to defer hard failure a little longer.
- ctx.newStubSymbol(owner, name)
+ // (1) Try name.
+ fromName(name) orElse {
+ // (2) Try with expanded name. Can happen if references to private
+ // symbols are read from outside: for instance when checking the children
+ // of a class. See #1722.
+ fromName(name.toTermName.expandedName(owner)) orElse {
+ // (3) Try as a nested object symbol.
+ nestedObjectSymbol orElse {
+ // // (4) Call the mirror's "missing" hook.
+ adjust(cctx.base.missingHook(owner, name)) orElse {
+ // }
+ // (5) Create a stub symbol to defer hard failure a little longer.
+ cctx.newStubSymbol(owner, name, source)
}
}
}
}
+ }
- tag match {
- case NONEsym => return NoSymbol
- case EXTref | EXTMODCLASSref => return readExtSymbol()
- case _ => ()
- }
+ tag match {
+ case NONEsym => return NoSymbol
+ case EXTref | EXTMODCLASSref => return readExtSymbol()
+ case _ =>
+ }
+
+ // symbols that were pickled with Pickler.writeSymInfo
+ val nameref = readNat()
+ val name = at(nameref, readName)
+ val owner = readSymbolRef()
+ val flags = unpickleScalaFlags(readLongNat())
+
+ def isClassRoot = (name == classRoot.name) && (owner == classRoot.owner)
+ def isModuleRoot = (name.toTermName == moduleRoot.name.toTermName) && (owner == moduleRoot.owner)
+
+ def completeRoot(denot: LazyClassDenotation): Symbol = {
+ atReadPos(start.value, () => completeLocal(denot))
+ denot.symbol
+ }
+
+ def finishSym(sym: Symbol): Symbol = {
+ if (sym.owner.isClass && !(
+ isUnpickleRoot(sym) ||
+ (sym is (ModuleClass | TypeParam | Scala2Existential)) ||
+ isRefinementClass(sym)))
+ symScope(sym.owner) enter sym
+ sym
+ }
+
+ finishSym(tag match {
+ case TYPEsym | ALIASsym =>
+ var name1 = name.asTypeName
+ var flags1 = flags
+ if (flags is TypeParam) {
+ name1 = name1.expandedName(owner)
+ flags1 |= TypeParamFlags
+ }
+ cctx.newLazySymbol(owner, name1, flags1, symUnpickler, off = start)
+ case CLASSsym =>
+ if (isClassRoot) completeRoot(classRoot)
+ else if (isModuleRoot) completeRoot(moduleRoot)
+ else cctx.newLazyClassSymbol(owner, name.asTypeName, flags, classUnpickler, off = start)
+ case MODULEsym | VALsym =>
+ if (isModuleRoot) {
+ moduleRoot.flags = flags
+ moduleRoot.symbol
+ } else cctx.newLazySymbol(owner, name.asTermName, flags, symUnpickler, off = start)
+ case _ =>
+ errorBadSignature("bad symbol tag: " + tag)
+ })
+ }
- // symbols that were pickled with Pickler.writeSymInfo
- val nameref = readNat()
- val name = at(nameref, readName)
- val owner = readSymbolRef()
- val flags = unpickleScalaFlags(readLongNat())
- var inforef = readNat()
- val privateWithin =
+ def completeLocal[D <: SymDenotation](denot: isLazy[D]): Unit = {
+ def parseToCompletion() = {
+ val tag = readByte()
+ val end = readNat() + readIndex
+ def atEnd = readIndex == end
+ val unusedNameref = readNat()
+ val unusedOwnerref = readNat()
+ val unusedFlags = readLongNat()
+ var inforef = readNat()
+ denot.privateWithin =
if (!isSymbolRef(inforef)) NoSymbol
else {
val pw = at(inforef, readSymbol)
inforef = readNat()
pw
}
-
- def isClassRoot = (name == classRoot.name) && (owner == classRoot.owner)
- def isModuleRoot = (name.toTermName == moduleRoot.name.toTermName) && (owner == moduleRoot.owner)
-
- def completeSym(tag: Int): SymCompleter = {
- val aliasRef =
+ val tp = at(inforef, () => readType(forceProperType = denot.isTerm))
+ denot match {
+ case denot: LazySymDenotation =>
+ denot.info = if (tag == ALIASsym) TypeAlias(tp) else depoly(tp)
if (atEnd) {
- assert(!(flags is SuperAccessor), name)
- -1
+ assert(!(denot is SuperAccessor), denot)
} else {
- assert(flags is (SuperAccessor | ParamAccessor), name)
- readNat()
+ 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
+ denot.addAnnotation(Annotation.makeAlias(alias))
}
- new SymRestCompleter(tag, inforef, aliasRef)
- }
-
- def completeClass: ClassCompleter = {
- val selfTypeRef = if (atEnd) -1 else readNat()
- new ClassRestCompleter(inforef, selfTypeRef)
- }
-
- def completeRoot(sym: Symbol): Symbol = {
- completeClass.complete(sym.denot.asInstanceOf[LazyClassDenotation])
- sym
+ case denot: LazyClassDenotation =>
+ val selfType = if (atEnd) denot.typeConstructor else readTypeRef()
+ assignClassFields(denot, tp, selfType)
}
+ }
+ try {
+ atReadPos(denot.symbol.offset.value, parseToCompletion)
+ } catch {
+ case e: MissingRequirementError => throw toTypeError(e)
+ }
+ }
- def finishSym(sym: Symbol): Symbol = {
- sym.denot.asInstanceOf[isLazy[_]].privateWithin = privateWithin
- if (sym.owner.isClass && !(
- sym == classRoot ||
- sym == moduleRoot ||
- (sym is (ModuleClass | TypeParam | Scala2Existential)) ||
- isRefinementClass(sym)))
- symScope(sym.owner) enter sym
- sym
- }
+ private object symUnpickler extends SymCompleter {
+ override def complete(denot: LazySymDenotation): Unit = completeLocal(denot)
+ }
- finishSym(tag match {
- case TYPEsym | ALIASsym =>
- var name1 = name.asTypeName
- var flags1 = flags
- if (flags is TypeParam) {
- name1 = name1.expandedName(owner)
- flags1 |= TypeParamFlags
- }
- ctx.newLazySymbol(owner, name1, flags1, completeSym(tag))
- case CLASSsym =>
- if (isClassRoot) completeRoot(classRoot)
- else if (isModuleRoot) completeRoot(moduleRoot)
- else ctx.newLazyClassSymbol(owner, name.asTypeName, flags, completeClass)
- case MODULEsym =>
- val info = at(inforef, () => readType()) // after the NMT_TRANSITION period, we can leave off the () => ... ()
- if (isModuleRoot) {
- moduleRoot.denot.asInstanceOf[LazyClassDenotation].flags = flags
- moduleRoot
- } else ctx.newSymbol(owner, name.asTermName, flags, info)
- case VALsym =>
- if (isModuleRoot) { assert(false); NoSymbol }
- else ctx.newLazySymbol(owner, name.asTermName, flags, completeSym(tag))
+ private object classUnpickler extends ClassCompleter {
+ override def complete(denot: LazyClassDenotation): Unit = completeLocal(denot)
+ }
- case _ =>
- errorBadSignature("bad symbol tag: " + tag)
- })
+ /** Convert
+ * tp { type name = sym } forSome { sym >: L <: H }
+ * to
+ * tp { name >: L <: H }
+ * and
+ * tp { name: sym } forSome { sym <: T with Singleton }
+ * to
+ * tp { name: T }
+ */
+ def elimExistentials(boundSyms: List[Symbol], tp: Type): Type = {
+ def removeSingleton(tp: Type): Type =
+ if (tp.typeSymbol == defn.SingletonClass) defn.AnyType else tp
+ def elim(tp: Type): Type = tp match {
+ case tp @ RefinedType(parent, name) =>
+ val parent1 = elim(tp.parent)
+ tp.info match {
+ case TypeAlias(info: TypeRefBySym) if boundSyms contains info.fixedSym =>
+ RefinedType(parent1, name, info.fixedSym.info)
+ case info: TypeRefBySym if boundSyms contains info.fixedSym =>
+ val info1 = info.fixedSym.info
+ assert(info1 <:< defn.SingletonClass.typeConstructor)
+ RefinedType(parent1, name, info1.mapAnd(removeSingleton))
+ case info =>
+ tp.derivedRefinedType(parent1, name, info)
+ }
+ case _ =>
+ tp
}
-
- case class TempPolyType(tparams: List[Symbol], tpe: Type) extends UncachedGroundType
-
- /** Temporary type for classinfos, will be decomposed on completion of the class */
- case class TempClassInfoType(parentTypes: List[Type], decls: Scope, clazz: Symbol) extends UncachedGroundType
-
- /** Convert
- * tp { type name = sym } forSome { sym >: L <: H }
- * to
- * tp { name >: L <: H }
- * and
- * tp { name: sym } forSome { sym <: T with Singleton }
- * to
- * tp { name: T }
- */
- def elimExistentials(boundSyms: List[Symbol], tp: Type): Type = {
- def removeSingleton(tp: Type): Type =
- if (tp.typeSymbol == defn.SingletonClass) defn.AnyType else tp
- def elim(tp: Type): Type = tp match {
- case tp @ RefinedType(parent, name) =>
- val parent1 = elim(tp.parent)
- tp.info match {
- case TypeAlias(info: TypeRefBySym) if boundSyms contains info.fixedSym =>
- RefinedType(parent1, name, info.fixedSym.info)
- case info: TypeRefBySym if boundSyms contains info.fixedSym =>
- val info1 = info.fixedSym.info
- assert(info1 <:< defn.SingletonClass.typeConstructor)
- RefinedType(parent1, name, info1.mapAnd(removeSingleton))
- case info =>
- tp.derivedRefinedType(parent1, name, info)
- }
- case _ =>
- tp
- }
- val tp1 = elim(tp)
- val isBound = (tp: Type) => boundSyms contains tp.typeSymbol
- if (tp1 exists isBound) {
- val tp2 = tp1.subst(boundSyms, boundSyms map (_ => defn.AnyType))
- ctx.warning(s"""failure to eliminate existential
- |original type : $tp forSome {${ctx.show(boundSyms, "; ")}}
+ val tp1 = elim(tp)
+ val isBound = (tp: Type) => boundSyms contains tp.typeSymbol
+ if (tp1 exists isBound) {
+ val tp2 = tp1.subst(boundSyms, boundSyms map (_ => defn.AnyType))
+ cctx.warning(s"""failure to eliminate existential
+ |original type : $tp forSome {${cctx.show(boundSyms, "; ")}}
|reduces to : $tp1
|type used instead: $tp2
|proceed at own risk.""".stripMargin)
- tp2
- } else tp1
- }
+ tp2
+ } else tp1
+ }
- /** Read a type
- *
- * @param forceProperType is used to ease the transition to NullaryMethodTypes (commentmarker: NMT_TRANSITION)
- * the flag say that a type of kind * is expected, so that PolyType(tps, restpe) can be disambiguated to PolyType(tps, NullaryMethodType(restpe))
- * (if restpe is not a ClassInfoType, a MethodType or a NullaryMethodType, which leaves TypeRef/SingletonType -- the latter would make the polytype a type constructor)
- */
- protected def readType(forceProperType: Boolean = false): Type = {
- val tag = readByte()
- val end = readNat() + readIndex
- (tag: @switch) match {
- case NOtpe =>
- NoType
- case NOPREFIXtpe =>
- NoPrefix
- case THIStpe =>
- val cls = readSymbolRef().asClass
- if (isRefinementClass(cls)) RefinedThis(refinementTypes(cls))
- else ThisType(cls)
- case SINGLEtpe =>
- val pre = readTypeRef()
- def notAMethod(sym: Symbol) = sym.info match {
- case _: PolyType | _: MethodType => false
- case _ => true
- }
- val sym = readDisambiguatedSymbol(notAMethod)
- if (isLocal(sym)) TermRef(pre, sym.asTerm)
- else TermRef(pre, sym.name.asTermName, NullSignature)
- case SUPERtpe =>
- val thistpe = readTypeRef()
- val supertpe = readTypeRef()
- SuperType(thistpe, supertpe)
- case CONSTANTtpe =>
- ConstantType(readConstantRef())
- case TYPEREFtpe =>
- val pre = readTypeRef()
- val sym = readSymbolRef()
- val tycon =
- if (isLocal(sym)) TypeRef(pre, sym.asType)
- else TypeRef(pre, sym.name.asTypeName)
- tycon.appliedTo(until(end, readTypeRef))
- case TYPEBOUNDStpe =>
- TypeBounds(readTypeRef(), readTypeRef())
- case REFINEDtpe =>
- val clazz = readSymbolRef()
- val decls = symScope(clazz)
- symScopes(clazz) = EmptyScope // prevent further additions
- val parents = until(end, readTypeRef)
- val parent = parents.reduceLeft(_ & _)
- if (decls.isEmpty) parent
- else {
- def addRefinement(tp: Type, sym: Symbol) =
- RefinedType(tp, sym.name, sym.info)
- val result = (parent /: decls.toList)(addRefinement).asInstanceOf[RefinedType]
- assert(!refinementTypes.isDefinedAt(clazz), clazz+"/"+decls)
- refinementTypes(clazz) = result
- result
+ /** Read a type
+ *
+ * @param forceProperType is used to ease the transition to NullaryMethodTypes (commentmarker: NMT_TRANSITION)
+ * the flag say that a type of kind * is expected, so that PolyType(tps, restpe) can be disambiguated to PolyType(tps, NullaryMethodType(restpe))
+ * (if restpe is not a ClassInfoType, a MethodType or a NullaryMethodType, which leaves TypeRef/SingletonType -- the latter would make the polytype a type constructor)
+ */
+ protected def readType(forceProperType: Boolean = false): Type = {
+ val tag = readByte()
+ val end = readNat() + readIndex
+ (tag: @switch) match {
+ case NOtpe =>
+ NoType
+ case NOPREFIXtpe =>
+ NoPrefix
+ case THIStpe =>
+ val cls = readSymbolRef().asClass
+ if (isRefinementClass(cls)) RefinedThis(refinementTypes(cls))
+ else ThisType(cls)
+ case SINGLEtpe =>
+ val pre = readTypeRef()
+ val sym = readDisambiguatedSymbol(_.isParameterless)
+ if (isLocal(sym)) TermRef(pre, sym.asTerm)
+ else TermRef(pre, sym.name.asTermName, NullSignature)
+ case SUPERtpe =>
+ val thistpe = readTypeRef()
+ val supertpe = readTypeRef()
+ SuperType(thistpe, supertpe)
+ case CONSTANTtpe =>
+ ConstantType(readConstantRef())
+ case TYPEREFtpe =>
+ val pre = readTypeRef()
+ val sym = readSymbolRef()
+ val tycon =
+ if (isLocal(sym)) TypeRef(pre, sym.asType)
+ else TypeRef(pre, sym.name.asTypeName)
+ tycon.appliedTo(until(end, readTypeRef))
+ case TYPEBOUNDStpe =>
+ TypeBounds(readTypeRef(), readTypeRef())
+ case REFINEDtpe =>
+ val clazz = readSymbolRef()
+ val decls = symScope(clazz)
+ symScopes(clazz) = EmptyScope // prevent further additions
+ val parents = until(end, readTypeRef)
+ val parent = parents.reduceLeft(_ & _)
+ if (decls.isEmpty) parent
+ else {
+ def addRefinement(tp: Type, sym: Symbol) =
+ RefinedType(tp, sym.name, sym.info)
+ val result = (parent /: decls.toList)(addRefinement).asInstanceOf[RefinedType]
+ assert(!refinementTypes.isDefinedAt(clazz), clazz + "/" + decls)
+ refinementTypes(clazz) = result
+ result
+ }
+ case CLASSINFOtpe =>
+ val clazz = readSymbolRef()
+ TempClassInfoType(until(end, readTypeRef), symScope(clazz), clazz)
+ case METHODtpe | IMPLICITMETHODtpe =>
+ val restpe = readTypeRef()
+ val params = until(end, readSymbolRef)
+ val maker = if (tag == METHODtpe) MethodType else ImplicitMethodType
+ maker.fromSymbols(params, restpe)
+ case POLYtpe =>
+ val restpe = readTypeRef()
+ val typeParams = until(end, readSymbolRef)
+ if (typeParams.nonEmpty) {
+ // NMT_TRANSITION: old class files denoted a polymorphic nullary method as PolyType(tps, restpe), we now require PolyType(tps, NullaryMethodType(restpe))
+ // when a type of kind * is expected (forceProperType is true), we know restpe should be wrapped in a NullaryMethodType (if it wasn't suitably wrapped yet)
+ def transitionNMT(restpe: Type) = {
+ val resTpeCls = restpe.getClass.toString // what's uglier than isInstanceOf? right! -- isInstanceOf does not work since the concrete types are defined in the compiler (not in scope here)
+ if (forceProperType /*&& pickleformat < 2.9 */ && !(resTpeCls.endsWith("MethodType"))) {
+ assert(!resTpeCls.contains("ClassInfoType"))
+ ExprType(restpe)
+ } else restpe
}
- case CLASSINFOtpe =>
- val clazz = readSymbolRef()
- TempClassInfoType(until(end, readTypeRef), symScope(clazz), clazz)
- case METHODtpe | IMPLICITMETHODtpe =>
- val restpe = readTypeRef()
- val params = until(end, readSymbolRef)
- val maker = if (tag == METHODtpe) MethodType else ImplicitMethodType
- maker.fromSymbols(params, restpe)
- case POLYtpe =>
- val restpe = readTypeRef()
- val typeParams = until(end, readSymbolRef)
- if (typeParams.nonEmpty) {
- // NMT_TRANSITION: old class files denoted a polymorphic nullary method as PolyType(tps, restpe), we now require PolyType(tps, NullaryMethodType(restpe))
- // when a type of kind * is expected (forceProperType is true), we know restpe should be wrapped in a NullaryMethodType (if it wasn't suitably wrapped yet)
- def transitionNMT(restpe: Type) = {
- val resTpeCls = restpe.getClass.toString // what's uglier than isInstanceOf? right! -- isInstanceOf does not work since the concrete types are defined in the compiler (not in scope here)
- if(forceProperType /*&& pickleformat < 2.9 */ && !(resTpeCls.endsWith("MethodType"))) { assert(!resTpeCls.contains("ClassInfoType"))
- ExprType(restpe) }
- else restpe
- }
- TempPolyType(typeParams, transitionNMT(restpe))
- } else ExprType(restpe)
- case EXISTENTIALtpe =>
- val restpe = readTypeRef()
- val boundSyms = until(end, readSymbolRef)
- elimExistentials(boundSyms, restpe)
- case ANNOTATEDtpe =>
- val tp = readTypeRef()
- // no annotation self type is supported, so no test whether this is a symbol ref
- val annots = until(end, readAnnotationRef)
- AnnotatedType(annots, tp)
- case _ =>
- noSuchTypeTag(tag, end)
- }
+ TempPolyType(typeParams, transitionNMT(restpe))
+ } else ExprType(restpe)
+ case EXISTENTIALtpe =>
+ val restpe = readTypeRef()
+ val boundSyms = until(end, readSymbolRef)
+ elimExistentials(boundSyms, restpe)
+ case ANNOTATEDtpe =>
+ val tp = readTypeRef()
+ // no annotation self type is supported, so no test whether this is a symbol ref
+ val annots = until(end, readAnnotationRef)
+ AnnotatedType(annots, tp)
+ case _ =>
+ noSuchTypeTag(tag, end)
}
+ }
- def noSuchTypeTag(tag: Int, end: Int): Type =
- errorBadSignature("bad type tag: " + tag)
-
- /** Read a constant */
- protected def readConstant(): Constant = {
- val tag = readByte().toInt
- val len = readNat()
- (tag: @switch) match {
- case LITERALunit => Constant(())
- case LITERALboolean => Constant(readLong(len) != 0L)
- case LITERALbyte => Constant(readLong(len).toByte)
- case LITERALshort => Constant(readLong(len).toShort)
- case LITERALchar => Constant(readLong(len).toChar)
- case LITERALint => Constant(readLong(len).toInt)
- case LITERALlong => Constant(readLong(len))
- case LITERALfloat => Constant(intBitsToFloat(readLong(len).toInt))
- case LITERALdouble => Constant(longBitsToDouble(readLong(len)))
- case LITERALstring => Constant(readNameRef().toString)
- case LITERALnull => Constant(null)
- case LITERALclass => Constant(readTypeRef())
- case LITERALenum => Constant(readSymbolRef())
- case _ => noSuchConstantTag(tag, len)
- }
+ def noSuchTypeTag(tag: Int, end: Int): Type =
+ errorBadSignature("bad type tag: " + tag)
+
+ /** Read a constant */
+ protected def readConstant(): Constant = {
+ val tag = readByte().toInt
+ val len = readNat()
+ (tag: @switch) match {
+ case LITERALunit => Constant(())
+ case LITERALboolean => Constant(readLong(len) != 0L)
+ case LITERALbyte => Constant(readLong(len).toByte)
+ case LITERALshort => Constant(readLong(len).toShort)
+ case LITERALchar => Constant(readLong(len).toChar)
+ case LITERALint => Constant(readLong(len).toInt)
+ case LITERALlong => Constant(readLong(len))
+ case LITERALfloat => Constant(intBitsToFloat(readLong(len).toInt))
+ case LITERALdouble => Constant(longBitsToDouble(readLong(len)))
+ case LITERALstring => Constant(readNameRef().toString)
+ case LITERALnull => Constant(null)
+ case LITERALclass => Constant(readTypeRef())
+ case LITERALenum => Constant(readSymbolRef())
+ case _ => noSuchConstantTag(tag, len)
}
+ }
- def noSuchConstantTag(tag: Int, len: Int): Constant =
- errorBadSignature("bad constant tag: " + tag)
+ def noSuchConstantTag(tag: Int, len: Int): Constant =
+ errorBadSignature("bad constant tag: " + tag)
- /** Read children and store them into the corresponding symbol.
- */
- protected def readChildren() {
- val tag = readByte()
- assert(tag == CHILDREN)
- val end = readNat() + readIndex
- val target = readSymbolRef()
- while (readIndex != end)
- target.addAnnotation(Annotation.makeChild(readSymbolRef().asClass))
- }
+ /** Read children and store them into the corresponding symbol.
+ */
+ protected def readChildren() {
+ val tag = readByte()
+ assert(tag == CHILDREN)
+ val end = readNat() + readIndex
+ val target = readSymbolRef()
+ while (readIndex != end)
+ target.addAnnotation(Annotation.makeChild(readSymbolRef()))
+ }
- /* Read a reference to a pickled item */
- protected def readSymbolRef(): Symbol = {//OPT inlined from: at(readNat(), readSymbol) to save on closure creation
- val i = readNat()
- var r = entries(i)
- if (r eq null) {
- val savedIndex = readIndex
- readIndex = index(i)
- r = readSymbol()
- assert(entries(i) eq null, entries(i))
- entries(i) = r
- readIndex = savedIndex
- }
- r.asInstanceOf[Symbol]
+ /* Read a reference to a pickled item */
+ protected def readSymbolRef(): Symbol = { //OPT inlined from: at(readNat(), readSymbol) to save on closure creation
+ val i = readNat()
+ var r = entries(i)
+ if (r eq null) {
+ val savedIndex = readIndex
+ readIndex = index(i)
+ r = readSymbol()
+ assert(entries(i) eq null, entries(i))
+ entries(i) = r
+ readIndex = savedIndex
}
+ r.asInstanceOf[Symbol]
+ }
- 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)
+ 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)
- protected def readTypeNameRef(): TypeName = readNameRef().toTypeName
- protected def readTermNameRef(): TermName = readNameRef().toTermName
+ protected def readTypeNameRef(): TypeName = readNameRef().toTypeName
+ protected def readTermNameRef(): TermName = readNameRef().toTermName
- protected def readAnnotationRef(): Annotation = at(readNat(), readAnnotation)
+ protected def readAnnotationRef(): Annotation = at(readNat(), readAnnotation)
-// protected def readModifiersRef(): Modifiers = at(readNat(), readModifiers)
- protected def readTreeRef(): TypedTree = at(readNat(), readTree)
+ // protected def readModifiersRef(): Modifiers = at(readNat(), readModifiers)
+ protected def readTreeRef(): TypedTree = at(readNat(), readTree)
- protected def readTree(): TypedTree = ???
+ protected def readTree(): TypedTree = ???
- /** Read an annotation argument, which is pickled either
- * as a Constant or a Tree.
- */
- protected def readAnnotArg(i: Int): TypedTree = bytes(index(i)) match {
- case TREE => at(i, readTree)
- case _ => mk.Literal(at(i, readConstant))
- }
+ /** Read an annotation argument, which is pickled either
+ * as a Constant or a Tree.
+ */
+ protected def readAnnotArg(i: Int): TypedTree = bytes(index(i)) match {
+ case TREE => at(i, readTree)
+ case _ => mk.Literal(at(i, readConstant))
+ }
- /** Read a ClassfileAnnotArg (argument to a classfile annotation)
- */
- private def readArrayAnnotArg(): TypedTree = {
- readByte() // skip the `annotargarray` tag
- val end = readNat() + readIndex
- // array elements are trees representing instances of scala.annotation.Annotation
- mk.ArrayValue(
- mk.TypeTree(defn.AnnotationClass.typeConstructor),
- until(end, () => readClassfileAnnotArg(readNat())))
- }
+ /** Read a ClassfileAnnotArg (argument to a classfile annotation)
+ */
+ private def readArrayAnnotArg(): TypedTree = {
+ readByte() // skip the `annotargarray` tag
+ val end = readNat() + readIndex
+ // array elements are trees representing instances of scala.annotation.Annotation
+ mk.ArrayValue(
+ mk.TypeTree(defn.AnnotationClass.typeConstructor),
+ until(end, () => readClassfileAnnotArg(readNat())))
+ }
- private def readAnnotInfoArg(): TypedTree = {
- readByte() // skip the `annotinfo` tag
- val end = readNat() + readIndex
- readAnnotationContents(end)
- }
+ private def readAnnotInfoArg(): TypedTree = {
+ readByte() // skip the `annotinfo` tag
+ val end = readNat() + readIndex
+ readAnnotationContents(end)
+ }
- protected def readClassfileAnnotArg(i: Int): TypedTree = bytes(index(i)) match {
- case ANNOTINFO => at(i, readAnnotInfoArg)
- case ANNOTARGARRAY => at(i, readArrayAnnotArg)
- case _ => readAnnotArg(i)
- }
+ protected def readClassfileAnnotArg(i: Int): TypedTree = bytes(index(i)) match {
+ case ANNOTINFO => at(i, readAnnotInfoArg)
+ case ANNOTARGARRAY => at(i, readArrayAnnotArg)
+ case _ => readAnnotArg(i)
+ }
- /** Read an annotation's contents. Not to be called directly, use
- * readAnnotation, readSymbolAnnotation, or readAnnotInfoArg
- */
- protected def readAnnotationContents(end: Int): TypedTree = {
- val atp = readTypeRef()
- val args = new ListBuffer[TypedTree]
- while (readIndex != end) {
- val argref = readNat()
- args += {
- if (isNameEntry(argref)) {
- val name = at(argref, readName)
- val arg = readClassfileAnnotArg(readNat())
- mk.NamedArg(name, arg)
- } else readAnnotArg(argref)
- }
+ /** Read an annotation's contents. Not to be called directly, use
+ * readAnnotation, readSymbolAnnotation, or readAnnotInfoArg
+ */
+ protected def readAnnotationContents(end: Int): TypedTree = {
+ val atp = readTypeRef()
+ val args = new ListBuffer[TypedTree]
+ while (readIndex != end) {
+ val argref = readNat()
+ args += {
+ if (isNameEntry(argref)) {
+ val name = at(argref, readName)
+ val arg = readClassfileAnnotArg(readNat())
+ mk.NamedArg(name, arg)
+ } else readAnnotArg(argref)
}
- mk.New(atp, args.toList)
}
+ mk.New(atp, args.toList)
+ }
- /** Read an annotation and as a side effect store it into
- * the symbol it requests. Called at top-level, for all
- * (symbol, annotInfo) entries. */
- protected def readSymbolAnnotation(): Unit = {
- val tag = readByte()
- if (tag != SYMANNOT)
- errorBadSignature("symbol annotation expected ("+ tag +")")
- val end = readNat() + readIndex
- val target = readSymbolRef()
- target.addAnnotation(ConcreteAnnotation(readAnnotationContents(end)))
- }
+ /** Read an annotation and as a side effect store it into
+ * the symbol it requests. Called at top-level, for all
+ * (symbol, annotInfo) entries.
+ */
+ protected def readSymbolAnnotation(): Unit = {
+ val tag = readByte()
+ if (tag != SYMANNOT)
+ errorBadSignature("symbol annotation expected (" + tag + ")")
+ val end = readNat() + readIndex
+ val target = readSymbolRef()
+ target.addAnnotation(ConcreteAnnotation(readAnnotationContents(end)))
+ }
- /** Read an annotation and return it. Used when unpickling
- * an ANNOTATED(WSELF)tpe or a NestedAnnotArg */
- protected def readAnnotation(): Annotation = {
- val tag = readByte()
- if (tag != ANNOTINFO)
- errorBadSignature("annotation expected (" + tag + ")")
- val end = readNat() + readIndex
- ConcreteAnnotation(readAnnotationContents(end))
- }
-/*
+ /** Read an annotation and return it. Used when unpickling
+ * an ANNOTATED(WSELF)tpe or a NestedAnnotArg
+ */
+ protected def readAnnotation(): Annotation = {
+ val tag = readByte()
+ if (tag != ANNOTINFO)
+ errorBadSignature("annotation expected (" + tag + ")")
+ val end = readNat() + readIndex
+ ConcreteAnnotation(readAnnotationContents(end))
+ }
+ /*
/* Read an abstract syntax tree */
protected def readTree(): Tree = {
val outerTag = readByte()
@@ -928,68 +1007,22 @@ abstract class UnPickler {
errorBadSignature("expected an TypeDef (" + other + ")")
}
*/
- protected def errorBadSignature(msg: String) =
- throw new RuntimeException("malformed Scala signature of " + classRoot.name + " at " + readIndex + "; " + msg)
-
- protected def errorMissingRequirement(name: Name, owner: Symbol): Symbol =
- MissingRequirementError.signal(
- s"bad reference while unpickling $filename: ${ctx.showDetailed(name)} not found in $owner"
- )
-
-// def inferMethodAlternative(fun: Tree, argtpes: List[Type], restpe: Type) {} // can't do it; need a compiler for that.
-
- /** Convert to a type error, that is printed gracefully instead of crashing.
- *
- * Similar in intent to what SymbolLoader does (but here we don't have access to
- * error reporting, so we rely on the typechecker to report the error).
- */
- def toTypeError(e: MissingRequirementError) = {
- // e.printStackTrace()
- new TypeError(e.msg)
- }
+ protected def errorBadSignature(msg: String) =
+ throw new RuntimeException("malformed Scala signature of " + classRoot.name + " at " + readIndex + "; " + msg)
- def depoly(tp: Type): Type = tp match {
- case TempPolyType(tparams, restpe) => PolyType.fromSymbols(tparams, restpe)
- case tp => tp
- }
+ protected def errorMissingRequirement(name: Name, owner: Symbol): Symbol =
+ MissingRequirementError.signal(
+ s"bad reference while unpickling source: ${cctx.showDetailed(name)} not found in $owner")
- /** A lazy type which when completed returns type at index `i` and
- * if `j >= 0`, set alias of completed symbol to symbol at index `j`.
- */
- private class SymRestCompleter(tag: Int, i: Int, j: Int) extends SymCompleter {
- override def complete(denot: LazySymDenotation) : Unit = try {
- val tp = at(i, () => readType(forceProperType = denot.isTerm))
- denot.info = if (tag == ALIASsym) TypeBounds(tp, tp) else depoly(tp)
- def disambiguate(alt: Symbol) =
- denot.info =:= denot.owner.thisType.memberInfo(alt)
- if (j >= 0) {
- val alias = at(j, readDisambiguatedSymbol(disambiguate)).asTerm
- denot.addAnnotation(Annotation.makeAlias(alias))
- }
- } catch {
- case e: MissingRequirementError => throw toTypeError(e)
- }
- }
+ // def inferMethodAlternative(fun: Tree, argtpes: List[Type], restpe: Type) {} // can't do it; need a compiler for that.
- /** A lazy type which when completed returns type at index `i` and
- * if `j >= 0`, set alias of completed symbol to symbol at index `j`.
- */
- private class ClassRestCompleter(i: Int, j: Int) extends ClassCompleter {
- override def complete(denot: LazyClassDenotation) : Unit = try {
- val cls = denot.symbol
- val (tparams, TempClassInfoType(parents, decls, clazz)) =
- at(i, () => readType()) match {
- case TempPolyType(tps, cinfo) => (tps, cinfo)
- case cinfo => (Nil, cinfo)
- }
- val selfType = if (j > 0) at(j, () => readType()) else denot.typeConstructor
- tparams foreach decls.enter
- denot.parents = ctx.normalizeToRefs(parents, cls, decls)
- denot.selfType = selfType
- denot.decls = decls
- } catch {
- case e: MissingRequirementError => throw toTypeError(e)
- }
- }
+ /** Convert to a type error, that is printed gracefully instead of crashing.
+ *
+ * Similar in intent to what SymbolLoader does (but here we don't have access to
+ * error reporting, so we rely on the typechecker to report the error).
+ */
+ def toTypeError(e: MissingRequirementError) = {
+ // e.printStackTrace()
+ new TypeError(e.msg)
}
}