Skip to content

Commit 71202fc

Browse files
committed
Tasty reflect load complete definition trees
1 parent 61cba97 commit 71202fc

File tree

15 files changed

+142
-42
lines changed

15 files changed

+142
-42
lines changed

compiler/src/dotty/tools/dotc/core/SymbolLoaders.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -389,8 +389,8 @@ class ClassfileLoader(val classfile: AbstractFile) extends SymbolLoader {
389389
}
390390
}
391391

392-
private def mayLoadTreesFromTasty(implicit ctx: Context): Boolean =
393-
ctx.settings.YretainTrees.value || ctx.settings.fromTasty.value
392+
private def mayLoadTreesFromTasty(implicit ctx: Context): Boolean = true
393+
// ctx.settings.YretainTrees.value || ctx.settings.fromTasty.value
394394
}
395395

396396
class SourcefileLoader(val srcfile: AbstractFile) extends SymbolLoader {

compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -836,7 +836,6 @@ class TreeUnpickler(reader: TastyReader,
836836
tree.setComment(comment)
837837
}
838838
}
839-
840839
tree
841840
}
842841

compiler/src/dotty/tools/dotc/tastyreflect/FromSymbol.scala

Lines changed: 44 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import dotty.tools.dotc.core.Types._
1010
object FromSymbol {
1111

1212
def definitionFromSym(sym: Symbol)(implicit ctx: Context): tpd.Tree = {
13+
assert(sym.exists)
1314
if (sym.is(Package)) packageDefFromSym(sym)
1415
else if (sym.isClass) classDef(sym.asClass)
1516
else if (sym.isType) typeDefFromSym(sym.asType)
@@ -19,21 +20,52 @@ object FromSymbol {
1920

2021
def packageDefFromSym(sym: Symbol)(implicit ctx: Context): PackageDefinition = PackageDefinitionImpl(sym)
2122

22-
def classDef(cls: ClassSymbol)(implicit ctx: Context): tpd.TypeDef = {
23-
val constrSym = cls.unforcedDecls.find(_.isPrimaryConstructor).orElse(
24-
// Dummy constructor for classes such as `<refinement>`
25-
ctx.newSymbol(cls, nme.CONSTRUCTOR, EmptyFlags, NoType)
26-
)
27-
val constr = tpd.DefDef(constrSym.asTerm)
28-
val parents = cls.classParents.map(tpd.TypeTree(_))
29-
val body = cls.unforcedDecls.filter(!_.isPrimaryConstructor).map(s => definitionFromSym(s))
30-
tpd.ClassDefWithParents(cls, constr, parents, body)
23+
def classDef(cls: ClassSymbol)(implicit ctx: Context): tpd.TypeDef = cls.tree match {
24+
case tree: tpd.TypeDef => tree
25+
case tpd.EmptyTree =>
26+
val constrSym = cls.unforcedDecls.find(_.isPrimaryConstructor).orElse(
27+
// Dummy constructor for classes such as `<refinement>`
28+
ctx.newSymbol(cls, nme.CONSTRUCTOR, EmptyFlags, NoType)
29+
)
30+
val constr = tpd.DefDef(constrSym.asTerm)
31+
val parents = cls.classParents.map(tpd.TypeTree(_))
32+
val body = cls.unforcedDecls.filter(!_.isPrimaryConstructor).map(s => definitionFromSym(s))
33+
tpd.ClassDefWithParents(cls, constr, parents, body)
3134
}
3235

33-
def typeDefFromSym(sym: TypeSymbol)(implicit ctx: Context): tpd.TypeDef = tpd.TypeDef(sym)
36+
// TODO: this logic could be moved inside sym.tree
3437

35-
def defDefFromSym(sym: TermSymbol)(implicit ctx: Context): tpd.DefDef = tpd.DefDef(sym)
38+
def typeDefFromSym(sym: TypeSymbol)(implicit ctx: Context): tpd.TypeDef = tree(sym) match {
39+
case tree: tpd.TypeDef => tree
40+
case tpd.EmptyTree => tpd.TypeDef(sym)
41+
}
42+
43+
def defDefFromSym(sym: TermSymbol)(implicit ctx: Context): tpd.DefDef = tree(sym) match {
44+
case tree: tpd.DefDef => tree
45+
case tpd.EmptyTree => tpd.DefDef(sym)
46+
}
47+
48+
def valDefFromSym(sym: TermSymbol)(implicit ctx: Context): tpd.ValDef = tree(sym) match {
49+
case tree: tpd.ValDef => tree
50+
case tpd.EmptyTree => tpd.ValDef(sym)
51+
}
52+
53+
private def tree(sym: Symbol)(implicit ctx: Context): tpd.Tree = sym.topLevelClass match {
54+
case top: ClassSymbol =>
55+
val findTree = new tpd.TreeAccumulator[tpd.Tree] {
56+
def apply(x: tpd.Tree, tree: tpd.Tree)(implicit ctx: Context): tpd.Tree = {
57+
if (!x.isEmpty) x
58+
else tree match {
59+
case tree: tpd.DefTree if tree.symbol == sym => tree
60+
// TODO avoid searching in all the tree, look at sym.ownerIterator.toSet
61+
case _ => foldOver(x, tree)
62+
}
3663

37-
def valDefFromSym(sym: TermSymbol)(implicit ctx: Context): tpd.ValDef = tpd.ValDef(sym)
64+
}
65+
}
66+
findTree(tpd.EmptyTree, top.tree)
67+
68+
case _ => tpd.EmptyTree
69+
}
3870

3971
}

compiler/src/dotty/tools/dotc/tastyreflect/TreeOpsImpl.scala

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@ trait TreeOpsImpl extends scala.tasty.reflect.TreeOps with TastyCoreImpl with He
1313

1414
def TreeDeco(tree: Tree): TreeAPI = new TreeAPI {
1515
def pos(implicit ctx: Context): Position = tree.pos
16+
def definition(implicit ctx: Context): Option[Definition] =
17+
if (tree.symbol.exists) Some(definitionFromSym(tree.symbol))
18+
else None
1619
}
1720

1821
object IsPackageClause extends IsPackageClauseExtractor {
@@ -29,10 +32,6 @@ trait TreeOpsImpl extends scala.tasty.reflect.TreeOps with TastyCoreImpl with He
2932
}
3033
}
3134

32-
def PackageClauseDeco(pack: PackageClause): PackageClauseAPI = new PackageClauseAPI {
33-
def definition(implicit ctx: Context): Definition = packageDefFromSym(pack.symbol)
34-
}
35-
3635
// ----- Statements -----------------------------------------------
3736

3837
object Import extends ImportExtractor {
@@ -342,7 +341,7 @@ trait TreeOpsImpl extends scala.tasty.reflect.TreeOps with TastyCoreImpl with He
342341
}
343342

344343
object Inlined extends InlinedExtractor {
345-
def unapply(x: Term)(implicit ctx: Context): Option[(Option[Term], List[Statement], Term)] = x match {
344+
def unapply(x: Term)(implicit ctx: Context): Option[(Option[Parent], List[Statement], Term)] = x match {
346345
case x: tpd.Inlined =>
347346
Some((optional(x.call), x.bindings, x.expansion))
348347
case _ => None

library/src/scala/tasty/reflect/TreeOps.scala

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ trait TreeOps extends TastyCore {
55

66
trait TreeAPI {
77
def pos(implicit ctx: Context): Position
8+
def definition(implicit ctx: Context): Option[Definition]
89
}
910
implicit def TreeDeco(tree: Tree): TreeAPI
1011

@@ -18,11 +19,6 @@ trait TreeOps extends TastyCore {
1819
def unapply(tree: Tree)(implicit ctx: Context): Option[(Term, List[Tree])]
1920
}
2021

21-
trait PackageClauseAPI {
22-
def definition(implicit ctx: Context): Definition
23-
}
24-
implicit def PackageClauseDeco(pack: PackageClause): PackageClauseAPI
25-
2622
// ----- Statements -----------------------------------------------
2723

2824
val Import: ImportExtractor
@@ -290,7 +286,7 @@ trait TreeOps extends TastyCore {
290286

291287
val Inlined: InlinedExtractor
292288
abstract class InlinedExtractor {
293-
def unapply(tree: Tree)(implicit ctx: Context): Option[(Option[Term], List[Definition], Term)]
289+
def unapply(tree: Tree)(implicit ctx: Context): Option[(Option[Parent], List[Definition], Term)]
294290
}
295291

296292
val SelectOuter: SelectOuterExtractor

library/src/scala/tasty/util/ShowExtractors.scala

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,9 @@ class ShowExtractors[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty
6767
case Term.Repeated(elems) =>
6868
this += "Term.Repeated(" ++= elems += ")"
6969
case Term.Inlined(call, bindings, expansion) =>
70-
this += "Term.Inlined(" += call += ", " ++= bindings += ", " += expansion += ")"
70+
this += "Term.Inlined("
71+
visitOption(call, visitParent)
72+
this += ", " ++= bindings += ", " += expansion += ")"
7173
case ValDef(name, tpt, rhs) =>
7274
this += "ValDef(\"" += name += "\", " += tpt += ", " += rhs += ")"
7375
case DefDef(name, typeParams, paramss, returnTpt, rhs) =>
@@ -76,10 +78,7 @@ class ShowExtractors[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty
7678
this += "TypeDef(\"" += name += "\", " += rhs += ")"
7779
case ClassDef(name, constr, parents, self, body) =>
7880
this += "ClassDef(\"" += name += "\", " += constr += ", "
79-
visitList[Parent](parents, {
80-
case IsTerm(parent) => this += parent
81-
case IsTypeTree(parent) => this += parent
82-
})
81+
visitList[Parent](parents, visitParent)
8382
this += ", " += self += ", " ++= body += ")"
8483
case PackageDef(name, owner) =>
8584
this += "PackageDef(\"" += name += "\", " += owner += ")"
@@ -140,6 +139,11 @@ class ShowExtractors[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty
140139
this += "Pattern.TypeTest(" += tpt += ")"
141140
}
142141

142+
def visitParent(x: Parent): Buffer = x match {
143+
case IsTerm(parent) => this += parent
144+
case IsTypeTree(parent) => this += parent
145+
}
146+
143147
def visitConstant(x: Constant): Buffer = x match {
144148
case Constant.Unit() => this += "Constant.Unit()"
145149
case Constant.Null() => this += "Constant.Null()"

library/src/scala/tasty/util/TreeAccumulator.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ abstract class TreeAccumulator[X, T <: Tasty with Singleton](val tasty: T) {
7474
case Import(expr, selectors) =>
7575
foldTree(x, expr)
7676
case IsPackageClause(clause @ PackageClause(pid, stats)) =>
77-
foldTrees(foldTree(x, pid), stats)(localCtx(clause.definition))
77+
foldTrees(foldTree(x, pid), stats)(localCtx(clause.definition.get))
7878
}
7979
}
8080

project/scripts/cmdTests

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ clear_out "$OUT"
5050
grep -qe "def main(args: scala.Array\[scala.Predef.String\]): scala.Unit =" "$tmp"
5151

5252
echo "testing scala.quoted.Expr.run from sbt dotr"
53-
"$SBT" ";dotty-compiler-bootstrapped/dotc -with-compiler tests/run-with-compiler/quote-run.scala; dotty-compiler-bootstrapped/dotr -with-compiler Test" > "$tmp"
53+
"$SBT" ";dotty-compiler-bootstrapped/dotc tests/run-with-compiler/quote-run.scala; dotty-compiler-bootstrapped/dotr -with-compiler Test" > "$tmp"
5454
grep -qe "val a: scala.Int = 3" "$tmp"
5555

5656

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,27 @@
11
foo
2-
DefDef("main", Nil, List(List(ValDef("args", TypeTree.Synthetic(), None))), TypeTree.Synthetic(), None)
2+
DefDef("main", Nil, List(List(ValDef("args", TypeTree.Applied(TypeTree.TypeIdent("Array"), List(TypeTree.TypeIdent("String"))), None))), TypeTree.TypeIdent("Unit"), Some(Term.Block(Nil, Term.Inlined(Some(TypeTree.TypeIdent("Macros$")), Nil, Term.Select(Term.Apply(Term.Apply(Term.TypeApply(Term.Ident("impl"), List(TypeTree.Synthetic())), List(Term.Apply(Term.TypeApply(Term.Ident("apply"), List(TypeTree.Synthetic())), List(Term.Inlined(None, Nil, Term.Block(List(DefDef("foo", Nil, Nil, TypeTree.Synthetic(), Some(Term.Block(List(DefDef("bar", Nil, Nil, TypeTree.Synthetic(), Some(Term.Literal(Constant.Int(1)))), ValDef("bar2", TypeTree.Synthetic(), Some(Term.Literal(Constant.Int(2))))), Term.Typed(Term.Ident("bar"), TypeTree.Synthetic())))), ValDef("foo2", TypeTree.Synthetic(), Some(Term.Block(List(DefDef("baz", Nil, Nil, TypeTree.Synthetic(), Some(Term.Literal(Constant.Int(3)))), ValDef("baz2", TypeTree.Synthetic(), Some(Term.Literal(Constant.Int(4))))), Term.Typed(Term.Ident("baz"), TypeTree.Synthetic())))), ClassDef("A", DefDef("<init>", Nil, List(Nil), TypeTree.Synthetic(), None), List(Term.Apply(Term.Select(Term.New(TypeTree.Synthetic()), "<init>", Some(Signature(Nil, java.lang.Object))), Nil)), None, List(TypeDef("B", TypeTree.TypeIdent("Int")), DefDef("b", Nil, Nil, TypeTree.Synthetic(), Some(Term.Literal(Constant.Int(5)))), ValDef("b2", TypeTree.Synthetic(), Some(Term.Literal(Constant.Int(6))))))), Term.Literal(Constant.Unit()))))))), List(Term.Select(Term.Ident("TopLevelSplice"), "tastyContext", Some(Signature(Nil, scala.tasty.Tasty))))), "unary_~", Some(Signature(Nil, java.lang.Object)))))))
33

44
bar
5-
DefDef("foo", Nil, Nil, TypeTree.Synthetic(), None)
5+
DefDef("foo", Nil, Nil, TypeTree.Synthetic(), Some(Term.Block(List(DefDef("bar", Nil, Nil, TypeTree.Synthetic(), Some(Term.Literal(Constant.Int(1)))), ValDef("bar2", TypeTree.Synthetic(), Some(Term.Literal(Constant.Int(2))))), Term.Typed(Term.Ident("bar"), TypeTree.Synthetic()))))
66

77
bar2
8-
DefDef("foo", Nil, Nil, TypeTree.Synthetic(), None)
8+
DefDef("foo", Nil, Nil, TypeTree.Synthetic(), Some(Term.Block(List(DefDef("bar", Nil, Nil, TypeTree.Synthetic(), Some(Term.Literal(Constant.Int(1)))), ValDef("bar2", TypeTree.Synthetic(), Some(Term.Literal(Constant.Int(2))))), Term.Typed(Term.Ident("bar"), TypeTree.Synthetic()))))
99

1010
foo2
11-
DefDef("main", Nil, List(List(ValDef("args", TypeTree.Synthetic(), None))), TypeTree.Synthetic(), None)
11+
DefDef("main", Nil, List(List(ValDef("args", TypeTree.Applied(TypeTree.TypeIdent("Array"), List(TypeTree.TypeIdent("String"))), None))), TypeTree.TypeIdent("Unit"), Some(Term.Block(Nil, Term.Inlined(Some(TypeTree.TypeIdent("Macros$")), Nil, Term.Select(Term.Apply(Term.Apply(Term.TypeApply(Term.Ident("impl"), List(TypeTree.Synthetic())), List(Term.Apply(Term.TypeApply(Term.Ident("apply"), List(TypeTree.Synthetic())), List(Term.Inlined(None, Nil, Term.Block(List(DefDef("foo", Nil, Nil, TypeTree.Synthetic(), Some(Term.Block(List(DefDef("bar", Nil, Nil, TypeTree.Synthetic(), Some(Term.Literal(Constant.Int(1)))), ValDef("bar2", TypeTree.Synthetic(), Some(Term.Literal(Constant.Int(2))))), Term.Typed(Term.Ident("bar"), TypeTree.Synthetic())))), ValDef("foo2", TypeTree.Synthetic(), Some(Term.Block(List(DefDef("baz", Nil, Nil, TypeTree.Synthetic(), Some(Term.Literal(Constant.Int(3)))), ValDef("baz2", TypeTree.Synthetic(), Some(Term.Literal(Constant.Int(4))))), Term.Typed(Term.Ident("baz"), TypeTree.Synthetic())))), ClassDef("A", DefDef("<init>", Nil, List(Nil), TypeTree.Synthetic(), None), List(Term.Apply(Term.Select(Term.New(TypeTree.Synthetic()), "<init>", Some(Signature(Nil, java.lang.Object))), Nil)), None, List(TypeDef("B", TypeTree.TypeIdent("Int")), DefDef("b", Nil, Nil, TypeTree.Synthetic(), Some(Term.Literal(Constant.Int(5)))), ValDef("b2", TypeTree.Synthetic(), Some(Term.Literal(Constant.Int(6))))))), Term.Literal(Constant.Unit()))))))), List(Term.Select(Term.Ident("TopLevelSplice"), "tastyContext", Some(Signature(Nil, scala.tasty.Tasty))))), "unary_~", Some(Signature(Nil, java.lang.Object)))))))
1212

1313
baz
14-
ValDef("foo2", TypeTree.Synthetic(), None)
14+
ValDef("foo2", TypeTree.Synthetic(), Some(Term.Block(List(DefDef("baz", Nil, Nil, TypeTree.Synthetic(), Some(Term.Literal(Constant.Int(3)))), ValDef("baz2", TypeTree.Synthetic(), Some(Term.Literal(Constant.Int(4))))), Term.Typed(Term.Ident("baz"), TypeTree.Synthetic()))))
1515

1616
baz2
17-
ValDef("foo2", TypeTree.Synthetic(), None)
17+
ValDef("foo2", TypeTree.Synthetic(), Some(Term.Block(List(DefDef("baz", Nil, Nil, TypeTree.Synthetic(), Some(Term.Literal(Constant.Int(3)))), ValDef("baz2", TypeTree.Synthetic(), Some(Term.Literal(Constant.Int(4))))), Term.Typed(Term.Ident("baz"), TypeTree.Synthetic()))))
1818

1919
<init>
20-
ClassDef("A", DefDef("<init>", Nil, List(Nil), TypeTree.Synthetic(), None), List(TypeTree.Synthetic()), None, List(TypeDef("B", SyntheticBounds()), DefDef("b", Nil, Nil, TypeTree.Synthetic(), None), ValDef("b2", TypeTree.Synthetic(), None)))
20+
ClassDef("A", DefDef("<init>", Nil, List(Nil), TypeTree.Synthetic(), None), List(Term.Apply(Term.Select(Term.New(TypeTree.Synthetic()), "<init>", Some(Signature(Nil, java.lang.Object))), Nil)), None, List(TypeDef("B", TypeTree.TypeIdent("Int")), DefDef("b", Nil, Nil, TypeTree.Synthetic(), Some(Term.Literal(Constant.Int(5)))), ValDef("b2", TypeTree.Synthetic(), Some(Term.Literal(Constant.Int(6))))))
2121

2222
b
23-
ClassDef("A", DefDef("<init>", Nil, List(Nil), TypeTree.Synthetic(), None), List(TypeTree.Synthetic()), None, List(TypeDef("B", SyntheticBounds()), DefDef("b", Nil, Nil, TypeTree.Synthetic(), None), ValDef("b2", TypeTree.Synthetic(), None)))
23+
ClassDef("A", DefDef("<init>", Nil, List(Nil), TypeTree.Synthetic(), None), List(Term.Apply(Term.Select(Term.New(TypeTree.Synthetic()), "<init>", Some(Signature(Nil, java.lang.Object))), Nil)), None, List(TypeDef("B", TypeTree.TypeIdent("Int")), DefDef("b", Nil, Nil, TypeTree.Synthetic(), Some(Term.Literal(Constant.Int(5)))), ValDef("b2", TypeTree.Synthetic(), Some(Term.Literal(Constant.Int(6))))))
2424

2525
b2
26-
ClassDef("A", DefDef("<init>", Nil, List(Nil), TypeTree.Synthetic(), None), List(TypeTree.Synthetic()), None, List(TypeDef("B", SyntheticBounds()), DefDef("b", Nil, Nil, TypeTree.Synthetic(), None), ValDef("b2", TypeTree.Synthetic(), None)))
26+
ClassDef("A", DefDef("<init>", Nil, List(Nil), TypeTree.Synthetic(), None), List(Term.Apply(Term.Select(Term.New(TypeTree.Synthetic()), "<init>", Some(Signature(Nil, java.lang.Object))), Nil)), None, List(TypeDef("B", TypeTree.TypeIdent("Int")), DefDef("b", Nil, Nil, TypeTree.Synthetic(), Some(Term.Literal(Constant.Int(5)))), ValDef("b2", TypeTree.Synthetic(), Some(Term.Literal(Constant.Int(6))))))
2727

tests/run/tasty-load-tree-1.check

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
DefDef("foo", Nil, Nil, TypeTree.TypeIdent("Int"), Some(Term.Apply(Term.Select(Term.Literal(Constant.Int(1)), "+", Some(Signature(List(scala.Int), scala.Int))), List(Term.Literal(Constant.Int(2))))))
2+
ValDef("bar", TypeTree.TypeIdent("Int"), Some(Term.Apply(Term.Select(Term.Literal(Constant.Int(2)), "+", Some(Signature(List(scala.Int), scala.Int))), List(Term.Literal(Constant.Int(3))))))
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import scala.quoted._
2+
3+
import scala.tasty._
4+
5+
object Foo {
6+
7+
transparent def inspectBody(i: => Int): String =
8+
~inspectBodyImpl('(i))(TopLevelSplice.tastyContext) // FIXME infer TopLevelSplice.tastyContext within top level ~
9+
10+
def inspectBodyImpl(x: Expr[Int])(implicit tasty: Tasty): Expr[String] = {
11+
import tasty._
12+
13+
def definitionString(tree: Tree): Expr[String] = tree.definition match {
14+
case Some(definition) => definition.show.toExpr
15+
case None => '("NO DEFINTION")
16+
}
17+
18+
x.toTasty match {
19+
case Term.Inlined(None, Nil, arg) => definitionString(arg)
20+
case arg => definitionString(arg) // TODO should all by name parameters be in an inline node
21+
}
22+
}
23+
24+
def foo: Int = 1 + 2
25+
val bar: Int = 2 + 3
26+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
2+
object Test {
3+
def main(args: Array[String]): Unit = {
4+
println(Foo.inspectBody(Foo.foo))
5+
println(Foo.inspectBody(Foo.bar))
6+
}
7+
}

tests/run/tasty-load-tree-2.check

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
DefDef("foo", Nil, Nil, TypeTree.TypeIdent("Int"), Some(Term.Apply(Term.Select(Term.Literal(Constant.Int(1)), "+", Some(Signature(List(scala.Int), scala.Int))), List(Term.Literal(Constant.Int(2))))))
2+
ValDef("bar", TypeTree.TypeIdent("Int"), Some(Term.Apply(Term.Select(Term.Literal(Constant.Int(2)), "+", Some(Signature(List(scala.Int), scala.Int))), List(Term.Literal(Constant.Int(3))))))
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import scala.quoted._
2+
3+
import scala.tasty._
4+
5+
object Foo {
6+
7+
transparent def inspectBody(i: => Int): String =
8+
~inspectBodyImpl('(i))(TopLevelSplice.tastyContext) // FIXME infer TopLevelSplice.tastyContext within top level ~
9+
10+
def inspectBodyImpl(x: Expr[Int])(implicit tasty: Tasty): Expr[String] = {
11+
import tasty._
12+
13+
def definitionString(tree: Tree): Expr[String] = tree.definition match {
14+
case Some(definition) => definition.show.toExpr
15+
case None => '("NO DEFINTION")
16+
}
17+
18+
x.toTasty match {
19+
case Term.Inlined(None, Nil, arg) => definitionString(arg)
20+
case arg => definitionString(arg) // TODO should all by name parameters be in an inline node
21+
}
22+
}
23+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
2+
object Test {
3+
def main(args: Array[String]): Unit = {
4+
println(Foo.inspectBody(foo))
5+
println(Foo.inspectBody(bar))
6+
}
7+
8+
def foo: Int = 1 + 2
9+
val bar: Int = 2 + 3
10+
}

0 commit comments

Comments
 (0)