@@ -21,6 +21,7 @@ import scala.collection.mutable
2121import scala .reflect .io .AbstractFile
2222import scala .reflect .internal .Variance
2323import scala .util .chaining ._
24+ import scala .collection .immutable .ArraySeq
2425
2526/** `TreeUnpickler` is responsible for traversing all trees in the "ASTs" section of a TASTy file, which represent the
2627 * definitions inside the classfile associated with the root class/module. `TreeUnpickler` will enter the public api
@@ -220,7 +221,7 @@ class TreeUnpickler[Tasty <: TastyUniverse](
220221 /** Read names in an interleaved sequence of types/bounds and (parameter) names,
221222 * possibly followed by a sequence of modifiers.
222223 */
223- def readParamNamesAndMods (end : Addr ): (List [TastyName ], TastyFlagSet ) = {
224+ def readParamNamesAndMods (end : Addr ): (ArraySeq [TastyName ], TastyFlagSet ) = {
224225 val names =
225226 collectWhile(currentAddr != end && ! isModifierTag(nextByte)) {
226227 skipTree()
@@ -234,7 +235,7 @@ class TreeUnpickler[Tasty <: TastyUniverse](
234235 case GIVEN => mods |= Given
235236 }
236237 }
237- (names, mods)
238+ (names.to( ArraySeq ) , mods)
238239 }
239240
240241 /** Read `n` parameter types or bounds which are interleaved with names */
@@ -332,18 +333,26 @@ class TreeUnpickler[Tasty <: TastyUniverse](
332333 def readLengthType (): Type = {
333334 val end = readEnd()
334335
335- def readMethodic [N <: TastyName ]
336- (companionOp : TastyFlagSet => LambdaTypeCompanion [N ], nameMap : TastyName => N )(implicit ctx : Context ): Type = {
336+ def readMethodic [N <: TastyName ](
337+ factory : LambdaFactory [N ],
338+ parseFlags : FlagSets .FlagParser ,
339+ nameMap : TastyName => N
340+ )(implicit ctx : Context ): Type = {
337341 val result = typeAtAddr.getOrElse(start, {
342+ // TODO [tasty]: can we share LambdaTypes/RecType/RefinedType safely
343+ // under a new context owner? (aka when referenced by a `SHAREDtype`).
344+ // Perhaps we should redesign so that when one of these is retrieved
345+ // from the cache, and the context owner does not match, all its parameters
346+ // are subtituted for fresh symbols within the new context owner.
338347 val nameReader = fork
339348 nameReader.skipTree() // skip result
340349 val paramReader = nameReader.fork
341350 val (paramNames, mods) = nameReader.readParamNamesAndMods(end)
342- companionOp(mods)( paramNames.map(nameMap))(
343- pt => typeAtAddr(start) = pt ,
344- () => paramReader.readParamTypes(paramNames.length ),
345- () => readType()
346- ).tap(typeAtAddr(start) = _)
351+ LambdaFactory .parse(factory, paramNames.map(nameMap), parseFlags(mods)(ctx ))(
352+ () => paramReader.readParamTypes(paramNames.length).to( ArraySeq ) ,
353+ () => readType( ),
354+ pt => typeAtAddr(start) = pt, // register the lambda so that we can access its parameters
355+ )
347356 })
348357 goto(end)
349358 result
@@ -382,18 +391,10 @@ class TreeUnpickler[Tasty <: TastyUniverse](
382391 case ORtype => unionIsUnsupported
383392 case SUPERtype => defn.SuperType (readType(), readType())
384393 case MATCHtype | MATCHCASEtype => matchTypeIsUnsupported
385- case POLYtype => readMethodic(Function .const(PolyType ), _.toTypeName)
386- case METHODtype =>
387- def companion (mods0 : TastyFlagSet ) = {
388- var mods = EmptyTastyFlags
389- if (mods0.is(Erased )) erasedRefinementIsUnsupported[Unit ]
390- if (mods0.isOneOf(Given | Implicit )) mods |= Implicit
391- methodTypeCompanion(mods)
392- }
393- readMethodic(companion, id)
394- case TYPELAMBDAtype => readMethodic(Function .const(HKTypeLambda ), _.toTypeName)
395- case PARAMtype => // reference to a type parameter within a LambdaType
396- readTypeRef().typeParams(readNat()).ref
394+ case POLYtype => readMethodic(PolyTypeLambda , FlagSets .addDeferred, _.toTypeName)
395+ case METHODtype => readMethodic(MethodTermLambda , FlagSets .parseMethod, id)
396+ case TYPELAMBDAtype => readMethodic(HKTypeLambda , FlagSets .addDeferred, _.toTypeName)
397+ case PARAMtype => defn.ParamRef (readTypeRef(), readNat()) // reference to a parameter within a LambdaType
397398 }
398399 assert(currentAddr === end, s " $start $currentAddr $end ${astTagToString(tag)}" )
399400 result
0 commit comments