@@ -16,11 +16,13 @@ import com.google.devtools.ksp.symbol.KSAnnotated
16
16
import com.google.devtools.ksp.symbol.KSFunctionDeclaration
17
17
import com.google.devtools.ksp.symbol.KSType
18
18
import com.google.devtools.ksp.symbol.Visibility
19
+ import com.squareup.kotlinpoet.CodeBlock
19
20
import com.squareup.kotlinpoet.FileSpec
20
21
import com.squareup.kotlinpoet.FunSpec
21
22
import com.squareup.kotlinpoet.KModifier
22
23
import com.squareup.kotlinpoet.MemberName
23
24
import com.squareup.kotlinpoet.ksp.writeTo
25
+ import dev.programadorthi.routing.annotation.Body
24
26
import dev.programadorthi.routing.annotation.Path
25
27
import dev.programadorthi.routing.annotation.Route
26
28
@@ -47,6 +49,8 @@ private class RoutingProcessor(
47
49
invoked = true
48
50
49
51
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" )
50
54
val handle = MemberName (" dev.programadorthi.routing.core" , " handle" )
51
55
52
56
val configureSpec = FunSpec
@@ -68,10 +72,6 @@ private class RoutingProcessor(
68
72
" $qualifiedName fun must not be private"
69
73
}
70
74
71
- check(func.packageName.asString().isNotBlank()) {
72
- " Top level fun '$qualifiedName ' must have a package"
73
- }
74
-
75
75
val routeAnnotation = checkNotNull(func.getAnnotationsByType(Route ::class ).firstOrNull()) {
76
76
" Invalid state because a @Route was not found to '$qualifiedName '"
77
77
}
@@ -83,19 +83,53 @@ private class RoutingProcessor(
83
83
" @Route using regex can't be named"
84
84
}
85
85
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
+ }
87
106
88
107
for (param in func.parameters) {
89
108
check(param.isVararg.not ()) {
90
109
" Vararg is not supported as fun parameter"
91
110
}
92
111
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
+
93
128
val customName = param
94
129
.getAnnotationsByType(Path ::class )
95
130
.firstOrNull()
96
131
?.value
97
132
? : paramName
98
- val paramType = param.type.resolve()
99
133
if (! isRegexRoute && routeAnnotation.path.contains(" {$customName ...}" )) {
100
134
val listDeclaration = checkNotNull(resolver.getClassDeclarationByName<List <* >>()) {
101
135
" Class declaration not found to List<String>?"
@@ -113,7 +147,11 @@ private class RoutingProcessor(
113
147
check(paramType.isMarkedNullable) {
114
148
" Tailcard list must be nullable as List<String>?"
115
149
}
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
+ }
117
155
continue
118
156
}
119
157
@@ -124,26 +162,26 @@ private class RoutingProcessor(
124
162
" '$qualifiedName ' has parameter '$paramName ' that is not declared as path parameter {$customName }"
125
163
}
126
164
val parsed = """ $paramName = %M.parameters["$customName "]"""
127
- parameters + = when {
165
+ val statement = when {
128
166
isOptional -> optionalParse(paramType, resolver, parsed)
129
167
else -> requiredParse(paramType, resolver, parsed)
130
168
}
169
+ when {
170
+ isMultipleParameters -> funcBuilder.addStatement(" $statement ," , call)
171
+ else -> funcBuilder.add(statement, call)
172
+ }
131
173
}
132
174
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(" )" )
138
181
}
139
182
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())
147
185
.endControlFlow()
148
186
}
149
187
0 commit comments