11import scala .quoted ._
22
33object Macro {
4-
54 case class Record (elems : (String , Any )* ) extends Selectable {
65 def selectDynamic (name : String ): Any = elems.find(_._1 == name).get._2
6+ def toTuple = {
7+ // todo: unnecessary transformation?
8+ Tuple .fromArray(elems.toArray)
9+ }
10+ }
11+
12+ object Record {
13+ def fromTuple (t : Tuple ): Record = Record (t.toArray.toSeq.map(e => e.asInstanceOf [(String , Any )]): _* )
714 }
815
916 inline def toHMap (s : Selectable ) <: Tuple = $ { toHMapImpl(' s )}
@@ -28,41 +35,37 @@ object Macro {
2835 }
2936 }
3037
31- // val list = println(rec(repr))
32-
3338 val ret = rec(repr).reverse.map(e => tupleElem(e._1, e._2))
3439
3540 Expr .ofTuple(ret)
3641 }
3742
38- inline def toSelectable [T ](s : Tuple )<: T = $ { toSelectableImpl(' s , ' [T ])}
43+ // note: T is not used ATM
44+ inline def toSelectable [T ](s : Tuple ) <: Any = $ { toSelectableImpl(' s , ' [T ])}
3945
40- def toSelectableImpl [T ](s : Expr [Tuple ], tpe : Type [T ])(given qctx : QuoteContext ): Expr [T ] = {
46+ def toSelectableImpl [T ](s : Expr [Tuple ], tpe : Type [T ])(given qctx : QuoteContext ): Expr [Any ] = {
4147 import qctx .tasty .{given , _ }
4248
4349 val repr = s.unseal.tpe.widenTermRefExpr.dealias
4450
45- println(repr.show)
46- println(repr.showExtractors)
47-
48- // new Record((res2._1._1, res2._1._2), (res2._2._1, res2._2._2)).asInstanceOf[Record {val name: String; val age: Int} ]
49-
5051 def rec (tpe : Type ): List [(String , Type )] = {
5152 tpe match {
52- // todo: check number based on prefix
53+ // todo:
54+ // check number based on prefix
55+ // capture the TupleXX variants in recursion
5356 case AppliedType (_, args) => args.map{
5457 case AppliedType (_, ConstantType (Constant (name : String )) :: (info : Type ) :: Nil ) => (name, info)
5558 }
5659 }
5760 }
58- val r = rec(repr)
59- println(r)
6061
61- println(tpe.unseal.symbol)
62- println(TypeIdent (tpe.unseal.symbol))
62+ val r = rec(repr)
6363
64- println( ' { new Record ()}.unseal.showExtractors)
64+ val refinementType = r.foldLeft( ' [ Record ].unseal.tpe)((acc, e) => Refinement (acc, e._1, e._2)).seal
6565
66- ' { ??? }
66+ refinementType match {
67+ case ' [$qType] =>
68+ ' { Record .fromTuple($ {s}).asInstanceOf [$ {qType}] }
69+ }
6770 }
6871}
0 commit comments