@@ -163,6 +163,11 @@ class TreeUnpickler(reader: TastyReader,
163163 def forkAt (start : Addr ): TreeReader = new TreeReader (subReader(start, endAddr))
164164 def fork : TreeReader = forkAt(currentAddr)
165165
166+ def skipParentTree (tag : Int ): Unit = {
167+ if tag == SPLITCLAUSE then ()
168+ else skipTree(tag)
169+ }
170+ def skipParentTree (): Unit = skipParentTree(readByte())
166171 def skipTree (tag : Int ): Unit = {
167172 if (tag >= firstLengthTreeTag) goto(readEnd())
168173 else if (tag >= firstNatASTTreeTag) { readNat(); skipTree() }
@@ -441,7 +446,11 @@ class TreeUnpickler(reader: TastyReader,
441446 readPackageRef().termRef
442447 case TYPEREF =>
443448 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)
445454 case TERMREF =>
446455 val sname = readName()
447456 val prefix = readType()
@@ -1007,7 +1016,7 @@ class TreeUnpickler(reader: TastyReader,
10071016 * parsed in this way as InferredTypeTrees.
10081017 */
10091018 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 } ) {
10111020 nextUnsharedTag match
10121021 case APPLY | TYPEAPPLY | BLOCK =>
10131022 if withArgs then readTree()
@@ -1034,7 +1043,8 @@ class TreeUnpickler(reader: TastyReader,
10341043 val bodyFlags = {
10351044 val bodyIndexer = fork
10361045 // 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()
10381048 bodyIndexer.indexStats(end)
10391049 }
10401050 val parentReader = fork
@@ -1053,7 +1063,38 @@ class TreeUnpickler(reader: TastyReader,
10531063 cls.owner.thisType, cls, parentTypes, cls.unforcedDecls,
10541064 selfInfo = if (self.isEmpty) NoType else self.tpt.tpe
10551065 ).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 ]
10571098 val mappedParents : LazyTreeList =
10581099 if parents.exists(_.isInstanceOf [InferredTypeTree ]) then
10591100 // parents were not read fully, will need to be read again later on demand
@@ -1174,6 +1215,9 @@ class TreeUnpickler(reader: TastyReader,
11741215
11751216// ------ Reading trees -----------------------------------------------------
11761217
1218+ private def ElidedTree (tpe : Type )(using Context ): Tree =
1219+ untpd.Ident (nme.WILDCARD ).withType(tpe)
1220+
11771221 def readTree ()(using Context ): Tree = {
11781222 val sctx = sourceChangeContext()
11791223 if (sctx `ne` ctx) return readTree()(using sctx)
@@ -1202,12 +1246,11 @@ class TreeUnpickler(reader: TastyReader,
12021246
12031247 def completeSelect (name : Name , sig : Signature , target : Name ): Select =
12041248 val qual = readTree()
1205- val denot0 = accessibleDenot(qual.tpe.widenIfUnstable, name, sig, target)
12061249 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
12091252 else
1210- denot0
1253+ accessibleDenot(qual.tpe.widenIfUnstable, name, sig, target)
12111254 makeSelect(qual, name, denot)
12121255
12131256 def readQualId (): (untpd.Ident , TypeRef ) =
@@ -1228,9 +1271,10 @@ class TreeUnpickler(reader: TastyReader,
12281271 untpd.Ident (readName()).withType(readType())
12291272 case ELIDED =>
12301273 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())
12341278 case IDENTtpt =>
12351279 untpd.Ident (readName().toTypeName).withType(readType())
12361280 case SELECT =>
0 commit comments