From 08f0aac09abd788a964f3b8341031f4acbe78f92 Mon Sep 17 00:00:00 2001 From: Jamie Thompson Date: Thu, 14 Oct 2021 11:31:25 +0200 Subject: [PATCH] add printTypesAndErasure to compare typer and erasure --- .../test/dotty/tools/DottyTypeStealer.scala | 71 +++++++++++++------ 1 file changed, 49 insertions(+), 22 deletions(-) diff --git a/compiler/test/dotty/tools/DottyTypeStealer.scala b/compiler/test/dotty/tools/DottyTypeStealer.scala index 24adda5887a2..52bf7a7e221a 100644 --- a/compiler/test/dotty/tools/DottyTypeStealer.scala +++ b/compiler/test/dotty/tools/DottyTypeStealer.scala @@ -3,30 +3,62 @@ package dotty.tools import dotc.ast.tpd import dotc.core.Names._ import dotc.ast.tpd._ -import dotc.core.Contexts.Context +import dotc.core.Contexts.{Context, atPhase} +import dotty.tools.dotc.core.Phases.{typerPhase, erasurePhase} +import dotc.core.Symbols.Symbol import dotc.core.Decorators._ import dotc.core.Types.Type +import scala.util.CommandLineParser.FromString + /**Pass a string representing a Scala source file, * and then some type signatures referencing prior definitions. * - * The type signatures will then be printed (singleton types - * are widened.) + * The type signatures will then be printed as raw data structures. * - * @param kind the kind of type we are inspecting [`rhs`, `method`, `class`, `type`] * @param source top level Scala definitions, e.g. `"class O { type X }"` + * @param kind the kind of type we are inspecting [`rhs`, `method`, `class`, `type`] * @param typeStrings Scala type signatures, e.g. `"O#X"` * * @syntax markdown */ -@main def printTypes(source: String, kind: String, typeStrings: String*) = { - val k = DottyTypeStealer.Kind.lookup(kind) - val (_, tpes) = DottyTypeStealer.stealType(source, k, typeStrings*) +@main def printTypes(source: String, kind: DottyTypeStealer.Kind, typeStrings: String*) = { + val (_, tpes) = DottyTypeStealer.stealType(source, kind, typeStrings*) tpes.foreach(t => println(s"$t [${t.getClass}]")) } +/**Pass a string representing a Scala source file, + * and then some type signatures referencing prior definitions. + * + * The type signatures will then be printed comparing between phase + * `typer` where types are as Scala understands them and phase `erasure`, + * which models the JVM types. + * + * @param source top level Scala definitions, e.g. `"class O { type X }"` + * @param kind the kind of type we are inspecting [`rhs`, `method`, `class`, `type`] + * @param typeStrings Scala type signatures, e.g. `"O#X"` + * + * @syntax markdown + */ +@main def printTypesAndErasure(source: String, kind: DottyTypeStealer.Kind, typeStrings: String*): Unit = + val (ictx, vdefs) = DottyTypeStealer.stealMember("erasure", source, kind, typeStrings*) + + given Context = ictx + + for vdef <- vdefs do + println(i"info @ typer => ${atPhase(typerPhase.next)(vdef.info)}") + println(i"info @ erasure => ${atPhase(erasurePhase.next)(vdef.info)}") +end printTypesAndErasure + object DottyTypeStealer extends DottyTest { + given FromString[Kind] = kind => + if kind == "" then + println(s"assuming kind `${Kind.rhs}`") + Kind.rhs + else + Kind.valueOf(kind) + enum Kind: case `rhs`, `method`, `class`, `type` @@ -36,24 +68,19 @@ object DottyTypeStealer extends DottyTest { case `class` => s"class $name $arg" case `type` => s"type $name $arg" - object Kind: - - def lookup(kind: String): Kind = - values.find(_.productPrefix == kind).getOrElse { - println(s"unknown kind `$kind`, assuming `$rhs`") - rhs - } - - end Kind - - def stealType(source: String, kind: Kind, typeStrings: String*): (Context, List[Type]) = { + val (scontext, members) = stealMember("typer", source, kind, typeStrings*) + given Context = scontext + (scontext, members.map(_.info)) + } + + def stealMember(lastPhase: String, source: String, kind: Kind, typeStrings: String*): (Context, List[Symbol]) = { val dummyName = "x_x_x" val vals = typeStrings.zipWithIndex.map{case (s, x) => kind.format(dummyName + x, s) }.mkString("\n") val gatheredSource = s" ${source}\n object A$dummyName {$vals}" var scontext : Context = null - var tp: List[Type] = null - checkCompile("typer", gatheredSource) { + var members: List[Symbol] = null + checkCompile(lastPhase, gatheredSource) { (tree, context) => given Context = context val findMemberDef: (List[MemberDef], tpd.Tree) => List[MemberDef] = @@ -64,9 +91,9 @@ object DottyTypeStealer extends DottyTest { case _ => acc } val d = new DeepFolder[List[MemberDef]](findMemberDef).foldOver(Nil, tree) - tp = d.map(_.symbol.info).reverse + members = d.map(_.symbol).reverse scontext = context } - (scontext, tp) + (scontext, members) } }