Skip to content

Commit

Permalink
Optimize code
Browse files Browse the repository at this point in the history
  • Loading branch information
Foso committed Sep 8, 2024
1 parent e99ac3f commit 36e9e04
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 75 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,6 @@ import com.squareup.kotlinpoet.ANY
import com.squareup.kotlinpoet.KModifier
import com.squareup.kotlinpoet.ksp.toKModifier
import com.squareup.kotlinpoet.ksp.toTypeName
import de.jensklingenberg.ktorfit.model.annotations.FormUrlEncoded
import de.jensklingenberg.ktorfit.model.annotations.Headers
import de.jensklingenberg.ktorfit.model.annotations.Multipart
import de.jensklingenberg.ktorfit.model.annotations.ParameterAnnotation
import de.jensklingenberg.ktorfit.model.annotations.ParameterAnnotation.Field
import de.jensklingenberg.ktorfit.utils.getKsFile

/**
Expand Down Expand Up @@ -51,7 +46,6 @@ fun KSClassDeclaration.toClassData(logger: KSPLogger): ClassData {
"io.ktor.client.request.HttpRequestBuilder",
"io.ktor.client.request.parameter",
"io.ktor.http.URLBuilder",
"io.ktor.http.HttpMethod",
"io.ktor.http.takeFrom",
"io.ktor.http.decodeURLQueryComponent",
typeDataClass.packageName + "." + typeDataClass.name,
Expand All @@ -70,20 +64,6 @@ fun KSClassDeclaration.toClassData(logger: KSPLogger): ClassData {
return@map funcDeclaration.toFunctionData(logger, addImport = { imports.add(it) })
}

functionDataList.forEach {
if (it.annotations.any { it is Headers || it is FormUrlEncoded }) {
imports.add("io.ktor.client.request.headers")
}
if (it.annotations.any { it is FormUrlEncoded || it is Multipart } ||
it.parameterDataList.any { param -> param.hasAnnotation<Field>() || param.hasAnnotation<ParameterAnnotation.Part>() }
) {
imports.add("io.ktor.client.request.forms.FormDataContent")
imports.add("io.ktor.client.request.forms.MultiPartFormDataContent")
imports.add("io.ktor.client.request.forms.formData")
imports.add("io.ktor.http.Parameters")
}
}

val filteredSupertypes =
ksClassDeclaration.superTypes.toList().filterNot {
/** In KSP Any is a supertype of an interface */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,13 @@ import com.google.devtools.ksp.symbol.KSFunctionDeclaration
import com.squareup.kotlinpoet.AnnotationSpec
import com.squareup.kotlinpoet.KModifier
import com.squareup.kotlinpoet.ksp.toAnnotationSpec
import de.jensklingenberg.ktorfit.model.annotations.FormUrlEncoded
import de.jensklingenberg.ktorfit.model.annotations.FunctionAnnotation
import de.jensklingenberg.ktorfit.model.annotations.Headers
import de.jensklingenberg.ktorfit.model.annotations.HttpMethod
import de.jensklingenberg.ktorfit.model.annotations.HttpMethodAnnotation
import de.jensklingenberg.ktorfit.model.annotations.Multipart
import de.jensklingenberg.ktorfit.model.annotations.ParameterAnnotation
import de.jensklingenberg.ktorfit.model.annotations.ParameterAnnotation.Header
import de.jensklingenberg.ktorfit.model.annotations.ParameterAnnotation.HeaderMap
import de.jensklingenberg.ktorfit.model.annotations.ParameterAnnotation.Body
Expand Down Expand Up @@ -75,30 +78,6 @@ fun KSFunctionDeclaration.toFunctionData(
typeName = findTypeName(resolvedReturnType, funcDeclaration.containingFile!!.filePath),
)

functionParameters.forEach { parameterData ->
parameterData.annotations.forEach {
if (it is Header || it is HeaderMap) {
addImport("io.ktor.client.request.headers")
}

if (it is Tag) {
addImport("io.ktor.util.AttributeKey")
}

if (it is Body) {
addImport("io.ktor.client.request.setBody")
}

if (it is Path && !it.encoded) {
addImport("io.ktor.http.encodeURLPath")
}

if (it is RequestType) {
addImport("kotlin.reflect.cast")
}
}
}

val functionAnnotationList = mutableListOf<FunctionAnnotation>()

funcDeclaration.getMultipartAnnotation()?.let {
Expand Down Expand Up @@ -156,6 +135,8 @@ fun KSFunctionDeclaration.toFunctionData(

if (httpMethodAnnoList.isEmpty()) {
logger.error(KtorfitError.noHttpAnnotationAt(functionName), funcDeclaration)
} else {
addImport("io.ktor.http.HttpMethod")
}

if (httpMethodAnnoList.size > 1) {
Expand Down Expand Up @@ -206,13 +187,6 @@ fun KSFunctionDeclaration.toFunctionData(
}
}

if (functionParameters.any { it.hasAnnotation<Path>() } && firstHttpMethodAnnotation.path.isEmpty()) {
logger.error(
KtorfitError.PATH_CAN_ONLY_BE_USED_WITH_RELATIVE_URL_ON + "@${firstHttpMethodAnnotation.httpMethod.keyword}",
funcDeclaration,
)
}

functionParameters.filter { it.hasAnnotation<Path>() }.forEach {
val pathAnnotation = it.findAnnotationOrNull<Path>()
if (!firstHttpMethodAnnotation.path.contains("{${pathAnnotation?.value ?: ""}}")) {
Expand All @@ -223,34 +197,81 @@ fun KSFunctionDeclaration.toFunctionData(
}
}

if (functionParameters.any { it.hasAnnotation<Url>() }) {
if (functionParameters.filter { it.hasAnnotation<Url>() }.size > 1) {
logger.error(KtorfitError.MULTIPLE_URL_METHOD_ANNOTATIONS_FOUND, funcDeclaration)
}
if (firstHttpMethodAnnotation.path.isNotEmpty()) {
logger.error(
KtorfitError.urlCanOnlyBeUsedWithEmpty(firstHttpMethodAnnotation.httpMethod.keyword),
funcDeclaration,
)
}
}
functionParameters.forEach { parameterData ->
parameterData.annotations.forEach {
if (it is Header || it is HeaderMap) {
addImport("io.ktor.client.request.headers")
}

if (functionParameters.any { it.hasAnnotation<Field>() } && funcDeclaration.getFormUrlEncodedAnnotation() == null) {
logger.error(KtorfitError.FIELD_PARAMETERS_CAN_ONLY_BE_USED_WITH_FORM_ENCODING, funcDeclaration)
}
if (it is Tag) {
addImport("io.ktor.util.AttributeKey")
}

if (functionParameters.any { it.hasAnnotation<FieldMap>() } && funcDeclaration.getFormUrlEncodedAnnotation() == null) {
logger.error(
KtorfitError.FIELD_MAP_PARAMETERS_CAN_ONLY_BE_USED_WITH_FORM_ENCODING,
funcDeclaration,
)
if (it is Body) {
addImport("io.ktor.client.request.setBody")
}

if (it is Path && !it.encoded) {
addImport("io.ktor.http.encodeURLPath")
}

if (it is RequestType) {
addImport("kotlin.reflect.cast")
}

if (it is Path && firstHttpMethodAnnotation.path.isEmpty()) {
logger.error(
KtorfitError.PATH_CAN_ONLY_BE_USED_WITH_RELATIVE_URL_ON + "@${firstHttpMethodAnnotation.httpMethod.keyword}",
funcDeclaration,
)
}

if (it is Url) {
if (functionParameters.filter { it.hasAnnotation<Url>() }.size > 1) {
logger.error(KtorfitError.MULTIPLE_URL_METHOD_ANNOTATIONS_FOUND, funcDeclaration)
}
if (firstHttpMethodAnnotation.path.isNotEmpty()) {
logger.error(
KtorfitError.urlCanOnlyBeUsedWithEmpty(firstHttpMethodAnnotation.httpMethod.keyword),
funcDeclaration,
)
}
}

if (it is Field && funcDeclaration.getFormUrlEncodedAnnotation() == null) {
logger.error(KtorfitError.FIELD_PARAMETERS_CAN_ONLY_BE_USED_WITH_FORM_ENCODING, funcDeclaration)
}

if (it is FieldMap && funcDeclaration.getFormUrlEncodedAnnotation() == null) {
logger.error(
KtorfitError.FIELD_MAP_PARAMETERS_CAN_ONLY_BE_USED_WITH_FORM_ENCODING,
funcDeclaration,
)
}

if (it is Body && funcDeclaration.getFormUrlEncodedAnnotation() != null) {
logger.error(
KtorfitError.BODY_PARAMETERS_CANNOT_BE_USED_WITH_FORM_OR_MULTI_PART_ENCODING,
funcDeclaration,
)
}
}
}

if (functionParameters.any { it.hasAnnotation<Body>() } && funcDeclaration.getFormUrlEncodedAnnotation() != null) {
logger.error(
KtorfitError.BODY_PARAMETERS_CANNOT_BE_USED_WITH_FORM_OR_MULTI_PART_ENCODING,
funcDeclaration,
)
functionAnnotationList.forEach {
if (it is Headers || it is FormUrlEncoded) {
addImport("io.ktor.client.request.headers")
}

if (it is FormUrlEncoded ||
it is Multipart ||
functionParameters.any { param -> param.hasAnnotation<Field>() || param.hasAnnotation<ParameterAnnotation.Part>() }
) {
addImport("io.ktor.client.request.forms.FormDataContent")
addImport("io.ktor.client.request.forms.MultiPartFormDataContent")
addImport("io.ktor.client.request.forms.formData")
addImport("io.ktor.http.Parameters")
}
}

val modifiers =
Expand Down

0 comments on commit 36e9e04

Please sign in to comment.