@@ -750,8 +750,7 @@ object JsonCodecMaker {
750
750
case TypeRef (SingleType (_, enumSymbol), _, _) => enumSymbol
751
751
}
752
752
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." )
755
754
756
755
def isImmutableArraySeq (tpe : Type ): Boolean =
757
756
isScala213 && tpe.typeSymbol.fullName == " scala.collection.immutable.ArraySeq"
@@ -762,45 +761,30 @@ object JsonCodecMaker {
762
761
def isCollisionProofHashMap (tpe : Type ): Boolean =
763
762
isScala213 && tpe.typeSymbol.fullName == " scala.collection.mutable.CollisionProofHashMap"
764
763
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)
780
765
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) {
785
767
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." )
790
775
}
791
776
}
792
777
793
- val inferredValueCodecs = mutable.Map .empty[Type , Tree ]
778
+ val rootTpe = weakTypeOf[A ].dealias
779
+ val inferredKeyCodecs = mutable.Map [Type , Tree ]((rootTpe, EmptyTree ))
794
780
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] " ))
804
788
805
789
val mathContexts = new mutable.LinkedHashMap [Int , (TermName , Tree )]
806
790
@@ -990,8 +974,9 @@ object JsonCodecMaker {
990
974
}
991
975
992
976
def genReadKey (types : List [Type ]): Tree = {
977
+ checkRecursionInTypes(types)
993
978
val tpe = types.head
994
- val implKeyCodec = findImplicitKeyCodec(types )
979
+ val implKeyCodec = findImplicitKeyCodec(tpe )
995
980
if (implKeyCodec.nonEmpty) q " $implKeyCodec.decodeKey(in) "
996
981
else if (tpe =:= typeOf[String ]) q " in.readKeyAsString() "
997
982
else if (tpe =:= definitions.BooleanTpe || tpe =:= typeOf[java.lang.Boolean ]) q " in.readKeyAsBoolean() "
@@ -1181,8 +1166,9 @@ object JsonCodecMaker {
1181
1166
1182
1167
@ tailrec
1183
1168
def genWriteKey (x : Tree , types : List [Type ]): Tree = {
1169
+ checkRecursionInTypes(types)
1184
1170
val tpe = types.head
1185
- val implKeyCodec = findImplicitKeyCodec(types )
1171
+ val implKeyCodec = findImplicitKeyCodec(tpe )
1186
1172
if (implKeyCodec.nonEmpty) q " $implKeyCodec.encodeKey( $x, out) "
1187
1173
else if (tpe =:= typeOf[String ] || tpe =:= definitions.BooleanTpe || tpe =:= typeOf[java.lang.Boolean ] ||
1188
1174
tpe =:= definitions.ByteTpe || tpe =:= typeOf[java.lang.Byte ] || tpe =:= definitions.CharTpe ||
@@ -1420,8 +1406,9 @@ object JsonCodecMaker {
1420
1406
}
1421
1407
1422
1408
def genNullValue (types : List [Type ]): Tree = {
1409
+ checkRecursionInTypes(types)
1423
1410
val tpe = types.head
1424
- val implValueCodec = findImplicitValueCodec(types )
1411
+ val implValueCodec = findImplicitValueCodec(tpe )
1425
1412
if (implValueCodec.nonEmpty) q " $implValueCodec.nullValue "
1426
1413
else if (tpe =:= typeOf[String ]) q " null "
1427
1414
else if (tpe =:= definitions.BooleanTpe || tpe =:= typeOf[java.lang.Boolean ]) q " false "
@@ -1622,10 +1609,11 @@ object JsonCodecMaker {
1622
1609
else q " x += ${genReadVal(types, genNullValue(types), isStringified, EmptyTree )}"
1623
1610
1624
1611
def genReadVal (types : List [Type ], default : Tree , isStringified : Boolean , discriminator : Tree ): Tree = {
1612
+ checkRecursionInTypes(types)
1625
1613
val tpe = types.head
1626
1614
lazy val methodKey = MethodKey (tpe, isStringified && (isCollection(tpe) || isOption(tpe, types.tail)), discriminator)
1627
1615
lazy val decodeMethodName = decodeMethodNames.get(methodKey)
1628
- val implValueCodec = findImplicitValueCodec(types )
1616
+ val implValueCodec = findImplicitValueCodec(tpe )
1629
1617
if (implValueCodec.nonEmpty) q " $implValueCodec.decodeValue(in, $default) "
1630
1618
else if (tpe =:= typeOf[String ]) q " in.readString( $default) "
1631
1619
else if (tpe =:= definitions.BooleanTpe || tpe =:= typeOf[java.lang.Boolean ]) {
@@ -2118,10 +2106,11 @@ object JsonCodecMaker {
2118
2106
}
2119
2107
2120
2108
def genWriteVal (m : Tree , types : List [Type ], isStringified : Boolean , discriminator : Tree ): Tree = {
2109
+ checkRecursionInTypes(types)
2121
2110
val tpe = types.head
2122
2111
lazy val methodKey = MethodKey (tpe, isStringified && (isCollection(tpe) || isOption(tpe, types.tail)), discriminator)
2123
2112
lazy val encodeMethodName = encodeMethodNames.get(methodKey)
2124
- val implValueCodec = findImplicitValueCodec(types )
2113
+ val implValueCodec = findImplicitValueCodec(tpe )
2125
2114
if (implValueCodec.nonEmpty) q " $implValueCodec.encodeValue( $m, out) "
2126
2115
else if (tpe =:= typeOf[String ]) q " out.writeVal( $m) "
2127
2116
else if (tpe =:= definitions.BooleanTpe || tpe =:= typeOf[java.lang.Boolean ] || tpe =:= definitions.ByteTpe ||
@@ -2341,7 +2330,7 @@ object JsonCodecMaker {
2341
2330
x
2342
2331
} """
2343
2332
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 ) {
2345
2334
c.info(c.enclosingPosition, s " Generated JSON codec for type ' $rootTpe': \n ${showCode(codec)}" , force = true )
2346
2335
}
2347
2336
c.Expr [JsonValueCodec [A ]](codec)
0 commit comments