1
1
import scala .quoted ._
2
2
3
3
object Macro {
4
-
5
4
case class Record (elems : (String , Any )* ) extends Selectable {
6
5
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 )]): _* )
7
14
}
8
15
9
16
inline def toHMap (s : Selectable ) <: Tuple = $ { toHMapImpl(' s )}
@@ -28,41 +35,37 @@ object Macro {
28
35
}
29
36
}
30
37
31
- // val list = println(rec(repr))
32
-
33
38
val ret = rec(repr).reverse.map(e => tupleElem(e._1, e._2))
34
39
35
40
Expr .ofTuple(ret)
36
41
}
37
42
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 ])}
39
45
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 ] = {
41
47
import qctx .tasty .{given , _ }
42
48
43
49
val repr = s.unseal.tpe.widenTermRefExpr.dealias
44
50
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
-
50
51
def rec (tpe : Type ): List [(String , Type )] = {
51
52
tpe match {
52
- // todo: check number based on prefix
53
+ // todo:
54
+ // check number based on prefix
55
+ // capture the TupleXX variants in recursion
53
56
case AppliedType (_, args) => args.map{
54
57
case AppliedType (_, ConstantType (Constant (name : String )) :: (info : Type ) :: Nil ) => (name, info)
55
58
}
56
59
}
57
60
}
58
- val r = rec(repr)
59
- println(r)
60
61
61
- println(tpe.unseal.symbol)
62
- println(TypeIdent (tpe.unseal.symbol))
62
+ val r = rec(repr)
63
63
64
- println( ' { new Record ()}.unseal.showExtractors)
64
+ val refinementType = r.foldLeft( ' [ Record ].unseal.tpe)((acc, e) => Refinement (acc, e._1, e._2)).seal
65
65
66
- ' { ??? }
66
+ refinementType match {
67
+ case ' [$qType] =>
68
+ ' { Record .fromTuple($ {s}).asInstanceOf [$ {qType}] }
69
+ }
67
70
}
68
71
}
0 commit comments