Skip to content

Commit

Permalink
fix #445 修复解析器构造方法有Type数组或Type类型可变参数时,生成的toXxx方法报错问题;代码优化
Browse files Browse the repository at this point in the history
  • Loading branch information
liujingxing committed Jun 29, 2023
1 parent 01b7d46 commit af86f09
Show file tree
Hide file tree
Showing 14 changed files with 491 additions and 522 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,6 @@ public class RxHttpGetEncryptParam : RxHttpNoBodyParam {
map: MutableMap<T, R>,
vararg b: Array<T>,
): RxHttpGetEncryptParam = apply {
(param as GetEncryptParam).test(a,map,*b)
(param as GetEncryptParam).test(a, map, *b)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ public class RxHttpPostEncryptFormParam : RxHttpFormParam {
}

public fun test2(a: Long, b: Float): RxHttpPostEncryptFormParam = apply {
(param as PostEncryptFormParam).test2(a,b)
(param as PostEncryptFormParam).test2(a, b)
}

public fun add(a: Int, b: Int): Int = (param as PostEncryptFormParam).add(a,b)
public fun add(a: Int, b: Int): Int = (param as PostEncryptFormParam).add(a, b)
}
10 changes: 10 additions & 0 deletions rxhttp-compiler/src/main/java/com/rxhttp/compiler/Constants.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
package com.rxhttp.compiler

import com.squareup.javapoet.ArrayTypeName
import com.squareup.javapoet.ClassName
import com.squareup.javapoet.TypeName
import com.squareup.kotlinpoet.ARRAY
import com.squareup.kotlinpoet.ParameterizedTypeName.Companion.parameterizedBy

/**
* User: ljx
Expand All @@ -19,3 +23,9 @@ const val rxhttp_android_platform = "rxhttp_android_platform"

val rxhttpKClass = com.squareup.kotlinpoet.ClassName(rxHttpPackage, RxHttp)
val rxhttpClass: ClassName = ClassName.get(rxHttpPackage, RxHttp)

val J_TYPE: TypeName = ClassName.bestGuess("java.lang.reflect.Type")
val J_ARRAY_TYPE: TypeName = ArrayTypeName.of(J_TYPE)

val K_TYPE = com.squareup.kotlinpoet.ClassName("java.lang.reflect", "Type")
val K_ARRAY_TYPE = ARRAY.parameterizedBy(K_TYPE)
Original file line number Diff line number Diff line change
Expand Up @@ -90,15 +90,13 @@ open class KaptProcessor : AbstractProcessor() {

override fun process(annotations: Set<TypeElement>, roundEnv: RoundEnvironment): Boolean {
if (debug) {
logger.printMessage(
Diagnostic.Kind.WARNING,
"""
process isOver = ${roundEnv.processingOver()}
processed = $processed
rootElements.size = ${roundEnv.rootElements.size}
annotations = $annotations
""".trimIndent()
)
val log = """
process isOver = ${roundEnv.processingOver()}
processed = $processed
rootElements.size = ${roundEnv.rootElements.size}
annotations = $annotations
""".trimIndent()
logger.printMessage(Diagnostic.Kind.WARNING, log)
}
if (annotations.isEmpty() || processed) return true
ClassHelper(isAndroidPlatform() && androidPlatform).generatorStaticClass(filer)
Expand Down
43 changes: 31 additions & 12 deletions rxhttp-compiler/src/main/java/com/rxhttp/compiler/common/KtUtil.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package com.rxhttp.compiler.common

import com.rxhttp.compiler.K_ARRAY_TYPE
import com.rxhttp.compiler.K_TYPE
import com.rxhttp.compiler.isDependenceRxJava
import com.rxhttp.compiler.ksp.isVararg
import com.rxhttp.compiler.ksp.parameterizedBy
import com.rxhttp.compiler.rxHttpPackage
import com.rxhttp.compiler.rxhttpKClass
Expand All @@ -17,6 +20,7 @@ import com.squareup.kotlinpoet.ParameterizedTypeName
import com.squareup.kotlinpoet.ParameterizedTypeName.Companion.parameterizedBy
import com.squareup.kotlinpoet.TypeVariableName
import com.squareup.kotlinpoet.UNIT
import java.util.Locale

/**
* User: ljx
Expand Down Expand Up @@ -110,14 +114,7 @@ fun FunSpec.generateToFlowXxxFun(): List<FunSpec> {
val funList = mutableListOf<FunSpec>()
val parseName = name.substring(7) // Remove the prefix `toAwait`
val typeVariables = typeVariables
val arguments = StringBuilder()
parameters.forEach { p ->
if (KModifier.VARARG in p.modifiers) {
arguments.append("*")
}
arguments.append(p.name).append(",")
}
if (arguments.isNotEmpty()) arguments.deleteCharAt(arguments.length - 1)
val paramNames = parameters.toParamNames()
val toAwaitXxxReturnType = returnType as ParameterizedTypeName
val toAwaitXxxTypeArguments = toAwaitXxxReturnType.typeArguments
FunSpec.builder("toFlow$parseName")
Expand All @@ -126,7 +123,7 @@ fun FunSpec.generateToFlowXxxFun(): List<FunSpec> {
.addParameters(parameters)
.addTypeVariables(typeVariables)
.addStatement(
"return %M(toAwait$parseName${getTypeVariableString(typeVariables)}($arguments))",
"return %M(toAwait$parseName${typeVariables.getTypeVariableString()}($paramNames))",
toFlow
)
.returns(flow.parameterizedBy(toAwaitXxxTypeArguments))
Expand All @@ -148,7 +145,7 @@ fun FunSpec.generateToFlowXxxFun(): List<FunSpec> {
.addParameter(capacityParam)
.addParameter(builder.build())
.addStatement(
"return %M(toAwait$parseName${getTypeVariableString(typeVariables)}($arguments), capacity, progress)",
"return %M(toAwait$parseName${typeVariables.getTypeVariableString()}($paramNames), capacity, progress)",
toFlow
)
.returns(flow.parameterizedBy(toAwaitXxxTypeArguments))
Expand All @@ -162,12 +159,34 @@ fun FunSpec.generateToFlowXxxFun(): List<FunSpec> {
.addParameters(parameters)
.addParameter(capacityParam)
.addStatement(
"return %M(toAwait$parseName${getTypeVariableString(typeVariables)}($arguments), capacity)",
"return %M(toAwait$parseName${typeVariables.getTypeVariableString()}($paramNames), capacity)",
toFlowProgress
)
.returns(flow.parameterizedBy(progressTName.parameterizedBy(toAwaitXxxTypeArguments)))
.build()
.apply { funList.add(this) }
}
return funList
}
}

fun List<ParameterSpec>.flapTypeParameterSpecTypes(
typeVariableNames: List<TypeVariableName>
): List<ParameterSpec> {
val parameterSpecs = mutableListOf<ParameterSpec>()
forEachIndexed { index, parameterSpec ->
if (index == 0 && typeVariableNames.isNotEmpty() &&
(parameterSpec.isArrayType() || parameterSpec.isVarargType())
) {
typeVariableNames.mapTo(parameterSpecs) { typeVariableName ->
val variableName = "${typeVariableName.name.lowercase(Locale.getDefault())}Type"
ParameterSpec.builder(variableName, K_TYPE).build()
}
} else {
parameterSpecs.add(parameterSpec)
}
}
return parameterSpecs
}

fun ParameterSpec.isArrayType() = type == K_ARRAY_TYPE
fun ParameterSpec.isVarargType() = isVararg() && type == K_TYPE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.rxhttp.compiler.common

import com.squareup.kotlinpoet.KModifier
import com.rxhttp.compiler.ksp.isVararg
import com.squareup.kotlinpoet.ParameterSpec
import com.squareup.kotlinpoet.TypeVariableName

Expand All @@ -10,32 +10,30 @@ import com.squareup.kotlinpoet.TypeVariableName
* Time: 11:28
*/
//返回参数名列表, 多个参数用逗号隔开, 如: a, b, c
fun getParamsName(parameterSpecs: List<ParameterSpec>): String {
val paramsName = StringBuilder()
parameterSpecs.forEachIndexed { index, parameterSpec ->
if (index > 0) paramsName.append(", ")
if (KModifier.VARARG in parameterSpec.modifiers) paramsName.append("*")
paramsName.append(parameterSpec.name)
fun List<ParameterSpec>.toParamNames(): String {
val paramNames = StringBuilder()
forEachIndexed { index, parameterSpec ->
if (index > 0) paramNames.append(", ")
if (parameterSpec.isVararg()) paramNames.append("*")
paramNames.append(parameterSpec.name)
}
return paramsName.toString()
return paramNames.toString()
}

//获取泛型字符串 比如:<T> 、<K, V>等等
fun getTypeVariableString(typeVariableNames: List<TypeVariableName>): String {
fun List<TypeVariableName>.getTypeVariableString(): String {
val type = StringBuilder()
val size = typeVariableNames.size
typeVariableNames.forEachIndexed { i, typeVariableName ->
if (i == 0) type.append("<")
forEachIndexed { i, typeVariableName ->
if (i > 0) type.append(", ")
type.append(typeVariableName.name)
type.append(if (i < size - 1) ", " else ">")
}
return type.toString()
return if (type.isEmpty()) "" else "<$type>"
}

//返回 javaTypeOf<T>, javaTypeOf<K>等
fun getTypeOfString(typeVariableNames: List<TypeVariableName>): String {
fun List<TypeVariableName>.getTypeOfString(): String {
val type = StringBuilder()
typeVariableNames.forEachIndexed { i, typeVariableName ->
forEachIndexed { i, typeVariableName ->
if (i > 0) type.append(", ")
type.append("javaTypeOf<${typeVariableName.name}>()")
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,14 +47,8 @@ class ParamsVisitor(private val logger: Messager) {
val methodList = ArrayList<MethodSpec>()
var method: MethodSpec.Builder
elementMap.forEach { (key, typeElement) ->
val type = StringBuilder()
val size = typeElement.typeParameters.size
val rxHttpTypeNames = typeElement.typeParameters.mapIndexed { i, parameterElement ->
TypeVariableName.get(parameterElement).also {
type.append(if (i == 0) "<" else ",")
type.append(it.name)
if (i == size - 1) type.append(">")
}
val rxHttpTypeNames = typeElement.typeParameters.map { parameterElement ->
TypeVariableName.get(parameterElement)
}
val param = ClassName.get(typeElement)
val rxHttpName = "RxHttp${typeElement.simpleName}"
Expand Down Expand Up @@ -131,18 +125,14 @@ class ParamsVisitor(private val logger: Messager) {
if (it == param) rxHttpParamName else it
}

val parametersSize = enclosedElement.parameters.size
//方法体
val methodBody = StringBuilder(enclosedElement.getSimpleName().toString())
.append(if (parametersSize == 0) "()" else "")
//方法参数
val parameterSpecs = enclosedElement.parameters.mapIndexed { i, variableElement ->
ParameterSpec.get(variableElement).apply {
methodBody.append(if (i == 0) "(" else ",")
methodBody.append(this.name)
if (i == parametersSize - 1) methodBody.append(")")
}
val parameterSpecs = enclosedElement.parameters.map { variableElement ->
ParameterSpec.get(variableElement)
}
//方法参数名字
val paramNames = parameterSpecs.toParamNames()
//方法体
val methodBody = "${enclosedElement.getSimpleName()}($paramNames)"
//方法声明的泛型
val typeVariableNames = enclosedElement.typeParameters.map {
TypeVariableName.get(it)
Expand Down
Loading

0 comments on commit af86f09

Please sign in to comment.