@@ -19,6 +19,8 @@ import scala.quoted.Exprs._
19
19
20
20
import scala .reflect .ClassTag
21
21
22
+ import scala .collection .mutable
23
+
22
24
object PickledQuotes {
23
25
import tpd ._
24
26
@@ -34,43 +36,58 @@ object PickledQuotes {
34
36
}
35
37
36
38
/** Transform the expression into its fully spliced Tree */
37
- def quotedExprToTree [T ](expr : quoted.Expr [T ])(implicit ctx : Context ): Tree = expr match {
38
- case expr : TastyExpr [_] => unpickleExpr(expr)
39
+ def quotedExprToTree [T ](expr : quoted.Expr [T ], nested : Boolean )(implicit ctx : Context ): Tree = expr match {
40
+ case expr : TastyExpr [_] => unpickleExpr(expr, nested )
39
41
case expr : LiftedExpr [T ] =>
40
42
expr.value match {
41
43
case value : Class [_] => ref(defn.Predef_classOf ).appliedToType(classToType(value))
42
- case value=> Literal (Constant (value))
44
+ case value => Literal (Constant (value))
43
45
}
44
46
case expr : TreeExpr [Tree ] @ unchecked => expr.tree
45
47
case expr : FunctionAppliedTo [_, _] =>
46
- functionAppliedTo(quotedExprToTree(expr.f), quotedExprToTree(expr.x))
48
+ functionAppliedTo(quotedExprToTree(expr.f, nested ), quotedExprToTree(expr.x, nested ))
47
49
}
48
50
49
51
/** Transform the expression into its fully spliced TypeTree */
50
- def quotedTypeToTree (expr : quoted.Type [_])(implicit ctx : Context ): Tree = expr match {
51
- case expr : TastyType [_] => unpickleType(expr)
52
+ def quotedTypeToTree (expr : quoted.Type [_], nested : Boolean )(implicit ctx : Context ): Tree = expr match {
53
+ case expr : TastyType [_] => unpickleType(expr, nested )
52
54
case expr : TaggedType [_] => classTagToTypeTree(expr.ct)
53
55
case expr : TreeType [Tree ] @ unchecked => expr.tree
54
56
}
55
57
56
58
/** Unpickle the tree contained in the TastyExpr */
57
- private def unpickleExpr (expr : TastyExpr [_])(implicit ctx : Context ): Tree = {
59
+ private def unpickleExpr (expr : TastyExpr [_], nested : Boolean )(implicit ctx : Context ): Tree = {
58
60
val tastyBytes = TastyString .unpickle(expr.tasty)
59
61
val unpickled = unpickle(tastyBytes, expr.args)
60
62
unpickled match {
61
63
case PackageDef (_, (vdef : ValDef ) :: Nil ) =>
62
- vdef.rhs.changeOwner (vdef.symbol, ctx.owner )
64
+ changeQuoteOwners (vdef.rhs, nested )
63
65
}
64
66
}
65
67
66
68
/** Unpickle the tree contained in the TastyType */
67
- private def unpickleType (ttpe : TastyType [_])(implicit ctx : Context ): Tree = {
69
+ private def unpickleType (ttpe : TastyType [_], nested : Boolean )(implicit ctx : Context ): Tree = {
68
70
val tastyBytes = TastyString .unpickle(ttpe.tasty)
69
71
val unpickled = unpickle(tastyBytes, ttpe.args)
70
72
unpickled match {
71
73
case PackageDef (_, (vdef : ValDef ) :: Nil ) =>
72
- vdef.rhs.asInstanceOf [TypeApply ].args.head
73
- .changeOwner(vdef.symbol, ctx.owner)
74
+ changeQuoteOwners(vdef.rhs.asInstanceOf [TypeApply ].args.head, nested)
75
+ }
76
+ }
77
+
78
+ private def changeQuoteOwners (tree : Tree , nested : Boolean )(implicit ctx : Context ): Tree = {
79
+ if (nested) tree
80
+ else {
81
+ val set = mutable.HashSet .empty[Symbol ]
82
+ new TreeTraverser {
83
+ override def traverse (tree : tpd.Tree )(implicit ctx : Context ): Unit = {
84
+ if (tree.symbol.exists && tree.symbol.owner.name == " $quote" .toTermName)
85
+ set += tree.symbol.owner
86
+ traverseChildren(tree)
87
+ }
88
+ }.traverse(tree)
89
+ val owners = set.toList
90
+ new TreeTypeMap (oldOwners = owners, newOwners = owners.map(_ => ctx.owner)).apply(tree)
74
91
}
75
92
}
76
93
0 commit comments