Skip to content

Commit b7ec43b

Browse files
committed
address most warnings
1 parent a88f37d commit b7ec43b

File tree

3 files changed

+77
-73
lines changed

3 files changed

+77
-73
lines changed

core/src/main/kotlin/com/fractalwrench/json2kotlin/JsonProcessor.kt

Lines changed: 0 additions & 66 deletions
This file was deleted.
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
package com.fractalwrench.json2kotlin
2+
3+
import com.google.gson.JsonElement
4+
import com.squareup.kotlinpoet.*
5+
import java.util.*
6+
7+
/**
8+
* Finds distinct types for a collection of fields.
9+
*/
10+
internal class TypeReducer(private val typeDetector: JsonTypeDetector) {
11+
12+
fun findDistinctTypes(fields: Collection<String>,
13+
commonElements: List<TypedJsonElement>,
14+
jsonElementMap: HashMap<JsonElement, TypeSpec>): Map<String, TypeName> {
15+
val fieldMap = HashMap<String, TypeName>()
16+
17+
fields.forEach {
18+
val distinctTypes = findDistinctTypesForField(commonElements, it, jsonElementMap)
19+
fieldMap.put(it, reduceToSingleType(distinctTypes))
20+
}
21+
return fieldMap
22+
}
23+
24+
private fun findDistinctTypesForField(commonElements: List<TypedJsonElement>,
25+
key: String,
26+
jsonElementMap: HashMap<JsonElement, TypeSpec>): List<TypeName?> {
27+
return commonElements.map {
28+
val fieldValue = it.asJsonObject.get(key)
29+
if (fieldValue != null) {
30+
typeDetector.typeForJsonElement(fieldValue, key, jsonElementMap)
31+
} else {
32+
null
33+
}
34+
}.distinct()
35+
}
36+
37+
/**
38+
* Determines a single type which fits multiple types.
39+
*/
40+
private fun reduceToSingleType(types: List<TypeName?>): TypeName {
41+
val anyClz = Any::class.asTypeName()
42+
val nullableClassName = anyClz.asNullable()
43+
val nullable = types.contains(nullableClassName) || types.contains(null)
44+
val nonNullTypes = types.filterNotNull().filter { it != nullableClassName }
45+
46+
val typeName: TypeName = when {
47+
nonNullTypes.size == 1 -> nonNullTypes[0]
48+
nonNullTypes.size == 2 -> reduceMultipleTypes(nonNullTypes, anyClz)
49+
else -> anyClz
50+
}
51+
return if (nullable) typeName.asNullable() else typeName
52+
}
53+
54+
private fun reduceMultipleTypes(nonNullTypes: List<TypeName>, anyClz: ClassName): TypeName {
55+
val parameterizedTypeName
56+
= nonNullTypes.filterIsInstance(ParameterizedTypeName::class.java).firstOrNull()
57+
58+
return when {
59+
parameterizedTypeName != null -> { // handle type params (recursive)
60+
val rawType = parameterizedTypeName.rawType
61+
parameterizedTypeName.typeArguments
62+
ParameterizedTypeName.get(rawType, reduceToSingleType(parameterizedTypeName.typeArguments))
63+
}
64+
nonNullTypes.contains(anyClz) -> // Any will be an empty/missing object
65+
nonNullTypes.filterNot { it == anyClz }.first()
66+
else -> anyClz
67+
}
68+
}
69+
70+
}

core/src/main/kotlin/com/fractalwrench/json2kotlin/TypeSpecGenerator.kt

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.fractalwrench.json2kotlin
22

3+
import com.google.gson.JsonElement
34
import com.squareup.kotlinpoet.*
45
import java.util.*
56

@@ -9,7 +10,8 @@ import java.util.*
910
internal class TypeSpecGenerator(private val delegate: SourceBuildDelegate,
1011
groupingStrategy: GroupingStrategy) {
1112

12-
private val jsonProcessor = JsonProcessor(JsonTypeDetector())
13+
private val jsonElementMap = HashMap<JsonElement, TypeSpec>()
14+
private val typeReducer = TypeReducer(JsonTypeDetector())
1315
private val jsonFieldGrouper = JsonFieldGrouper(groupingStrategy)
1416

1517
/**
@@ -69,11 +71,9 @@ internal class TypeSpecGenerator(private val delegate: SourceBuildDelegate,
6971
it.toKotlinIdentifier().toLowerCase()
7072
}).build()
7173

72-
// FIXME encapsulation broken from this point
73-
return commonElements.filterNot {
74-
// reuse any types which already exist in the map
75-
val containsValue = jsonProcessor.jsonElementMap.containsValue(classType)
76-
jsonProcessor.jsonElementMap.put(it.jsonElement, classType)
74+
return commonElements.filterNot { // reuse any types which already exist in the map
75+
val containsValue = jsonElementMap.containsValue(classType)
76+
jsonElementMap.put(it.jsonElement, classType)
7777
containsValue
7878
}.map { classType }
7979
}
@@ -87,7 +87,7 @@ internal class TypeSpecGenerator(private val delegate: SourceBuildDelegate,
8787
val constructor = FunSpec.constructorBuilder()
8888

8989
if (fields.isNotEmpty()) {
90-
val fieldTypeMap = jsonProcessor.findDistinctTypesForFields(fields, commonElements)
90+
val fieldTypeMap = typeReducer.findDistinctTypes(fields, commonElements, jsonElementMap)
9191
fields.forEach {
9292
buildProperty(it, fieldTypeMap, commonElements, classBuilder, constructor)
9393
}

0 commit comments

Comments
 (0)