fix: type erasure breaking nested generics (#285)
This commit is contained in:
@ -13,6 +13,7 @@ import kotlin.reflect.KProperty
|
||||
import kotlin.reflect.KType
|
||||
import kotlin.reflect.KTypeParameter
|
||||
import kotlin.reflect.KTypeProjection
|
||||
import kotlin.reflect.full.createType
|
||||
import kotlin.reflect.full.memberProperties
|
||||
import kotlin.reflect.full.primaryConstructor
|
||||
|
||||
@ -22,9 +23,12 @@ object SimpleObjectHandler {
|
||||
// cache[type.getSimpleSlug()] = ReferenceDefinition("RECURSION_PLACEHOLDER")
|
||||
val typeMap = clazz.typeParameters.zip(type.arguments).toMap()
|
||||
val props = clazz.memberProperties.associate { prop ->
|
||||
val schema = when (typeMap.containsKey(prop.returnType.classifier)) {
|
||||
true -> handleGenericProperty(prop, typeMap, cache)
|
||||
false -> handleProperty(prop, cache)
|
||||
val schema = when (prop.needsToInjectGenerics(typeMap)) {
|
||||
true -> handleNestedGenerics(typeMap, prop, cache)
|
||||
false -> when (typeMap.containsKey(prop.returnType.classifier)) {
|
||||
true -> handleGenericProperty(prop, typeMap, cache)
|
||||
false -> handleProperty(prop, cache)
|
||||
}
|
||||
}
|
||||
|
||||
prop.name to schema
|
||||
@ -48,6 +52,34 @@ object SimpleObjectHandler {
|
||||
}
|
||||
}
|
||||
|
||||
private fun KProperty<*>.needsToInjectGenerics(
|
||||
typeMap: Map<KTypeParameter, KTypeProjection>
|
||||
): Boolean {
|
||||
val typeSymbols = returnType.arguments.map { it.type.toString() }
|
||||
return typeMap.any { (k, _) -> typeSymbols.contains(k.name) }
|
||||
}
|
||||
|
||||
private fun handleNestedGenerics(
|
||||
typeMap: Map<KTypeParameter, KTypeProjection>,
|
||||
prop: KProperty<*>,
|
||||
cache: MutableMap<String, JsonSchema>
|
||||
): JsonSchema {
|
||||
val propClass = prop.returnType.classifier as KClass<*>
|
||||
val types = prop.returnType.arguments.map {
|
||||
val typeSymbol = it.type.toString()
|
||||
typeMap.filterKeys { k -> k.name == typeSymbol }.values.first()
|
||||
}
|
||||
val constructedType = propClass.createType(types)
|
||||
return SchemaGenerator.fromTypeToSchema(constructedType, cache).let {
|
||||
if (it is TypeDefinition && it.type == "object") {
|
||||
cache[constructedType.getSimpleSlug()] = it
|
||||
ReferenceDefinition(prop.returnType.getReferenceSlug())
|
||||
} else {
|
||||
it
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleGenericProperty(
|
||||
prop: KProperty<*>,
|
||||
typeMap: Map<KTypeParameter, KTypeProjection>,
|
||||
|
Reference in New Issue
Block a user