Skip to content

Commit

Permalink
Optimize code generation (#550)
Browse files Browse the repository at this point in the history
  • Loading branch information
Foso authored May 18, 2024
1 parent 5959774 commit bc761da
Show file tree
Hide file tree
Showing 39 changed files with 165 additions and 125 deletions.
5 changes: 5 additions & 0 deletions docs/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ and this project orients towards [Semantic Versioning](http://semver.org/spec/v2
Note: This project needs KSP to work and every new Ktorfit with an update of the KSP version is technically a breaking change.
But there is no intent to bump the Ktorfit major version for every KSP update.

2.0.0-beta2 - 2024-05-16
========================================
- Build with KSP 1.0.20, Kotlin 2.0.0-RC3, Ktor 2.3.11
- Optimize code generation

2.0.0-beta1 - 2024-04-28
========================================
### Breaking Changes
Expand Down
8 changes: 4 additions & 4 deletions example/AndroidOnlyExample/app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ plugins {
id("org.jetbrains.kotlin.android")
id("com.google.devtools.ksp") version "1.9.23-1.0.20"
id("org.jetbrains.kotlin.plugin.serialization") version "1.9.23"
id("de.jensklingenberg.ktorfit") version "2.0.0-beta1"
id("de.jensklingenberg.ktorfit") version "2.0.0-beta2-SNAPSHOT"
}


Expand Down Expand Up @@ -51,7 +51,7 @@ tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile>().configureEach
}
}

val ktorfit = "2.0.0-beta1"
val ktorfit = "2.0.0-beta2-SNAPSHOT"
val ktor = "2.3.10"
val compose_ui_version = "1.5.1"
dependencies {
Expand All @@ -65,8 +65,8 @@ dependencies {
implementation("de.jensklingenberg.ktorfit:ktorfit-converters-flow:$ktorfit")


implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.6.2")
implementation("androidx.activity:activity-compose:1.8.0")
implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.8.0")
implementation("androidx.activity:activity-compose:1.9.0")
implementation("androidx.compose.ui:ui:$compose_ui_version")
implementation("androidx.compose.ui:ui-tooling-preview:$compose_ui_version")
implementation("androidx.compose.material:material:1.5.2")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ val ktorfit = ktorfit {
)

}
val api: StarWarsApi = ktorfit.create<StarWarsApi>()

class MainActivity : ComponentActivity() {

Expand All @@ -59,7 +58,7 @@ class MainActivity : ComponentActivity() {
}

lifecycleScope.launch {
peopleState.value = api.getPerson(1)
peopleState.value = ktorfit.create<StarWarsApi>().getPerson(1)
}
}
}
4 changes: 2 additions & 2 deletions example/MultiplatformExample/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ buildscript {
}
}
dependencies {
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.23")
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:2.0.0-RC3")
classpath("com.android.tools.build:gradle:7.3.1")
classpath("org.jetbrains.kotlin:kotlin-serialization:1.9.23")
classpath("org.jetbrains.kotlin:kotlin-serialization:2.0.0-RC3")

}
}
Expand Down
6 changes: 3 additions & 3 deletions example/MultiplatformExample/shared/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@ plugins {
kotlin("multiplatform")
kotlin("native.cocoapods")
id("com.android.library")
id("com.google.devtools.ksp") version "1.9.23-1.0.20"
id("com.google.devtools.ksp") version "2.0.0-RC3-1.0.20"
id("kotlinx-serialization")
id("de.jensklingenberg.ktorfit") version "2.0.0-beta1"
id("de.jensklingenberg.ktorfit") version "2.0.0-beta2-SNAPSHOT"
}

version = "1.0"
val ktorVersion = "2.3.10"
val ktorfitVersion = "2.0.0-beta1"
val ktorfitVersion = "2.0.0-beta2-SNAPSHOT"

kotlin {
jvmToolchain(8)
Expand Down
18 changes: 12 additions & 6 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,23 @@
autoService = "1.1.1"
autoServiceKsp = "1.10"
binaryCompatibilityValidator = "0.13.2"
coroutines = "1.7.3"
coroutines = "1.8.0"
detekt = "1.23.6"
junit = "4.13.2"
kctfork = "0.4.1"
kotlin = "2.0.0-RC1"
kotlin = "2.0.0-RC3"
kotlinPoet = "1.16.0"
kspVersion = "2.0.0-RC1-1.0.20"
ktorfit = "2.0.0-beta1"
kspVersion = "2.0.0-RC3-1.0.20"
ktorfit = "2.0.0-beta2-SNAPSHOT"
ktorfitKsp = "2.0.0-beta2-SNAPSHOT"
ktorfitCompiler = "2.0.0-beta2-SNAPSHOT"
ktorfitCallConverter = "2.0.0-beta2-SNAPSHOT"
ktorfitFlowConverter = "2.0.0-beta2-SNAPSHOT"
ktorfitResponseConverter = "2.0.0-beta2-SNAPSHOT"

ktorfitGradlePlugin = "1.14.0"
ktorVersion = "2.3.10"
mockk = "1.13.10"
ktorVersion = "2.3.11"
mockk = "1.13.8"
mockito-kotlin = "4.1.0"
gradleMavenPublishPlugin = "0.25.3"
vannikMavenPublish = "0.25.3"
Expand Down
2 changes: 1 addition & 1 deletion ktorfit-compiler-plugin/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ licensee {
}

mavenPublishing {
coordinates("de.jensklingenberg.ktorfit", "compiler-plugin", libs.versions.ktorfit.get())
coordinates("de.jensklingenberg.ktorfit", "compiler-plugin", libs.versions.ktorfitCompiler.get())
publishToMavenCentral()
// publishToMavenCentral(SonatypeHost.S01) for publishing through s01.oss.sonatype.org
if (enableSigning) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ class CreateFuncTransformer(
val implClassSymbol = pluginContext.referenceClass(
ClassId(
FqName(packageName),
Name.identifier("_$className" + "Impl")
Name.identifier("_$className" + "Provider")
)
) ?: throw IllegalStateException(ERROR_IMPL_NOT_FOUND(argumentType.originalKotlinType.toString()))

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,12 @@ class FunctionTransformerTest {
package de.jensklingenberg.ktorfit
class Ktorfit(){
fun <T> create(ktorfitService: KtorfitService? = null): T {
fun <T> create(ktorfitService: ClassProvider<T>? = null): T {
return ktorfitService as T
}
}
interface KtorfitService
class Default : KtorfitService
interface ClassProvider<T>
"""
)
Expand All @@ -41,11 +39,13 @@ class Default : KtorfitService
package com.example.api
import de.jensklingenberg.ktorfit.Ktorfit
import de.jensklingenberg.ktorfit.KtorfitService
import de.jensklingenberg.ktorfit.ClassProvider
interface TestService
class _TestServiceImpl : TestService, KtorfitService
class _TestServiceImpl : TestService{
}
class _TestServiceProvider : ClassProvider<TestService>
class TestClass{
val api = Ktorfit().create<TestService>()
}
Expand All @@ -69,11 +69,9 @@ package de.jensklingenberg.ktorfit
class Ktorfit()
interface KtorfitService
class Default : KtorfitService
interface ClassProvider
fun <T> Ktorfit.create(ktorfitService: KtorfitService = Default()): T {
fun <T> Ktorfit.create(ktorfitService: ClassProvider? = null): T {
return this.create(ktorfitService)
}
Expand All @@ -84,10 +82,12 @@ fun <T> Ktorfit.create(ktorfitService: KtorfitService = Default()): T {
package com.example.api
import de.jensklingenberg.ktorfit.Ktorfit
import de.jensklingenberg.ktorfit.create
import de.jensklingenberg.ktorfit.KtorfitService
import de.jensklingenberg.ktorfit.ClassProvider
interface TestService
class _TestServiceImpl : TestService, KtorfitService
class _TestServiceImpl : TestService{
companion object : ClassProvider
}
class TestClass{
Expand Down
2 changes: 1 addition & 1 deletion ktorfit-converters/call/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ mavenPublishing {
coordinates(
"de.jensklingenberg.ktorfit",
"ktorfit-converters-call",
libs.versions.ktorfit.get()
libs.versions.ktorfitCallConverter.get()
)
publishToMavenCentral()
// publishToMavenCentral(SonatypeHost.S01) for publishing through s01.oss.sonatype.org
Expand Down
2 changes: 1 addition & 1 deletion ktorfit-converters/flow/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ mavenPublishing {
coordinates(
"de.jensklingenberg.ktorfit",
"ktorfit-converters-flow",
libs.versions.ktorfit.get()
libs.versions.ktorfitFlowConverter.get()
)
publishToMavenCentral()
// publishToMavenCentral(SonatypeHost.S01) for publishing through s01.oss.sonatype.org
Expand Down
2 changes: 1 addition & 1 deletion ktorfit-converters/response/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ mavenPublishing {
coordinates(
"de.jensklingenberg.ktorfit",
"ktorfit-converters-response",
libs.versions.ktorfit.get()
libs.versions.ktorfitResponseConverter.get()
)
publishToMavenCentral()
// publishToMavenCentral(SonatypeHost.S01) for publishing through s01.oss.sonatype.org
Expand Down
2 changes: 1 addition & 1 deletion ktorfit-gradle-plugin/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ mavenPublishing {
coordinates(
"de.jensklingenberg.ktorfit",
"ktorfit-gradle-plugin",
libs.versions.ktorfit.get()
libs.versions.ktorfitCompiler.get()
)
publishToMavenCentral()
// publishToMavenCentral(SonatypeHost.S01) for publishing through s01.oss.sonatype.org
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ internal class KtorfitCompilerSubPlugin : KotlinCompilerPluginSupportPlugin {
return SubpluginArtifact(
groupId = SERIALIZATION_GROUP_NAME,
artifactId = ARTIFACT_NAME,
version = "2.0.0-beta1" // remember to bump this version before any release!
version = "2.0.0-beta2-SNAPSHOT" // remember to bump this version before any release!
)
}
}
6 changes: 5 additions & 1 deletion ktorfit-ksp/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,11 @@ tasks.withType<KotlinCompile> {
}

mavenPublishing {
coordinates("de.jensklingenberg.ktorfit", "ktorfit-ksp", libs.versions.ktorfit.get())
coordinates(
"de.jensklingenberg.ktorfit",
"ktorfit-ksp",
libs.versions.ktorfitKsp.get()
)
publishToMavenCentral()
// publishToMavenCentral(SonatypeHost.S01) for publishing through s01.oss.sonatype.org
if (enableSigning) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,16 @@ package de.jensklingenberg.ktorfit.model
import com.google.devtools.ksp.getDeclaredFunctions
import com.google.devtools.ksp.processing.KSPLogger
import com.google.devtools.ksp.processing.Resolver
import com.google.devtools.ksp.symbol.ClassKind
import com.google.devtools.ksp.symbol.KSClassDeclaration
import com.google.devtools.ksp.symbol.KSFile
import com.google.devtools.ksp.symbol.KSPropertyDeclaration
import com.google.devtools.ksp.symbol.KSTypeReference
import com.google.devtools.ksp.symbol.*
import com.squareup.kotlinpoet.*
import com.squareup.kotlinpoet.ParameterizedTypeName.Companion.parameterizedBy
import com.squareup.kotlinpoet.ksp.toKModifier
import com.squareup.kotlinpoet.ksp.toTypeName
import de.jensklingenberg.ktorfit.KtorfitOptions
import de.jensklingenberg.ktorfit.model.KtorfitError.Companion.PROPERTIES_NOT_SUPPORTED
import de.jensklingenberg.ktorfit.model.annotations.FormUrlEncoded
import de.jensklingenberg.ktorfit.model.annotations.Multipart
import de.jensklingenberg.ktorfit.model.annotations.ParameterAnnotation.Field
import de.jensklingenberg.ktorfit.model.annotations.ParameterAnnotation.Part
import de.jensklingenberg.ktorfit.model.annotations.ParameterAnnotation.RequestType
import de.jensklingenberg.ktorfit.model.annotations.ParameterAnnotation.*
import de.jensklingenberg.ktorfit.utils.addImports

/**
Expand Down Expand Up @@ -80,22 +75,44 @@ fun ClassData.getImplClassFileSource(resolver: Resolver, ktorfitOptions: Ktorfit

val implClassName = "_${classData.name}Impl"

val converterProperty =
val helperProperty =
PropertySpec.builder(converterHelper.objectName, converterHelper.toClassName())
.addModifiers(KModifier.LATEINIT, KModifier.OVERRIDE)
.mutable(true)
.initializer("${converterHelper.name}(${ktorfitClass.objectName})")
.addModifiers(KModifier.PRIVATE)
.build()

val implClassSpec = TypeSpec.classBuilder(implClassName)
val companion = TypeSpec.classBuilder("_${classData.name}Provider")
.addModifiers(classData.modifiers)
.addSuperinterface(
exampleInterface.toClassName().parameterizedBy(ClassName(classData.packageName, classData.name))
)
.addFunction(
FunSpec.builder("create")
.returns(ClassName(classData.packageName, classData.name))
.addStatement("return _${classData.name}Impl(${ktorfitClass.objectName})")
.addModifiers(KModifier.OVERRIDE)
.addParameter(ktorfitClass.objectName, ktorfitClass.toClassName())
.build()
)
.build()

.addAnnotation(
optinAnnotation
val implClassSpec = TypeSpec.classBuilder(implClassName)
.primaryConstructor(
FunSpec.constructorBuilder()
.addParameter(ktorfitClass.objectName, ktorfitClass.toClassName())
.build()
)
.addProperty(
PropertySpec.builder(ktorfitClass.objectName, ktorfitClass.toClassName())
.initializer(ktorfitClass.objectName)
.addModifiers(KModifier.PRIVATE)
.build()
)
.addAnnotation(optinAnnotation)
.addModifiers(classData.modifiers)
.addSuperinterface(ClassName(classData.packageName, classData.name))
.addSuperinterface(ktorfitInterface.toClassName())
.addKtorfitSuperInterface(classData.superClasses)
.addProperties(listOf(converterProperty) + properties)
.addProperties(listOf(helperProperty) + properties)
.addFunctions(classData.functions.map { it.toFunSpec(resolver, ktorfitOptions.setQualifiedType) })
.build()

Expand All @@ -104,6 +121,7 @@ fun ClassData.getImplClassFileSource(resolver: Resolver, ktorfitOptions: Ktorfit
.addFileComment("Generated by Ktorfit")
.addImports(classData.imports)
.addType(implClassSpec)
.addType(companion)
.addFunction(createExtensionFunctionSpec)
.build()
.toString()
Expand All @@ -118,7 +136,7 @@ private fun getCreateExtensionFunctionSpec(
val functionName = "create${classData.name}"
return FunSpec.builder(functionName)
.addModifiers(classData.modifiers)
.addStatement("return this.create(_${classData.name}Impl().apply { ${converterHelper.objectName}= ${converterHelper.name}(this@$functionName) })")
.addStatement("return _${classData.name}Impl(this)")
.receiver(ktorfitClass.toClassName())
.returns(ClassName(classData.packageName, classData.name))
.build()
Expand Down Expand Up @@ -233,7 +251,7 @@ private fun TypeSpec.Builder.addKtorfitSuperInterface(superClasses: List<KSTypeR
this.addSuperinterface(
ClassName(superTypePackage, superTypeClassName),
CodeBlock.of(
"%L._%LImpl()",
"%L._%LImpl(${ktorfitClass.objectName})",
superTypePackage,
superTypeClassName
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,12 @@ data class KtorfitClass(val name: String, val packageName: String, val objectNam

val ktorfitClass = KtorfitClass("Ktorfit", "de.jensklingenberg.ktorfit", "_ktorfit")
val ktorfitInterface = KtorfitClass("KtorfitInterface", "de.jensklingenberg.ktorfit.internal", "EMPTY")
val exampleInterface = KtorfitClass("ClassProvider", "de.jensklingenberg.ktorfit.internal", "EMPTY")

val typeDataClass = KtorfitClass("TypeData", "de.jensklingenberg.ktorfit.converter", "_typeData")
val extDataClass = KtorfitClass("HttpRequestBuilder.() -> Unit", "", "_ext")
val formParameters = KtorfitClass("", "", "__formParameters")
val converterHelper = KtorfitClass("KtorfitConverterHelper","de.jensklingenberg.ktorfit.internal", "_converter")
val converterHelper = KtorfitClass("KtorfitConverterHelper","de.jensklingenberg.ktorfit.internal", "_helper")
val internalApi = ClassName("de.jensklingenberg.ktorfit.internal", "InternalKtorfitApi")

fun KtorfitClass.toClassName() = ClassName(packageName, name)
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ fun getUrlCode(params: List<ParameterData>, methodAnnotation: HttpMethodAnnotati
""
} else {
params.firstOrNull { it.hasAnnotation<Url>() }?.let { parameterData ->
"(${converterHelper.objectName}.baseUrl.takeIf{ !${parameterData.name}.startsWith(\"http\")} ?: \"\") + "
} ?: "${converterHelper.objectName}.baseUrl + "
"(${ktorfitClass.objectName}.baseUrl.takeIf{ !${parameterData.name}.startsWith(\"http\")} ?: \"\") + "
} ?: "${ktorfitClass.objectName}.baseUrl + "
}

params.filter { it.hasAnnotation<Path>() }.forEach { parameterData ->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ interface TestService {
val expectedFunctionText = """val _ext: HttpRequestBuilder.() -> Unit = {
method = HttpMethod.parse("GET2")
url{
takeFrom(_converter.baseUrl + "user")
takeFrom(_ktorfit.baseUrl + "user")
}
setBody(body)
}"""
Expand Down
Loading

0 comments on commit bc761da

Please sign in to comment.