Skip to content

Commit a15cfad

Browse files
Merge pull request #4577 from dotty-staging/add-tasty-show
Add tasty Show type class and us in Tasty.XYZ.show
2 parents c963249 + b315dbf commit a15cfad

File tree

16 files changed

+191
-49
lines changed

16 files changed

+191
-49
lines changed

compiler/src/dotty/tools/dotc/tasty/TastyImpl.scala

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import dotty.tools.dotc.util.SourcePosition
1111

1212
import scala.quoted
1313
import scala.reflect.ClassTag
14+
import scala.tasty.util.{Show, ShowExtractors}
1415

1516
object TastyImpl extends scala.tasty.Tasty {
1617

@@ -24,6 +25,15 @@ object TastyImpl extends scala.tasty.Tasty {
2425
def toTasty(implicit ctx: Context): TypeTree = PickledQuotes.quotedTypeToTree(x)
2526
}
2627

28+
// ===== Show =====================================================
29+
30+
def defaultShow: Show[this.type] = showExtractors
31+
32+
def showExtractors: Show[this.type] = new ShowExtractors(this)
33+
34+
// TODO
35+
// def showSourceCode: Show[this.type] = ???
36+
2737
// ===== Contexts =================================================
2838

2939
type Context = Contexts.Context
@@ -53,8 +63,9 @@ object TastyImpl extends scala.tasty.Tasty {
5363

5464
type Tree = tpd.Tree
5565

56-
def TreeDeco(t: Tree): AbstractTree = new AbstractTree {
57-
def pos(implicit ctx: Context): Position = t.pos
66+
def TreeDeco(tree: Tree): AbstractTree = new AbstractTree {
67+
def show(implicit ctx: Context, s: Show[TastyImpl.this.type]): String = s.showTree(tree)
68+
def pos(implicit ctx: Context): Position = tree.pos
5869
}
5970

6071
type PackageClause = tpd.PackageDef
@@ -449,8 +460,9 @@ object TastyImpl extends scala.tasty.Tasty {
449460

450461
type TypeOrBoundsTree = tpd.Tree
451462

452-
def TypeOrBoundsTreeDeco(x: TypeOrBoundsTree): AbstractTypeOrBoundsTree = new AbstractTypeOrBoundsTree {
453-
def tpe(implicit ctx: Context): Type = x.tpe.stripTypeVar
463+
def TypeOrBoundsTreeDeco(tpt: TypeOrBoundsTree): AbstractTypeOrBoundsTree = new AbstractTypeOrBoundsTree {
464+
def show(implicit ctx: Context, s: Show[TastyImpl.this.type]): String = s.showTypeOrBoundsTree(tpt)
465+
def tpe(implicit ctx: Context): Type = tpt.tpe.stripTypeVar
454466
}
455467

456468
// ----- TypeTrees ------------------------------------------------
@@ -559,6 +571,10 @@ object TastyImpl extends scala.tasty.Tasty {
559571

560572
type TypeOrBounds = Types.Type
561573

574+
def TypeOrBoundsDeco(tpe: Types.Type): AbstractTypeOrBounds = new AbstractTypeOrBounds {
575+
def show(implicit ctx: Context, s: Show[TastyImpl.this.type]): String = s.showTypeOrBounds(tpe)
576+
}
577+
562578
// ----- Types ----------------------------------------------------
563579

564580
type Type = Types.Type
@@ -756,8 +772,9 @@ object TastyImpl extends scala.tasty.Tasty {
756772

757773
type Constant = Constants.Constant
758774

759-
def ConstantDeco(x: Constant): AbstractConstant = new AbstractConstant {
760-
def value: Any = x.value
775+
def ConstantDeco(const: Constant): AbstractConstant = new AbstractConstant {
776+
def show(implicit ctx: Context, s: Show[TastyImpl.this.type]): String = s.showConstant(const)
777+
def value: Any = const.value
761778
}
762779

763780
def constantClassTag: ClassTag[Constant] = implicitly[ClassTag[Constant]]

library/src/scala/tasty/Tasty.scala

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
package scala.tasty
22

33
import scala.reflect.ClassTag
4+
import scala.tasty.util.Show
45

5-
abstract class Tasty {
6+
abstract class Tasty { tasty =>
67

78
// ===== Quotes ===================================================
89

@@ -16,14 +17,23 @@ abstract class Tasty {
1617
}
1718
implicit def QuotedTypeDeco[T](x: quoted.Type[T]): AbstractQuotedType
1819

20+
// ===== Show =====================================================
21+
22+
implicit def defaultShow: Show[tasty.type]
23+
24+
def showExtractors: Show[tasty.type]
25+
26+
// TODO
27+
// def showSourceCode: Show[tasty.type]
28+
1929
// ===== Contexts =================================================
2030

2131
type Context
2232

2333
trait AbstractContext {
2434
def owner: Definition
2535
}
26-
implicit def ContextDeco(x: Context): AbstractContext
36+
implicit def ContextDeco(ctx: Context): AbstractContext
2737

2838
// ===== Id =======================================================
2939

@@ -43,8 +53,10 @@ abstract class Tasty {
4353

4454
type Tree
4555

46-
trait AbstractTree extends Positioned
47-
implicit def TreeDeco(t: Tree): AbstractTree
56+
trait AbstractTree extends Positioned {
57+
def show(implicit ctx: Context, s: Show[tasty.type]): String
58+
}
59+
implicit def TreeDeco(tree: Tree): AbstractTree
4860

4961
type PackageClause <: Tree
5062

@@ -335,9 +347,10 @@ abstract class Tasty {
335347
type TypeOrBoundsTree
336348

337349
trait AbstractTypeOrBoundsTree {
350+
def show(implicit ctx: Context, s: Show[tasty.type]): String
338351
def tpe(implicit ctx: Context): TypeOrBounds
339352
}
340-
implicit def TypeOrBoundsTreeDeco(x: TypeOrBoundsTree): AbstractTypeOrBoundsTree
353+
implicit def TypeOrBoundsTreeDeco(tpt: TypeOrBoundsTree): AbstractTypeOrBoundsTree
341354

342355

343356
// ----- TypeTrees ------------------------------------------------
@@ -430,6 +443,11 @@ abstract class Tasty {
430443
def tpe(implicit ctx: Context): Type
431444
}
432445

446+
trait AbstractTypeOrBounds {
447+
def show(implicit ctx: Context, s: Show[tasty.type]): String
448+
}
449+
implicit def TypeOrBoundsDeco(tpe: TypeOrBounds): AbstractTypeOrBounds
450+
433451
// ----- Types ----------------------------------------------------
434452

435453
type Type <: TypeOrBounds
@@ -576,9 +594,10 @@ abstract class Tasty {
576594

577595
type Constant
578596
trait AbstractConstant {
597+
def show(implicit ctx: Context, s: Show[tasty.type]): String
579598
def value: Any
580599
}
581-
implicit def ConstantDeco(x: Constant): AbstractConstant
600+
implicit def ConstantDeco(const: Constant): AbstractConstant
582601

583602
implicit def constantClassTag: ClassTag[Constant]
584603

library/src/scala/tasty/Universe.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package scala.tasty
22

33
trait Universe {
4-
implicit val tasty: Tasty
4+
val tasty: Tasty
55
implicit val context: tasty.Context
66
}
77

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package scala.tasty.util
2+
3+
import scala.tasty.Tasty
4+
5+
abstract class Show[T <: Tasty with Singleton](val tasty: T) {
6+
7+
def showTree(tree: tasty.Tree)(implicit ctx: tasty.Context): String
8+
9+
def showTypeOrBoundsTree(tpt: tasty.TypeOrBoundsTree)(implicit ctx: tasty.Context): String
10+
11+
def showTypeOrBounds(tpe: tasty.TypeOrBounds)(implicit ctx: tasty.Context): String
12+
13+
def showConstant(const: tasty.Constant)(implicit ctx: tasty.Context): String
14+
15+
}

library/src/scala/tasty/util/TastyPrinter.scala renamed to library/src/scala/tasty/util/ShowExtractors.scala

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,19 @@ package scala.tasty.util
22

33
import scala.tasty.Tasty
44

5-
class TastyPrinter[T <: Tasty with Singleton](val tasty: T) {
5+
class ShowExtractors[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty0) {
66
import tasty._
77

8-
def stringOfTree(tree: Tree)(implicit ctx: Context): String =
8+
def showTree(tree: Tree)(implicit ctx: Context): String =
99
new Buffer().visitTree(tree).result()
1010

11-
def stringOfTypeTree(tree: TypeOrBoundsTree)(implicit ctx: Context): String =
12-
new Buffer().visitTypeTree(tree).result()
11+
def showTypeOrBoundsTree(tpt: TypeOrBoundsTree)(implicit ctx: Context): String =
12+
new Buffer().visitTypeTree(tpt).result()
1313

14-
def stringOfType(tpe: TypeOrBounds)(implicit ctx: Context): String =
14+
def showTypeOrBounds(tpe: TypeOrBounds)(implicit ctx: Context): String =
1515
new Buffer().visitType(tpe).result()
1616

17-
def stringOfModifier(mod: Modifier)(implicit ctx: Context): String =
18-
new Buffer().visitModifier(mod).result()
19-
20-
def stringOfConstant(const: Constant)(implicit ctx: Context): String =
17+
def showConstant(const: Constant)(implicit ctx: Context): String =
2118
new Buffer().visitConstant(const).result()
2219

2320
private class Buffer(implicit ctx: Context) { self =>

tests/run/tasty-custom-show.check

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
foo
2+
Tree
3+
4+
bar
5+
Tree
6+
7+
bar2
8+
Tree
9+
10+
foo2
11+
Tree
12+
13+
baz
14+
Tree
15+
16+
baz2
17+
Tree
18+
19+
<init>
20+
Tree
21+
22+
b
23+
Tree
24+
25+
b2
26+
Tree
27+
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import scala.quoted._
2+
import dotty.tools.dotc.quoted.Toolbox._
3+
4+
import scala.tasty.Universe
5+
import scala.tasty.Tasty
6+
import scala.tasty.util.{TreeTraverser, Show}
7+
8+
object Macros {
9+
10+
implicit inline def printOwners[T](x: => T): Unit =
11+
~impl('(x))(Universe.compilationUniverse) // FIXME infer Universe.compilationUniverse within top level ~
12+
13+
def impl[T](x: Expr[T])(implicit u: Universe): Expr[Unit] = {
14+
import u._
15+
import u.tasty._
16+
17+
18+
val buff = new StringBuilder
19+
20+
val output = new TreeTraverser(u.tasty) {
21+
override def traverseTree(tree: Tree)(implicit ctx: Context): Unit = {
22+
// Use custom Show[_] here
23+
implicit val printer = new DummyShow(tasty)
24+
tree match {
25+
case tree @ DefDef(name, _, _, _, _) =>
26+
buff.append(name)
27+
buff.append("\n")
28+
buff.append(tree.owner.show)
29+
buff.append("\n\n")
30+
case tree @ ValDef(name, _, _) =>
31+
buff.append(name)
32+
buff.append("\n")
33+
buff.append(tree.owner.show)
34+
buff.append("\n\n")
35+
case _ =>
36+
}
37+
traverseTreeChildren(tree)
38+
}
39+
}
40+
41+
val tree = x.toTasty
42+
output.traverseTree(tree)
43+
'(print(~buff.result().toExpr))
44+
}
45+
46+
}
47+
48+
class DummyShow[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty0) {
49+
import tasty._
50+
def showTree(tree: Tree)(implicit ctx: Context): String = "Tree"
51+
def showTypeOrBoundsTree(tpt: TypeOrBoundsTree)(implicit ctx: Context): String = "TypeOrBoundsTree"
52+
def showTypeOrBounds(tpe: TypeOrBounds)(implicit ctx: Context): String = "TypeOrBounds"
53+
def showConstant(const: Constant)(implicit ctx: Context): String = "Constant"
54+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
2+
import Macros._
3+
4+
object Test {
5+
def main(args: Array[String]): Unit = {
6+
printOwners {
7+
def foo = {
8+
def bar = 1
9+
val bar2 = 2
10+
bar
11+
}
12+
val foo2 = {
13+
def baz = 3
14+
val baz2 = 4
15+
baz
16+
}
17+
class A {
18+
type B = Int
19+
def b = 5
20+
val b2 = 6
21+
}
22+
}
23+
}
24+
}

tests/run/tasty-eval/quoted_1.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import scala.quoted._
22

33
import scala.tasty.Universe
4-
import scala.tasty.util.{TastyPrinter, TreeTraverser}
4+
import scala.tasty.util.TreeTraverser
55

66
object Macros {
77

tests/run/tasty-extractors-1/quoted_1.scala

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import scala.quoted._
22
import dotty.tools.dotc.quoted.Toolbox._
33

44
import scala.tasty.Universe
5-
import scala.tasty.util.TastyPrinter
65

76
object Macros {
87

@@ -13,9 +12,8 @@ object Macros {
1312
import u._
1413
import tasty._
1514
val tree = x.toTasty
16-
val printer = new TastyPrinter(tasty)
17-
val treeStr = printer.stringOfTree(tree)
18-
val treeTpeStr = printer.stringOfType(tree.tpe)
15+
val treeStr = tree.show
16+
val treeTpeStr = tree.tpe.show
1917

2018
'{
2119
println(~treeStr.toExpr)

tests/run/tasty-extractors-2/quoted_1.scala

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import scala.quoted._
22
import dotty.tools.dotc.quoted.Toolbox._
33

44
import scala.tasty.Universe
5-
import scala.tasty.util.TastyPrinter
65

76
object Macros {
87

@@ -13,9 +12,9 @@ object Macros {
1312
import u._
1413
import tasty._
1514
val tree = x.toTasty
16-
val printer = new TastyPrinter(tasty)
17-
val treeStr = printer.stringOfTree(tree)
18-
val treeTpeStr = printer.stringOfType(tree.tpe)
15+
16+
val treeStr = tree.show
17+
val treeTpeStr = tree.tpe.show
1918

2019
'{
2120
println(~treeStr.toExpr)

tests/run/tasty-extractors-3/quoted_1.scala

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import scala.quoted._
22
import dotty.tools.dotc.quoted.Toolbox._
33

44
import scala.tasty.Universe
5-
import scala.tasty.util.{TastyPrinter, TreeTraverser}
5+
import scala.tasty.util.TreeTraverser
66

77
object Macros {
88

@@ -13,12 +13,10 @@ object Macros {
1313
import u._
1414
import u.tasty._
1515

16-
val printer = new TastyPrinter(tasty)
17-
1816
val buff = new StringBuilder
1917
val traverser = new TreeTraverser(u.tasty) {
2018
override def traverseTypeTree(tree: TypeOrBoundsTree)(implicit ctx: Context): Unit = {
21-
buff.append(printer.stringOfType(tree.tpe))
19+
buff.append(tree.tpe.show)
2220
buff.append("\n\n")
2321
traverseTypeTreeChildren(tree)
2422
}

0 commit comments

Comments
 (0)