Skip to content

Commit abdff10

Browse files
Merge branch 'pr-852'
2 parents e9becdf + 95affd4 commit abdff10

2 files changed

Lines changed: 28 additions & 4 deletions

File tree

build.sbt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ val versions = new {
2424
val platforms = List(VirtualAxis.jvm, VirtualAxis.js, VirtualAxis.native)
2525

2626
// Dependencies.
27-
val macroCommons = "2.0.2"
27+
val macroCommons = "2.1.0"
2828
val cats = "2.13.0"
2929
val kindProjector = "0.13.4"
3030
val munit = "1.2.4"
@@ -47,7 +47,7 @@ val versions = new {
4747
case Some((2, 12)) => for2_12
4848
case Some((2, 13)) => for2_13
4949
case Some((3, _)) => for3
50-
case _ => sys.error(s"Unsupported Scala version: $scalaVersion")
50+
case _ => Seq.empty // for sbt
5151
}
5252
}
5353

chimney/src/main/scala-3/io/scalaland/chimney/internal/compiletime/dsl/utils/DslMacroUtils.scala

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,35 @@ private[chimney] class DslMacroUtils()(using quotes: Quotes) {
1111

1212
private object SelectLike {
1313
def unapply(term: Term): Option[(Term, String)] = term match {
14-
case Select(instance, name) => Some((instance, name))
15-
case Apply(Select(instance, name), Nil) => Some((instance, name))
14+
case Select(instance, name) => Some((instance, name))
15+
case Apply(Select(instance, name), Nil) => Some((instance, name))
16+
case Apply(
17+
Apply(TypeApply(Select(Ident("NamedTuple"), "apply"), List(fieldNames, _)), List(instance)),
18+
List(Literal(IntConstant(i)))
19+
) =>
20+
for {
21+
fieldNameStrings <- tupleUnrollStrings(fieldNames.tpe)
22+
fieldName <- fieldNameStrings.lift(i)
23+
} yield (instance, fieldName)
1624
case Block(_, SelectLike(instance, name)) => Some((instance, name))
1725
case _ => None
1826
}
27+
28+
// Borrowed from an amazing work by @arainko,
29+
// https://github.com/arainko/ducktape/blob/7984125ffe3493c2e61b72dea799017bb31597f7/ducktape/src/main/scala/io/github/arainko/ducktape/internal/Tuples.scala#L8-L30
30+
private def tupleUnroll(tpe: quoted.Type[?]): Option[List[TypeRepr]] = {
31+
// TODO: duplicated from chimney-macro-commons, should be shared
32+
@scala.annotation.tailrec
33+
def loop(curr: quoted.Type[?], acc: List[TypeRepr]): Option[List[reflect.TypeRepr]] = curr match {
34+
case '[head *: tail] => loop(quoted.Type.of[tail], TypeRepr.of[head] :: acc)
35+
case '[EmptyTuple] => Some(acc)
36+
case other => None
37+
}
38+
loop(tpe, Nil).map(_.reverse)
39+
}
40+
41+
private def tupleUnrollStrings(tr: TypeRepr): Option[List[String]] =
42+
tupleUnroll(tr.asType).map(_.map { case ConstantType(StringConstant(s)) => s })
1943
}
2044

2145
private object IsOptionOf {

0 commit comments

Comments
 (0)