@@ -9,7 +9,9 @@ import java.util.HashSet
99
1010internal class JsonTypeDetector {
1111
12- internal fun typeForJsonField (jsonElement : JsonElement , key : String , jsonElementMap : Map <JsonElement , TypeSpec >): TypeName {
12+ internal fun typeForJsonField (jsonElement : JsonElement ,
13+ key : String ,
14+ jsonElementMap : Map <JsonElement , TypeSpec >): TypeName {
1315 with (jsonElement) {
1416 return when {
1517 isJsonPrimitive -> typeForJsonPrimitive(asJsonPrimitive)
@@ -21,7 +23,7 @@ internal class JsonTypeDetector {
2123 }
2224 }
2325
24- internal fun typeForJsonPrimitive (primitive : JsonPrimitive ): TypeName {
26+ private fun typeForJsonPrimitive (primitive : JsonPrimitive ): TypeName {
2527 return when {
2628 primitive.isBoolean -> Boolean ::class
2729 primitive.isNumber -> Number ::class
@@ -30,41 +32,48 @@ internal class JsonTypeDetector {
3032 }.asTypeName()
3133 }
3234
33-
34- // FIXME feels really messy from here on out
35-
36-
37- internal fun typeForJsonObject (jsonObject : JsonObject , key : String , jsonElementMap : Map <JsonElement , TypeSpec >): TypeName {
35+ private fun typeForJsonObject (jsonObject : JsonObject ,
36+ key : String ,
37+ jsonElementMap : Map <JsonElement , TypeSpec >): TypeName {
3838 val existingTypeName = jsonElementMap[jsonObject]
39- if (existingTypeName != null ) {
40- return ClassName .bestGuess(existingTypeName.name!! )
41- }
42-
43- val identifier = key.toKotlinIdentifier().capitalize()
39+ val identifier = existingTypeName?.name ? : key.toKotlinIdentifier().capitalize()
4440 return ClassName .bestGuess(identifier)
4541 }
4642
47- internal fun typeForJsonArray (jsonArray : JsonArray , key : String , jsonElementMap : Map <JsonElement , TypeSpec >): TypeName {
43+ private fun typeForJsonArray (jsonArray : JsonArray ,
44+ key : String ,
45+ jsonElementMap : Map <JsonElement , TypeSpec >): TypeName {
46+ val pair = findAllArrayTypes(jsonArray, key, jsonElementMap)
47+ val arrayTypes = pair.first
48+ val nullable = pair.second
49+ val arrayType = deduceArrayType(arrayTypes, nullable)
50+ return ParameterizedTypeName .get(Array <Any >::class .asClassName(), arrayType)
51+ }
52+
53+ private fun findAllArrayTypes (jsonArray : JsonArray ,
54+ key : String ,
55+ jsonElementMap : Map <JsonElement , TypeSpec >): Pair <HashSet <TypeName >, Boolean> {
4856 val arrayTypes = HashSet <TypeName >()
4957 var nullable = false
5058
5159 jsonArray.withIndex().forEach {
5260 val sanitisedName = key.toKotlinIdentifier()
61+ val fieldKey = nameForArrayField(it.index, sanitisedName)
62+
5363 with (it.value) {
5464 when {
5565 isJsonPrimitive -> arrayTypes.add(typeForJsonPrimitive(asJsonPrimitive))
56- isJsonArray -> arrayTypes.add(typeForJsonArray(asJsonArray, nameForArrayField(it.index, sanitisedName) , jsonElementMap))
57- isJsonObject -> arrayTypes.add(typeForJsonObject(asJsonObject, nameForArrayField(it.index, sanitisedName) , jsonElementMap))
66+ isJsonArray -> arrayTypes.add(typeForJsonArray(asJsonArray, fieldKey , jsonElementMap))
67+ isJsonObject -> arrayTypes.add(typeForJsonObject(asJsonObject, fieldKey , jsonElementMap))
5868 isJsonNull -> nullable = true
5969 else -> throw IllegalStateException (" Unexpected state in array" )
6070 }
6171 }
6272 }
63- val arrayType = deduceArrayType(arrayTypes, nullable)
64- return ParameterizedTypeName .get(Array <Any >::class .asClassName(), arrayType)
73+ return Pair (arrayTypes, nullable)
6574 }
6675
67- internal fun deduceArrayType (arrayTypes : HashSet <TypeName >, nullable : Boolean ): TypeName {
76+ private fun deduceArrayType (arrayTypes : HashSet <TypeName >, nullable : Boolean ): TypeName {
6877 val hasMultipleType = arrayTypes.size > 1 || arrayTypes.isEmpty()
6978 val arrayTypeName = when {
7079 hasMultipleType -> Any ::class .asTypeName()
0 commit comments