@@ -16,11 +16,13 @@ import com.google.devtools.ksp.symbol.KSAnnotated
1616import com.google.devtools.ksp.symbol.KSFunctionDeclaration
1717import com.google.devtools.ksp.symbol.KSType
1818import com.google.devtools.ksp.symbol.Visibility
19+ import com.squareup.kotlinpoet.CodeBlock
1920import com.squareup.kotlinpoet.FileSpec
2021import com.squareup.kotlinpoet.FunSpec
2122import com.squareup.kotlinpoet.KModifier
2223import com.squareup.kotlinpoet.MemberName
2324import com.squareup.kotlinpoet.ksp.writeTo
25+ import dev.programadorthi.routing.annotation.Body
2426import dev.programadorthi.routing.annotation.Path
2527import dev.programadorthi.routing.annotation.Route
2628
@@ -47,6 +49,8 @@ private class RoutingProcessor(
4749 invoked = true
4850
4951 val call = MemberName (" dev.programadorthi.routing.core.application" , " call" )
52+ val receive = MemberName (" dev.programadorthi.routing.core.application" , " receive" )
53+ val receiveNullable = MemberName (" dev.programadorthi.routing.core.application" , " receiveNullable" )
5054 val handle = MemberName (" dev.programadorthi.routing.core" , " handle" )
5155
5256 val configureSpec = FunSpec
@@ -68,10 +72,6 @@ private class RoutingProcessor(
6872 " $qualifiedName fun must not be private"
6973 }
7074
71- check(func.packageName.asString().isNotBlank()) {
72- " Top level fun '$qualifiedName ' must have a package"
73- }
74-
7575 val routeAnnotation = checkNotNull(func.getAnnotationsByType(Route ::class ).firstOrNull()) {
7676 " Invalid state because a @Route was not found to '$qualifiedName '"
7777 }
@@ -83,19 +83,53 @@ private class RoutingProcessor(
8383 " @Route using regex can't be named"
8484 }
8585
86- val parameters = mutableListOf<String >()
86+ val named = when {
87+ routeAnnotation.name.isBlank() -> " name = null"
88+ else -> """ name = "${routeAnnotation.name} """"
89+ }
90+ if (isRegexRoute) {
91+ configureSpec.beginControlFlow(" %M(%T(%S))" , handle, Regex ::class , routeAnnotation.regex)
92+ } else {
93+ configureSpec.beginControlFlow(" %M(path = %S, $named )" , handle, routeAnnotation.path)
94+ }
95+
96+ val funcMember = MemberName (func.packageName.asString(), func.simpleName.asString())
97+ val funcBuilder = CodeBlock .builder()
98+ val isMultipleParameters = func.parameters.size > 1
99+ if (isMultipleParameters) {
100+ funcBuilder
101+ .addStatement(" %M(" , funcMember)
102+ .indent()
103+ } else {
104+ funcBuilder.add(" %M(" , funcMember)
105+ }
87106
88107 for (param in func.parameters) {
89108 check(param.isVararg.not ()) {
90109 " Vararg is not supported as fun parameter"
91110 }
92111 val paramName = param.name?.asString()
112+ val paramType = param.type.resolve()
113+ val body = param
114+ .getAnnotationsByType(Body ::class )
115+ .firstOrNull()
116+ if (body != null ) {
117+ val member = when {
118+ paramType.isMarkedNullable -> receiveNullable
119+ else -> receive
120+ }
121+ when {
122+ isMultipleParameters -> funcBuilder.addStatement(" $paramName = %M.%M()," , call, member)
123+ else -> funcBuilder.add(" $paramName = %M.%M()" , call, member)
124+ }
125+ continue
126+ }
127+
93128 val customName = param
94129 .getAnnotationsByType(Path ::class )
95130 .firstOrNull()
96131 ?.value
97132 ? : paramName
98- val paramType = param.type.resolve()
99133 if (! isRegexRoute && routeAnnotation.path.contains(" {$customName ...}" )) {
100134 val listDeclaration = checkNotNull(resolver.getClassDeclarationByName<List <* >>()) {
101135 " Class declaration not found to List<String>?"
@@ -113,7 +147,11 @@ private class RoutingProcessor(
113147 check(paramType.isMarkedNullable) {
114148 " Tailcard list must be nullable as List<String>?"
115149 }
116- parameters + = """ $paramName = %M.parameters.getAll("$customName ")"""
150+
151+ when {
152+ isMultipleParameters -> funcBuilder.addStatement(""" $paramName = %M.parameters.getAll("$customName "),""" , call)
153+ else -> funcBuilder.add(""" $paramName = %M.parameters.getAll("$customName ")""" , call)
154+ }
117155 continue
118156 }
119157
@@ -124,26 +162,26 @@ private class RoutingProcessor(
124162 " '$qualifiedName ' has parameter '$paramName ' that is not declared as path parameter {$customName }"
125163 }
126164 val parsed = """ $paramName = %M.parameters["$customName "]"""
127- parameters + = when {
165+ val statement = when {
128166 isOptional -> optionalParse(paramType, resolver, parsed)
129167 else -> requiredParse(paramType, resolver, parsed)
130168 }
169+ when {
170+ isMultipleParameters -> funcBuilder.addStatement(" $statement ," , call)
171+ else -> funcBuilder.add(statement, call)
172+ }
131173 }
132174
133- val calls = Array (size = parameters.size) { call }
134- val params = parameters.joinToString(prefix = " (" , postfix = " )" ) { " \n $it " }
135- val named = when {
136- routeAnnotation.name.isBlank() -> " name = null"
137- else -> """ name = "${routeAnnotation.name} """"
175+ if (isMultipleParameters) {
176+ funcBuilder
177+ .unindent()
178+ .addStatement(" )" )
179+ } else {
180+ funcBuilder.addStatement(" )" )
138181 }
139182
140- with (configureSpec) {
141- if (isRegexRoute) {
142- beginControlFlow(""" %M(%T(%S))""" , handle, Regex ::class , routeAnnotation.regex)
143- } else {
144- beginControlFlow(""" %M(path = %S, $named )""" , handle, routeAnnotation.path)
145- }
146- }.addStatement(""" $qualifiedName$params """ , * calls)
183+ configureSpec
184+ .addCode(funcBuilder.build())
147185 .endControlFlow()
148186 }
149187
0 commit comments