@@ -61,19 +61,101 @@ object PickledQuotes {
61
61
}.apply(tp)
62
62
63
63
/** Unpickle the tree contained in the TastyExpr */
64
- def unpickleExpr (tasty : PickledQuote , args : PickledArgs )(implicit ctx : Context ): Tree = {
64
+ def unpickleExpr (tasty : PickledQuote , splices : PickledArgs )(implicit ctx : Context ): Tree = {
65
65
val tastyBytes = TastyString .unpickle(tasty)
66
- val unpickled = unpickle(tastyBytes, args , isType = false )(ctx.addMode(Mode .ReadPositions ))
66
+ val unpickled = unpickle(tastyBytes, splices , isType = false )(ctx.addMode(Mode .ReadPositions ))
67
67
/** Force unpickling of the tree, removes the spliced type `@quotedTypeTag type` definitions and dealiases references to `@quotedTypeTag type` */
68
- val forceAndCleanArtefacts = new TreeMap {
69
- override def transform (tree : tpd.Tree )(implicit ctx : Context ): tpd.Tree = tree match {
68
+
69
+ if ctx.settings.YprintDebug .value then
70
+
71
+
72
+ val Inlined (call, Nil , expnasion) = unpickled
73
+
74
+ val (typeSpliceMap, expnasion1) = expnasion match
70
75
case Block (stat :: rest, expr1) if stat.symbol.hasAnnotation(defn.InternalQuoted_QuoteTypeTagAnnot ) =>
71
- assert(rest.forall { case tdef : TypeDef => tdef.symbol.hasAnnotation(defn.InternalQuoted_QuoteTypeTagAnnot ) })
72
- transform(expr1)
73
- case tree => super .transform(tree).withType(dealiasTypeTags(tree.tpe))
76
+ val map = (stat :: rest).iterator.map {
77
+ case tdef : TypeDef =>
78
+ assert(tdef.symbol.hasAnnotation(defn.InternalQuoted_QuoteTypeTagAnnot ))
79
+ val TypeBoundsTree (_, Hole (_, idx, args), _) = tdef.rhs
80
+ val quotedType = splices(idx).asInstanceOf [Seq [Any ] => quoted.Type [? ]](args)
81
+ val tree = PickledQuotes .quotedTypeToTree(quotedType)
82
+ (tdef.symbol, tree.tpe)
83
+ }.toMap
84
+ (map, expr1)
85
+ case _ => (Map .empty, expnasion)
86
+
87
+ def spliceTypes (tp : Type )(implicit ctx : Context ): Type = new TypeMap () {
88
+ override def apply (tp : Type ): Type = {
89
+ val tp1 = tp match {
90
+ case tp : TypeRef if tp.typeSymbol.hasAnnotation(defn.InternalQuoted_QuoteTypeTagAnnot ) =>
91
+ typeSpliceMap(tp.symbol)
92
+ case _ => tp
93
+ }
94
+ mapOver(tp1)
95
+ }
96
+ }.apply(tp)
97
+ // println("::::::::::::::::::::::::::::::::::::")
98
+ // println(typeSpliceMap)
99
+ // println()
100
+ // println()
101
+
102
+ val evaluateHoles = new TreeMap {
103
+ // private var typeSpliceMap = Map.empty[Symbol, Type]
104
+ override def transform (tree : tpd.Tree )(implicit ctx : Context ): tpd.Tree = tree match {
105
+ // case Block(stat :: rest, expr1) if stat.symbol.hasAnnotation(defn.InternalQuoted_QuoteTypeTagAnnot) =>
106
+ // val splicedTypes = (stat :: rest).map {
107
+ // case tdef: TypeDef =>
108
+ // assert(tdef.symbol.hasAnnotation(defn.InternalQuoted_QuoteTypeTagAnnot))
109
+ // val TypeBoundsTree(_, hi, _) = transform(tdef.rhs)
110
+ // (tdef.symbol, hi.tpe)
111
+ // }
112
+ // typeSpliceMap = splicedTypes.toMap
113
+ // transform(expr1)
114
+ case Hole (isType, idx, args) =>
115
+ val splice = splices(idx)
116
+ def wrap (arg : Tree ) =
117
+ if (arg.isTerm) (qctx : scala.quoted.QuoteContext ) ?=> new TastyTreeExpr (arg, QuoteContext .scopeId)
118
+ else new TreeType (arg, QuoteContext .scopeId)
119
+ val reifiedArgs = args.map(wrap)
120
+ val filled = if (isType) {
121
+ ???
122
+ val quotedType = splice.asInstanceOf [Seq [Any ] => quoted.Type [? ]](reifiedArgs)
123
+ PickledQuotes .quotedTypeToTree(quotedType)
124
+ }
125
+ else {
126
+ val splice1 = splice.asInstanceOf [Seq [Any ] => scala.quoted.QuoteContext ?=> quoted.Expr [? ]]
127
+ val quotedExpr = splice1(reifiedArgs)(using dotty.tools.dotc.quoted.QuoteContext ())
128
+ PickledQuotes .quotedExprToTree(quotedExpr)
129
+ }
130
+ // We need to make sure a hole is created with the source file of the surrounding context, even if
131
+ // it filled with contents a different source file. Otherwise nodes contqaining holes might end
132
+ // up without a position. PositionPickler makes sure that holes always get spans assigned,
133
+ // so we can just return the filler tree with the new source and no span here.
134
+ if (filled.source == ctx.source) filled
135
+ else {
136
+ val filled1 = filled.cloneIn(ctx.source)
137
+ // filled1.span = NoSpan
138
+ filled1
139
+ }
140
+
141
+ // super.transform(tree).withType(dealiasTypeTags(tree.tpe))
142
+ case tree =>
143
+ super .transform(tree).withType(spliceTypes(tree.tpe))
144
+ }
74
145
}
75
- }
76
- forceAndCleanArtefacts.transform(unpickled)
146
+ val evaluatedExpansion = evaluateHoles.transform(expnasion1)
147
+ cpy.Inlined (unpickled)(call, Nil , evaluatedExpansion)
148
+ else
149
+ val forceAndCleanArtefacts = new TreeMap {
150
+ override def transform (tree : tpd.Tree )(implicit ctx : Context ): tpd.Tree = tree match {
151
+ case Block (stat :: rest, expr1) if stat.symbol.hasAnnotation(defn.InternalQuoted_QuoteTypeTagAnnot ) =>
152
+ assert(rest.forall { case tdef : TypeDef => tdef.symbol.hasAnnotation(defn.InternalQuoted_QuoteTypeTagAnnot ) })
153
+ transform(expr1)
154
+ case tree => super .transform(tree).withType(dealiasTypeTags(tree.tpe))
155
+ }
156
+ }
157
+ forceAndCleanArtefacts.transform(unpickled)
158
+
77
159
}
78
160
79
161
/** Unpickle the tree contained in the TastyType */
0 commit comments