Skip to content

Commit 8b17ed0

Browse files
committed
Fix toSelectableImpl
1 parent b44002c commit 8b17ed0

File tree

3 files changed

+26
-20
lines changed

3 files changed

+26
-20
lines changed
Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
1-
((name,Emma),(age,42))
1+
((name,Emma),(age,42))
2+
3+
Record(ArraySeq((name,Emma), (age,42)))
Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,16 @@
11
import scala.quoted._
22

33
object 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
}

tests/run-macros/structural-macro/Test_2.scala

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,10 @@ object Test {
1313
val res: (("name", String), ("age", Int)) = toHMap(person)
1414

1515
println(res)
16+
println()
1617

17-
// val res2: Person = toSelectable[Record](res)
18+
val res2: Person = toSelectable(res)
1819

19-
// new Record((res2._1._1, res2._1._2), (res2._2._1, res2._2._2)).asInstanceOf[Record {val name: String; val age: Int} ]
20+
println(res2)
2021
}
2122
}

0 commit comments

Comments
 (0)