@@ -245,105 +245,101 @@ object InlineHKDGeneric:
245
245
arr
246
246
}
247
247
248
- private class ProductElementIdExactExpander [Q <: Quotes , Fields <: Tuple : Type ](using val q : Q )
249
- extends q.reflect.TreeMap {
248
+ private class TreeMaps [Q <: Quotes ](using val q : Q ) {
250
249
import q .reflect .*
251
250
252
- override def transformTerm (tree : Term )(owner : Symbol ): Term =
253
- try {
254
- tree.asExpr match {
255
- case ' { InlineHKDGeneric .productElementIdExact[a2, elemTop]($a, $idx) } =>
256
- transformExact(a, idx)
257
- case _ =>
258
- super .transformTerm(tree)(owner)
251
+ class ProductElementIdExactExpander [Fields <: Tuple : Type ] extends TreeMap {
252
+ override def transformTerm (tree : Term )(owner : Symbol ): Term =
253
+ try {
254
+ tree.asExpr match {
255
+ case ' { InlineHKDGeneric .productElementIdExact[a2, elemTop]($a, $idx) } =>
256
+ transformExact(a, idx)
257
+ case _ =>
258
+ super .transformTerm(tree)(owner)
259
+ }
260
+ } catch {
261
+ case e : Exception =>
262
+ // Tried to convert partially applied type to Expr. Ignoring it
263
+ tree
259
264
}
260
- } catch {
261
- case e : Exception =>
262
- // Tried to convert partially applied type to Expr. Ignoring it
263
- tree
264
- }
265
265
266
- def transformExact [A ](a : Expr [A ], idxExpr : Expr [Int ]): Term = {
267
- def findConstantIdx (tpe : TypeRepr ): Option [Int ] = tpe match {
268
- case AndType (a, b) => findConstantIdx(a).orElse(findConstantIdx(b))
269
- case ConstantType (IntConstant (i)) => Some (i)
270
- case Refinement (a, _, _) => findConstantIdx(a)
271
- case t => None
272
- }
266
+ def transformExact [A ](a : Expr [A ], idxExpr : Expr [Int ]): Term = {
267
+ def findConstantIdx (tpe : TypeRepr ): Option [Int ] = tpe match {
268
+ case AndType (a, b) => findConstantIdx(a).orElse(findConstantIdx(b))
269
+ case ConstantType (IntConstant (i)) => Some (i)
270
+ case Refinement (a, _, _) => findConstantIdx(a)
271
+ case t => None
272
+ }
273
273
274
- val idx = findConstantIdx(idxExpr.asTerm.tpe.widenTermRefByName).getOrElse(idxExpr.valueOrAbort)
274
+ val idx = findConstantIdx(idxExpr.asTerm.tpe.widenTermRefByName).getOrElse(idxExpr.valueOrAbort)
275
275
276
- val field = Helpers .valuesOfConstantTuple(TypeRepr .of[Fields ], Nil ) match {
277
- case Some (seq) => seq(idx).asExprOf[String ].valueOrAbort
278
- case None => report.errorAndAbort(" productElementIdExact called with non constant fields type" )
279
- }
276
+ val field = Helpers .valuesOfConstantTuple(TypeRepr .of[Fields ], Nil ) match {
277
+ case Some (seq) => seq(idx).asExprOf[String ].valueOrAbort
278
+ case None => report.errorAndAbort(" productElementIdExact called with non constant fields type" )
279
+ }
280
280
281
- Select .unique(a.asTerm, field)
281
+ Select .unique(a.asTerm, field)
282
+ }
282
283
}
283
- }
284
284
285
- private class RefReplacer [Q <: Quotes ](using val q : Q )(oldRef : q.reflect.Symbol , newRef : q.reflect.Ref )
286
- extends q.reflect.TreeMap {
287
- import q .reflect .*
285
+ class RefReplacer (oldRef : q.reflect.Symbol , newRef : q.reflect.Ref ) extends TreeMap {
286
+ override def transformTerm (tree : Term )(owner : Symbol ): Term =
287
+ tree match {
288
+ case Ident (id) if id == oldRef.name => newRef
289
+ case _ => super .transformTerm(tree)(owner)
290
+ }
291
+ }
288
292
289
- override def transformTerm (tree : Term )(owner : Symbol ): Term =
290
- tree match {
291
- case Ident (id) if id == oldRef.name => newRef
292
- case _ => super .transformTerm(tree)(owner)
293
+ class LateInlineMatchExpander extends TreeMap {
294
+ override def transformTerm (tree : Term )(owner : Symbol ): Term = {
295
+ tree.asExpr match {
296
+ case ' { InlineHKDGeneric .lateInlineMatch[a]($a) } =>
297
+ transformMatch(a, owner)
298
+ case _ =>
299
+ try {
300
+ super .transformTerm(tree)(owner)
301
+ } catch {
302
+ case _ : Exception =>
303
+ // FIXME: Have no idea why this happens. Just ignoring it for now.
304
+ tree
305
+ }
306
+ }
293
307
}
294
- }
295
308
296
- private class LateInlineMatchExpander [Q <: Quotes ]()(using val q : Q ) extends q.reflect.TreeMap {
297
- import q .reflect .*
309
+ def transformMatch [A : Type ](aExpr : Expr [A ], owner : Symbol ): Term = aExpr.asTerm match {
310
+ case m @ Match (scrutinee, cases) =>
311
+ val tpe = scrutinee.tpe.widenTermRefByName
298
312
299
- override def transformTerm (tree : Term )(owner : Symbol ): Term = {
300
- tree.asExpr match {
301
- case ' { InlineHKDGeneric .lateInlineMatch[a]($a) } =>
302
- transformMatch(a, owner)
303
- case _ =>
304
- try {
305
- super .transformTerm(tree)(owner)
306
- } catch {
307
- case _ : Exception =>
308
- // FIXME: Have no idea why this happens. Just ignoring it for now.
309
- tree
313
+ cases.foreach {
314
+ case CaseDef (_, Some (_), _) => report.errorAndAbort(" Cases in match can not have guards" )
315
+ case CaseDef (Bind (_, Typed (Ident (_), _)), _, _) =>
316
+ case CaseDef (Bind (_, Ident (_)), _, _) =>
317
+ case caseDef => report.errorAndAbort(" Invalid case in match inside lateInlineMatch" , caseDef.pos)
310
318
}
311
- }
312
- }
313
-
314
- def transformMatch [A : Type ](aExpr : Expr [A ], owner : Symbol ): Term = aExpr.asTerm match {
315
- case m @ Match (scrutinee, cases) =>
316
- val tpe = scrutinee.tpe.widenTermRefByName
317
319
318
- cases.foreach {
319
- case CaseDef (_, Some (_), _) => report.errorAndAbort(" Cases in match can not have guards" )
320
- case CaseDef (Bind (_, Typed (Ident (_), _)), _, _) =>
321
- case CaseDef (Bind (_, Ident (_)), _, _) =>
322
- case caseDef => report.errorAndAbort(" Invalid case in match inside lateInlineMatch" , caseDef.pos)
323
- }
320
+ val hasDefaultCase = cases.exists {
321
+ case CaseDef (Bind (_, Ident (_)), _, _) => true
322
+ case _ => false
323
+ }
324
+ if ! hasDefaultCase then report.errorAndAbort(" Match must have a default case" , m.pos)
324
325
325
- val hasDefaultCase = cases.exists {
326
- case CaseDef (Bind (_, Ident (_)), _, _) => true
327
- case _ => false
328
- }
329
- if ! hasDefaultCase then report.errorAndAbort(" Match must have a default case" , m.pos)
326
+ val (bind, rhs) = cases
327
+ .collectFirst {
328
+ case CaseDef (bind @ Bind (_, typed @ Typed (Ident (_), _)), _, rhs) if tpe <:< typed.symbol.typeRef =>
329
+ (bind, rhs)
330
+ }
331
+ .getOrElse {
332
+ cases.collectFirst { case CaseDef (bind @ Bind (_, Ident (_)), _, rhs) =>
333
+ (bind, rhs)
334
+ }.get
335
+ }
330
336
331
- val (bind, rhs) = cases
332
- .collectFirst {
333
- case CaseDef (bind @ Bind (_, typed @ Typed (Ident (_), _)), _, rhs) if tpe <:< typed.symbol.typeRef =>
334
- (bind, rhs)
335
- }
336
- .getOrElse {
337
- cases.collectFirst { case CaseDef (bind @ Bind (_, Ident (_)), _, rhs) =>
338
- (bind, rhs)
339
- }.get
337
+ ValDef .let(owner, bind.name + " Replaced" , scrutinee) { newRef =>
338
+ val replacer = new RefReplacer (bind.symbol, newRef)
339
+ replacer.transformTerm(rhs)(owner)
340
340
}
341
-
342
- ValDef .let(owner, bind.name + " Replaced" , scrutinee) { newRef =>
343
- val replacer = new RefReplacer [q.type ](bind.symbol, newRef)
344
- replacer.transformTerm(rhs)(owner)
345
- }
346
- case _ => report.errorAndAbort(" Body of lateInlineMatch must be a match" , aExpr)
341
+ case _ => report.errorAndAbort(" Body of lateInlineMatch must be a match" , aExpr)
342
+ }
347
343
}
348
344
}
349
345
@@ -352,8 +348,9 @@ object InlineHKDGeneric:
352
348
): Expr [A ] =
353
349
import q .reflect .*
354
350
355
- val productElementIdExactExpander = new ProductElementIdExactExpander [q.type , Fields ]()
356
- val lateInlineMatchExpander = new LateInlineMatchExpander [q.type ]()
351
+ val treeMaps = new TreeMaps [q.type ]()
352
+ val productElementIdExactExpander = new treeMaps.ProductElementIdExactExpander [Fields ]()
353
+ val lateInlineMatchExpander = new treeMaps.LateInlineMatchExpander ()
357
354
358
355
val r1 = productElementIdExactExpander.transformTerm(e.asTerm)(Symbol .spliceOwner)
359
356
val r2 = lateInlineMatchExpander.transformTerm(r1)(Symbol .spliceOwner)
0 commit comments