|
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