Skip to content

Commit 8cf7ae5

Browse files
committed
refactor lambdaTypeCompanion
1 parent d6a621a commit 8cf7ae5

File tree

3 files changed

+62
-98
lines changed

3 files changed

+62
-98
lines changed

src/compiler/scala/tools/nsc/tasty/TreeUnpickler.scala

Lines changed: 11 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -297,40 +297,27 @@ class TreeUnpickler[Tasty <: TastyUniverse](
297297
val tag = readByte()
298298
ctx.log(s"reading type ${astTagToString(tag)} at $start")
299299

300-
def registeringType[T](tp: Type, op: => T): T = {
300+
def registeringTypeWith[T](tp: Type, op: => T): T = {
301301
typeAtAddr(start) = tp
302302
op
303303
}
304304

305305
def readLengthType(): Type = {
306306
val end = readEnd()
307307

308-
def readMethodic[N <: Name, PInfo <: Type, LT <: LambdaType]
309-
(companion: LambdaTypeCompanion[N, PInfo, LT], nameMap: TastyName => N, varianceMap: TastyName => Variance)(implicit ctx: Context): Type = {
310-
val complete = typeAtAddr.contains(start)
311-
val stored = typeAtAddr.getOrElse(start, {
308+
def readMethodic[N <: Name, PInfo <: Type, LT <: LambdaType, Res <: Type]
309+
(companion: LambdaTypeCompanion[N, PInfo, LT, Res], nameMap: TastyName => N)(implicit ctx: Context): Res = {
310+
val result = typeAtAddr.getOrElse(start, {
312311
val nameReader = fork
313312
nameReader.skipTree() // skip result
314313
val paramReader = nameReader.fork
315314
val paramNames = nameReader.readParamNames(end)
316-
val encodedNames = paramNames.map(nameMap)
317-
val nameVariances = paramNames.map(varianceMap)
318-
companion(encodedNames, nameVariances)(
319-
pt => registeringType(pt, paramReader.readParamTypes[PInfo](end)),
320-
pt => readType())
315+
companion(paramNames)(nameMap,
316+
pt => registeringTypeWith(pt, paramReader.readParamTypes[PInfo](end)),
317+
pt => readType()).tap(typeAtAddr(start) = _)
321318
})
322319
goto(end)
323-
val canonical = {
324-
if (complete) {
325-
stored
326-
}
327-
else {
328-
val canonical = stored.asInstanceOf[LT].canonicalForm
329-
typeAtAddr.update(start, canonical)
330-
canonical
331-
}
332-
}
333-
canonical
320+
result.asInstanceOf[Res]
334321
}
335322

336323
val result =
@@ -390,9 +377,9 @@ class TreeUnpickler[Tasty <: TastyUniverse](
390377
// case IMPLICITMETHODtype =>
391378
// readMethodic(ImplicitMethodType, _.toTermName)
392379
case TYPELAMBDAtype =>
393-
readMethodic(HKTypeLambda, _.toEncodedTermName.toTypeName, _.variance)
380+
readMethodic(HKTypeLambda, _.toEncodedTermName.toTypeName)
394381
case PARAMtype =>
395-
readTypeRef().asInstanceOf[LambdaType].typeParams(readNat()).ref
382+
readTypeRef().typeParams(readNat()).ref
396383
}
397384
assert(currentAddr === end, s"$start $currentAddr $end ${astTagToString(tag)}")
398385
result
@@ -1467,7 +1454,7 @@ class TreeUnpickler[Tasty <: TastyUniverse](
14671454
case LAMBDAtpt =>
14681455
val tparams = readParams[NoCycle](TYPEPARAM)
14691456
val body = readTpt()
1470-
TypeTree(TypeParamLambda(tparams.map(symFromNoCycle), body.tpe).canonicalForm) //LambdaTypeTree(tparams, body)
1457+
TypeTree(mkLambdaFromParams(tparams.map(symFromNoCycle), body.tpe)) //LambdaTypeTree(tparams, body)
14711458
// case MATCHtpt =>
14721459
// val fst = readTpt()
14731460
// val (bound, scrut) =

src/compiler/scala/tools/nsc/tasty/bridge/TastyKernel.scala

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -57,10 +57,6 @@ trait TastyKernel { self: TastyUniverse =>
5757
def empty: TypeBounds = symbolTable.TypeBounds.empty
5858
def upper(hi: Type): TypeBounds = symbolTable.TypeBounds.upper(hi)
5959
def lower(lo: Type): TypeBounds = symbolTable.TypeBounds.lower(lo)
60-
def addLower(tpe: Type): TypeBounds = tpe match {
61-
case tpe: TypeBounds => tpe
62-
case tpe => upper(tpe)
63-
}
6460
def bounded(lo: Type, hi: Type): TypeBounds = symbolTable.TypeBounds.apply(lo, hi)
6561
}
6662

src/compiler/scala/tools/nsc/tasty/bridge/TypeOps.scala

Lines changed: 51 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ trait TypeOps extends TastyKernel { self: TastyUniverse =>
5050
mkPolyType(hi.typeParams, TypeBounds.bounded(nuLo, hi.resultType.upperBound))
5151
}
5252
else bounds match {
53-
case TypeBounds(lo: LambdaEncoding, hi: LambdaEncoding) => TypeBounds.bounded(lo.toNested,hi.toNested)
53+
case TypeBounds(lo: LambdaPolyType, hi: LambdaPolyType) => TypeBounds.bounded(lo.toNested,hi.toNested)
5454
case _ => bounds
5555
}
5656
}
@@ -73,11 +73,11 @@ trait TypeOps extends TastyKernel { self: TastyUniverse =>
7373
mkAppliedType(tycon, args)
7474
}
7575

76-
if (args.exists(tpe => tpe.isInstanceOf[TypeBounds] | tpe.isInstanceOf[LambdaEncoding])) {
76+
if (args.exists(tpe => tpe.isInstanceOf[TypeBounds] | tpe.isInstanceOf[LambdaPolyType])) {
7777
val syms = mutable.ListBuffer.empty[Symbol]
7878
def bindWildcards(tpe: Type) = tpe match {
7979
case tpe: TypeBounds => ctx.newWildcardSym(tpe).tap(syms += _).pipe(_.ref)
80-
case tpe: LambdaEncoding => tpe.toNested
80+
case tpe: LambdaPolyType => tpe.toNested
8181
case tpe => tpe
8282
}
8383
val args1 = args.map(bindWildcards)
@@ -221,114 +221,90 @@ trait TypeOps extends TastyKernel { self: TastyUniverse =>
221221
tpeOrErr.fold(reportThenErrorTpe, identity)
222222
}
223223

224-
abstract class LambdaTypeCompanion[N <: Name, PInfo <: Type, LT <: LambdaType] {
225-
def apply(paramNames: List[N], paramVariances: List[Variance])(paramInfosExp: LT => List[PInfo], resultTypeExp: LT => Type)(implicit ctx: Context): LT
224+
def lambdaResultType(resType: Type): Type = resType match {
225+
case res: LambdaPolyType => res.toNested
226+
case res => res
226227
}
227228

228-
final class LambdaEncoding(override val typeParams: List[Symbol], val resTpe: Type) extends PolyType(typeParams, TypeBounds.addLower(resTpe)) {
229-
def toNested: PolyType = resTpe match {
229+
abstract class LambdaTypeCompanion[N <: Name, PInfo <: Type, LT <: LambdaType, Res <: Type] {
230+
def apply(paramNames: List[TastyName])(nameMap: TastyName => N, paramInfosExp: LT => List[PInfo], resultTypeExp: LT => Type)(implicit ctx: Context): Res
231+
}
232+
233+
final class LambdaPolyType(typeParams: List[Symbol], resType: Type) extends PolyType(typeParams, LambdaPolyType.addLower(resType)) {
234+
def toNested: PolyType = resType match {
230235
case _: TypeBounds => this
231-
case _ => mkPolyType(typeParams, resTpe)
236+
case _ => mkPolyType(typeParams, resType)
232237
}
233238
}
234239

235-
def mkLambdaEncoding(typeParams: List[Symbol], resTpe: Type) = new LambdaEncoding(typeParams, resTpe)
236-
237-
object TypeParamLambda {
238-
def apply(typeParams: List[Symbol], ret: Type): LambdaType = new TypeParamLambda(typeParams, ret)
240+
object LambdaPolyType {
241+
private def addLower(tpe: Type): TypeBounds = tpe match {
242+
case tpe: TypeBounds => tpe
243+
case tpe => TypeBounds.upper(tpe)
244+
}
239245
}
240246

241-
final class TypeParamLambda(override val typeParams: List[Symbol], val resType: Type) extends LambdaType {
242-
type ThisName = TypeName
243-
type PInfo = TypeBounds
247+
def mkLambdaPolyType(typeParams: List[Symbol], resTpe: Type): LambdaPolyType = new LambdaPolyType(typeParams, resTpe)
248+
def mkLambdaFromParams(typeParams: List[Symbol], ret: Type): PolyType = mkPolyType(typeParams, lambdaResultType(ret))
244249

245-
val paramVariances: List[Variance] = typeParams.map(_.variance)
246-
val paramNames: List[TypeName] = typeParams.map(_.name.toTypeName)
247-
val paramInfos: List[TypeBounds] = typeParams.map(_.tpe.bounds)
250+
type LambdaType = Type with Lambda
248251

249-
validateThisLambda()
250-
251-
override val productPrefix = "TypeParamLambda"
252-
override def canEqual(that: Any): Boolean = that.isInstanceOf[TypeParamLambda]
253-
}
254-
255-
abstract class LambdaType extends Type with Product { lambdaTpe =>
252+
trait Lambda extends Product with Serializable {
253+
self: Type =>
256254
type ThisName <: Name
257255
type PInfo <: Type
258256

259257
val paramNames: List[ThisName]
260-
val paramVariances: List[Variance]
261258
val paramInfos: List[PInfo]
262259
val resType: Type
263260

264-
override final def safeToString: String = {
265-
val args = paramNames.zip(paramInfos).map {
266-
case (name, info) => s"${name}$info"
267-
}.mkString("[", ", ", "]")
268-
s"$args =>> $resType"
269-
}
270-
271261
def typeParams: List[Symbol] // deferred to final implementation
272262

273263
final protected def validateThisLambda(): Unit = {
274-
assert(resType.isComplete, this)
275-
assert(paramNames.nonEmpty, this)
276-
assert(paramInfos.length == paramNames.length, this)
264+
assert(resType.isComplete, self)
265+
assert(paramNames.nonEmpty, self)
266+
assert(paramInfos.length == paramNames.length, self)
277267
}
278268

279-
/**Best effort to transform this to an equivalent canonical representation in scalac.
280-
*/
281-
final def canonicalForm(implicit ctx: Context): Type = {
282-
val res = resType match {
283-
case res: LambdaEncoding => res.toNested
284-
case res => res
285-
}
286-
lambdaTpe match {
287-
case _: HKTypeLambda => mkLambdaEncoding(typeParams, res)
288-
case _: TypeParamLambda => mkPolyType(typeParams, res)
289-
}
290-
}.tap(res => ctx.log(s"""|canonical form of ${lambdaTpe.productPrefix}:
291-
| TASTy = $lambdaTpe
292-
| scala.reflect = $res""".stripMargin))
269+
override final def productArity: Int = 2
293270

294-
final def productArity: Int = 2
295-
final def productElement(n: Int): Any = n match {
271+
override final def productElement(n: Int): Any = n match {
296272
case 0 => paramNames
297273
case 1 => resType
298274
case _ => throw new IndexOutOfBoundsException(n.toString)
299275
}
300-
def canEqual(that: Any): Boolean = that.isInstanceOf[LambdaType]
276+
277+
def canEqual(that: Any): Boolean = that.isInstanceOf[Lambda]
278+
301279
override final def equals(that: Any): Boolean = that match {
302-
case lambdaType: LambdaType =>
303-
(lambdaType.canEqual(this)
304-
&& lambdaType.paramNames == paramNames
305-
&& lambdaType.resType == resType)
280+
case that: Lambda =>
281+
(that.canEqual(self)
282+
&& that.paramNames == paramNames
283+
&& that.resType == resType)
306284
case _ => false
307285
}
308286
}
309287

310-
object HKTypeLambda extends LambdaTypeCompanion[TypeName, TypeBounds, HKTypeLambda] {
311-
def apply(paramNames: List[TypeName], paramVariances: List[Variance])(
312-
paramInfosExp: HKTypeLambda => List[TypeBounds], resultTypeExp: HKTypeLambda => Type)(implicit ctx: Context): HKTypeLambda =
313-
new HKTypeLambda(paramNames, paramVariances)(paramInfosExp, resultTypeExp)
288+
object HKTypeLambda extends LambdaTypeCompanion[TypeName, TypeBounds, HKTypeLambda, LambdaPolyType] {
289+
def apply(paramNames: List[TastyName])(nameMap: TastyName => TypeName,
290+
paramInfosExp: HKTypeLambda => List[TypeBounds], resultTypeExp: HKTypeLambda => Type)(implicit ctx: Context): LambdaPolyType =
291+
new HKTypeLambda(paramNames)(nameMap, paramInfosExp, resultTypeExp).toPolyType
314292
}
315293

316-
final class HKTypeLambda(val paramNames: List[TypeName], val paramVariances: List[Variance])(
294+
final class HKTypeLambda(params: List[TastyName])(nameMap: TastyName => TypeName,
317295
paramInfosExp: HKTypeLambda => List[TypeBounds], resultTypeExp: HKTypeLambda => Type)(implicit ctx: Context)
318-
extends LambdaType {
296+
extends Type with Lambda { hkLambda =>
319297
type ThisName = TypeName
320298
type PInfo = TypeBounds
321299

322300
private[this] var myTypeParams: List[Symbol] = _
323301

324302
override val productPrefix = "HKTypeLambda"
325-
val paramInfos: List[TypeBounds] = paramInfosExp(this)
326-
val resType: Type = resultTypeExp(this)
327-
328-
validateThisLambda()
303+
val paramNames: List[TypeName] = params.map(nameMap)
304+
val paramInfos: List[TypeBounds] = paramInfosExp(hkLambda)
329305

330-
override def typeParams: List[Symbol] = {
331-
if (myTypeParams `eq` null) myTypeParams = paramNames.lazyZip(paramInfos).lazyZip(paramVariances).map {
306+
override val typeParams: List[Symbol] = {
307+
paramNames.lazyZip(paramInfos).lazyZip(params.map(_.variance)).map {
332308
case (name, bounds, variance) =>
333309
val flags0 = Param | Deferred
334310
val flags = variance match {
@@ -339,9 +315,14 @@ trait TypeOps extends TastyKernel { self: TastyUniverse =>
339315
val argInfo = normaliseBounds(bounds)
340316
ctx.owner.newTypeParameter(name, noPosition, flags).setInfo(argInfo)
341317
}
342-
myTypeParams
343318
}
344319

320+
val resType: Type = lambdaResultType(resultTypeExp(hkLambda))
321+
322+
validateThisLambda()
323+
324+
final def toPolyType: LambdaPolyType = mkLambdaPolyType(typeParams, resType)
325+
345326
override def canEqual(that: Any): Boolean = that.isInstanceOf[HKTypeLambda]
346327
}
347328

0 commit comments

Comments
 (0)