Skip to content

add printTypesAndErasure test main method to compare typer and erasure #13745

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 49 additions & 22 deletions compiler/test/dotty/tools/DottyTypeStealer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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`

Expand All @@ -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] =
Expand All @@ -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)
}
}