@@ -54,12 +54,24 @@ object PickledQuotes {
54
54
55
55
/** Unpickle the tree contained in the TastyExpr */
56
56
def unpickleTerm (pickled : String | List [String ], typeHole : (Int , Seq [Any ]) => scala.quoted.Type [? ], termHole : (Int , Seq [Any ], scala.quoted.Quotes ) => scala.quoted.Expr [? ])(using Context ): Tree = {
57
+ val t0 = System .nanoTime()
57
58
val unpickled = withMode(Mode .ReadPositions )(unpickle(pickled, isType = false ))
58
59
val Inlined (call, Nil , expnasion) = unpickled
60
+ val t1 = System .nanoTime()
59
61
val inlineCtx = inlineContext(call)
62
+ val t2 = System .nanoTime()
60
63
val expansion1 = spliceTypes(expnasion, typeHole, termHole)(using inlineCtx)
64
+ val t3 = System .nanoTime()
61
65
val expansion2 = spliceTerms(expansion1, typeHole, termHole)(using inlineCtx)
62
- cpy.Inlined (unpickled)(call, Nil , expansion2)
66
+ val t4 = System .nanoTime()
67
+ val res = cpy.Inlined (unpickled)(call, Nil , expansion2)
68
+ val t5 = System .nanoTime()
69
+ // println(s"""
70
+ // |unpickle> ${ (t1 - t0).toDouble / 1000 }μs
71
+ // |spliceTypes> ${(t3 - t2).toDouble / 1000 }μs
72
+ // |spliceTerms> ${(t4 - t3).toDouble / 1000 }μs
73
+ // |""".stripMargin)
74
+ res
63
75
}
64
76
65
77
/** Unpickle the tree contained in the TastyType */
@@ -179,27 +191,41 @@ object PickledQuotes {
179
191
pickled
180
192
}
181
193
194
+ private val cache = collection.mutable.Map .empty[String | List [String ], Tree ]
195
+
182
196
/** Unpickle TASTY bytes into it's tree */
183
197
private def unpickle (pickled : String | List [String ], isType : Boolean )(using Context ): Tree = {
184
- val bytes = pickled match
185
- case pickled : String => TastyString .unpickle(pickled)
186
- case pickled : List [String ] => TastyString .unpickle(pickled)
198
+ QuotesCache .get(pickled) match
199
+ case Some (tree) => tree
200
+ case _ =>
201
+ val bytes = pickled match
202
+ case pickled : String => TastyString .unpickle(pickled)
203
+ case pickled : List [String ] => TastyString .unpickle(pickled)
187
204
188
- quotePickling.println(s " **** unpickling quote from TASTY \n ${TastyPrinter .show(bytes)}" )
205
+ quotePickling.println(s " **** unpickling quote from TASTY \n ${TastyPrinter .show(bytes)}" )
189
206
190
- val mode = if (isType) UnpickleMode .TypeTree else UnpickleMode .Term
191
- val unpickler = new DottyUnpickler (bytes, mode)
192
- unpickler.enter(Set .empty)
207
+ val mode = if (isType) UnpickleMode .TypeTree else UnpickleMode .Term
208
+ val unpickler = new DottyUnpickler (bytes, mode)
209
+ unpickler.enter(Set .empty)
193
210
194
- val tree = unpickler.tree
211
+ val tree = unpickler.tree
195
212
196
- // Make sure trees and positions are fully loaded
197
- new TreeTraverser {
198
- def traverse (tree : Tree )(using Context ): Unit = traverseChildren(tree)
199
- }.traverse(tree)
213
+ var holeWithCapture = false // FIXME: remove this. TypeTreeMap is probably not changing the references in the Hole
200
214
201
- quotePickling.println(i " **** unpickled quote \n $tree" )
202
- tree
215
+ // Make sure trees and positions are fully loaded
216
+ new TreeTraverser {
217
+ def traverse (tree : Tree )(using Context ): Unit =
218
+ tree match
219
+ case Hole (_, _, _ :: _) =>
220
+ holeWithCapture = true
221
+ case _ =>
222
+ traverseChildren(tree)
223
+ }.traverse(tree)
224
+
225
+ quotePickling.println(i " **** unpickled quote \n $tree" )
226
+ if ! holeWithCapture then
227
+ QuotesCache (pickled) = tree
228
+ tree
203
229
}
204
230
205
231
}
0 commit comments