@@ -163,6 +163,11 @@ class TreeUnpickler(reader: TastyReader,
163
163
def forkAt (start : Addr ): TreeReader = new TreeReader (subReader(start, endAddr))
164
164
def fork : TreeReader = forkAt(currentAddr)
165
165
166
+ def skipParentTree (tag : Int ): Unit = {
167
+ if tag == SPLITCLAUSE then ()
168
+ else skipTree(tag)
169
+ }
170
+ def skipParentTree (): Unit = skipParentTree(readByte())
166
171
def skipTree (tag : Int ): Unit = {
167
172
if (tag >= firstLengthTreeTag) goto(readEnd())
168
173
else if (tag >= firstNatASTTreeTag) { readNat(); skipTree() }
@@ -441,7 +446,11 @@ class TreeUnpickler(reader: TastyReader,
441
446
readPackageRef().termRef
442
447
case TYPEREF =>
443
448
val name = readName().toTypeName
444
- TypeRef (readType(), name)
449
+ val pre = readType()
450
+ if unpicklingJava && name == tpnme.Object && (pre.termSymbol eq defn.JavaLangPackageVal ) then
451
+ defn.FromJavaObjectType
452
+ else
453
+ TypeRef (pre, name)
445
454
case TERMREF =>
446
455
val sname = readName()
447
456
val prefix = readType()
@@ -1007,7 +1016,7 @@ class TreeUnpickler(reader: TastyReader,
1007
1016
* parsed in this way as InferredTypeTrees.
1008
1017
*/
1009
1018
def readParents (withArgs : Boolean )(using Context ): List [Tree ] =
1010
- collectWhile(nextByte != SELFDEF && nextByte != DEFDEF ) {
1019
+ collectWhile({ val tag = nextByte; tag != SELFDEF && tag != DEFDEF && tag != SPLITCLAUSE } ) {
1011
1020
nextUnsharedTag match
1012
1021
case APPLY | TYPEAPPLY | BLOCK =>
1013
1022
if withArgs then readTree()
@@ -1034,7 +1043,8 @@ class TreeUnpickler(reader: TastyReader,
1034
1043
val bodyFlags = {
1035
1044
val bodyIndexer = fork
1036
1045
// The first DEFDEF corresponds to the primary constructor
1037
- while (bodyIndexer.reader.nextByte != DEFDEF ) bodyIndexer.skipTree()
1046
+ while ({val tag = bodyIndexer.reader.nextByte; tag != DEFDEF && tag != SPLITCLAUSE }) do
1047
+ bodyIndexer.skipParentTree()
1038
1048
bodyIndexer.indexStats(end)
1039
1049
}
1040
1050
val parentReader = fork
@@ -1053,7 +1063,38 @@ class TreeUnpickler(reader: TastyReader,
1053
1063
cls.owner.thisType, cls, parentTypes, cls.unforcedDecls,
1054
1064
selfInfo = if (self.isEmpty) NoType else self.tpt.tpe
1055
1065
).integrateOpaqueMembers
1056
- val constr = readIndexedDef().asInstanceOf [DefDef ]
1066
+
1067
+ val constr =
1068
+ if nextByte == SPLITCLAUSE then
1069
+ assert(unpicklingJava, s " unexpected SPLITCLAUSE at $start" )
1070
+ val tag = readByte()
1071
+ def ta = ctx.typeAssigner
1072
+ val flags = Flags .JavaDefined | Flags .PrivateLocal | Flags .Invisible
1073
+ val ctorCompleter = new LazyType {
1074
+ def complete (denot : SymDenotation )(using Context ) =
1075
+ val sym = denot.symbol
1076
+ val pflags = flags | Flags .Param
1077
+ val tparamRefs = tparams.map(_.symbol.asType)
1078
+ lazy val derivedTparamSyms : List [TypeSymbol ] = tparams.map: tdef =>
1079
+ val completer = new LazyType {
1080
+ def complete (denot : SymDenotation )(using Context ) =
1081
+ denot.info = tdef.symbol.asType.info.subst(tparamRefs, derivedTparamRefs)
1082
+ }
1083
+ newSymbol(sym, tdef.name, Flags .JavaDefined | Flags .Param , completer, coord = cls.coord)
1084
+ lazy val derivedTparamRefs : List [Type ] = derivedTparamSyms.map(_.typeRef)
1085
+ val vparamSym =
1086
+ newSymbol(sym, nme.syntheticParamName(1 ), pflags, defn.UnitType , coord = cls.coord)
1087
+ val vparamSymss : List [List [Symbol ]] = List (vparamSym) :: Nil
1088
+ val paramSymss =
1089
+ if derivedTparamSyms.nonEmpty then derivedTparamSyms :: vparamSymss else vparamSymss
1090
+ val res = effectiveResultType(sym, paramSymss)
1091
+ denot.info = methodType(paramSymss, res)
1092
+ denot.setParamss(paramSymss)
1093
+ }
1094
+ val ctorSym = newSymbol(ctx.owner, nme.CONSTRUCTOR , flags, ctorCompleter, coord = coordAt(start))
1095
+ tpd.DefDef (ctorSym, EmptyTree ).setDefTree // fake primary constructor
1096
+ else
1097
+ readIndexedDef().asInstanceOf [DefDef ]
1057
1098
val mappedParents : LazyTreeList =
1058
1099
if parents.exists(_.isInstanceOf [InferredTypeTree ]) then
1059
1100
// parents were not read fully, will need to be read again later on demand
@@ -1174,6 +1215,9 @@ class TreeUnpickler(reader: TastyReader,
1174
1215
1175
1216
// ------ Reading trees -----------------------------------------------------
1176
1217
1218
+ private def ElidedTree (tpe : Type )(using Context ): Tree =
1219
+ untpd.Ident (nme.WILDCARD ).withType(tpe)
1220
+
1177
1221
def readTree ()(using Context ): Tree = {
1178
1222
val sctx = sourceChangeContext()
1179
1223
if (sctx `ne` ctx) return readTree()(using sctx)
@@ -1202,12 +1246,11 @@ class TreeUnpickler(reader: TastyReader,
1202
1246
1203
1247
def completeSelect (name : Name , sig : Signature , target : Name ): Select =
1204
1248
val qual = readTree()
1205
- val denot0 = accessibleDenot(qual.tpe.widenIfUnstable, name, sig, target)
1206
1249
val denot =
1207
- if unpicklingJava && name == tpnme.Object && denot0 .symbol == defn.ObjectClass then
1208
- defn.FromJavaObjectType .denot
1250
+ if unpicklingJava && name == tpnme.Object && qual .symbol == defn.JavaLangPackageVal then
1251
+ defn.FromJavaObjectSymbol .denot
1209
1252
else
1210
- denot0
1253
+ accessibleDenot(qual.tpe.widenIfUnstable, name, sig, target)
1211
1254
makeSelect(qual, name, denot)
1212
1255
1213
1256
def readQualId (): (untpd.Ident , TypeRef ) =
@@ -1228,9 +1271,10 @@ class TreeUnpickler(reader: TastyReader,
1228
1271
untpd.Ident (readName()).withType(readType())
1229
1272
case ELIDED =>
1230
1273
if ! isOutline then
1231
- report.error(
1232
- s " Illegal elided tree in unpickler without ${attributeTagToString(OUTLINEattr )}, ${ctx.source}" )
1233
- untpd.Ident (nme.WILDCARD ).withType(readType())
1274
+ val msg =
1275
+ s " Illegal elided tree in unpickler at $start without ${attributeTagToString(OUTLINEattr )}, ${ctx.source}"
1276
+ report.error(msg)
1277
+ ElidedTree (readType())
1234
1278
case IDENTtpt =>
1235
1279
untpd.Ident (readName().toTypeName).withType(readType())
1236
1280
case SELECT =>
0 commit comments