diff --git a/core/build.gradle.kts b/core/build.gradle.kts index 24bb272..8685e10 100644 --- a/core/build.gradle.kts +++ b/core/build.gradle.kts @@ -2,6 +2,7 @@ import kotlinx.kover.gradle.plugin.dsl.KoverProjectExtension plugins { kotlin("multiplatform") + alias(libs.plugins.ksp) id("org.jetbrains.kotlinx.kover") alias(libs.plugins.maven.publish) } @@ -20,6 +21,11 @@ kotlin { api(libs.ktor.http) } } + commonTest { + dependencies { + implementation(projects.ksp.coreAnnotations) + } + } } } @@ -36,3 +42,11 @@ configure { } } } + +dependencies { + add("kspJvmTest", projects.ksp.coreProcessor) +} + +ksp { + arg("Routing_Module_Name", "Core") +} diff --git a/samples/ksp-sample/src/commonMain/kotlin/dev/programadorthi/routing/sample/Routes.kt b/core/common/test/dev/programadorthi/routing/core/Routes.kt similarity index 82% rename from samples/ksp-sample/src/commonMain/kotlin/dev/programadorthi/routing/sample/Routes.kt rename to core/common/test/dev/programadorthi/routing/core/Routes.kt index e282650..4297986 100644 --- a/samples/ksp-sample/src/commonMain/kotlin/dev/programadorthi/routing/sample/Routes.kt +++ b/core/common/test/dev/programadorthi/routing/core/Routes.kt @@ -1,10 +1,10 @@ -package dev.programadorthi.routing.sample +package dev.programadorthi.routing.core import dev.programadorthi.routing.annotation.Body import dev.programadorthi.routing.annotation.Path import dev.programadorthi.routing.annotation.Route -import dev.programadorthi.routing.core.RouteMethod import dev.programadorthi.routing.core.application.Application +import dev.programadorthi.routing.core.application.ApplicationCall import io.ktor.http.Parameters import io.ktor.util.Attributes @@ -29,7 +29,9 @@ fun named(name: String) { } @Route(path = "/custom/{random}", name = "custom") -fun custom(@Path("random") value: String) { +fun custom( + @Path("random") value: String +) { println(">>>> value: $value") } @@ -54,12 +56,16 @@ fun regex2(number: Int) { } @Route("/with-body") -fun withBody(@Body user: User) { +fun withBody( + @Body user: User +) { println(">>>> with body $user") } @Route("/with-null-body") -fun withNullBody(@Body user: User?) { +fun withNullBody( + @Body user: User? +) { println(">>>> null body $user") } @@ -73,22 +79,22 @@ fun multiParameters(part1: Int, part2: String) { println(">>>> Parts: $part1 and $part2") } +@Route("/call") +fun call(call: ApplicationCall) { + println(">>>> call: $call") +} + @Route("/call/{part1}/{part2}") fun callParameters( application: Application, parameters: Parameters, attributes: Attributes, ) { - println(""" + println( + """ >>>> application: $application >>>> parameters: $parameters >>>> attributes: $attributes - """.trimIndent()) -} - -class Routes { - //@Route("/path") - fun run() { - println(">>>> I'm routing") - } + """.trimIndent() + ) } diff --git a/ksp/core-processor/build.gradle.kts b/ksp/core-processor/build.gradle.kts index 4524e01..d6eee13 100644 --- a/ksp/core-processor/build.gradle.kts +++ b/ksp/core-processor/build.gradle.kts @@ -10,7 +10,6 @@ kotlin { sourceSets { jvmMain { dependencies { - implementation(projects.core) implementation(projects.ksp.coreAnnotations) implementation(libs.kotlin.poet) implementation(libs.kotlin.poet.ksp) diff --git a/ksp/core-processor/jvm/src/dev/programadorthi/routing/ksp/RoutingProcessor.kt b/ksp/core-processor/jvm/src/dev/programadorthi/routing/ksp/RoutingProcessor.kt index 7a1db91..ddf6ca0 100644 --- a/ksp/core-processor/jvm/src/dev/programadorthi/routing/ksp/RoutingProcessor.kt +++ b/ksp/core-processor/jvm/src/dev/programadorthi/routing/ksp/RoutingProcessor.kt @@ -28,13 +28,11 @@ import com.squareup.kotlinpoet.FileSpec import com.squareup.kotlinpoet.FunSpec import com.squareup.kotlinpoet.KModifier import com.squareup.kotlinpoet.MemberName +import com.squareup.kotlinpoet.ksp.toTypeName import com.squareup.kotlinpoet.ksp.writeTo import dev.programadorthi.routing.annotation.Body import dev.programadorthi.routing.annotation.Path import dev.programadorthi.routing.annotation.Route -import dev.programadorthi.routing.core.application.Application -import io.ktor.http.Parameters -import io.ktor.util.Attributes public class RoutingProcessorProvider : SymbolProcessorProvider { override fun create(environment: SymbolProcessorEnvironment): SymbolProcessor { @@ -66,7 +64,7 @@ private class RoutingProcessor( val configureSpec = FunSpec .builder("configure") .addModifiers(KModifier.INTERNAL) - .receiver(dev.programadorthi.routing.core.Route::class) + .receiver(route) resolver .getSymbolsWithAnnotation(Route::class.java.name) @@ -110,9 +108,11 @@ private class RoutingProcessor( check(classKind == ClassKind.OBJECT || classKind == ClassKind.CLASS) { "$qualifiedName must be a class or object. ${classKind.type} is not supported" } - check(superTypes.any { type -> - type.resolve().declaration.qualifiedName?.asString() == VOYAGER_SCREEN_QUALIFIED_NAME - }) { + check( + superTypes.any { type -> + type.resolve().declaration.qualifiedName?.asString() == VOYAGER_SCREEN_QUALIFIED_NAME + } + ) { "@Route can be applied to object or class that inherit from '$VOYAGER_SCREEN_QUALIFIED_NAME' only" } logger.info(">>>> transforming class: $qualifiedName") @@ -230,16 +230,17 @@ private class RoutingProcessor( when { classKind == ClassKind.OBJECT -> funcBuilder.addStatement(template, member) hasZeroOrOneParameter -> funcBuilder.add(template, member) - else -> funcBuilder - .addStatement(template, member) - .indent() + else -> + funcBuilder + .addStatement(template, member) + .indent() } for (param in parameters) { check(param.isVararg.not()) { "Vararg is not supported as fun parameter" } - var applied = param.tryApplyCallProperty(hasZeroOrOneParameter, resolver, funcBuilder) + var applied = param.tryApplyCallProperty(hasZeroOrOneParameter, funcBuilder) if (!applied) { applied = param.tryApplyBody(hasZeroOrOneParameter, funcBuilder) } @@ -377,17 +378,25 @@ private class RoutingProcessor( private fun KSValueParameter.tryApplyCallProperty( hasZeroOrOneParameter: Boolean, - resolver: Resolver, builder: CodeBlock.Builder, ): Boolean { val paramType = type.resolve() - val propertyName = when (paramType.declaration) { - resolver.getClassDeclarationByName() -> "application" - resolver.getClassDeclarationByName() -> "parameters" - resolver.getClassDeclarationByName() -> "attributes" + val paramName = name?.asString() + val asTypeName = paramType.toTypeName() + if (asTypeName == applicationCall) { + when { + hasZeroOrOneParameter -> builder.add(CALL_TEMPLATE, paramName, call, "") + else -> builder.addStatement(CALL_TEMPLATE, paramName, call, ",") + } + return true + } + + val propertyName = when (asTypeName) { + application -> "application" + parameters -> "parameters" + attributes -> "attributes" else -> return false } - val paramName = name?.asString() when { hasZeroOrOneParameter -> builder.add(CALL_PROPERTY_TEMPLATE, paramName, call, propertyName, "") else -> builder.addStatement(CALL_PROPERTY_TEMPLATE, paramName, call, propertyName, ",") @@ -437,6 +446,12 @@ private class RoutingProcessor( } private companion object { + private val route = ClassName("dev.programadorthi.routing.core", "Route") + private val application = ClassName("dev.programadorthi.routing.core.application", "Application") + private val applicationCall = ClassName("dev.programadorthi.routing.core.application", "ApplicationCall") + private val parameters = ClassName("io.ktor.http", "Parameters") + private val attributes = ClassName("io.ktor.util", "Attributes") + private val screen = MemberName("dev.programadorthi.routing.voyager", "screen") private val composable = MemberName("dev.programadorthi.routing.compose", "composable") private val handle = MemberName("dev.programadorthi.routing.core", "handle") @@ -446,6 +461,7 @@ private class RoutingProcessor( private val receiveNullable = MemberName("dev.programadorthi.routing.core.application", "receiveNullable") + private const val CALL_TEMPLATE = """%L = %M%L""" private const val CALL_PROPERTY_TEMPLATE = """%L = %M.%L%L""" private const val BODY_TEMPLATE = "%L = %M.%M()%L" private const val FUN_INVOKE_END = ")" @@ -461,5 +477,4 @@ private class RoutingProcessor( private const val CONSTRUCTOR_NAME = "" } - }