Skip to content

Commit 5a76013

Browse files
Merge pull request #5164 from dotty-staging/tasty-reflect-skip-vals
Tasty reflect underlying tree
2 parents 49db535 + 82b6f95 commit 5a76013

File tree

11 files changed

+199
-9
lines changed

11 files changed

+199
-9
lines changed

compiler/src/dotty/tools/dotc/ast/tpd.scala

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -919,7 +919,17 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
919919
def outerSelect(levels: Int, tp: Type)(implicit ctx: Context): Tree =
920920
untpd.Select(tree, OuterSelectName(EmptyTermName, levels)).withType(SkolemType(tp))
921921

922-
def underlyingArgument(implicit ctx: Context): Tree = mapToUnderlying.transform(tree)
922+
/** Replace Inlined nodes and InlineProxy references to underlying arguments */
923+
def underlyingArgument(implicit ctx: Context): Tree = {
924+
val mapToUnderlying = new MapToUnderlying {
925+
override def skipLocal(sym: Symbol): Boolean =
926+
sym.is(InlineProxy) || sym.is(Synthetic)
927+
}
928+
mapToUnderlying.transform(tree)
929+
}
930+
931+
/** Replace Ident nodes references to the underlying tree that defined them */
932+
def underlying(implicit ctx: Context): Tree = new MapToUnderlying().transform(tree)
923933

924934
// --- Higher order traversal methods -------------------------------
925935

@@ -947,18 +957,22 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
947957
}
948958
}
949959

950-
/** Map Inlined nodes, InlineProxy references and Synthetic val references to underlying arguments */
951-
object mapToUnderlying extends TreeMap {
960+
/** Map Inlined nodes, NamedArgs, Blocks with no statements and local references to underlying arguments.
961+
* Also drops Inline and Block with no statements.
962+
*/
963+
class MapToUnderlying extends TreeMap {
952964
override def transform(tree: Tree)(implicit ctx: Context): Tree = tree match {
953-
case tree: Ident if tree.symbol.is(InlineProxy) || (tree.symbol.is(Synthetic) && !tree.symbol.owner.isClass) =>
965+
case tree: Ident if !tree.symbol.owner.isClass && skipLocal(tree.symbol) =>
954966
tree.symbol.defTree match {
955967
case defTree: ValOrDefDef => transform(defTree.rhs)
956968
case _ => tree
957969
}
958970
case Inlined(_, _, arg) => transform(arg)
971+
case Block(Nil, arg) => transform(arg)
959972
case NamedArg(_, arg) => transform(arg)
960973
case tree => super.transform(tree)
961974
}
975+
def skipLocal(sym: Symbol): Boolean = true
962976
}
963977

964978
implicit class ListOfTreeDecorator(val xs: List[tpd.Tree]) extends AnyVal {

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

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -186,12 +186,11 @@ trait TreeOpsImpl extends scala.tasty.reflect.TreeOps with TastyCoreImpl with He
186186
// ----- Terms ----------------------------------------------------
187187

188188
def TermDeco(term: Term): TermAPI = new TermAPI {
189+
import tpd._
189190
def pos(implicit ctx: Context): Position = term.pos
190191
def tpe(implicit ctx: Context): Type = term.tpe
191-
def underlyingArgument(implicit ctx: Context): Term = {
192-
import tpd._
193-
term.underlyingArgument
194-
}
192+
def underlyingArgument(implicit ctx: Context): Term = term.underlyingArgument
193+
def underlying(implicit ctx: Context): Term = term.underlying
195194
}
196195

197196
object IsTerm extends IsTermExtractor {

compiler/test/dotc/run-test-pickling.blacklist

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ t7374
5959
t7859
6060
t8133
6161
t8133b
62+
tasty-argument-tree-1
6263
tasty-custom-show
6364
tasty-definitions-1
6465
tasty-definitions-2
@@ -91,4 +92,5 @@ typelevel-patmat.scala
9192
typelevel.scala
9293
typelevel1.scala
9394
typelevel3.scala
94-
xml-interpolation
95+
xml-interpolation-1
96+
xml-interpolation-2

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,7 @@ trait TreeOps extends TastyCore {
156156
def tpe(implicit ctx: Context): Type
157157
def pos(implicit ctx: Context): Position
158158
def underlyingArgument(implicit ctx: Context): Term
159+
def underlying(implicit ctx: Context): Term
159160
}
160161
implicit def TermDeco(term: Term): TermAPI
161162

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

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
2+
tree: Term.Literal(Constant.Int(3))
3+
tree deref. vals: Term.Literal(Constant.Int(3))
4+
5+
tree: Term.Ident("v")
6+
tree deref. vals: Term.Literal(Constant.Int(1))
7+
8+
tree: Term.Ident("x")
9+
tree deref. vals: Term.Literal(Constant.Int(2))
10+
11+
tree: Term.Ident("l")
12+
tree deref. vals: Term.Literal(Constant.Int(3))
13+
14+
tree: Term.Ident("a")
15+
tree deref. vals: Term.Ident("a")
16+
17+
tree: Term.Ident("x")
18+
tree deref. vals: Term.Ident("b")
19+
20+
tree: Term.Ident("vv")
21+
tree deref. vals: Term.Literal(Constant.Int(1))
22+
23+
tree: Term.Ident("x")
24+
tree deref. vals: Term.Literal(Constant.Int(1))
25+
26+
tree: Term.Ident("vd")
27+
tree deref. vals: Term.Literal(Constant.Int(2))
28+
29+
tree: Term.Ident("x")
30+
tree deref. vals: Term.Literal(Constant.Int(2))
31+
32+
tree: Term.Ident("x")
33+
tree deref. vals: Term.Apply(Term.TypeApply(Term.Select(Term.Ident("Tuple2"), "apply", Some(Signature(List(java.lang.Object, java.lang.Object), scala.Tuple2))), List(TypeTree.Synthetic(), TypeTree.Synthetic())), List(Term.Literal(Constant.Int(1)), Term.Literal(Constant.Int(2))))
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import scala.quoted._
2+
import scala.tasty._
3+
4+
object Macros {
5+
6+
inline def inspect[T](x: T): Unit = ~impl('(x))
7+
8+
def impl[T](x: Expr[T])(implicit tasty: Tasty): Expr[Unit] = {
9+
import tasty._
10+
val tree = x.toTasty
11+
'{
12+
println()
13+
println("tree: " + ~tree.show.toExpr)
14+
println("tree deref. vals: " + ~tree.underlying.show.toExpr)
15+
}
16+
}
17+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
2+
import Macros.inspect
3+
4+
object Test {
5+
val a: Int = 4
6+
def b: Int = 5
7+
8+
def main(args: Array[String]): Unit = {
9+
val v: Int = 1
10+
def d: Int = 2
11+
lazy val l: Int = 3
12+
inspect(3)
13+
inspect(v)
14+
inspect(d)
15+
inspect(l)
16+
inspect(a)
17+
inspect(b)
18+
19+
val vv = v
20+
def dv = v
21+
val vd = d
22+
def dd = d
23+
inspect(vv)
24+
inspect(dv)
25+
inspect(vd)
26+
inspect(dd)
27+
28+
inspect((dv, vd))
29+
30+
}
31+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import XmlQuote._
2+
3+
object Test {
4+
def main(args: Array[String]): Unit = {
5+
6+
assert(xml"Hello Allan!" == Xml("Hello Allan!", Nil))
7+
8+
val name = new Object{}
9+
assert(xml"Hello $name!" == Xml("Hello ??!", List(name)))
10+
11+
val ctx0 = new StringContext("Hello !")
12+
assert(ctx0.xml() == Xml("Hello !", Nil))
13+
assert(new SCOps(ctx0).xml() == Xml("Hello !", Nil))
14+
15+
val ctx1 = new StringContext("Hello ", "!")
16+
assert(ctx1.xml(name) == Xml("Hello ??!", List(name)))
17+
assert(new SCOps(ctx1).xml(name) == Xml("Hello ??!", List(name)))
18+
19+
val hello: String = "Hello "
20+
val ctx2 = new StringContext(hello, "!")
21+
assert(ctx2.xml(name) == Xml("Hello ??!", List(name)))
22+
assert(new SCOps(ctx2).xml(name) == Xml("Hello ??!", List(name)))
23+
24+
val args = Seq(name)
25+
assert(new SCOps(ctx2).xml(args: _*) == Xml("Hello ??!", List(name)))
26+
}
27+
}

0 commit comments

Comments
 (0)