|
1 | 1 | package com.papsign.ktor.openapigen.modules.schema |
2 | 2 |
|
3 | 3 | import com.papsign.kotlin.reflection.getKType |
| 4 | +import com.papsign.kotlin.reflection.toInvariantFlexibleProjection |
4 | 5 | import com.papsign.kotlin.reflection.toKType |
5 | 6 | import com.papsign.ktor.openapigen.classLogger |
6 | 7 | import com.papsign.ktor.openapigen.openapi.Schema |
7 | 8 | import kotlin.reflect.KType |
| 9 | +import kotlin.reflect.KTypeParameter |
8 | 10 | import kotlin.reflect.KVisibility |
9 | 11 | import kotlin.reflect.full.declaredMemberProperties |
10 | 12 | import kotlin.reflect.full.isSubclassOf |
11 | 13 | import kotlin.reflect.full.starProjectedType |
| 14 | +import kotlin.reflect.full.withNullability |
12 | 15 | import kotlin.reflect.jvm.jvmErasure |
13 | 16 |
|
14 | 17 | open class SimpleSchemaRegistrar(val namer: SchemaNamer) : SchemaRegistrar { |
@@ -52,17 +55,23 @@ open class SimpleSchemaRegistrar(val namer: SchemaNamer) : SchemaRegistrar { |
52 | 55 |
|
53 | 56 | private fun SchemaRegistrar.makeObjectSchema(type: KType): Schema<*> { |
54 | 57 | val erasure = type.jvmErasure |
| 58 | + val typeParameters = erasure.typeParameters.zip(type.arguments).associate { Pair(it.first.name, it.second.type) } |
55 | 59 | if (erasure.isSealed) { |
56 | 60 | return Schema.OneSchemaOf(erasure.sealedSubclasses.map { get(it.starProjectedType).schema }) |
57 | 61 | } |
58 | | - val props = erasure.declaredMemberProperties.filter { it.visibility == KVisibility.PUBLIC } |
59 | | - val properties = props.associate { |
60 | | - Pair(it.name, get(it.returnType).schema) |
61 | | - } |
| 62 | + val props = erasure.declaredMemberProperties.filter { it.visibility == KVisibility.PUBLIC }.associateWith { |
| 63 | + val retType = it.returnType |
| 64 | + when(val classifier = retType.classifier) { |
| 65 | + is KTypeParameter -> typeParameters[classifier.name] ?: it.returnType |
| 66 | + else -> it.returnType |
| 67 | + } } |
| 68 | + val properties = props.map { (key, value) -> |
| 69 | + Pair(key.name, get(value.withNullability(false)).schema) |
| 70 | + }.associate { it } |
62 | 71 | if (properties.isEmpty()) log.warn("No public properties found in object $type") |
63 | 72 | return Schema.SchemaObj<Any>( |
64 | 73 | properties, |
65 | | - props.filter { !it.returnType.isMarkedNullable }.map { it.name }) |
| 74 | + props.filterValues { value -> !value.isMarkedNullable }.map { it.key.name }) |
66 | 75 | } |
67 | 76 |
|
68 | 77 | private fun SchemaRegistrar.makeMapSchema(type: KType): Schema<*> { |
|
0 commit comments