Skip to content

Commit c23f16b

Browse files
committed
Add missing dealiasing when deriving codecs for generic and named tuples
1 parent 4d1e659 commit c23f16b

File tree

3 files changed

+22
-9
lines changed

3 files changed

+22
-9
lines changed

jsoniter-scala-macros/shared/src/main/scala-3/com/github/plokhotnyuk/jsoniter_scala/macros/JsonCodecMaker.scala

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -774,20 +774,20 @@ object JsonCodecMaker {
774774
def isTuple(tpe: TypeRepr): Boolean = tpe <:< TypeRepr.of[Tuple]
775775

776776
def isGenericTuple(tpe: TypeRepr): Boolean = tpe match {
777-
case AppliedType(tTpe, _) if tTpe =:= TypeRepr.of[*:] => true
777+
case AppliedType(gtTpe, _) if gtTpe.dealias =:= TypeRepr.of[*:] => true
778778
case _ => tpe =:= TypeRepr.of[EmptyTuple]
779779
}
780780

781+
def tupleTypeArgs(t: Type[?]): List[TypeRepr] = t match {
782+
case '[head *: tail] => TypeRepr.of[head].dealias :: tupleTypeArgs(Type.of[tail])
783+
case _ => Nil
784+
}
785+
781786
def isNamedTuple(tpe: TypeRepr): Boolean = tpe match {
782787
case AppliedType(ntTpe, _) if ntTpe.dealias.typeSymbol.fullName == "scala.NamedTuple$.NamedTuple" => true
783788
case _ => false
784789
}
785790

786-
def tupleTypeArgs(t: Type[?]): List[TypeRepr] = t match {
787-
case '[head *: tail] => TypeRepr.of[head] :: tupleTypeArgs(Type.of[tail])
788-
case _ => Nil
789-
}
790-
791791
def valueClassValueSymbol(tpe: TypeRepr): Symbol = tpe.typeSymbol.fieldMembers.head
792792

793793
def valueClassValueType(tpe: TypeRepr): TypeRepr = tpe.memberType(valueClassValueSymbol(tpe)).dealias
@@ -1000,14 +1000,14 @@ object JsonCodecMaker {
10001000
tpe match {
10011001
case AppliedType(_, List(nTpe, tTpe)) =>
10021002
// Borrowed from an amazing work of Aleksander Rainko: https://github.com/arainko/ducktape/blob/8d779f0303c23fd45815d3574467ffc321a8db2b/ducktape/src/main/scala/io/github/arainko/ducktape/internal/Structure.scala#L188-L199
1003-
val names = tupleTypeArgs(nTpe.asType).map { case ConstantType(StringConstant(n)) => n }
1004-
val typeArgs = tupleTypeArgs(tTpe.asType)
1003+
val names = tupleTypeArgs(nTpe.dealias.asType).map { case ConstantType(StringConstant(n)) => n }
1004+
val typeArgs = tupleTypeArgs(tTpe.dealias.asType)
10051005
val size = typeArgs.size
10061006
val tupleTpe =
10071007
if (size > 0 && size <= 22) defn.TupleClass(size).typeRef.appliedTo(typeArgs)
10081008
else typeArgs.foldRight(TypeRepr.of[EmptyTuple]) {
10091009
val tupleCons = TypeRepr.of[*:]
1010-
(curr, acc) => tupleCons.appliedTo(curr :: acc :: Nil)
1010+
(curr, acc) => tupleCons.appliedTo(List(curr, acc))
10111011
}
10121012
val noSymbol = Symbol.noSymbol
10131013
var i = - 1

jsoniter-scala-macros/shared/src/test/scala-3/com/github/plokhotnyuk/jsoniter_scala/macros/JsonCodecMakerNewTypeSpec.scala

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,9 +63,15 @@ class JsonCodecMakerNewTypeSpec extends VerifyingSpec {
6363
"""[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,"24"]""")
6464
}
6565
"serialize and deserialize generic tuples" in {
66+
type B = Byte
67+
type I = Int
68+
type L = Long
69+
type S = Short
70+
6671
verifySerDeser(make[EmptyTuple], EmptyTuple, "[]")
6772
verifySerDeser(make[Tuple.Drop[(Long, Int, String), 3]], EmptyTuple, "[]")
6873
verifySerDeser(make[Byte *: Short *: Int *: Long *: EmptyTuple], (1: Byte, 2: Short, 3, 4L), "[1,2,3,4]")
74+
verifySerDeser(make[B *: S *: I *: L *: EmptyTuple], (1: Byte, 2: Short, 3, 4L), "[1,2,3,4]")
6975
verifySerDeser(make[Byte *: Short *: Tuple2[Int, Long]], (1: Byte, 2: Short, 3, 4L), "[1,2,3,4]")
7076
verifySerDeser(make[Tuple.Concat[(Byte, Short), (Int, Long)]], (1: Byte, 2: Short, 3, 4L), "[1,2,3,4]")
7177
verifySerDeser(make[Tuple.Append[(Byte, Short), Int]], (1: Byte, 2: Short, 3), "[1,2,3]")

jsoniter-scala-next-tests/shared/src/test/scala-3/com/github/plokhotnyuk/jsoniter_scala/macros/JsonCodecMakerNamedTupleSpec.scala

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,13 @@ class JsonCodecMakerNamedTupleSpec extends VerifyingSpec {
2323
"serialize and deserialize complex named tuples" in {
2424
case class Record(i: Int, s: String)
2525

26+
type *:: = *:
27+
type Names = "i" *:: "s" *:: EmptyTuple
28+
type I = Int
29+
type S = String
30+
type Values = I *:: S *:: EmptyTuple
31+
32+
verifySerDeser(make[NamedTuple.NamedTuple[Names, Values]], (i = 1, s = "VVV"), """{"i":1,"s":"VVV"}""")
2633
verifySerDeser(make[NamedTuple.From[Record]], (i = 1, s = "VVV"), """{"i":1,"s":"VVV"}""")
2734
verifySerDeser(make[NamedTuple.Reverse[(i: Int, s: String)]], (s = "VVV", i = 1), """{"s":"VVV","i":1}""")
2835
verifySerDeser(make[NamedTuple.Concat[(i: Int), (s: String)]], (i = 1, s = "VVV"), """{"i":1,"s":"VVV"}""")

0 commit comments

Comments
 (0)