Skip to content

Commit 5f224a4

Browse files
Fix pretty printer to handle using and erased modifier (#17952)
The existing pretty printer doesn't handle using/erased keyword, making it a bit misleading when investigating code generated by macros. This PR add support for those two modifiers
2 parents ac69c66 + 056fbc5 commit 5f224a4

File tree

4 files changed

+73
-33
lines changed

4 files changed

+73
-33
lines changed

compiler/src/scala/quoted/runtime/impl/printers/SourceCode.scala

+29-18
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ object SourceCode {
158158
for paramClause <- paramss do
159159
paramClause match
160160
case TermParamClause(params) =>
161-
printArgsDefs(params)
161+
printMethdArgsDefs(params)
162162
case TypeParamClause(params) =>
163163
printTargsDefs(stats.collect { case targ: TypeDef => targ }.filter(_.symbol.isTypeParam).zip(params))
164164
}
@@ -313,7 +313,7 @@ object SourceCode {
313313
this += highlightKeyword("def ") += highlightValDef(name1)
314314
for clause <- paramss do
315315
clause match
316-
case TermParamClause(params) => printArgsDefs(params)
316+
case TermParamClause(params) => printMethdArgsDefs(params)
317317
case TypeParamClause(params) => printTargsDefs(params.zip(params))
318318
if (!isConstructor) {
319319
this += ": "
@@ -460,7 +460,7 @@ object SourceCode {
460460

461461
case tree @ Lambda(params, body) => // must come before `Block`
462462
inParens {
463-
printArgsDefs(params)
463+
printLambdaArgsDefs(params)
464464
this += (if tree.tpe.isContextFunctionType then " ?=> " else " => ")
465465
printTree(body)
466466
}
@@ -804,29 +804,37 @@ object SourceCode {
804804
}
805805
}
806806

807-
private def printArgsDefs(args: List[ValDef])(using elideThis: Option[Symbol]): Unit = {
807+
private def printSeparatedParamDefs(list: List[ValDef])(using elideThis: Option[Symbol]): Unit = list match {
808+
case Nil =>
809+
case x :: Nil => printParamDef(x)
810+
case x :: xs =>
811+
printParamDef(x)
812+
this += ", "
813+
printSeparatedParamDefs(xs)
814+
}
815+
816+
private def printMethdArgsDefs(args: List[ValDef])(using elideThis: Option[Symbol]): Unit = {
808817
val argFlags = args match {
809818
case Nil => Flags.EmptyFlags
810819
case arg :: _ => arg.symbol.flags
811820
}
812-
if (argFlags.is(Flags.Erased | Flags.Given)) {
813-
if (argFlags.is(Flags.Given)) this += " given"
814-
if (argFlags.is(Flags.Erased)) this += " erased"
815-
this += " "
816-
}
817821
inParens {
818822
if (argFlags.is(Flags.Implicit) && !argFlags.is(Flags.Given)) this += "implicit "
823+
if (argFlags.is(Flags.Given)) this += "using "
819824

820-
def printSeparated(list: List[ValDef]): Unit = list match {
821-
case Nil =>
822-
case x :: Nil => printParamDef(x)
823-
case x :: xs =>
824-
printParamDef(x)
825-
this += ", "
826-
printSeparated(xs)
827-
}
825+
printSeparatedParamDefs(args)
826+
}
827+
}
828+
829+
private def printLambdaArgsDefs(args: List[ValDef])(using elideThis: Option[Symbol]): Unit = {
830+
val argFlags = args match {
831+
case Nil => Flags.EmptyFlags
832+
case arg :: _ => arg.symbol.flags
833+
}
834+
inParens {
835+
if (argFlags.is(Flags.Implicit) && !argFlags.is(Flags.Given)) this += "implicit "
828836

829-
printSeparated(args)
837+
printSeparatedParamDefs(args)
830838
}
831839
}
832840

@@ -846,6 +854,9 @@ object SourceCode {
846854
private def printParamDef(arg: ValDef)(using elideThis: Option[Symbol]): Unit = {
847855
val name = splicedName(arg.symbol).getOrElse(arg.symbol.name)
848856
val sym = arg.symbol.owner
857+
858+
if (arg.symbol.flags.is(Flags.Erased)) this += "erased "
859+
849860
if sym.isDefDef && sym.name == "<init>" then
850861
val ClassDef(_, _, _, _, body) = sym.owner.tree: @unchecked
851862
body.collectFirst {

tests/run-macros/term-show.check

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
{
2+
class C() {
3+
def a: scala.Int = 0
4+
private[this] def b: scala.Int = 0
5+
private[this] def c: scala.Int = 0
6+
private[C] def d: scala.Int = 0
7+
protected def e: scala.Int = 0
8+
protected[this] def f: scala.Int = 0
9+
protected[C] def g: scala.Int = 0
10+
}
11+
()
12+
}
13+
@scala.annotation.internal.SourceFile("tests/run-macros/term-show/Test_2.scala") trait A() extends java.lang.Object {
14+
def imp(x: scala.Int)(implicit str: scala.Predef.String): scala.Int
15+
def use(`x₂`: scala.Int)(using `str₂`: scala.Predef.String): scala.Int
16+
def era(`x₃`: scala.Int)(erased `str₃`: scala.Predef.String): scala.Int
17+
def f1(x1: scala.Int, erased x2: scala.Int): scala.Int
18+
def f2(erased `x1₂`: scala.Int, erased `x2₂`: scala.Int): scala.Int
19+
def f3(using `x1₃`: scala.Int, erased `x2₃`: scala.Int): scala.Int
20+
def f4(using erased `x1₄`: scala.Int, erased `x2₄`: scala.Int): scala.Int
21+
}

tests/run-macros/term-show/Macro_1.scala

+7
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,11 @@ object TypeToolbox {
55
private def showImpl(using Quotes)(v: Expr[Any]): Expr[String] =
66
import quotes.reflect.*
77
Expr(v.show)
8+
9+
inline def showTree(inline className: String): String = ${ showTreeImpl('className) }
10+
private def showTreeImpl(className: Expr[String])(using Quotes) : Expr[String] =
11+
import quotes.reflect.*
12+
val name = className.valueOrAbort
13+
val res = Symbol.requiredClass(name).tree.show
14+
Expr(res)
815
}
+16-15
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,19 @@
1+
import scala.language.experimental.erasedDefinitions
2+
3+
trait A:
4+
def imp(x: Int)(implicit str: String): Int
5+
def use(x: Int)(using str: String): Int
6+
def era(x: Int)(erased str: String): Int
7+
8+
def f1(x1: Int, erased x2: Int): Int
9+
def f2(erased x1: Int, erased x2: Int): Int
10+
def f3(using x1: Int, erased x2: Int): Int
11+
def f4(using erased x1: Int, erased x2: Int): Int
12+
113
object Test {
214
import TypeToolbox.*
315
def main(args: Array[String]): Unit = {
4-
assert(show {
16+
println(show {
517
class C {
618
def a = 0
719
private def b = 0
@@ -11,19 +23,8 @@ object Test {
1123
protected[this] def f = 0
1224
protected[C] def g = 0
1325
}
14-
}
15-
==
16-
"""{
17-
| class C() {
18-
| def a: scala.Int = 0
19-
| private[this] def b: scala.Int = 0
20-
| private[this] def c: scala.Int = 0
21-
| private[C] def d: scala.Int = 0
22-
| protected def e: scala.Int = 0
23-
| protected[this] def f: scala.Int = 0
24-
| protected[C] def g: scala.Int = 0
25-
| }
26-
| ()
27-
|}""".stripMargin)
26+
})
27+
28+
println(showTree("A"))
2829
}
2930
}

0 commit comments

Comments
 (0)