Skip to content

Commit 412fe37

Browse files
Merge pull request #4052 from dotty-staging/add-quote-show-tree-cleaner
Add quote.show tree cleaner
2 parents c7ac32a + 8216c5a commit 412fe37

26 files changed

+338
-100
lines changed

compiler/src/dotty/tools/dotc/quoted/QuoteDriver.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,8 @@ class QuoteDriver extends Driver {
4444
def show(tree: Tree, ctx: Context): String = {
4545
val printer = new DecompilerPrinter(ctx)
4646
val pageWidth = ctx.settings.pageWidth.value(ctx)
47-
printer.toText(tree).mkString(pageWidth, false)
47+
val tree1 = if (settings.rawTree) tree else (new TreeCleaner).transform(tree)(ctx)
48+
printer.toText(tree1).mkString(pageWidth, false)
4849
}
4950
withTree(expr, show, settings)
5051
}

compiler/src/dotty/tools/dotc/quoted/Toolbox.scala

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ object Toolbox {
5353

5454
}
5555

56-
class Settings[T] private (val outDir: Option[String], val compilerArgs: List[String])
56+
class Settings[T] private (val outDir: Option[String], val rawTree: Boolean, val compilerArgs: List[String])
5757

5858
object Settings {
5959

@@ -69,19 +69,22 @@ object Toolbox {
6969
): Settings[Run] = {
7070
var compilerArgs1 = compilerArgs
7171
if (optimise) compilerArgs1 = "-optimise" :: compilerArgs1
72-
new Settings(outDir, compilerArgs1)
72+
new Settings(outDir, false, compilerArgs1)
7373
}
7474

7575
/** Quote show settings
76+
* @param color Print output with colors
77+
* @param rawTree Do not remove quote tree artifacts
7678
* @param compilerArgs Compiler arguments. Use only if you know what you are doing.
7779
*/
7880
def show(
7981
color: Boolean = false,
82+
rawTree: Boolean = false,
8083
compilerArgs: List[String] = Nil
8184
): Settings[Show] = {
8285
var compilerArgs1 = compilerArgs
8386
compilerArgs1 = s"-color:${if (color) "always" else "never"}" :: compilerArgs1
84-
new Settings(None, compilerArgs1)
87+
new Settings(None, rawTree, compilerArgs1)
8588
}
8689

8790
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
package dotty.tools.dotc.quoted
2+
3+
import dotty.tools.dotc.ast.Trees._
4+
import dotty.tools.dotc.ast.tpd
5+
import dotty.tools.dotc.core.Contexts._
6+
import dotty.tools.dotc.core.Constants._
7+
import dotty.tools.dotc.core.Symbols._
8+
import dotty.tools.dotc.core.Types._
9+
10+
/** Clean up quote artifacts from the tree to make it simpler to read.
11+
* - Flattens block and remove blocks with not statements
12+
* - Inline type aliases in the tree
13+
*/
14+
class TreeCleaner extends tpd.TreeMap {
15+
import tpd._
16+
17+
/** List of symbols and their types for type aliases `type T = U` */
18+
private[this] var aliasesSyms: List[Symbol] = Nil
19+
private[this] var aliasesTypes: List[Type] = Nil
20+
21+
override def transform(tree: Tree)(implicit ctx: Context): Tree = {
22+
val tree0 = tree match {
23+
case TypeDef(_, TypeBoundsTree(lo, hi)) if lo == hi =>
24+
aliasesSyms = tree.symbol :: aliasesSyms
25+
aliasesTypes = lo.tpe :: aliasesTypes
26+
Literal(Constant(()))
27+
case _ => tree
28+
}
29+
30+
super.transform(tree0) match {
31+
case Block(Nil, expr1) => expr1
32+
case Block(stats1, expr1) =>
33+
val flatStats = stats1.flatMap {
34+
case Block(stats2, expr2) => stats2 ::: expr2 :: Nil
35+
case Literal(Constant(())) => Nil
36+
case stat => stat :: Nil
37+
}
38+
expr1 match {
39+
case Block(stats3, expr3) => Block(flatStats ::: stats3, expr3)
40+
case expr3 => Block(flatStats, expr3)
41+
}
42+
case tree1: TypeTree => TypeTree(tree1.tpe.subst(aliasesSyms, aliasesTypes))
43+
case tree1 => tree1
44+
}
45+
}
46+
}

tests/run-with-compiler/i3823-c.check

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,4 @@
11
{
2-
type T = Int
3-
{
4-
val z: T = 2
5-
()
6-
}
2+
val z: Int = 2
3+
()
74
}

tests/run-with-compiler/i3876-b.check

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
6
22
{
33
val x$1: Int = 3
4-
{
5-
def f(x: Int): Int = x.+(x)
6-
f(x$1)
7-
}
4+
def f(x: Int): Int = x.+(x)
5+
f(x$1)
86
}

tests/run-with-compiler/i3876-c.check

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,14 @@
11
6
22
{
33
val x$1: Int = 3
4-
{
5-
val f:
6-
Function1[Int, Int]
7-
{
8-
def apply(x: Int): Int
9-
}
10-
=
4+
val f:
5+
Function1[Int, Int]
116
{
12-
(x: Int) => x.+(x)
7+
def apply(x: Int): Int
138
}
14-
(f: (x: Int) => Int).apply(x$1)
15-
}
9+
=
10+
{
11+
(x: Int) => x.+(x)
12+
}
13+
(f: (x: Int) => Int).apply(x$1)
1614
}

tests/run-with-compiler/i3876.check

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
6
22
{
33
val x$1: Int = 3
4-
{
5-
x$1.+(x$1)
6-
}
4+
x$1.+(x$1)
75
}
Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,12 @@
11
1.0
22
5.0
33
{
4+
val y: Double = 5.0.*(5.0)
5+
y
6+
}
7+
5.0.*(
48
{
59
val y: Double = 5.0.*(5.0)
610
y
711
}
8-
}
9-
{
10-
5.0.*(
11-
{
12-
{
13-
val y: Double = 5.0.*(5.0)
14-
y
15-
}
16-
}
17-
)
18-
}
12+
)
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
3
2+
4
3+
abc
4+
null
5+
OK
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import scala.quoted._
2+
3+
import dotty.tools.dotc.quoted.Toolbox._
4+
5+
object Test {
6+
7+
def main(args: Array[String]): Unit = {
8+
(3: Expr[Int]) match { case Constant(n) => println(n) }
9+
'(4) match { case Constant(n) => println(n) }
10+
'("abc") match { case Constant(n) => println(n) }
11+
'(null) match { case Constant(n) => println(n) }
12+
13+
'(new Object) match { case Constant(n) => println(n); case _ => println("OK") }
14+
}
15+
}

0 commit comments

Comments
 (0)