Skip to content

Commit 37453e0

Browse files
authored
Merge pull request #13 from papsign/experimental-parameters
Experimental parameters
2 parents 5acd9fa + 486ba71 commit 37453e0

File tree

81 files changed

+1694
-118
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

81 files changed

+1694
-118
lines changed

build.gradle

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,6 @@ dependencies {
1818
implementation "io.ktor:ktor-metrics:$ktor_version"
1919
implementation "io.ktor:ktor-server-sessions:$ktor_version"
2020

21-
// needed for oauth interop
22-
implementation "io.ktor:ktor-auth:$ktor_version"
23-
implementation "io.ktor:ktor-client-core:$ktor_version"
24-
implementation "io.ktor:ktor-client-core-jvm:$ktor_version"
25-
implementation "io.ktor:ktor-client-apache:$ktor_version"
26-
// ------------------------
27-
2821
implementation "io.ktor:ktor-jackson:$ktor_version" // needed for parameter parsing and multipart parsing
2922
implementation "com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.9.8" // needed for multipart parsing
3023
implementation 'org.webjars:swagger-ui:3.18.2'
@@ -37,10 +30,11 @@ dependencies {
3730
}
3831

3932
compileKotlin {
40-
kotlinOptions.jvmTarget = "1.8"
33+
kotlinOptions.jvmTarget = "1.6"
34+
kotlinOptions.freeCompilerArgs += ["-Xuse-experimental=kotlin.ExperimentalStdlibApi"]
4135
}
4236
compileTestKotlin {
43-
kotlinOptions.jvmTarget = "1.8"
37+
kotlinOptions.jvmTarget = "1.6"
4438
}
4539

4640
wrapper {
Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1+
#Mon Mar 02 14:17:20 CET 2020
2+
distributionUrl=https\://services.gradle.org/distributions/gradle-6.0.1-all.zip
13
distributionBase=GRADLE_USER_HOME
24
distributionPath=wrapper/dists
3-
distributionUrl=https\://services.gradle.org/distributions/gradle-6.0.1-bin.zip
4-
zipStoreBase=GRADLE_USER_HOME
55
zipStorePath=wrapper/dists
6+
zipStoreBase=GRADLE_USER_HOME

src/main/kotlin/com/papsign/kotlin/reflection/Reflection.kt

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import kotlin.reflect.*
55
import kotlin.reflect.full.createType
66
import kotlin.reflect.full.declaredMemberProperties
77
import kotlin.reflect.full.isSubclassOf
8-
import kotlin.reflect.full.withNullability
98
import kotlin.reflect.jvm.jvmErasure
109

1110
val unitKType = getKType<Unit>()
@@ -15,7 +14,8 @@ inline fun <reified T> isNullable(): Boolean {
1514
}
1615

1716
inline fun <reified T> getKType(): KType {
18-
return object : SuperTypeTokenHolder<T>() { }.getKTypeImpl().withNullability(isNullable<T>())
17+
return typeOf<T>()
18+
// return object : SuperTypeTokenHolder<T>() {}.getKTypeImpl().withNullability(isNullable<T>())
1919
}
2020

2121
// TODO: Lobby for a real kotlin ::type for types because the status quo sucks
@@ -24,7 +24,7 @@ inline fun <reified T> getKType(): KType {
2424
open class SuperTypeTokenHolder<T>
2525

2626
fun SuperTypeTokenHolder<*>.getKTypeImpl(): KType =
27-
javaClass.genericSuperclass.toKType().arguments.single().type!!
27+
javaClass.genericSuperclass.toKType().arguments.single().type!!
2828

2929
fun KClass<*>.toInvariantFlexibleProjection(arguments: List<KTypeProjection> = emptyList()): KTypeProjection {
3030
// TODO: there should be an API in kotlin-reflect which creates KType instances corresponding to flexible types
@@ -41,13 +41,15 @@ fun Type.toKTypeProjection(): KTypeProjection = when (this) {
4141
is Class<*> -> this.kotlin.toInvariantFlexibleProjection()
4242
is ParameterizedType -> {
4343
val erasure = (rawType as Class<*>).kotlin
44-
erasure.toInvariantFlexibleProjection((erasure.typeParameters.zip(actualTypeArguments).map { (parameter, argument) ->
45-
val projection = argument.toKTypeProjection()
46-
projection.takeIf {
47-
// Get rid of use-site projections on arguments, where the corresponding parameters already have a declaration-site projection
48-
parameter.variance == KVariance.INVARIANT || parameter.variance != projection.variance
49-
} ?: KTypeProjection.invariant(projection.type!!)
50-
}))
44+
erasure.toInvariantFlexibleProjection(
45+
(erasure.typeParameters.zip(actualTypeArguments).map { (parameter, argument) ->
46+
val projection = argument.toKTypeProjection()
47+
projection.takeIf {
48+
// Get rid of use-site projections on arguments, where the corresponding parameters already have a declaration-site projection
49+
parameter.variance == KVariance.INVARIANT || parameter.variance != projection.variance
50+
} ?: KTypeProjection.invariant(projection.type!!)
51+
})
52+
)
5153
}
5254
is WildcardType -> when {
5355
lowerBounds.isNotEmpty() -> KTypeProjection.contravariant(lowerBounds.single().toKType())
@@ -122,4 +124,4 @@ fun KType.getObjectSubtypes(): Set<KType> {
122124
// println(getKType<Array<Int?>?>())
123125
// println(getKType<Array<Array<String>>>())
124126
// println(getKType<Unit>())
125-
//}
127+
//}
Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,14 @@
11
package com.papsign.ktor.openapigen.annotations.parameters
22

33
import com.papsign.ktor.openapigen.openapi.ParameterLocation
4+
import com.papsign.ktor.openapigen.parameters.PathParamStyle
45

56
@Target(AnnotationTarget.FIELD, AnnotationTarget.PROPERTY, AnnotationTarget.VALUE_PARAMETER)
67
@Retention(AnnotationRetention.RUNTIME)
78
@APIParam(ParameterLocation.path)
8-
annotation class PathParam(val description: String, val required: Boolean = true, val deprecated: Boolean = false)
9+
annotation class PathParam(
10+
val description: String,
11+
val style: PathParamStyle = PathParamStyle.simple,
12+
val explode: Boolean = false,
13+
val deprecated: Boolean = false
14+
)
Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,15 @@
11
package com.papsign.ktor.openapigen.annotations.parameters
22

33
import com.papsign.ktor.openapigen.openapi.ParameterLocation
4+
import com.papsign.ktor.openapigen.parameters.QueryParamStyle
45

56
@Target(AnnotationTarget.FIELD, AnnotationTarget.PROPERTY, AnnotationTarget.VALUE_PARAMETER)
67
@Retention(AnnotationRetention.RUNTIME)
78
@APIParam(ParameterLocation.query)
8-
annotation class QueryParam(val description: String, val allowEmptyValues: Boolean = false, val required: Boolean = true, val deprecated: Boolean = false)
9+
annotation class QueryParam(
10+
val description: String,
11+
val style: QueryParamStyle = QueryParamStyle.form,
12+
val explode: Boolean = true,
13+
val allowEmptyValues: Boolean = false,
14+
val deprecated: Boolean = false
15+
)

src/main/kotlin/com/papsign/ktor/openapigen/generator/ParamBuilder.kt

Lines changed: 0 additions & 55 deletions
This file was deleted.

src/main/kotlin/com/papsign/ktor/openapigen/modules/handlers/RequestHandlerModule.kt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import com.papsign.ktor.openapigen.classLogger
77
import com.papsign.ktor.openapigen.content.type.BodyParser
88
import com.papsign.ktor.openapigen.content.type.ContentTypeProvider
99
import com.papsign.ktor.openapigen.content.type.SelectedParser
10-
import com.papsign.ktor.openapigen.generator.ParamBuilder
1110
import com.papsign.ktor.openapigen.modules.ModuleProvider
1211
import com.papsign.ktor.openapigen.modules.ofClass
1312
import com.papsign.ktor.openapigen.modules.openapi.OperationModule
@@ -36,7 +35,7 @@ class RequestHandlerModule<T : Any>(
3635

3736
val requestMeta = requestClass.findAnnotation<Request>()
3837

39-
val parameters = provider.ofClass<ParameterProvider>().flatMap { it.getParameters(ParamBuilder(apiGen, provider)) }
38+
val parameters = provider.ofClass<ParameterProvider>().flatMap { it.getParameters(apiGen, provider) }
4039
operation.parameters = operation.parameters?.let { (it + parameters).distinct() } ?: parameters
4140
operation.requestBody = operation.requestBody?.apply {
4241
map.forEach { (key, value) ->

src/main/kotlin/com/papsign/ktor/openapigen/modules/handlers/RouteHandler.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ object RouteHandler: HandlerModule {
2121
val methods = provider.ofClass<MethodProvider>()
2222
if (methods.size > 1) error("API cannot have two methods simultaneously: ${methods.map { it.method.value }}")
2323
val paths = provider.ofClass<PathProvider>()
24-
val path = "/${paths.map { it.path.trim('/') }.filter { it.isNotBlank() }.joinToString("/")}"
24+
val path = "/${paths.flatMap { it.path.split('/').filter(String::isNotEmpty) }.joinToString("/")}"
2525
val operationModules = provider.ofClass<OperationModule>()
2626
apiGen.api.paths.getOrPut(path) { PathItem() }.also {pathItem ->
2727
methods.forEach {

src/main/kotlin/com/papsign/ktor/openapigen/modules/openapi/HandlerModule.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,4 @@ import com.papsign.ktor.openapigen.modules.OpenAPIModule
66

77
interface HandlerModule: OpenAPIModule {
88
fun configure(apiGen: OpenAPIGen, provider: ModuleProvider<*>)
9-
}
9+
}
Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
package com.papsign.ktor.openapigen.modules.providers
22

3-
import com.papsign.ktor.openapigen.generator.ParamBuilder
3+
import com.papsign.ktor.openapigen.OpenAPIGen
4+
import com.papsign.ktor.openapigen.modules.ModuleProvider
45
import com.papsign.ktor.openapigen.modules.OpenAPIModule
56
import com.papsign.ktor.openapigen.openapi.Parameter
67

78
interface ParameterProvider: OpenAPIModule {
8-
fun getParameters(builder: ParamBuilder): List<Parameter<*>>
9-
}
9+
fun getParameters(apiGen: OpenAPIGen, provider: ModuleProvider<*>): List<Parameter<*>>
10+
}

0 commit comments

Comments
 (0)