@@ -21,6 +21,7 @@ import scala.collection.mutable
21
21
import scala .reflect .io .AbstractFile
22
22
import scala .reflect .internal .Variance
23
23
import scala .util .chaining ._
24
+ import scala .collection .immutable .ArraySeq
24
25
25
26
/** `TreeUnpickler` is responsible for traversing all trees in the "ASTs" section of a TASTy file, which represent the
26
27
* definitions inside the classfile associated with the root class/module. `TreeUnpickler` will enter the public api
@@ -220,7 +221,7 @@ class TreeUnpickler[Tasty <: TastyUniverse](
220
221
/** Read names in an interleaved sequence of types/bounds and (parameter) names,
221
222
* possibly followed by a sequence of modifiers.
222
223
*/
223
- def readParamNamesAndMods (end : Addr ): (List [TastyName ], TastyFlagSet ) = {
224
+ def readParamNamesAndMods (end : Addr ): (ArraySeq [TastyName ], TastyFlagSet ) = {
224
225
val names =
225
226
collectWhile(currentAddr != end && ! isModifierTag(nextByte)) {
226
227
skipTree()
@@ -234,7 +235,7 @@ class TreeUnpickler[Tasty <: TastyUniverse](
234
235
case GIVEN => mods |= Given
235
236
}
236
237
}
237
- (names, mods)
238
+ (names.to( ArraySeq ) , mods)
238
239
}
239
240
240
241
/** Read `n` parameter types or bounds which are interleaved with names */
@@ -332,18 +333,26 @@ class TreeUnpickler[Tasty <: TastyUniverse](
332
333
def readLengthType (): Type = {
333
334
val end = readEnd()
334
335
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 = {
337
341
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.
338
347
val nameReader = fork
339
348
nameReader.skipTree() // skip result
340
349
val paramReader = nameReader.fork
341
350
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
+ )
347
356
})
348
357
goto(end)
349
358
result
@@ -382,18 +391,10 @@ class TreeUnpickler[Tasty <: TastyUniverse](
382
391
case ORtype => unionIsUnsupported
383
392
case SUPERtype => defn.SuperType (readType(), readType())
384
393
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
397
398
}
398
399
assert(currentAddr === end, s " $start $currentAddr $end ${astTagToString(tag)}" )
399
400
result
0 commit comments