aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/core
diff options
context:
space:
mode:
Diffstat (limited to 'src/dotty/tools/dotc/core')
-rw-r--r--src/dotty/tools/dotc/core/StdNames.scala6
-rw-r--r--src/dotty/tools/dotc/core/TypeApplications.scala5
-rw-r--r--src/dotty/tools/dotc/core/TypeComparer.scala2
-rw-r--r--src/dotty/tools/dotc/core/Types.scala10
-rw-r--r--src/dotty/tools/dotc/core/classfile/ClassfileParser.scala2
-rw-r--r--src/dotty/tools/dotc/core/tasty/PositionPickler.scala26
-rw-r--r--src/dotty/tools/dotc/core/tasty/TastyFormat.scala153
-rw-r--r--src/dotty/tools/dotc/core/tasty/TastyPickler.scala11
-rw-r--r--src/dotty/tools/dotc/core/tasty/TreeBuffer.scala27
-rw-r--r--src/dotty/tools/dotc/core/tasty/TreePickler.scala398
-rw-r--r--src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala132
-rw-r--r--src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala24
12 files changed, 449 insertions, 347 deletions
diff --git a/src/dotty/tools/dotc/core/StdNames.scala b/src/dotty/tools/dotc/core/StdNames.scala
index 920c9635e..c2a14b36f 100644
--- a/src/dotty/tools/dotc/core/StdNames.scala
+++ b/src/dotty/tools/dotc/core/StdNames.scala
@@ -735,15 +735,11 @@ object StdNames {
class ScalaTypeNames extends ScalaNames[TypeName] {
protected implicit def fromString(s: String): TypeName = typeName(s)
- def syntheticTypeParamName(i: Int): TypeName = "T" + i
- def syntheticLambdaParamName(i: Int): TypeName = "X" + i
+ def syntheticTypeParamName(i: Int): TypeName = "X" + i
def syntheticTypeParamNames(num: Int): List[TypeName] =
(0 until num).map(syntheticTypeParamName)(breakOut)
- def syntheticLambdaParamNames(num: Int): List[TypeName] =
- (0 until num).map(syntheticLambdaParamName)(breakOut)
-
final val Conforms = encode("<:<")
final val Uninstantiated: TypeName = "?$"
diff --git a/src/dotty/tools/dotc/core/TypeApplications.scala b/src/dotty/tools/dotc/core/TypeApplications.scala
index 8aaf77032..70819e590 100644
--- a/src/dotty/tools/dotc/core/TypeApplications.scala
+++ b/src/dotty/tools/dotc/core/TypeApplications.scala
@@ -340,10 +340,11 @@ class TypeApplications(val self: Type) extends AnyVal {
def LambdaAbstract(tparams: List[TypeParamInfo])(implicit ctx: Context): Type = {
def expand(tp: Type) =
PolyType(
- tpnme.syntheticLambdaParamNames(tparams.length), tparams.map(_.paramVariance))(
+ tparams.map(_.paramName), tparams.map(_.paramVariance))(
tl => tparams.map(tparam => tl.lifted(tparams, tparam.paramBounds).bounds),
tl => tl.lifted(tparams, tp))
- self match {
+ if (tparams.isEmpty) self
+ else self match {
case self: TypeAlias =>
self.derivedTypeAlias(expand(self.alias))
case self @ TypeBounds(lo, hi) =>
diff --git a/src/dotty/tools/dotc/core/TypeComparer.scala b/src/dotty/tools/dotc/core/TypeComparer.scala
index 0e1d373a8..f78820fff 100644
--- a/src/dotty/tools/dotc/core/TypeComparer.scala
+++ b/src/dotty/tools/dotc/core/TypeComparer.scala
@@ -1267,7 +1267,7 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
original(tp1.appliedTo(tp1.typeParams.map(_.paramBoundsAsSeenFrom(tp1))), tp2)
else
PolyType(
- paramNames = tpnme.syntheticLambdaParamNames(tparams1.length),
+ paramNames = tpnme.syntheticTypeParamNames(tparams1.length),
variances = (tparams1, tparams2).zipped.map((tparam1, tparam2) =>
(tparam1.paramVariance + tparam2.paramVariance) / 2))(
paramBoundsExp = tl => (tparams1, tparams2).zipped.map((tparam1, tparam2) =>
diff --git a/src/dotty/tools/dotc/core/Types.scala b/src/dotty/tools/dotc/core/Types.scala
index ae248295c..89bc21929 100644
--- a/src/dotty/tools/dotc/core/Types.scala
+++ b/src/dotty/tools/dotc/core/Types.scala
@@ -2526,7 +2526,7 @@ object Types {
case _: MethodType => true
case _ => false
}
-
+
/** Is this polytype a higher-kinded type lambda as opposed to a polymorphic?
* method type? Only type lambdas get created with variances, that's how we can tell.
*/
@@ -2621,17 +2621,11 @@ object Types {
unique(new PolyType(paramNames, vs)(paramBoundsExp, resultTypeExp))
}
- def fromSymbols(tparams: List[Symbol], resultType: Type)(implicit ctx: Context): Type =
- if (tparams.isEmpty) resultType
- else apply(tparams map (_.name.asTypeName), tparams.map(_.variance))(
- pt => tparams.map(tparam => pt.lifted(tparams, tparam.info).bounds),
- pt => pt.lifted(tparams, resultType))
-
def unapply(tl: PolyType): Some[(List[LambdaParam], Type)] =
Some((tl.typeParams, tl.resType))
def any(n: Int)(implicit ctx: Context) =
- apply(tpnme.syntheticLambdaParamNames(n), List.fill(n)(0))(
+ apply(tpnme.syntheticTypeParamNames(n), List.fill(n)(0))(
pt => List.fill(n)(TypeBounds.empty), pt => defn.AnyType)
}
diff --git a/src/dotty/tools/dotc/core/classfile/ClassfileParser.scala b/src/dotty/tools/dotc/core/classfile/ClassfileParser.scala
index 1570dbca0..97a82e80d 100644
--- a/src/dotty/tools/dotc/core/classfile/ClassfileParser.scala
+++ b/src/dotty/tools/dotc/core/classfile/ClassfileParser.scala
@@ -217,7 +217,7 @@ class ClassfileParser(
if (isEnum) denot.info = ConstantType(Constant(sym))
if (isConstructor) stripOuterParamFromConstructor()
setPrivateWithin(denot, jflags)
- denot.info = depoly(parseAttributes(sym, denot.info), denot)
+ denot.info = translateTempPoly(parseAttributes(sym, denot.info))
if (isConstructor) normalizeConstructorInfo()
if ((denot is Flags.Method) && (jflags & JAVA_ACC_VARARGS) != 0)
diff --git a/src/dotty/tools/dotc/core/tasty/PositionPickler.scala b/src/dotty/tools/dotc/core/tasty/PositionPickler.scala
index 4b67bc188..546894a9e 100644
--- a/src/dotty/tools/dotc/core/tasty/PositionPickler.scala
+++ b/src/dotty/tools/dotc/core/tasty/PositionPickler.scala
@@ -13,7 +13,7 @@ import collection.mutable
import TastyBuffer._
import util.Positions._
-class PositionPickler(pickler: TastyPickler, addrsOfTree: tpd.Tree => List[Addr]) {
+class PositionPickler(pickler: TastyPickler, addrOfTree: tpd.Tree => Option[Addr]) {
val buf = new TastyBuffer(5000)
pickler.newSection("Positions", buf)
import buf._
@@ -21,21 +21,6 @@ class PositionPickler(pickler: TastyPickler, addrsOfTree: tpd.Tree => List[Addr]
private val remainingAddrs = new java.util.IdentityHashMap[Tree, Iterator[Addr]]
- def nextTreeAddr(tree: Tree): Option[Addr] = remainingAddrs.get(tree) match {
- case null =>
- addrsOfTree(tree) match {
- case Nil =>
- None
- case addr :: Nil =>
- Some(addr)
- case addrs =>
- remainingAddrs.put(tree, addrs.iterator)
- nextTreeAddr(tree)
- }
- case it: Iterator[_] =>
- if (it.hasNext) Some(it.next) else None
- }
-
def header(addrDelta: Int, hasStartDelta: Boolean, hasEndDelta: Boolean, hasPoint: Boolean) = {
def toInt(b: Boolean) = if (b) 1 else 0
(addrDelta << 3) | (toInt(hasStartDelta) << 2) | (toInt(hasEndDelta) << 1) | toInt(hasPoint)
@@ -60,8 +45,7 @@ class PositionPickler(pickler: TastyPickler, addrsOfTree: tpd.Tree => List[Addr]
*/
def alwaysNeedsPos(x: Positioned) = x match {
case _: WithLazyField[_] // initialPos is inaccurate for trees with lazy field
- | _: Trees.PackageDef[_] => true // package defs might be split into several Tasty files
- case x: Trees.Tree[_] => x.isType // types are unpickled as TypeTrees, so child positions are not available
+ | _: Trees.PackageDef[_] => true // package defs might be split into several Tasty files
case _ => false
}
@@ -69,7 +53,7 @@ class PositionPickler(pickler: TastyPickler, addrsOfTree: tpd.Tree => List[Addr]
case x: Tree @unchecked =>
val pos = if (x.isInstanceOf[MemberDef]) x.pos else x.pos.toSynthetic
if (pos.exists && (pos != x.initialPos.toSynthetic || alwaysNeedsPos(x))) {
- nextTreeAddr(x) match {
+ addrOfTree(x) match {
case Some(addr) =>
//println(i"pickling $x with $pos at $addr")
pickleDeltas(addr.index, pos)
@@ -79,13 +63,15 @@ class PositionPickler(pickler: TastyPickler, addrsOfTree: tpd.Tree => List[Addr]
}
//else if (x.pos.exists) println(i"skipping $x")
x match {
- case x: MemberDef @unchecked =>
+ case x: MemberDef @unchecked =>
for (ann <- x.symbol.annotations) traverse(ann.tree)
case _ =>
}
traverse(x.productIterator)
case xs: TraversableOnce[_] =>
xs.foreach(traverse)
+ case x: Annotation =>
+ traverse(x.tree)
case _ =>
}
traverse(roots)
diff --git a/src/dotty/tools/dotc/core/tasty/TastyFormat.scala b/src/dotty/tools/dotc/core/tasty/TastyFormat.scala
index f9743d9d2..cb1b56c3c 100644
--- a/src/dotty/tools/dotc/core/tasty/TastyFormat.scala
+++ b/src/dotty/tools/dotc/core/tasty/TastyFormat.scala
@@ -71,10 +71,11 @@ Standard-Section: "ASTs" TopLevelStat*
Term = Path
Application
- IDENT NameRef Type // used when ident’s type is not a TermRef
+ IDENT NameRef Type // used when term ident’s type is not a TermRef
SELECT possiblySigned_NameRef qual_Term
+ QUALTHIS typeIdent_Tree
NEW cls_Type
- SUPER Length this_Term mixinTrait_Type?
+ SUPER Length this_Term mixinTypeIdent_Tree?
TYPED Length expr_Term ascription_Type
NAMEDARG Length paramName_NameRef arg_Term
ASSIGN Length lhs_Term rhs_Term
@@ -89,6 +90,17 @@ Standard-Section: "ASTs" TopLevelStat*
BIND Length boundName_NameRef patType_Type pat_Term
ALTERNATIVE Length alt_Term*
UNAPPLY Length fun_Term ImplicitArg* pat_Type pat_Term*
+ IDENTtpt NameRef Type // used for all type idents
+ SELECTtpt NameRef qual_Term
+ SINGLETONtpt Path
+ REFINEDtpt Length underlying_Term refinement_Stat*
+ APPLIEDtpt Length tycon_Term arg_Term*
+ POLYtpt Length TypeParam* body_Term
+ TYPEBOUNDStpt Length low_Term high_Term
+ ANNOTATEDtpt Length underlying_Term fullAnnotation_Term
+ ANDtpt Length left_Term right_Term
+ ORtpt Length left_Term right_Term
+ BYNAMEtpt underlying_Term
EMPTYTREE
SHARED term_ASTRef
Application = APPLY Length fn_Term arg_Term*
@@ -133,7 +145,7 @@ Standard-Section: "ASTs" TopLevelStat*
APPLIEDtype Length tycon_Type arg_Type*
TYPEBOUNDS Length low_Type high_Type
TYPEALIAS Length alias_Type (COVARIANT | CONTRAVARIANT)?
- ANNOTATED Length underlying_Type fullAnnotation_Term
+ ANNOTATEDtype Length underlying_Type fullAnnotation_Term
ANDtype Length left_Type right_Type
ORtype Length left_Type right_Type
BIND Length boundName_NameRef bounds_Type
@@ -268,22 +280,27 @@ object TastyFormat {
final val RENAMED = 79
final val THIS = 96
- final val CLASSconst = 97
- final val ENUMconst = 98
- final val BYNAMEtype = 99
- final val NEW = 100
- final val IMPLICITarg = 101
- final val PRIVATEqualified = 102
- final val PROTECTEDqualified = 103
- final val RECtype = 104
+ final val QUALTHIS = 97
+ final val CLASSconst = 98
+ final val ENUMconst = 99
+ final val BYNAMEtype = 100
+ final val BYNAMEtpt = 101
+ final val NEW = 102
+ final val IMPLICITarg = 103
+ final val PRIVATEqualified = 104
+ final val PROTECTEDqualified = 105
+ final val RECtype = 106
+ final val SINGLETONtpt = 107
final val IDENT = 112
- final val SELECT = 113
- final val TERMREFsymbol = 114
- final val TERMREF = 115
- final val TYPEREFsymbol = 116
- final val TYPEREF = 117
- final val SELFDEF = 118
+ final val IDENTtpt = 113
+ final val SELECT = 114
+ final val SELECTtpt = 115
+ final val TERMREFsymbol = 116
+ final val TERMREF = 117
+ final val TYPEREFsymbol = 118
+ final val TYPEREF = 119
+ final val SELFDEF = 120
final val PACKAGE = 128
final val VALDEF = 129
@@ -293,39 +310,44 @@ object TastyFormat {
final val TYPEPARAM = 133
final val PARAMS = 134
final val PARAM = 136
-
- final val APPLY = 139
- final val TYPEAPPLY = 140
-
- final val TYPED = 143
- final val NAMEDARG = 144
- final val ASSIGN = 145
- final val BLOCK = 146
- final val IF = 147
- final val LAMBDA = 148
- final val MATCH = 149
- final val RETURN = 150
- final val TRY = 151
- final val INLINED = 152
- final val REPEATED = 153
- final val BIND = 154
- final val ALTERNATIVE = 155
- final val UNAPPLY = 156
- final val ANNOTATED = 157
- final val CASEDEF = 158
- final val TEMPLATE = 160
- final val SUPER = 163
- final val SUPERtype = 166
- final val REFINEDtype = 167
- final val APPLIEDtype = 168
- final val TYPEBOUNDS = 169
- final val TYPEALIAS = 170
- final val ANDtype = 171
- final val ORtype = 172
- final val METHODtype = 174
- final val POLYtype = 175
- final val PARAMtype = 176
- final val ANNOTATION = 177
+ final val APPLY = 137
+ final val TYPEAPPLY = 138
+ final val TYPED = 139
+ final val NAMEDARG = 140
+ final val ASSIGN = 141
+ final val BLOCK = 142
+ final val IF = 143
+ final val LAMBDA = 144
+ final val MATCH = 145
+ final val RETURN = 146
+ final val TRY = 147
+ final val INLINED = 148
+ final val REPEATED = 149
+ final val BIND = 150
+ final val ALTERNATIVE = 151
+ final val UNAPPLY = 152
+ final val ANNOTATEDtype = 153
+ final val ANNOTATEDtpt = 154
+ final val CASEDEF = 155
+ final val TEMPLATE = 156
+ final val SUPER = 157
+ final val SUPERtype = 158
+ final val REFINEDtype = 159
+ final val REFINEDtpt = 160
+ final val APPLIEDtype = 161
+ final val APPLIEDtpt = 162
+ final val TYPEBOUNDS = 163
+ final val TYPEBOUNDStpt = 164
+ final val TYPEALIAS = 165
+ final val ANDtype = 166
+ final val ANDtpt = 167
+ final val ORtype = 168
+ final val ORtpt = 169
+ final val METHODtype = 170
+ final val POLYtype = 171
+ final val POLYtpt = 172
+ final val PARAMtype = 173
+ final val ANNOTATION = 174
final val firstSimpleTreeTag = UNITconst
final val firstNatTreeTag = SHARED
@@ -367,7 +389,22 @@ object TastyFormat {
| PRIVATEqualified
| PROTECTEDqualified => true
case _ => false
- }
+ }
+
+ def isTypeTreeTag(tag: Int) = tag match {
+ case IDENTtpt
+ | SELECTtpt
+ | SINGLETONtpt
+ | REFINEDtpt
+ | APPLIEDtpt
+ | POLYtpt
+ | TYPEBOUNDStpt
+ | ANNOTATEDtpt
+ | ANDtpt
+ | ORtpt
+ | BYNAMEtpt => true
+ case _ => false
+ }
def nameTagToString(tag: Int): String = tag match {
case UTF8 => "UTF8"
@@ -429,7 +466,9 @@ object TastyFormat {
case RECtype => "RECtype"
case IDENT => "IDENT"
+ case IDENTtpt => "IDENTtpt"
case SELECT => "SELECT"
+ case SELECTtpt => "SELECTtpt"
case TERMREFsymbol => "TERMREFsymbol"
case TERMREF => "TERMREF"
case TYPEREFsymbol => "TYPEREFsymbol"
@@ -462,24 +501,34 @@ object TastyFormat {
case BIND => "BIND"
case ALTERNATIVE => "ALTERNATIVE"
case UNAPPLY => "UNAPPLY"
- case ANNOTATED => "ANNOTATED"
+ case ANNOTATEDtype => "ANNOTATEDtype"
+ case ANNOTATEDtpt => "ANNOTATEDtpt"
case CASEDEF => "CASEDEF"
case IMPLICITarg => "IMPLICITarg"
case TEMPLATE => "TEMPLATE"
case SELFDEF => "SELFDEF"
case THIS => "THIS"
+ case QUALTHIS => "QUALTHIS"
case SUPER => "SUPER"
case CLASSconst => "CLASSconst"
case ENUMconst => "ENUMconst"
+ case SINGLETONtpt => "SINGLETONtpt"
case SUPERtype => "SUPERtype"
case REFINEDtype => "REFINEDtype"
+ case REFINEDtpt => "REFINEDtpt"
case APPLIEDtype => "APPLIEDtype"
+ case APPLIEDtpt => "APPLIEDtpt"
case TYPEBOUNDS => "TYPEBOUNDS"
+ case TYPEBOUNDStpt => "TYPEBOUNDStpt"
case TYPEALIAS => "TYPEALIAS"
case ANDtype => "ANDtype"
+ case ANDtpt => "ANDtpt"
case ORtype => "ORtype"
+ case ORtpt => "ORtpt"
case BYNAMEtype => "BYNAMEtype"
+ case BYNAMEtpt => "BYNAMEtpt"
case POLYtype => "POLYtype"
+ case POLYtpt => "POLYtpt"
case METHODtype => "METHODtype"
case PARAMtype => "PARAMtype"
case ANNOTATION => "ANNOTATION"
diff --git a/src/dotty/tools/dotc/core/tasty/TastyPickler.scala b/src/dotty/tools/dotc/core/tasty/TastyPickler.scala
index f847dda68..c844d522e 100644
--- a/src/dotty/tools/dotc/core/tasty/TastyPickler.scala
+++ b/src/dotty/tools/dotc/core/tasty/TastyPickler.scala
@@ -54,14 +54,11 @@ class TastyPickler {
all.bytes
}
- /**
- * Addresses in TASTY file of trees, stored by pickling.
- * Note that trees are checked for reference equality,
- * so one can reliably use this function only directly after `pickler`.
- * Note that a tree can have several addresses, if it is shared,
- * i.e. accessible from different paths. Any such sharing is undone by pickling.
+ /** The address in the TASTY file of a given tree, or None if unknown.
+ * Note that trees are looked up by reference equality,
+ * so one can reliably use this function only directly after `pickler`.
*/
- var addrsOfTree: tpd.Tree => List[Addr] = (_ => Nil)
+ var addrOfTree: tpd.Tree => Option[Addr] = (_ => None)
/**
* Addresses in TASTY file of symbols, stored by pickling.
diff --git a/src/dotty/tools/dotc/core/tasty/TreeBuffer.scala b/src/dotty/tools/dotc/core/tasty/TreeBuffer.scala
index f2681ecde..6c7982d78 100644
--- a/src/dotty/tools/dotc/core/tasty/TreeBuffer.scala
+++ b/src/dotty/tools/dotc/core/tasty/TreeBuffer.scala
@@ -17,26 +17,17 @@ class TreeBuffer extends TastyBuffer(50000) {
private var delta: Array[Int] = _
private var numOffsets = 0
- private type TreeAddrs = Any // really: Addr | List[Addr]
+ /** A map from trees to the address at which a tree is pickled. */
+ private val treeAddrs = new java.util.IdentityHashMap[Tree, Any] // really: Addr | Null
- /** A map from trees to the address(es) at which a tree is pickled. There may be several
- * such addresses if the tree is shared. To keep the map compact, the value type is a
- * disjunction of a single address (which is the common case) and a list of addresses.
- */
- private val treeAddrs = new java.util.IdentityHashMap[Tree, TreeAddrs]
+ def registerTreeAddr(tree: Tree): Addr = treeAddrs.get(tree) match {
+ case null => treeAddrs.put(tree, currentAddr); currentAddr
+ case addr: Addr => addr
+ }
- def registerTreeAddr(tree: Tree) =
- treeAddrs.put(tree,
- treeAddrs.get(tree) match {
- case null => currentAddr
- case x: Addr => x :: currentAddr :: Nil
- case xs: List[_] => xs :+ currentAddr
- })
-
- def addrsOfTree(tree: Tree): List[Addr] = treeAddrs.get(tree) match {
- case null => Nil
- case addr: Addr => addr :: Nil
- case addrs: List[Addr] => addrs
+ def addrOfTree(tree: Tree): Option[Addr] = treeAddrs.get(tree) match {
+ case null => None
+ case addr: Addr => Some(addr)
}
private def offset(i: Int): Addr = Addr(offsets(i))
diff --git a/src/dotty/tools/dotc/core/tasty/TreePickler.scala b/src/dotty/tools/dotc/core/tasty/TreePickler.scala
index 9dfb78798..80270aa25 100644
--- a/src/dotty/tools/dotc/core/tasty/TreePickler.scala
+++ b/src/dotty/tools/dotc/core/tasty/TreePickler.scala
@@ -10,6 +10,7 @@ import Contexts._, Symbols._, Types._, Names._, Constants._, Decorators._, Annot
import collection.mutable
import typer.Inliner
import NameOps._
+import StdNames.nme
import TastyBuffer._
import TypeApplications._
@@ -49,10 +50,6 @@ class TreePickler(pickler: TastyPickler) {
case None =>
}
}
-
- def rhs(tdef: TypeDef)(implicit ctx: Context) =
- if (tdef.symbol.isClass) tdef.rhs
- else TypeTree(tdef.symbol.info).withPos(tdef.rhs.pos)
private def pickleName(name: Name): Unit = writeNat(nameIndex(name).index)
private def pickleName(name: TastyName): Unit = writeNat(nameIndex(name).index)
@@ -157,11 +154,6 @@ class TreePickler(pickler: TastyPickler) {
throw ex
}
- def pickleTypeWithPos(tpe: Type, tree: Tree)(implicit ctx: Context): Unit = {
- registerTreeAddr(tree)
- pickleType(tpe)
- }
-
private def pickleNewType(tpe: Type, richTypes: Boolean)(implicit ctx: Context): Unit = try { tpe match {
case AppliedType(tycon, args) =>
writeByte(APPLIEDtype)
@@ -253,7 +245,7 @@ class TreePickler(pickler: TastyPickler) {
writeByte(TYPEBOUNDS)
withLength { pickleType(tpe.lo, richTypes); pickleType(tpe.hi, richTypes) }
case tpe: AnnotatedType =>
- writeByte(ANNOTATED)
+ writeByte(ANNOTATEDtype)
withLength { pickleType(tpe.tpe, richTypes); pickleTree(tpe.annot.tree) }
case tpe: AndOrType =>
writeByte(if (tpe.isAnd) ANDtype else ORtype)
@@ -310,7 +302,7 @@ class TreePickler(pickler: TastyPickler) {
}
def pickleTpt(tpt: Tree)(implicit ctx: Context): Unit =
- pickleTypeWithPos(tpt.tpe, tpt) // TODO correlate with original when generating positions
+ pickleTree(tpt)
def pickleTreeUnlessEmpty(tree: Tree)(implicit ctx: Context): Unit =
if (!tree.isEmpty) pickleTree(tree)
@@ -336,7 +328,7 @@ class TreePickler(pickler: TastyPickler) {
tree match {
case tree: ValDef => pickleDef(PARAM, tree.symbol, tree.tpt)
case tree: DefDef => pickleDef(PARAM, tree.symbol, tree.tpt, tree.rhs)
- case tree: TypeDef => pickleDef(TYPEPARAM, tree.symbol, rhs(tree))
+ case tree: TypeDef => pickleDef(TYPEPARAM, tree.symbol, tree.rhs)
}
}
@@ -350,181 +342,231 @@ class TreePickler(pickler: TastyPickler) {
stats.foreach(stat => if (!stat.isEmpty) pickleTree(stat))
}
- def pickleTree(tree: Tree)(implicit ctx: Context): Unit = try {
- registerTreeAddr(tree)
- tree match {
- case tree if tree.isType =>
- pickleTpt(tree)
- case Ident(name) =>
- tree.tpe match {
- case tp: TermRef => pickleType(tp)
- case _ =>
- writeByte(IDENT)
- pickleName(name)
- pickleType(tree.tpe)
- }
- case This(_) =>
- pickleType(tree.tpe)
- case Select(qual, name) =>
- writeByte(SELECT)
- val realName = tree.tpe match {
- case tp: NamedType if tp.name.isShadowedName => tp.name
- case _ => name
- }
- val sig = tree.tpe.signature
- if (sig == Signature.NotAMethod) pickleName(realName)
- else pickleNameAndSig(realName, sig)
- pickleTree(qual)
- case Apply(fun, args) =>
- writeByte(APPLY)
- withLength {
- pickleTree(fun)
- args.foreach(pickleTree)
- }
- case TypeApply(fun, args) =>
- writeByte(TYPEAPPLY)
- withLength {
- pickleTree(fun)
- args.foreach(pickleTpt)
- }
- case Literal(const1) =>
- pickleConstant {
+ def pickleTree(tree: Tree)(implicit ctx: Context): Unit = {
+ val addr = registerTreeAddr(tree)
+ if (addr != currentAddr) {
+ writeByte(SHARED)
+ writeRef(addr)
+ }
+ else
+ try tree match {
+ case Ident(name) =>
tree.tpe match {
- case ConstantType(const2) => const2
- case _ => const1
+ case tp: TermRef if name != nme.WILDCARD =>
+ // wildcards are pattern bound, need to be preserved as ids.
+ pickleType(tp)
+ case _ =>
+ writeByte(if (tree.isType) IDENTtpt else IDENT)
+ pickleName(name)
+ pickleType(tree.tpe)
}
- }
- case Super(qual, mix) =>
- writeByte(SUPER)
- withLength {
- pickleTree(qual);
- if (!mix.isEmpty) {
- val SuperType(_, mixinType) = tree.tpe
- pickleType(mixinType)
+ case This(qual) =>
+ if (qual.isEmpty) pickleType(tree.tpe)
+ else {
+ writeByte(QUALTHIS)
+ val ThisType(tref) = tree.tpe
+ pickleTree(qual.withType(tref))
}
- }
- case New(tpt) =>
- writeByte(NEW)
- pickleTpt(tpt)
- case Typed(expr, tpt) =>
- writeByte(TYPED)
- withLength { pickleTree(expr); pickleTpt(tpt) }
- case NamedArg(name, arg) =>
- writeByte(NAMEDARG)
- withLength { pickleName(name); pickleTree(arg) }
- case Assign(lhs, rhs) =>
- writeByte(ASSIGN)
- withLength { pickleTree(lhs); pickleTree(rhs) }
- case Block(stats, expr) =>
- writeByte(BLOCK)
- stats.foreach(preRegister)
- withLength { pickleTree(expr); stats.foreach(pickleTree) }
- case If(cond, thenp, elsep) =>
- writeByte(IF)
- withLength{ pickleTree(cond); pickleTree(thenp); pickleTree(elsep) }
- case Closure(env, meth, tpt) =>
- writeByte(LAMBDA)
- assert(env.isEmpty)
- withLength{
- pickleTree(meth)
- if (tpt.tpe.exists) pickleTpt(tpt)
- }
- case Match(selector, cases) =>
- writeByte(MATCH)
- withLength { pickleTree(selector); cases.foreach(pickleTree) }
- case CaseDef(pat, guard, rhs) =>
- writeByte(CASEDEF)
- withLength { pickleTree(pat); pickleTree(rhs); pickleTreeUnlessEmpty(guard) }
- case Return(expr, from) =>
- writeByte(RETURN)
- withLength { pickleSymRef(from.symbol); pickleTreeUnlessEmpty(expr) }
- case Try(block, cases, finalizer) =>
- writeByte(TRY)
- withLength { pickleTree(block); cases.foreach(pickleTree); pickleTreeUnlessEmpty(finalizer) }
- case SeqLiteral(elems, elemtpt) =>
- writeByte(REPEATED)
- withLength { pickleTree(elemtpt); elems.foreach(pickleTree) }
- case Inlined(call, bindings, expansion) =>
- writeByte(INLINED)
- bindings.foreach(preRegister)
- withLength { pickleTree(call); pickleTree(expansion); bindings.foreach(pickleTree) }
- case Bind(name, body) =>
- registerDef(tree.symbol)
- writeByte(BIND)
- withLength { pickleName(name); pickleType(tree.symbol.info); pickleTree(body) }
- case Alternative(alts) =>
- writeByte(ALTERNATIVE)
- withLength { alts.foreach(pickleTree) }
- case UnApply(fun, implicits, patterns) =>
- writeByte(UNAPPLY)
- withLength {
- pickleTree(fun)
- for (implicitArg <- implicits) {
- writeByte(IMPLICITarg)
- pickleTree(implicitArg)
+ case Select(qual, name) =>
+ writeByte(if (name.isTypeName) SELECTtpt else SELECT)
+ val realName = tree.tpe match {
+ case tp: NamedType if tp.name.isShadowedName => tp.name
+ case _ => name
}
- pickleType(tree.tpe)
- patterns.foreach(pickleTree)
- }
- case tree: ValDef =>
- pickleDef(VALDEF, tree.symbol, tree.tpt, tree.rhs)
- case tree: DefDef =>
- def pickleAllParams = {
- pickleParams(tree.tparams)
- for (vparams <- tree.vparamss) {
- writeByte(PARAMS)
- withLength { pickleParams(vparams) }
+ val sig = tree.tpe.signature
+ if (sig == Signature.NotAMethod) pickleName(realName)
+ else pickleNameAndSig(realName, sig)
+ pickleTree(qual)
+ case Apply(fun, args) =>
+ writeByte(APPLY)
+ withLength {
+ pickleTree(fun)
+ args.foreach(pickleTree)
}
- }
- pickleDef(DEFDEF, tree.symbol, tree.tpt, tree.rhs, pickleAllParams)
- case tree: TypeDef =>
- pickleDef(TYPEDEF, tree.symbol, rhs(tree))
- case tree: Template =>
- registerDef(tree.symbol)
- writeByte(TEMPLATE)
- val (params, rest) = tree.body partition {
- case stat: TypeDef => stat.symbol is Flags.Param
- case stat: ValOrDefDef =>
- stat.symbol.is(Flags.ParamAccessor) && !stat.symbol.isSetter
- case _ => false
- }
- withLength {
- pickleParams(params)
- tree.parents.foreach(pickleTree)
- val cinfo @ ClassInfo(_, _, _, _, selfInfo) = tree.symbol.owner.info
- if ((selfInfo ne NoType) || !tree.self.isEmpty) {
- writeByte(SELFDEF)
- pickleName(tree.self.name)
- if (!tree.self.isEmpty) registerTreeAddr(tree.self.tpt)
- pickleType {
- cinfo.selfInfo match {
- case sym: Symbol => sym.info
- case tp: Type => tp
+ case TypeApply(fun, args) =>
+ writeByte(TYPEAPPLY)
+ withLength {
+ pickleTree(fun)
+ args.foreach(pickleTpt)
+ }
+ case Literal(const1) =>
+ pickleConstant {
+ tree.tpe match {
+ case ConstantType(const2) => const2
+ case _ => const1
+ }
+ }
+ case Super(qual, mix) =>
+ writeByte(SUPER)
+ withLength {
+ pickleTree(qual);
+ if (!mix.isEmpty) {
+ val SuperType(_, mixinType: TypeRef) = tree.tpe
+ pickleTree(mix.withType(mixinType))
+ }
+ }
+ case New(tpt) =>
+ writeByte(NEW)
+ pickleTpt(tpt)
+ case Typed(expr, tpt) =>
+ writeByte(TYPED)
+ withLength { pickleTree(expr); pickleTpt(tpt) }
+ case NamedArg(name, arg) =>
+ writeByte(NAMEDARG)
+ withLength { pickleName(name); pickleTree(arg) }
+ case Assign(lhs, rhs) =>
+ writeByte(ASSIGN)
+ withLength { pickleTree(lhs); pickleTree(rhs) }
+ case Block(stats, expr) =>
+ writeByte(BLOCK)
+ stats.foreach(preRegister)
+ withLength { pickleTree(expr); stats.foreach(pickleTree) }
+ case If(cond, thenp, elsep) =>
+ writeByte(IF)
+ withLength { pickleTree(cond); pickleTree(thenp); pickleTree(elsep) }
+ case Closure(env, meth, tpt) =>
+ writeByte(LAMBDA)
+ assert(env.isEmpty)
+ withLength {
+ pickleTree(meth)
+ if (tpt.tpe.exists) pickleTpt(tpt)
+ }
+ case Match(selector, cases) =>
+ writeByte(MATCH)
+ withLength { pickleTree(selector); cases.foreach(pickleTree) }
+ case CaseDef(pat, guard, rhs) =>
+ writeByte(CASEDEF)
+ withLength { pickleTree(pat); pickleTree(rhs); pickleTreeUnlessEmpty(guard) }
+ case Return(expr, from) =>
+ writeByte(RETURN)
+ withLength { pickleSymRef(from.symbol); pickleTreeUnlessEmpty(expr) }
+ case Try(block, cases, finalizer) =>
+ writeByte(TRY)
+ withLength { pickleTree(block); cases.foreach(pickleTree); pickleTreeUnlessEmpty(finalizer) }
+ case SeqLiteral(elems, elemtpt) =>
+ writeByte(REPEATED)
+ withLength { pickleTree(elemtpt); elems.foreach(pickleTree) }
+ case Inlined(call, bindings, expansion) =>
+ writeByte(INLINED)
+ bindings.foreach(preRegister)
+ withLength { pickleTree(call); pickleTree(expansion); bindings.foreach(pickleTree) }
+ case Bind(name, body) =>
+ registerDef(tree.symbol)
+ writeByte(BIND)
+ withLength { pickleName(name); pickleType(tree.symbol.info); pickleTree(body) }
+ case Alternative(alts) =>
+ writeByte(ALTERNATIVE)
+ withLength { alts.foreach(pickleTree) }
+ case UnApply(fun, implicits, patterns) =>
+ writeByte(UNAPPLY)
+ withLength {
+ pickleTree(fun)
+ for (implicitArg <- implicits) {
+ writeByte(IMPLICITarg)
+ pickleTree(implicitArg)
+ }
+ pickleType(tree.tpe)
+ patterns.foreach(pickleTree)
+ }
+ case tree: ValDef =>
+ pickleDef(VALDEF, tree.symbol, tree.tpt, tree.rhs)
+ case tree: DefDef =>
+ def pickleAllParams = {
+ pickleParams(tree.tparams)
+ for (vparams <- tree.vparamss) {
+ writeByte(PARAMS)
+ withLength { pickleParams(vparams) }
+ }
+ }
+ pickleDef(DEFDEF, tree.symbol, tree.tpt, tree.rhs, pickleAllParams)
+ case tree: TypeDef =>
+ pickleDef(TYPEDEF, tree.symbol, tree.rhs)
+ case tree: Template =>
+ registerDef(tree.symbol)
+ writeByte(TEMPLATE)
+ val (params, rest) = tree.body partition {
+ case stat: TypeDef => stat.symbol is Flags.Param
+ case stat: ValOrDefDef =>
+ stat.symbol.is(Flags.ParamAccessor) && !stat.symbol.isSetter
+ case _ => false
+ }
+ withLength {
+ pickleParams(params)
+ tree.parents.foreach(pickleTree)
+ val cinfo @ ClassInfo(_, _, _, _, selfInfo) = tree.symbol.owner.info
+ if ((selfInfo ne NoType) || !tree.self.isEmpty) {
+ writeByte(SELFDEF)
+ pickleName(tree.self.name)
+
+ if (!tree.self.tpt.isEmpty) pickleTree(tree.self.tpt)
+ else {
+ if (!tree.self.isEmpty) registerTreeAddr(tree.self)
+ pickleType {
+ cinfo.selfInfo match {
+ case sym: Symbol => sym.info
+ case tp: Type => tp
+ }
+ }
}
}
+ pickleStats(tree.constr :: rest)
}
- pickleStats(tree.constr :: rest)
- }
- case Import(expr, selectors) =>
- writeByte(IMPORT)
- withLength {
- pickleTree(expr)
- selectors foreach {
- case Thicket((from @ Ident(_)) :: (to @ Ident(_)) :: Nil) =>
- pickleSelector(IMPORTED, from)
- pickleSelector(RENAMED, to)
- case id @ Ident(_) =>
- pickleSelector(IMPORTED, id)
+ case Import(expr, selectors) =>
+ writeByte(IMPORT)
+ withLength {
+ pickleTree(expr)
+ selectors foreach {
+ case Thicket((from @ Ident(_)) :: (to @ Ident(_)) :: Nil) =>
+ pickleSelector(IMPORTED, from)
+ pickleSelector(RENAMED, to)
+ case id @ Ident(_) =>
+ pickleSelector(IMPORTED, id)
+ }
}
- }
- case PackageDef(pid, stats) =>
- writeByte(PACKAGE)
- withLength { pickleType(pid.tpe); pickleStats(stats) }
- }}
- catch {
- case ex: AssertionError =>
- println(i"error when pickling tree $tree")
- throw ex
+ case PackageDef(pid, stats) =>
+ writeByte(PACKAGE)
+ withLength { pickleType(pid.tpe); pickleStats(stats) }
+ case tree: TypeTree =>
+ pickleType(tree.tpe)
+ case SingletonTypeTree(ref) =>
+ writeByte(SINGLETONtpt)
+ pickleTree(ref)
+ case RefinedTypeTree(parent, refinements) =>
+ if (refinements.isEmpty) pickleTree(parent)
+ else {
+ val refineCls = refinements.head.symbol.owner.asClass
+ pickledTypes.put(refineCls.typeRef, currentAddr)
+ writeByte(REFINEDtpt)
+ refinements.foreach(preRegister)
+ withLength { pickleTree(parent); refinements.foreach(pickleTree) }
+ }
+ case AppliedTypeTree(tycon, args) =>
+ writeByte(APPLIEDtpt)
+ withLength { pickleTree(tycon); args.foreach(pickleTree) }
+ case AndTypeTree(tp1, tp2) =>
+ writeByte(ANDtpt)
+ withLength { pickleTree(tp1); pickleTree(tp2) }
+ case OrTypeTree(tp1, tp2) =>
+ writeByte(ORtpt)
+ withLength { pickleTree(tp1); pickleTree(tp2) }
+ case ByNameTypeTree(tp) =>
+ writeByte(BYNAMEtpt)
+ pickleTree(tp)
+ case Annotated(tree, annot) =>
+ writeByte(ANNOTATEDtpt)
+ withLength { pickleTree(tree); pickleTree(annot.tree) }
+ case PolyTypeTree(tparams, body) =>
+ writeByte(POLYtpt)
+ withLength { pickleParams(tparams); pickleTree(body) }
+ case TypeBoundsTree(lo, hi) =>
+ writeByte(TYPEBOUNDStpt)
+ withLength { pickleTree(lo); pickleTree(hi) }
+ }
+ catch {
+ case ex: AssertionError =>
+ println(i"error when pickling tree $tree")
+ throw ex
+ }
}
def pickleSelector(tag: Int, id: untpd.Ident)(implicit ctx: Context): Unit = {
diff --git a/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala b/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala
index d2605afea..eba9ab533 100644
--- a/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala
+++ b/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala
@@ -256,7 +256,7 @@ class TreeUnpickler(reader: TastyReader, tastyName: TastyName.Table, posUnpickle
else if (nextByte == CONTRAVARIANT) { readByte(); -1 }
else 0
TypeAlias(alias, variance)
- case ANNOTATED =>
+ case ANNOTATEDtype =>
AnnotatedType(readType(), Annotation(readTerm()))
case ANDtype =>
AndType(readType(), readType())
@@ -368,7 +368,7 @@ class TreeUnpickler(reader: TastyReader, tastyName: TastyName.Table, posUnpickle
private def readPackageRef()(implicit ctx: Context): TermSymbol = {
val name = readName()
- if (name == nme.ROOT) defn.RootPackage
+ if (name == nme.ROOT || name == nme.ROOTPKG) defn.RootPackage
else if (name == nme.EMPTY_PACKAGE) defn.EmptyPackageVal
else ctx.requiredPackage(name)
}
@@ -389,11 +389,11 @@ class TreeUnpickler(reader: TastyReader, tastyName: TastyName.Table, posUnpickle
if (owner.isClass) lctx.setScope(owner.unforcedDecls) else lctx.setNewScope
}
- private def normalizeFlags(tag: Int, givenFlags: FlagSet, name: Name, isAbstractType: Boolean, rhsIsEmpty: Boolean)(implicit ctx: Context): FlagSet = {
+ private def normalizeFlags(tag: Int, givenFlags: FlagSet, name: Name, isAbsType: Boolean, rhsIsEmpty: Boolean)(implicit ctx: Context): FlagSet = {
val lacksDefinition =
rhsIsEmpty &&
name.isTermName && !name.isConstructorName && !givenFlags.is(ParamOrAccessor) ||
- isAbstractType
+ isAbsType
var flags = givenFlags
if (lacksDefinition && tag != PARAM) flags |= Deferred
if (tag == DEFDEF) flags |= Method
@@ -407,6 +407,17 @@ class TreeUnpickler(reader: TastyReader, tastyName: TastyName.Table, posUnpickle
flags
}
+ def isAbstractType(ttag: Int)(implicit ctx: Context): Boolean = nextUnsharedTag match {
+ case POLYtpt =>
+ val rdr = fork
+ rdr.reader.readByte() // tag
+ rdr.reader.readNat() // length
+ rdr.skipParams() // tparams
+ rdr.isAbstractType(rdr.nextUnsharedTag)
+ case TYPEBOUNDS | TYPEBOUNDStpt => true
+ case _ => false
+ }
+
/** Create symbol of definition node and enter in symAtAddr map
* @return the created symbol
*/
@@ -433,7 +444,7 @@ class TreeUnpickler(reader: TastyReader, tastyName: TastyName.Table, posUnpickle
if (tag == TYPEDEF || tag == TYPEPARAM) name = name.toTypeName
skipParams()
val ttag = nextUnsharedTag
- val isAbstractType = ttag == TYPEBOUNDS
+ val isAbsType = isAbstractType(ttag)
val isClass = ttag == TEMPLATE
val templateStart = currentAddr
skipTree() // tpt
@@ -447,7 +458,7 @@ class TreeUnpickler(reader: TastyReader, tastyName: TastyName.Table, posUnpickle
case _ => EmptyFlags
}
pickling.println(i"creating symbol $name at $start with flags $givenFlags")
- val flags = normalizeFlags(tag, givenFlags | nameFlags(rawName), name, isAbstractType, rhsIsEmpty)
+ val flags = normalizeFlags(tag, givenFlags | nameFlags(rawName), name, isAbsType, rhsIsEmpty)
def adjustIfModule(completer: LazyType) =
if (flags is Module) ctx.adjustModuleCompleter(completer, name) else completer
val sym =
@@ -623,11 +634,6 @@ class TreeUnpickler(reader: TastyReader, tastyName: TastyName.Table, posUnpickle
val tag = readByte()
val end = readEnd()
- def readParams[T <: MemberDef](tag: Int)(implicit ctx: Context): List[T] = {
- fork.indexParams(tag)(localContext(sym))
- readIndexedParams(tag)
- }
-
def readParamss(implicit ctx: Context): List[List[ValDef]] = {
collectWhile(nextByte == PARAMS) {
readByte()
@@ -696,7 +702,10 @@ class TreeUnpickler(reader: TastyReader, tastyName: TastyName.Table, posUnpickle
TypeDef(readTemplate(localCtx))
} else {
val rhs = readTpt()
- sym.info = rhs.tpe
+ sym.info = rhs.tpe match {
+ case _: TypeBounds | _: ClassInfo => rhs.tpe
+ case _ => TypeAlias(rhs.tpe, sym.variance)
+ }
TypeDef(rhs)
}
case PARAM =>
@@ -846,9 +855,14 @@ class TreeUnpickler(reader: TastyReader, tastyName: TastyName.Table, posUnpickle
def readIndexedParams[T <: MemberDef](tag: Int)(implicit ctx: Context): List[T] =
collectWhile(nextByte == tag) { readIndexedDef().asInstanceOf[T] }
-// ------ Reading terms -----------------------------------------------------
+ def readParams[T <: MemberDef](tag: Int)(implicit ctx: Context): List[T] = {
+ fork.indexParams(tag)
+ readIndexedParams(tag)
+ }
- def readTerm()(implicit ctx: Context): Tree = {
+// ------ Reading trees -----------------------------------------------------
+
+ def readTerm()(implicit ctx: Context): Tree = { // TODO: rename to readTree
val start = currentAddr
val tag = readByte()
pickling.println(s"reading term ${astTagToString(tag)} at $start")
@@ -856,34 +870,52 @@ class TreeUnpickler(reader: TastyReader, tastyName: TastyName.Table, posUnpickle
def readPathTerm(): Tree = {
goto(start)
readType() match {
+ case path: TypeRef => TypeTree(path)
case path: TermRef => ref(path)
case path: ThisType => This(path.cls)
case path: ConstantType => Literal(path.value)
}
}
+ def completeSelect(name: Name, tpf: Type => Type): Select = {
+ val localCtx =
+ if (name == nme.CONSTRUCTOR) ctx.addMode(Mode.InSuperCall) else ctx
+ val qual = readTerm()(localCtx)
+ val unshadowed = if (name.isShadowedName) name.revertShadowed else name
+ untpd.Select(qual, unshadowed).withType(tpf(qual.tpe.widenIfUnstable))
+ }
+
+ def readQualId(): (untpd.Ident, TypeRef) = {
+ val qual = readTerm().asInstanceOf[untpd.Ident]
+ (untpd.Ident(qual.name).withPos(qual.pos), qual.tpe.asInstanceOf[TypeRef])
+ }
+
def readSimpleTerm(): Tree = tag match {
+ case SHARED =>
+ forkAt(readAddr()).readTerm()
case IDENT =>
untpd.Ident(readName()).withType(readType())
+ case IDENTtpt =>
+ untpd.Ident(readName().toTypeName).withType(readType())
case SELECT =>
- def readQual(name: Name) = {
- val localCtx =
- if (name == nme.CONSTRUCTOR) ctx.addMode(Mode.InSuperCall) else ctx
- readTerm()(localCtx)
- }
- def readRest(name: Name, sig: Signature) = {
- val unshadowed = if (name.isShadowedName) name.revertShadowed else name
- val qual = readQual(name)
- untpd.Select(qual, unshadowed)
- .withType(TermRef.withSig(qual.tpe.widenIfUnstable, name.asTermName, sig))
- }
+ def readRest(name: Name, sig: Signature) =
+ completeSelect(name, TermRef.withSig(_, name.asTermName, sig))
readNameSplitSig match {
case name: Name => readRest(name, Signature.NotAMethod)
case (name: Name, sig: Signature) => readRest(name, sig)
}
-
+ case SELECTtpt =>
+ val name = readName().toTypeName
+ completeSelect(name, TypeRef(_, name))
+ case QUALTHIS =>
+ val (qual, tref) = readQualId()
+ untpd.This(qual).withType(ThisType.raw(tref))
case NEW =>
New(readTpt())
+ case SINGLETONtpt =>
+ SingletonTypeTree(readTerm())
+ case BYNAMEtpt =>
+ ByNameTypeTree(readTpt())
case _ =>
readPathTerm()
}
@@ -891,10 +923,15 @@ class TreeUnpickler(reader: TastyReader, tastyName: TastyName.Table, posUnpickle
def readLengthTerm(): Tree = {
val end = readEnd()
+ def localNonClassCtx = {
+ val ctx1 = ctx.fresh.setNewScope
+ if (ctx.owner.isClass) ctx1.setOwner(ctx1.newLocalDummy(ctx.owner)) else ctx1
+ }
+
def readBlock(mkTree: (List[Tree], Tree) => Tree): Tree = {
val exprReader = fork
skipTree()
- val localCtx = ctx.fresh.setNewScope
+ val localCtx = localNonClassCtx
val stats = readStats(ctx.owner, end)(localCtx)
val expr = exprReader.readTerm()(localCtx)
mkTree(stats, expr)
@@ -904,9 +941,8 @@ class TreeUnpickler(reader: TastyReader, tastyName: TastyName.Table, posUnpickle
(tag: @switch) match {
case SUPER =>
val qual = readTerm()
- val mixClass = ifBefore(end)(readType().typeSymbol, NoSymbol)
- val mixName = if (mixClass.exists) mixClass.name.asTypeName else tpnme.EMPTY
- tpd.Super(qual, mixName, ctx.mode.is(Mode.InSuperCall), mixClass)
+ val (mixId, mixTpe) = ifBefore(end)(readQualId(), (untpd.EmptyTypeIdent, NoType))
+ tpd.Super(qual, mixId, ctx.mode.is(Mode.InSuperCall), mixTpe.typeSymbol)
case APPLY =>
val fn = readTerm()
val isJava = fn.symbol.is(JavaDefined)
@@ -934,7 +970,7 @@ class TreeUnpickler(reader: TastyReader, tastyName: TastyName.Table, posUnpickle
case BLOCK =>
readBlock(Block)
case INLINED =>
- val call = setPos(currentAddr, TypeTree(readType()))
+ val call = readTerm()
readBlock((defs, expr) => Inlined(call, defs.asInstanceOf[List[MemberDef]], expr))
case IF =>
If(readTerm(), readTerm(), readTerm())
@@ -971,6 +1007,28 @@ class TreeUnpickler(reader: TastyReader, tastyName: TastyName.Table, posUnpickle
val patType = readType()
val argPats = until(end)(readTerm())
UnApply(fn, implicitArgs, argPats, patType)
+ case REFINEDtpt =>
+ val refineCls = ctx.newCompleteClassSymbol(
+ ctx.owner, tpnme.REFINE_CLASS, Fresh, parents = Nil)
+ typeAtAddr(start) = refineCls.typeRef
+ val parent = readTpt()
+ val refinements = readStats(refineCls, end)(localContext(refineCls))
+ RefinedTypeTree(parent, refinements, refineCls)
+ case APPLIEDtpt =>
+ AppliedTypeTree(readTpt(), until(end)(readTpt()))
+ case ANDtpt =>
+ AndTypeTree(readTpt(), readTpt())
+ case ORtpt =>
+ OrTypeTree(readTpt(), readTpt())
+ case ANNOTATEDtpt =>
+ Annotated(readTpt(), readTerm())
+ case POLYtpt =>
+ val localCtx = localNonClassCtx
+ val tparams = readParams[TypeDef](TYPEPARAM)(localCtx)
+ val body = readTpt()(localCtx)
+ PolyTypeTree(tparams, body)
+ case TYPEBOUNDStpt =>
+ TypeBoundsTree(readTpt(), readTpt())
case _ =>
readPathTerm()
}
@@ -983,11 +1041,13 @@ class TreeUnpickler(reader: TastyReader, tastyName: TastyName.Table, posUnpickle
setPos(start, tree)
}
- def readTpt()(implicit ctx: Context) = {
- val start = currentAddr
- val tp = readType()
- if (tp.exists) setPos(start, TypeTree(tp)) else EmptyTree
- }
+ def readTpt()(implicit ctx: Context) =
+ if (isTypeTreeTag(nextUnsharedTag)) readTerm()
+ else {
+ val start = currentAddr
+ val tp = readType()
+ if (tp.exists) setPos(start, TypeTree(tp)) else EmptyTree
+ }
def readCases(end: Addr)(implicit ctx: Context): List[CaseDef] =
collectWhile(nextByte == CASEDEF && currentAddr != end) { readCase()(ctx.fresh.setNewScope) }
diff --git a/src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala b/src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala
index 70148b3e2..b01f6cc6a 100644
--- a/src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala
+++ b/src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala
@@ -40,29 +40,15 @@ object Scala2Unpickler {
/** 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 temp poly type to some native Dotty idiom.
- * @param denot The denotation that gets the converted type as info.
- * If `denot` is not an abstract type, this simply returns an equivalent `PolyType`.
- * If `denot` is an abstract type, it converts a
- *
- * TempPolyType(List(v_1 T_1, ..., v_n T_n), lo .. hi)
- *
- * to a type lambda using `parameterizeWith/LambdaAbstract`.
- */
- def depoly(tp: Type, denot: SymDenotation)(implicit ctx: Context): Type = tp match {
- case TempPolyType(tparams, restpe) =>
- if (denot.isType) {
- assert(!denot.isClass)
- restpe.LambdaAbstract(tparams)
- }
- else
- PolyType.fromSymbols(tparams, restpe)
+ /** Convert temp poly type to poly type and leave other types alone. */
+ def translateTempPoly(tp: Type)(implicit ctx: Context): Type = tp match {
+ case TempPolyType(tparams, restpe) => restpe.LambdaAbstract(tparams)
case tp => tp
}
def addConstructorTypeParams(denot: SymDenotation)(implicit ctx: Context) = {
assert(denot.isConstructor)
- denot.info = PolyType.fromSymbols(denot.owner.typeParams, denot.info)
+ denot.info = denot.info.LambdaAbstract(denot.owner.typeParams)
}
/** Convert array parameters denoting a repeated parameter of a Java method
@@ -549,7 +535,7 @@ class Scala2Unpickler(bytes: Array[Byte], classRoot: ClassDenotation, moduleClas
val selfInfo = if (atEnd) NoType else readTypeRef()
setClassInfo(denot, tp, selfInfo)
case denot =>
- val tp1 = depoly(tp, denot)
+ val tp1 = translateTempPoly(tp)
denot.info =
if (tag == ALIASsym) TypeAlias(tp1)
else if (denot.isType) checkNonCyclic(denot.symbol, tp1, reportErrors = false)