@@ -14,6 +14,7 @@ import scala.collection.mutable.ArrayBuffer
1414import scala .language .implicitConversions
1515import scala .quoted ._
1616import scala .reflect .ClassTag
17+ import scala .runtime .TupleXXL
1718
1819@ field
1920final class named (val name : String ) extends StaticAnnotation
@@ -790,11 +791,9 @@ object JsonCodecMaker {
790791 def toTuple (typeArgs : List [TypeRepr ]): TypeRepr = {
791792 val size = typeArgs.size
792793 if (size > 0 && size <= 22 ) defn.TupleClass (size).typeRef.appliedTo(typeArgs)
793- else {
794- typeArgs.foldRight(TypeRepr .of[EmptyTuple ]) {
795- val tupleCons = TypeRepr .of[*: ]
796- (curr, acc) => tupleCons.appliedTo(List (curr, acc))
797- }
794+ else typeArgs.foldRight(TypeRepr .of[EmptyTuple ]) {
795+ val tupleCons = TypeRepr .of[*: ]
796+ (curr, acc) => tupleCons.appliedTo(List (curr, acc))
798797 }
799798 }
800799
@@ -865,17 +864,19 @@ object JsonCodecMaker {
865864 Apply (TypeApply (Select (New (TypeIdent (defn.ArrayClass )), defn.ArrayClass .primaryConstructor), List (TypeTree .of[T ])),
866865 List (size.asTerm)).asExprOf[Array [T ]]
867866
867+ def symbol (name : String , tpe : TypeRepr , flags : Flags = Flags .EmptyFlags ): Symbol =
868+ Symbol .newVal(Symbol .spliceOwner, name, tpe, flags, Symbol .noSymbol)
869+
868870 val rootTpe = TypeRepr .of[A ].dealias
869871 val inferredOrderings = mutable.Map .empty[TypeRepr , Term ]
870- val inferredKeyCodecs = mutable.Map .empty[TypeRepr , Option [Expr [JsonKeyCodec [? ]]]]
871- val inferredValueCodecs = mutable.Map .empty[TypeRepr , Option [Expr [JsonValueCodec [? ]]]]
872- val classTags = mutable.Map .empty[TypeRepr , ValDef ]
873872
874873 def summonOrdering (tpe : TypeRepr ): Term = inferredOrderings.getOrElseUpdate(tpe, {
875874 tpe.asType match
876875 case ' [t] => Expr .summon[Ordering [t]].fold(fail(s " Can't summon Ordering[ ${tpe.show}] " ))(_.asTerm)
877876 })
878877
878+ val classTags = mutable.Map .empty[TypeRepr , ValDef ]
879+
879880 def summonClassTag (tpe : TypeRepr ): Term = Ref (classTags.getOrElseUpdate(tpe, {
880881 tpe.asType match
881882 case ' [t] =>
@@ -888,9 +889,6 @@ object JsonCodecMaker {
888889 case v : ImplicitSearchSuccess => Some (v.tree.asExprOf[T ])
889890 case _ => None
890891
891- def symbol (name : String , tpe : TypeRepr , flags : Flags = Flags .EmptyFlags ): Symbol =
892- Symbol .newVal(Symbol .spliceOwner, name, tpe, flags, Symbol .noSymbol)
893-
894892 def checkRecursionInTypes (types : List [TypeRepr ]): Unit =
895893 if (! cfg.allowRecursiveTypes) {
896894 val tpe = types.head
@@ -905,6 +903,8 @@ object JsonCodecMaker {
905903 }
906904 }
907905
906+ val inferredKeyCodecs = mutable.Map .empty[TypeRepr , Option [Expr [JsonKeyCodec [? ]]]]
907+
908908 def findImplicitKeyCodec (types : List [TypeRepr ]): Option [Expr [JsonKeyCodec [? ]]] =
909909 checkRecursionInTypes(types)
910910 val tpe = types.head
@@ -913,6 +913,8 @@ object JsonCodecMaker {
913913 inferImplicitValue[JsonKeyCodec [? ]](TypeRepr .of[JsonKeyCodec ].appliedTo(tpe))
914914 })
915915
916+ val inferredValueCodecs = mutable.Map .empty[TypeRepr , Option [Expr [JsonValueCodec [? ]]]]
917+
916918 def findImplicitValueCodec (types : List [TypeRepr ]): Option [Expr [JsonValueCodec [? ]]] =
917919 checkRecursionInTypes(types)
918920 val tpe = types.head
@@ -1001,18 +1003,17 @@ object JsonCodecMaker {
10011003 if (typeArgs.isEmpty) Expr (EmptyTuple ).asTerm
10021004 else {
10031005 val arraySym = symbol(" as" , TypeRepr .of[Array [Any ]])
1004- val arrayRef = Ref (arraySym).asExprOf[Array [Any ]]
10051006 val arrayValDef = ValDef (arraySym, Some (' { new Array [Any ]($ {Expr (typeArgs.size)}) }.asTerm))
1007+ val arrayUpdate = Select .unique(Ref (arraySym), " update" )
10061008 val assignments = args.map {
10071009 var i = - 1
10081010 term =>
10091011 i += 1
1010- ' { $arrayRef( $ { Expr (i)}) = $ { term.asExprOf[ Any ]} }.asTerm
1012+ Apply (arrayUpdate, List ( Literal ( IntConstant (i)), term))
10111013 }
1012- val block = Block (arrayValDef :: assignments, arrayRef.asTerm ).asExprOf[Array [Any ]]
1014+ val block = Block (arrayValDef :: assignments, Ref (arraySym) ).asExprOf[Array [Any ]]
10131015 tupleType match
1014- case ' [tt] =>
1015- ' { scala.runtime.TupleXXL .fromIArray($block.asInstanceOf [IArray [Object ]]).asInstanceOf [tt] }.asTerm
1016+ case ' [tt] => ' { TupleXXL .fromIArray($block.asInstanceOf [IArray [Object ]]).asInstanceOf [tt] }.asTerm
10161017 }
10171018 } else {
10181019 val constructorNoTypes = Select (New (Inferred (tupleTpe)), tupleTpe.typeSymbol.primaryConstructor)
@@ -1030,12 +1031,11 @@ object JsonCodecMaker {
10301031 val names = tupleTypeArgs(nTpe.dealias.asType).map { case ConstantType (StringConstant (name)) => name }
10311032 val typeArgs = tupleTypeArgs(tTpe.dealias.asType)
10321033 val tupleTpe = toTuple(typeArgs)
1033- val noSymbol = Symbol .noSymbol
10341034 var i = - 1
10351035 NamedTupleInfo (tpe, tupleTpe, typeArgs, List (names.zip(typeArgs).map { case (name, fTpe) =>
10361036 i += 1
10371037 val mappedName = cfg.fieldNameMapper(name).getOrElse(name)
1038- FieldInfo (noSymbol, mappedName, noSymbol, None , fTpe, false , false , i)
1038+ FieldInfo (Symbol . noSymbol, mappedName, Symbol . noSymbol, None , fTpe, false , false , i)
10391039 }))
10401040 case _ => fail(s " Unexpected named type: ${tpe.show}" )
10411041 }
@@ -2167,8 +2167,7 @@ object JsonCodecMaker {
21672167 }
21682168 $ {Block (checkReqVars, construct).asExprOf[T ]}
21692169 }.asTerm)
2170- If (' { $in.isNextToken('{' ) }.asTerm, readNonEmpty,
2171- ' { $in.readNullOrTokenError($default, '{' ) }.asTerm).asExprOf[T ]
2170+ If (' { $in.isNextToken('{' ) }.asTerm, readNonEmpty, ' { $in.readNullOrTokenError($default, '{' ) }.asTerm).asExprOf[T ]
21722171 }
21732172
21742173 def genReadConstType [T : Type ](tpe : TypeRepr , isStringified : Boolean , in : Expr [JsonReader ])(using Quotes ): Expr [T ] = tpe match
@@ -2444,8 +2443,7 @@ object JsonCodecMaker {
24442443 x => ' { $x.update($readKey, { if ($in.isNextToken(',' )) $readVal else $in.commaError() }) },
24452444 identity, in, tDefault).asExprOf[T ]
24462445 } else {
2447- genReadMap(newBuilder,
2448- x => ' { $x.update($in.readKeyAsLong(), $readVal) }, identity, in, tDefault).asExprOf[T ]
2446+ genReadMap(newBuilder, x => ' { $x.update($in.readKeyAsLong(), $readVal) }, identity, in, tDefault).asExprOf[T ]
24492447 }
24502448 } else if (tpe <:< TypeRepr .of[immutable.LongMap [? ]]) withDecoderFor(methodKey, default, in) { (in, default) =>
24512449 val tpe1 = typeArg1(tpe)
@@ -2480,8 +2478,7 @@ object JsonCodecMaker {
24802478 else $tEmpty
24812479 }.asExprOf[T & mutable.Map [t1, t2]]
24822480
2483- def readVal2 (using Quotes ) =
2484- genReadVal(tpe2 :: types, genNullValue[t2](tpe2 :: types), isStringified, false , in)
2481+ def readVal2 (using Quotes ) = genReadVal(tpe2 :: types, genNullValue[t2](tpe2 :: types), isStringified, false , in)
24852482
24862483 if (cfg.mapAsArray) {
24872484 val readVal1 = genReadVal(tpe1 :: types, genNullValue[t1](tpe1 :: types), isStringified, false , in)
@@ -2500,24 +2497,22 @@ object JsonCodecMaker {
25002497 def builderNoApply =
25012498 TypeApply (Select .unique(scalaCollectionCompanion(tpe), " newBuilder" ), List (TypeTree .of[t1], TypeTree .of[t2]))
25022499
2500+ def readKey (using Quotes ) = genReadKey[t1](tpe1 :: types, in)
2501+
2502+ def readVal2 (using Quotes ) = genReadVal(tpe2 :: types, genNullValue[t2](tpe2 :: types), isStringified, false , in)
2503+
2504+ def readVal1 (using Quotes ) = genReadVal(tpe1 :: types, genNullValue[t1](tpe1 :: types), isStringified, false , in)
2505+
25032506 val newBuilder =
25042507 (if (tpe <:< TypeRepr .of[collection.SortedMap [? , ? ]]) Apply (builderNoApply, List (summonOrdering(tpe1)))
25052508 else if (tpe <:< TypeRepr .of[immutable.TreeSeqMap [? , ? ]]) ' { immutable.TreeSeqMap .newBuilder[t1, t2] }.asTerm
25062509 else builderNoApply).asExprOf[mutable.Builder [(t1, t2), T & collection.Map [t1, t2]]]
25072510
2508- def readVal2 (using Quotes ) =
2509- genReadVal(tpe2 :: types, genNullValue[t2](tpe2 :: types), isStringified, false , in)
2510-
25112511 if (cfg.mapAsArray) {
2512- def readVal1 (using Quotes ) =
2513- genReadVal(tpe1 :: types, genNullValue[t1](tpe1 :: types), isStringified, false , in)
2514-
25152512 genReadMapAsArray(newBuilder,
25162513 x => ' { $x.addOne(new Tuple2 ($readVal1, { if ($in.isNextToken(',' )) $readVal2 else $in.commaError() })): Unit },
25172514 x => ' { $x.result() }, in, default).asExprOf[T ]
25182515 } else {
2519- def readKey (using Quotes ) = genReadKey[t1](tpe1 :: types, in)
2520-
25212516 genReadMap(newBuilder, x => ' { $x.addOne(new Tuple2 ($readKey, $readVal2)): Unit },
25222517 x => ' { $x.result() }, in, default).asExprOf[T ]
25232518 }
@@ -2720,16 +2715,16 @@ object JsonCodecMaker {
27202715 if (size == 0 ) Expr (EmptyTuple )
27212716 else if (size > 22 ) {
27222717 val arraySym = symbol(" as" , TypeRepr .of[Array [Any ]])
2723- val arrayRef = Ref (arraySym).asExprOf[Array [Any ]]
27242718 val arrayValDef = ValDef (arraySym, Some (' { new Array [Any ]($ {Expr (size)}) }.asTerm))
2719+ val arrayUpdate = Select .unique(Ref (arraySym), " update" )
27252720 val assignments = valDefs.map {
27262721 var i = - 1
27272722 valDef =>
27282723 i += 1
2729- ' { $arrayRef( $ { Expr (i)}) = $ { Ref (valDef.symbol).asExprOf[ Any ]} }.asTerm
2724+ Apply (arrayUpdate, List ( Literal ( IntConstant (i)), Ref (valDef.symbol)))
27302725 }
2731- val block = Block (arrayValDef :: assignments, arrayRef.asTerm ).asExprOf[Array [Any ]]
2732- ' { scala.runtime. TupleXXL .fromIArray($block.asInstanceOf [IArray [Object ]]).asInstanceOf [T ] }
2726+ val block = Block (arrayValDef :: assignments, Ref (arraySym) ).asExprOf[Array [Any ]]
2727+ ' { TupleXXL .fromIArray($block.asInstanceOf [IArray [Object ]]).asInstanceOf [T ] }
27332728 } else {
27342729 val constructorNoTypes = Select (New (Inferred (tTpe)), tTpe.typeSymbol.primaryConstructor)
27352730 Apply (TypeApply (constructorNoTypes, indexedTypes.map(Inferred (_))), valDefs.map(x => Ref (x.symbol))).asExpr
@@ -2763,18 +2758,11 @@ object JsonCodecMaker {
27632758 val (valDefs, valRef) =
27642759 typeInfo match
27652760 case namedTupleInfo : NamedTupleInfo =>
2766- val valDef = ValDef (
2767- Symbol .newVal(Symbol .spliceOwner, " t" , namedTupleInfo.tupleTpe, Flags .EmptyFlags , Symbol .noSymbol),
2768- Some (
2769- Apply (
2770- Select
2771- .unique(Ref (Symbol .requiredModule(" scala.NamedTuple" )), " toTuple" )
2772- .appliedToTypeTrees(tpe.typeArgs.map(_.asType match { case ' [t] => TypeTree .of[t] })),
2773- List (x.asTerm)
2774- )
2775- )
2776- )
2777- (List (valDef), Ref (valDef.symbol))
2761+ val sym = symbol(" t" , namedTupleInfo.tupleTpe)
2762+ val toTupleMethod =
2763+ Select .unique(Ref (Symbol .requiredModule(" scala.NamedTuple" )), " toTuple" ).appliedToTypes(tpe.typeArgs)
2764+ val valDef = ValDef (sym, Some (Apply (toTupleMethod, List (x.asTerm))))
2765+ (List (valDef), Ref (sym))
27782766 case _ => (Nil , x.asTerm)
27792767 val writeFields = typeInfo.fields.map { fieldInfo =>
27802768 val fDefault =
0 commit comments