@@ -778,15 +778,17 @@ object JsonCodecMaker {
778
778
case _ => tpe =:= TypeRepr .of[EmptyTuple ]
779
779
}
780
780
781
+ // Borrowed from an amazing work of Aleksander Rainko:
781
782
// https://github.com/arainko/ducktape/blob/8d779f0303c23fd45815d3574467ffc321a8db2b/ducktape/src/main/scala/io/github/arainko/ducktape/internal/Structure.scala#L253-L270
782
783
def tupleTypeArgs (t : Type [? ]): List [TypeRepr ] = t match {
783
784
case ' [head *: tail] => TypeRepr .of[head].dealias :: tupleTypeArgs(Type .of[tail])
784
785
case _ => Nil
785
786
}
786
787
788
+ // Borrowed from an amazing work of Aleksander Rainko:
787
789
// https://github.com/arainko/ducktape/blob/8d779f0303c23fd45815d3574467ffc321a8db2b/ducktape/src/main/scala/io/github/arainko/ducktape/internal/Structure.scala#L277-L295
788
790
def toTuple (typeArgs : List [TypeRepr ]): TypeRepr = {
789
- val size = typeArgs.size
791
+ val size = typeArgs.size
790
792
if (size > 0 && size <= 22 ) defn.TupleClass (size).typeRef.appliedTo(typeArgs)
791
793
else {
792
794
typeArgs.foldRight(TypeRepr .of[EmptyTuple ]) {
@@ -879,7 +881,7 @@ object JsonCodecMaker {
879
881
case ' [t] =>
880
882
val sym = symbol(" ct" + classTags.size, TypeRepr .of[ClassTag [t]])
881
883
val ct = Expr .summon[ClassTag [t]].fold(fail(s " Can't summon ClassTag[ ${tpe.show}] " ))(_.asTerm)
882
- ValDef (sym, Some (ct.changeOwner(sym) ))
884
+ ValDef (sym, Some (ct))
883
885
}).symbol)
884
886
885
887
def inferImplicitValue [T : Type ](typeToSearch : TypeRepr ): Option [Expr [T ]] = Implicits .search(typeToSearch) match
@@ -928,15 +930,15 @@ object JsonCodecMaker {
928
930
else if (precision == MathContext .UNLIMITED .getPrecision) ' { (MathContext .UNLIMITED : java.math.MathContext ) }
929
931
else Ref (mathContexts.getOrElseUpdate(precision, {
930
932
val sym = symbol(" mc" + mathContexts.size, TypeRepr .of[MathContext ])
931
- ValDef (sym, Some (' { new MathContext ($ {Expr (cfg.bigDecimalPrecision)}, java.math.RoundingMode .HALF_EVEN ) }.asTerm.changeOwner(sym) ))
933
+ ValDef (sym, Some (' { new MathContext ($ {Expr (cfg.bigDecimalPrecision)}, java.math.RoundingMode .HALF_EVEN ) }.asTerm))
932
934
}).symbol).asExprOf[MathContext ]
933
935
934
936
val scalaEnumCaches = new mutable.LinkedHashMap [TypeRepr , ValDef ]
935
937
936
938
def withScalaEnumCacheFor [K : Type , T : Type ](tpe : TypeRepr )(using Quotes ): Expr [ConcurrentHashMap [K , T ]] =
937
939
Ref (scalaEnumCaches.getOrElseUpdate(tpe, {
938
940
val sym = symbol(" ec" + scalaEnumCaches.size, TypeRepr .of[ConcurrentHashMap [K , T ]])
939
- ValDef (sym, Some (' { new ConcurrentHashMap [K , T ] }.asTerm.changeOwner(sym) ))
941
+ ValDef (sym, Some (' { new ConcurrentHashMap [K , T ] }.asTerm))
940
942
}).symbol).asExprOf[ConcurrentHashMap [K , T ]]
941
943
942
944
case class JavaEnumValueInfo (value : Symbol , name : String , transformed : Boolean )
@@ -996,7 +998,10 @@ object JsonCodecMaker {
996
998
def genNew (argss : List [List [Term ]]): Term = {
997
999
val args = argss.flatten
998
1000
if (isGeneric) Expr .ofTupleFromSeq(args.map(_.asExpr)).asTerm
999
- else Apply (TypeApply (Select .unique(New (Inferred (tupleTpe)), " <init>" ), typeArgs.map(x => Inferred (x))), args)
1001
+ else {
1002
+ val constructorNoTypes = Select (New (Inferred (tupleTpe)), tupleTpe.typeSymbol.primaryConstructor)
1003
+ Apply (TypeApply (constructorNoTypes, typeArgs.map(Inferred (_))), args)
1004
+ }
1000
1005
}
1001
1006
}
1002
1007
@@ -1644,10 +1649,7 @@ object JsonCodecMaker {
1644
1649
val nullValues = new mutable.LinkedHashMap [TypeRepr , ValDef ]
1645
1650
1646
1651
def withNullValueFor [T : Type ](tpe : TypeRepr )(f : => Expr [T ]): Expr [T ] =
1647
- Ref (nullValues.getOrElseUpdate(tpe, {
1648
- val sym = symbol(" c" + nullValues.size, tpe)
1649
- ValDef (sym, Some (f.asTerm.changeOwner(sym)))
1650
- }).symbol).asExprOf[T ]
1652
+ Ref (nullValues.getOrElseUpdate(tpe, ValDef (symbol(" c" + nullValues.size, tpe), Some (f.asTerm))).symbol).asExprOf[T ]
1651
1653
1652
1654
val fieldIndexAccessors = new mutable.LinkedHashMap [TypeRepr , DefDef ]
1653
1655
@@ -1663,7 +1665,7 @@ object JsonCodecMaker {
1663
1665
i += 1
1664
1666
CaseDef (Literal (IntConstant (i)), None , Literal (StringConstant (n)))
1665
1667
}
1666
- Some (Match (param.asExprOf[Int ].asTerm, cases).changeOwner(sym) )
1668
+ Some (Match (param.asExprOf[Int ].asTerm, cases))
1667
1669
})
1668
1670
}).symbol)
1669
1671
@@ -1898,10 +1900,7 @@ object JsonCodecMaker {
1898
1900
def genReadLeafClass [T : Type ](subTpe : TypeRepr )(using Quotes ): Expr [T ] =
1899
1901
val useDiscriminator = cfg.discriminatorFieldName.isDefined
1900
1902
if (subTpe =:= tpe) {
1901
- val typeInfo =
1902
- if (isNamedTuple(tpe)) getNamedTupleInfo(tpe)
1903
- else getClassInfo(tpe)
1904
- genReadNonAbstractScalaClass(typeInfo, types, useDiscriminator, in, genNullValue[T ](types))
1903
+ genReadNonAbstractScalaClass(getClassInfo(tpe), types, useDiscriminator, in, genNullValue[T ](types))
1905
1904
} else genReadVal(subTpe :: types, genNullValue[T ](subTpe :: types), isStringified, useDiscriminator, in)
1906
1905
1907
1906
def genReadCollisions [T : Type ](subTpes : collection.Seq [TypeRepr ], l : Expr [Int ])(using Quotes ): Expr [T ] =
@@ -2122,7 +2121,7 @@ object JsonCodecMaker {
2122
2121
cfg.discriminatorFieldName.map { fieldName =>
2123
2122
if (cfg.checkFieldDuplication) {
2124
2123
val sym = symbol(" pd" , TypeRepr .of[Boolean ], Flags .Mutable )
2125
- ReadDiscriminator (Some (ValDef (sym, Some (Literal (BooleanConstant (true )).changeOwner(sym) ))))
2124
+ ReadDiscriminator (Some (ValDef (sym, Some (Literal (BooleanConstant (true ))))))
2126
2125
} else ReadDiscriminator (None )
2127
2126
}
2128
2127
} else None
@@ -2142,7 +2141,6 @@ object JsonCodecMaker {
2142
2141
2143
2142
def blockWithVars (next : Term ): Term =
2144
2143
Block (readVars ++ paramVars.toList ++ optDiscriminatorVar.toList, next.changeOwner(Symbol .spliceOwner))
2145
- .changeOwner(Symbol .spliceOwner) // All owners should be from top Symbol.spliceOwner because vals are created with this owner
2146
2144
2147
2145
val readNonEmpty = blockWithVars(' {
2148
2146
if (! $in.isNextToken('}' )) {
@@ -2154,10 +2152,10 @@ object JsonCodecMaker {
2154
2152
}
2155
2153
if (! $in.isCurrentToken('}' )) $in.objectEndOrCommaError()
2156
2154
}
2157
- $ {Block (checkReqVars, construct).changeOwner( Symbol .spliceOwner). asExprOf[T ]}
2155
+ $ {Block (checkReqVars, construct).asExprOf[T ]}
2158
2156
}.asTerm)
2159
- If (' { $in.isNextToken('{' ) }.asTerm.changeOwner( Symbol .spliceOwner) , readNonEmpty,
2160
- ' { $in.readNullOrTokenError($default, '{' ) }.asTerm.changeOwner( Symbol .spliceOwner) ).asExprOf[T ]
2157
+ If (' { $in.isNextToken('{' ) }.asTerm, readNonEmpty,
2158
+ ' { $in.readNullOrTokenError($default, '{' ) }.asTerm).asExprOf[T ]
2161
2159
}
2162
2160
2163
2161
def genReadConstType [T : Type ](tpe : TypeRepr , isStringified : Boolean , in : Expr [JsonReader ])(using Quotes ): Expr [T ] = tpe match
@@ -2694,7 +2692,6 @@ object JsonCodecMaker {
2694
2692
i += 1
2695
2693
te.asType match
2696
2694
case ' [t] =>
2697
- val sym = symbol(" _r" + i, te)
2698
2695
val nullVal = genNullValue[t](te :: types)
2699
2696
val rhs =
2700
2697
if (i == 1 ) genReadVal(te :: types, nullVal, isStringified, false , in)
@@ -2703,19 +2700,19 @@ object JsonCodecMaker {
2703
2700
$ {genReadVal(te :: types, nullVal, isStringified, false , in)}
2704
2701
} else $in.commaError()
2705
2702
}
2706
- ValDef (sym, Some (rhs.asTerm.changeOwner(sym) ))
2703
+ ValDef (symbol( " _r " + i, te), Some (rhs.asTerm))
2707
2704
}
2708
2705
val readCreateBlock = Block (valDefs, ' {
2709
2706
if ($in.isNextToken(']' )) $ {
2710
2707
val size = indexedTypes.size
2711
2708
if (size == 0 ) Expr (EmptyTuple )
2712
2709
else if (size > 22 ) Expr .ofTupleFromSeq(valDefs.map(x => Ref (x.symbol).asExprOf[Any ]))
2713
2710
else {
2714
- Apply ( TypeApply ( Select .unique (New (Inferred (tTpe)), " <init> " ),
2715
- indexedTypes.map(x => Inferred (x ))), valDefs.map(x => Ref (x.symbol))).asExpr
2711
+ val constructorNoTypes = Select (New (Inferred (tTpe)), tTpe.typeSymbol.primaryConstructor)
2712
+ Apply ( TypeApply (constructorNoTypes, indexedTypes.map(Inferred (_ ))), valDefs.map(x => Ref (x.symbol))).asExpr
2716
2713
}
2717
2714
} else $in.arrayEndError()
2718
- }.asTerm)
2715
+ }.asTerm.changeOwner( Symbol .spliceOwner) )
2719
2716
' {
2720
2717
if ($in.isNextToken('[' )) $ {readCreateBlock.asExprOf[T ]}
2721
2718
else $in.readNullOrTokenError($default, '[' )
@@ -2900,8 +2897,8 @@ object JsonCodecMaker {
2900
2897
}
2901
2898
val allWriteFields = optDiscriminator.fold(writeFields)(_.write(out) :: writeFields)
2902
2899
Block (valDefs,
2903
- Block (' { $out.writeObjectStart() }.asTerm :: allWriteFields.map(_.asTerm.changeOwner( Symbol .spliceOwner) ),
2904
- ' { $out.writeObjectEnd() }.asTerm)
2900
+ Block (' { $out.writeObjectStart() }.asTerm :: allWriteFields.map(_.asTerm),
2901
+ ' { $out.writeObjectEnd() }.asTerm).changeOwner( Symbol .spliceOwner)
2905
2902
).asExprOf[Unit ]
2906
2903
2907
2904
def getWriteConstType (tpe : TypeRepr , isStringified : Boolean , out : Expr [JsonWriter ])(using Quotes ): Expr [Unit ] =
@@ -3192,23 +3189,23 @@ object JsonCodecMaker {
3192
3189
val indexedTypes =
3193
3190
if (isGenericTuple(tpe)) tupleTypeArgs(tpe.asType)
3194
3191
else typeArgs(tpe)
3195
- val size = indexedTypes.size
3196
3192
val tTpe = toTuple(indexedTypes)
3197
3193
val xTerm =
3198
3194
tTpe.asType match
3199
3195
case ' [tt] => ' { $x.asInstanceOf [tt & Tuple ] }.asTerm
3200
3196
val writeFields = indexedTypes.map {
3197
+ val isGeneric = indexedTypes.size > 22
3201
3198
var i = 0
3202
3199
te =>
3203
3200
i += 1
3204
3201
te.asType match
3205
3202
case ' [t] =>
3206
- val select =
3207
- if (size > 22 ) {
3208
- val getter = Select .unique(xTerm, " productElement" ).appliedTo(Literal (IntConstant (i - 1 ))).asExprOf[Any ]
3209
- ' { $getter .asInstanceOf [t] }.asExprOf[t]
3203
+ val getter =
3204
+ if (isGeneric ) {
3205
+ val select = Select .unique(xTerm, " productElement" ).appliedTo(Literal (IntConstant (i - 1 ))).asExprOf[Any ]
3206
+ ' { $select .asInstanceOf [t] }.asExprOf[t]
3210
3207
} else Select .unique(xTerm, " _" + i).asExprOf[t]
3211
- genWriteVal(select , te :: types, isStringified, None , out).asTerm
3208
+ genWriteVal(getter , te :: types, isStringified, None , out).asTerm
3212
3209
}
3213
3210
Block (' { $out.writeArrayStart() }.asTerm :: writeFields, ' { $out.writeArrayEnd() }.asTerm).asExprOf[Unit ]
3214
3211
} else if (isEnumOrModuleValue(tpe) && ! (cfg.alwaysEmitDiscriminator && hasSealedParent(tpe))) withEncoderFor(methodKey, m, out) { (out, x) =>
@@ -3222,10 +3219,7 @@ object JsonCodecMaker {
3222
3219
subTpe.asType match
3223
3220
case ' [st] =>
3224
3221
if (subTpe =:= tpe) {
3225
- val typeInfo =
3226
- if (isNamedTuple(tpe)) getNamedTupleInfo(tpe)
3227
- else getClassInfo(tpe)
3228
- genWriteNonAbstractScalaClass(vx.asExprOf[st], typeInfo, types, discriminator, out)
3222
+ genWriteNonAbstractScalaClass(vx.asExprOf[st], getClassInfo(tpe), types, discriminator, out)
3229
3223
} else genWriteVal(vx.asExprOf[st], subTpe :: types, isStringified, discriminator, out)
3230
3224
3231
3225
val leafClasses = adtLeafClasses(tpe)
0 commit comments