Skip to content

Add tasty Show type class and us in Tasty.XYZ.show #4577

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 1 commit into from
May 25, 2018
Merged
Show file tree
Hide file tree
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
29 changes: 23 additions & 6 deletions compiler/src/dotty/tools/dotc/tasty/TastyImpl.scala
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import dotty.tools.dotc.util.SourcePosition

import scala.quoted
import scala.reflect.ClassTag
import scala.tasty.util.{Show, ShowExtractors}

object TastyImpl extends scala.tasty.Tasty {

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

// ===== Show =====================================================

def defaultShow: Show[this.type] = showExtractors
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using def here makes the member unstable problems, see c9dbecc — I'm not using the API you used, but I'd expect both to work as they usually do.


def showExtractors: Show[this.type] = new ShowExtractors(this)

// TODO
// def showSourceCode: Show[this.type] = ???

// ===== Contexts =================================================

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

type Tree = tpd.Tree

def TreeDeco(t: Tree): AbstractTree = new AbstractTree {
def pos(implicit ctx: Context): Position = t.pos
def TreeDeco(tree: Tree): AbstractTree = new AbstractTree {
def show(implicit ctx: Context, s: Show[TastyImpl.this.type]): String = s.showTree(tree)
def pos(implicit ctx: Context): Position = tree.pos
}

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

type TypeOrBoundsTree = tpd.Tree

def TypeOrBoundsTreeDeco(x: TypeOrBoundsTree): AbstractTypeOrBoundsTree = new AbstractTypeOrBoundsTree {
def tpe(implicit ctx: Context): Type = x.tpe.stripTypeVar
def TypeOrBoundsTreeDeco(tpt: TypeOrBoundsTree): AbstractTypeOrBoundsTree = new AbstractTypeOrBoundsTree {
def show(implicit ctx: Context, s: Show[TastyImpl.this.type]): String = s.showTypeOrBoundsTree(tpt)
def tpe(implicit ctx: Context): Type = tpt.tpe.stripTypeVar
}

// ----- TypeTrees ------------------------------------------------
Expand Down Expand Up @@ -559,6 +571,10 @@ object TastyImpl extends scala.tasty.Tasty {

type TypeOrBounds = Types.Type

def TypeOrBoundsDeco(tpe: Types.Type): AbstractTypeOrBounds = new AbstractTypeOrBounds {
def show(implicit ctx: Context, s: Show[TastyImpl.this.type]): String = s.showTypeOrBounds(tpe)
}

// ----- Types ----------------------------------------------------

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

type Constant = Constants.Constant

def ConstantDeco(x: Constant): AbstractConstant = new AbstractConstant {
def value: Any = x.value
def ConstantDeco(const: Constant): AbstractConstant = new AbstractConstant {
def show(implicit ctx: Context, s: Show[TastyImpl.this.type]): String = s.showConstant(const)
def value: Any = const.value
}

def constantClassTag: ClassTag[Constant] = implicitly[ClassTag[Constant]]
Expand Down
31 changes: 25 additions & 6 deletions library/src/scala/tasty/Tasty.scala
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
package scala.tasty

import scala.reflect.ClassTag
import scala.tasty.util.Show

abstract class Tasty {
abstract class Tasty { tasty =>

// ===== Quotes ===================================================

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

// ===== Show =====================================================

implicit def defaultShow: Show[tasty.type]

def showExtractors: Show[tasty.type]

// TODO
// def showSourceCode: Show[tasty.type]

// ===== Contexts =================================================

type Context

trait AbstractContext {
def owner: Definition
}
implicit def ContextDeco(x: Context): AbstractContext
implicit def ContextDeco(ctx: Context): AbstractContext

// ===== Id =======================================================

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

type Tree

trait AbstractTree extends Positioned
implicit def TreeDeco(t: Tree): AbstractTree
trait AbstractTree extends Positioned {
def show(implicit ctx: Context, s: Show[tasty.type]): String
}
implicit def TreeDeco(tree: Tree): AbstractTree

type PackageClause <: Tree

Expand Down Expand Up @@ -335,9 +347,10 @@ abstract class Tasty {
type TypeOrBoundsTree

trait AbstractTypeOrBoundsTree {
def show(implicit ctx: Context, s: Show[tasty.type]): String
def tpe(implicit ctx: Context): TypeOrBounds
}
implicit def TypeOrBoundsTreeDeco(x: TypeOrBoundsTree): AbstractTypeOrBoundsTree
implicit def TypeOrBoundsTreeDeco(tpt: TypeOrBoundsTree): AbstractTypeOrBoundsTree


// ----- TypeTrees ------------------------------------------------
Expand Down Expand Up @@ -430,6 +443,11 @@ abstract class Tasty {
def tpe(implicit ctx: Context): Type
}

trait AbstractTypeOrBounds {
def show(implicit ctx: Context, s: Show[tasty.type]): String
}
implicit def TypeOrBoundsDeco(tpe: TypeOrBounds): AbstractTypeOrBounds

// ----- Types ----------------------------------------------------

type Type <: TypeOrBounds
Expand Down Expand Up @@ -576,9 +594,10 @@ abstract class Tasty {

type Constant
trait AbstractConstant {
def show(implicit ctx: Context, s: Show[tasty.type]): String
def value: Any
}
implicit def ConstantDeco(x: Constant): AbstractConstant
implicit def ConstantDeco(const: Constant): AbstractConstant

implicit def constantClassTag: ClassTag[Constant]

Expand Down
2 changes: 1 addition & 1 deletion library/src/scala/tasty/Universe.scala
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package scala.tasty

trait Universe {
implicit val tasty: Tasty
val tasty: Tasty
implicit val context: tasty.Context
}

Expand Down
15 changes: 15 additions & 0 deletions library/src/scala/tasty/util/Show.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package scala.tasty.util

import scala.tasty.Tasty

abstract class Show[T <: Tasty with Singleton](val tasty: T) {

def showTree(tree: tasty.Tree)(implicit ctx: tasty.Context): String

def showTypeOrBoundsTree(tpt: tasty.TypeOrBoundsTree)(implicit ctx: tasty.Context): String

def showTypeOrBounds(tpe: tasty.TypeOrBounds)(implicit ctx: tasty.Context): String

def showConstant(const: tasty.Constant)(implicit ctx: tasty.Context): String

}
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,19 @@ package scala.tasty.util

import scala.tasty.Tasty

class TastyPrinter[T <: Tasty with Singleton](val tasty: T) {
class ShowExtractors[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty0) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I hope the name ShowExtractors can be improved later if possible.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes

import tasty._

def stringOfTree(tree: Tree)(implicit ctx: Context): String =
def showTree(tree: Tree)(implicit ctx: Context): String =
new Buffer().visitTree(tree).result()

def stringOfTypeTree(tree: TypeOrBoundsTree)(implicit ctx: Context): String =
new Buffer().visitTypeTree(tree).result()
def showTypeOrBoundsTree(tpt: TypeOrBoundsTree)(implicit ctx: Context): String =
new Buffer().visitTypeTree(tpt).result()

def stringOfType(tpe: TypeOrBounds)(implicit ctx: Context): String =
def showTypeOrBounds(tpe: TypeOrBounds)(implicit ctx: Context): String =
new Buffer().visitType(tpe).result()

def stringOfModifier(mod: Modifier)(implicit ctx: Context): String =
new Buffer().visitModifier(mod).result()

def stringOfConstant(const: Constant)(implicit ctx: Context): String =
def showConstant(const: Constant)(implicit ctx: Context): String =
new Buffer().visitConstant(const).result()

private class Buffer(implicit ctx: Context) { self =>
Expand Down
27 changes: 27 additions & 0 deletions tests/run/tasty-custom-show.check
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
foo
Tree

bar
Tree

bar2
Tree

foo2
Tree

baz
Tree

baz2
Tree

<init>
Tree

b
Tree

b2
Tree

54 changes: 54 additions & 0 deletions tests/run/tasty-custom-show/quoted_1.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import scala.quoted._
import dotty.tools.dotc.quoted.Toolbox._

import scala.tasty.Universe
import scala.tasty.Tasty
import scala.tasty.util.{TreeTraverser, Show}

object Macros {

implicit inline def printOwners[T](x: => T): Unit =
~impl('(x))(Universe.compilationUniverse) // FIXME infer Universe.compilationUniverse within top level ~

def impl[T](x: Expr[T])(implicit u: Universe): Expr[Unit] = {
import u._
import u.tasty._


val buff = new StringBuilder

val output = new TreeTraverser(u.tasty) {
override def traverseTree(tree: Tree)(implicit ctx: Context): Unit = {
// Use custom Show[_] here
implicit val printer = new DummyShow(tasty)
tree match {
case tree @ DefDef(name, _, _, _, _) =>
buff.append(name)
buff.append("\n")
buff.append(tree.owner.show)
buff.append("\n\n")
case tree @ ValDef(name, _, _) =>
buff.append(name)
buff.append("\n")
buff.append(tree.owner.show)
buff.append("\n\n")
case _ =>
}
traverseTreeChildren(tree)
}
}

val tree = x.toTasty
output.traverseTree(tree)
'(print(~buff.result().toExpr))
}

}

class DummyShow[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty0) {
import tasty._
def showTree(tree: Tree)(implicit ctx: Context): String = "Tree"
def showTypeOrBoundsTree(tpt: TypeOrBoundsTree)(implicit ctx: Context): String = "TypeOrBoundsTree"
def showTypeOrBounds(tpe: TypeOrBounds)(implicit ctx: Context): String = "TypeOrBounds"
def showConstant(const: Constant)(implicit ctx: Context): String = "Constant"
}
24 changes: 24 additions & 0 deletions tests/run/tasty-custom-show/quoted_2.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@

import Macros._

object Test {
def main(args: Array[String]): Unit = {
printOwners {
def foo = {
def bar = 1
val bar2 = 2
bar
}
val foo2 = {
def baz = 3
val baz2 = 4
baz
}
class A {
type B = Int
def b = 5
val b2 = 6
}
}
}
}
2 changes: 1 addition & 1 deletion tests/run/tasty-eval/quoted_1.scala
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import scala.quoted._

import scala.tasty.Universe
import scala.tasty.util.{TastyPrinter, TreeTraverser}
import scala.tasty.util.TreeTraverser

object Macros {

Expand Down
6 changes: 2 additions & 4 deletions tests/run/tasty-extractors-1/quoted_1.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import scala.quoted._
import dotty.tools.dotc.quoted.Toolbox._

import scala.tasty.Universe
import scala.tasty.util.TastyPrinter

object Macros {

Expand All @@ -13,9 +12,8 @@ object Macros {
import u._
import tasty._
val tree = x.toTasty
val printer = new TastyPrinter(tasty)
val treeStr = printer.stringOfTree(tree)
val treeTpeStr = printer.stringOfType(tree.tpe)
val treeStr = tree.show
val treeTpeStr = tree.tpe.show

'{
println(~treeStr.toExpr)
Expand Down
7 changes: 3 additions & 4 deletions tests/run/tasty-extractors-2/quoted_1.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import scala.quoted._
import dotty.tools.dotc.quoted.Toolbox._

import scala.tasty.Universe
import scala.tasty.util.TastyPrinter

object Macros {

Expand All @@ -13,9 +12,9 @@ object Macros {
import u._
import tasty._
val tree = x.toTasty
val printer = new TastyPrinter(tasty)
val treeStr = printer.stringOfTree(tree)
val treeTpeStr = printer.stringOfType(tree.tpe)

val treeStr = tree.show
val treeTpeStr = tree.tpe.show

'{
println(~treeStr.toExpr)
Expand Down
6 changes: 2 additions & 4 deletions tests/run/tasty-extractors-3/quoted_1.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import scala.quoted._
import dotty.tools.dotc.quoted.Toolbox._

import scala.tasty.Universe
import scala.tasty.util.{TastyPrinter, TreeTraverser}
import scala.tasty.util.TreeTraverser

object Macros {

Expand All @@ -13,12 +13,10 @@ object Macros {
import u._
import u.tasty._

val printer = new TastyPrinter(tasty)

val buff = new StringBuilder
val traverser = new TreeTraverser(u.tasty) {
override def traverseTypeTree(tree: TypeOrBoundsTree)(implicit ctx: Context): Unit = {
buff.append(printer.stringOfType(tree.tpe))
buff.append(tree.tpe.show)
buff.append("\n\n")
traverseTypeTreeChildren(tree)
}
Expand Down
Loading