@@ -750,8 +750,7 @@ object JsonCodecMaker {
750750 case TypeRef (SingleType (_, enumSymbol), _, _) => enumSymbol
751751 }
752752
753- val isScala213 : Boolean = util.Properties .versionNumberString.startsWith(" 2.13." )
754- val rootTpe = weakTypeOf[A ].dealias
753+ val isScala213 = util.Properties .versionNumberString.startsWith(" 2.13." )
755754
756755 def isImmutableArraySeq (tpe : Type ): Boolean =
757756 isScala213 && tpe.typeSymbol.fullName == " scala.collection.immutable.ArraySeq"
@@ -762,45 +761,30 @@ object JsonCodecMaker {
762761 def isCollisionProofHashMap (tpe : Type ): Boolean =
763762 isScala213 && tpe.typeSymbol.fullName == " scala.collection.mutable.CollisionProofHashMap"
764763
765- def inferImplicitValue (typeTree : Tree ): Tree = c.inferImplicitValue(c.typecheck(typeTree, c.TYPEmode ).tpe)
766-
767- def checkRecursionInTypes (types : List [Type ]): Unit =
768- if (! cfg.allowRecursiveTypes) {
769- val tpe = types.head
770- val nestedTypes = types.tail
771- val recursiveIdx = nestedTypes.indexOf(tpe)
772- if (recursiveIdx >= 0 ) {
773- val recTypes = nestedTypes.take(recursiveIdx + 1 ).reverse.mkString(" '" , " ', '" , " '" )
774- fail(s " Recursive type(s) detected: $recTypes. Please consider using a custom implicitly " +
775- s " accessible codec for this type to control the level of recursion or turn on the " +
776- s " ' ${typeOf[CodecMakerConfig ]}.allowRecursiveTypes' for the trusted input that " +
777- " will not exceed the thread stack size." )
778- }
779- }
764+ def summon (typeTree : Tree ): Tree = c.inferImplicitValue(c.typecheck(typeTree, c.TYPEmode ).tpe)
780765
781- val inferredKeyCodecs = mutable.Map .empty[Type , Tree ]
782-
783- def findImplicitKeyCodec (types : List [Type ]): Tree = {
784- checkRecursionInTypes(types)
766+ def checkRecursionInTypes (types : List [Type ]): Unit = if (! cfg.allowRecursiveTypes) {
785767 val tpe = types.head
786- if (tpe =:= rootTpe) EmptyTree
787- else {
788- inferredKeyCodecs.getOrElseUpdate(tpe,
789- inferImplicitValue(tq " _root_.com.github.plokhotnyuk.jsoniter_scala.core.JsonKeyCodec[ $tpe] " ))
768+ val nestedTypes = types.tail
769+ val recursiveIdx = nestedTypes.indexOf(tpe)
770+ if (recursiveIdx >= 0 ) {
771+ val recTypes = nestedTypes.take(recursiveIdx + 1 ).reverse.mkString(" '" , " ', '" , " '" )
772+ fail(s " Recursive type(s) detected: $recTypes. Please consider using a custom implicitly accessible codec for " +
773+ s " this type to control the level of recursion or turn on the ' ${typeOf[CodecMakerConfig ]}.allowRecursiveTypes' " +
774+ " for the trusted input that will not exceed the thread stack size." )
790775 }
791776 }
792777
793- val inferredValueCodecs = mutable.Map .empty[Type , Tree ]
778+ val rootTpe = weakTypeOf[A ].dealias
779+ val inferredKeyCodecs = mutable.Map [Type , Tree ]((rootTpe, EmptyTree ))
794780
795- def findImplicitValueCodec (types : List [Type ]): Tree = {
796- checkRecursionInTypes(types)
797- val tpe = types.head
798- if (tpe =:= rootTpe) EmptyTree
799- else {
800- inferredValueCodecs.getOrElseUpdate(tpe,
801- inferImplicitValue(tq " _root_.com.github.plokhotnyuk.jsoniter_scala.core.JsonValueCodec[ $tpe] " ))
802- }
803- }
781+ def findImplicitKeyCodec (tpe : Type ): Tree =
782+ inferredKeyCodecs.getOrElseUpdate(tpe, summon(tq " com.github.plokhotnyuk.jsoniter_scala.core.JsonKeyCodec[ $tpe] " ))
783+
784+ val inferredValueCodecs = mutable.Map [Type , Tree ]((rootTpe, EmptyTree ))
785+
786+ def findImplicitValueCodec (tpe : Type ): Tree =
787+ inferredValueCodecs.getOrElseUpdate(tpe, summon(tq " com.github.plokhotnyuk.jsoniter_scala.core.JsonValueCodec[ $tpe] " ))
804788
805789 val mathContexts = new mutable.LinkedHashMap [Int , (TermName , Tree )]
806790
@@ -990,8 +974,9 @@ object JsonCodecMaker {
990974 }
991975
992976 def genReadKey (types : List [Type ]): Tree = {
977+ checkRecursionInTypes(types)
993978 val tpe = types.head
994- val implKeyCodec = findImplicitKeyCodec(types )
979+ val implKeyCodec = findImplicitKeyCodec(tpe )
995980 if (implKeyCodec.nonEmpty) q " $implKeyCodec.decodeKey(in) "
996981 else if (tpe =:= typeOf[String ]) q " in.readKeyAsString() "
997982 else if (tpe =:= definitions.BooleanTpe || tpe =:= typeOf[java.lang.Boolean ]) q " in.readKeyAsBoolean() "
@@ -1181,8 +1166,9 @@ object JsonCodecMaker {
11811166
11821167 @ tailrec
11831168 def genWriteKey (x : Tree , types : List [Type ]): Tree = {
1169+ checkRecursionInTypes(types)
11841170 val tpe = types.head
1185- val implKeyCodec = findImplicitKeyCodec(types )
1171+ val implKeyCodec = findImplicitKeyCodec(tpe )
11861172 if (implKeyCodec.nonEmpty) q " $implKeyCodec.encodeKey( $x, out) "
11871173 else if (tpe =:= typeOf[String ] || tpe =:= definitions.BooleanTpe || tpe =:= typeOf[java.lang.Boolean ] ||
11881174 tpe =:= definitions.ByteTpe || tpe =:= typeOf[java.lang.Byte ] || tpe =:= definitions.CharTpe ||
@@ -1420,8 +1406,9 @@ object JsonCodecMaker {
14201406 }
14211407
14221408 def genNullValue (types : List [Type ]): Tree = {
1409+ checkRecursionInTypes(types)
14231410 val tpe = types.head
1424- val implValueCodec = findImplicitValueCodec(types )
1411+ val implValueCodec = findImplicitValueCodec(tpe )
14251412 if (implValueCodec.nonEmpty) q " $implValueCodec.nullValue "
14261413 else if (tpe =:= typeOf[String ]) q " null "
14271414 else if (tpe =:= definitions.BooleanTpe || tpe =:= typeOf[java.lang.Boolean ]) q " false "
@@ -1622,10 +1609,11 @@ object JsonCodecMaker {
16221609 else q " x += ${genReadVal(types, genNullValue(types), isStringified, EmptyTree )}"
16231610
16241611 def genReadVal (types : List [Type ], default : Tree , isStringified : Boolean , discriminator : Tree ): Tree = {
1612+ checkRecursionInTypes(types)
16251613 val tpe = types.head
16261614 lazy val methodKey = MethodKey (tpe, isStringified && (isCollection(tpe) || isOption(tpe, types.tail)), discriminator)
16271615 lazy val decodeMethodName = decodeMethodNames.get(methodKey)
1628- val implValueCodec = findImplicitValueCodec(types )
1616+ val implValueCodec = findImplicitValueCodec(tpe )
16291617 if (implValueCodec.nonEmpty) q " $implValueCodec.decodeValue(in, $default) "
16301618 else if (tpe =:= typeOf[String ]) q " in.readString( $default) "
16311619 else if (tpe =:= definitions.BooleanTpe || tpe =:= typeOf[java.lang.Boolean ]) {
@@ -2118,10 +2106,11 @@ object JsonCodecMaker {
21182106 }
21192107
21202108 def genWriteVal (m : Tree , types : List [Type ], isStringified : Boolean , discriminator : Tree ): Tree = {
2109+ checkRecursionInTypes(types)
21212110 val tpe = types.head
21222111 lazy val methodKey = MethodKey (tpe, isStringified && (isCollection(tpe) || isOption(tpe, types.tail)), discriminator)
21232112 lazy val encodeMethodName = encodeMethodNames.get(methodKey)
2124- val implValueCodec = findImplicitValueCodec(types )
2113+ val implValueCodec = findImplicitValueCodec(tpe )
21252114 if (implValueCodec.nonEmpty) q " $implValueCodec.encodeValue( $m, out) "
21262115 else if (tpe =:= typeOf[String ]) q " out.writeVal( $m) "
21272116 else if (tpe =:= definitions.BooleanTpe || tpe =:= typeOf[java.lang.Boolean ] || tpe =:= definitions.ByteTpe ||
@@ -2341,7 +2330,7 @@ object JsonCodecMaker {
23412330 x
23422331 } """
23432332 if (c.settings.contains(" print-codecs" ) ||
2344- inferImplicitValue (tq " _root_. com.github.plokhotnyuk.jsoniter_scala.macros.CodecMakerConfig.PrintCodec" ) != EmptyTree ) {
2333+ summon (tq " com.github.plokhotnyuk.jsoniter_scala.macros.CodecMakerConfig.PrintCodec " ) != EmptyTree ) {
23452334 c.info(c.enclosingPosition, s " Generated JSON codec for type ' $rootTpe': \n ${showCode(codec)}" , force = true )
23462335 }
23472336 c.Expr [JsonValueCodec [A ]](codec)
0 commit comments