from deepseek

🐛 主要Bug

1. 类型提取逻辑缺陷

kotlin

private fun extractTypeInfo(type: Type): TypeInfo {
    if (type !is ParameterizedType) {
        return TypeInfo(null, null) // ❌ 这里有问题
    }
    // ...
}

问题:当类型是简单泛型(如Query<String>)时,rawType应该能正确提取,但当前逻辑在某些情况下会失败。

2. 参数名获取不可靠

kotlin

private fun getParameterName(param: Parameter): String {
    return param.getAnnotation(Param::class.java)?.value?.takeIf { it.isNotEmpty() }
        ?: param.name.takeUnless { it.matches(Regex("arg\\d+")) }
        ?: "" // ❌ 可能返回空字符串
}

问题:当编译时参数名丢失(常见情况)且没有@Param注解时,返回空字符串会导致后续提取失败。

3. 异常处理重复

kotlin

try {
    // ...
} catch (e: ExtractionError) {
    throw e  // ❌ 冗余的catch-rethrow
} catch (e: InvocationError) {
    throw e  // ❌ 冗余的catch-rethrow
} catch (e: Exception) {
    throw InvocationError(handlerName, method.name, e.cause ?: e)
}

⚡ 优化建议

1. 改进类型提取

kotlin

private fun extractTypeInfo(type: Type): TypeInfo {
    return when (type) {
        is Class<*> -> TypeInfo(type, null)
        is ParameterizedType -> {
            val rawType = type.rawType as? Class<*>
            val firstArg = type.actualTypeArguments.firstOrNull()
            
            when {
                rawType?.isList() == true && firstArg is Class<*> -> 
                    TypeInfo(rawType, firstArg)
                firstArg is Class<*> -> 
                    TypeInfo(firstArg, null)
                else -> TypeInfo(rawType, null)
            }
        }
        else -> TypeInfo(null, null)
    }
}

2. 增强参数名处理

kotlin

private fun getParameterName(param: Parameter): String {
    val annotatedName = param.getAnnotation(Param::class.java)?.value
    if (!annotatedName.isNullOrEmpty()) return annotatedName
    
    val paramName = param.name
    if (!paramName.isNullOrEmpty() && !paramName.matches(Regex("arg\\d+"))) {
        return paramName
    }
    
    // 提供更好的错误信息
    throw ExtractionError.InvalidType(
        param.type.simpleName, 
        "Parameter name not available. Use @Param annotation or enable parameter name retention."
    )
}

3. 简化异常处理

kotlin

try {
    val args = extractors.map { it(ctx) }
    method.invoke(null, *args.toTypedArray())
} catch (e: ExtractionError) {
    throw e
} catch (e: InvocationError) {
    throw e
} catch (e: Exception) {
    throw InvocationError(handlerName, method.name, e.cause ?: e)
}
// 可以简化为:
try {
    val args = extractors.map { it(ctx) }
    method.invoke(null, *args.toTypedArray())
} catch (e: ExtractionError) {
    throw e
} catch (e: InvocationError) {
    throw e
} catch (e: Exception) {
    throw InvocationError(handlerName, method.name, e.cause ?: e)
}

4. 增加类型安全

kotlin

// 添加类型检查
private fun validateExtractorType(param: Parameter, expectedTypes: Set<Class<*>>) {
    if (!expectedTypes.contains(param.type)) {
        throw ExtractionError.InvalidType(
            param.type.simpleName,
            "Expected one of: ${expectedTypes.joinToString { it.simpleName }}"
        )
    }
}

// 在 buildExtractor 中使用:
when (rawType) {
    Path::class.java -> {
        validateExtractorType(param, setOf(Path::class.java))
        buildPathExtractor(ctx, typeInfo)
    }
    // ...
}

5. 改进默认值处理

kotlin

private fun getDefaultValue(clazz: Class<*>): Any? = when (clazz) {
    Int::class.java, Integer::class.java -> 0
    Long::class.java, java.lang.Long::class.java -> 0L
    Double::class.java, java.lang.Double::class.java -> 0.0
    Float::class.java, java.lang.Float::class.java -> 0.0f
    Boolean::class.java, java.lang.Boolean::class.java -> false
    String::class.java -> ""
    else -> null  // 对于不支持的类型返回null
}

6. 添加缓存优化

kotlin

// 缓存提取器构建结果
private val extractorCache = ConcurrentHashMap<String, (Context) -> Any?>()

private fun buildExtractor(param: Parameter, handler: String, method: String): (Context) -> Any? {
    val cacheKey = "$handler.$method.${param.name}.${param.type.name}"
    
    return extractorCache.getOrPut(cacheKey) {
        // 原有的构建逻辑
        buildExtractorInternal(param, handler, method)
    }
}

7. 增强错误信息

kotlin

private data class ExtractorContext(
    val handler: String,
    val method: String,
    val paramName: String,
    val paramType: String,
    val parameterIndex: Int  // 添加参数位置信息
) {
    override fun toString() = "$handler.$method(#$parameterIndex $paramType $paramName)"
}

🔧 其他改进

  1. 添加输入验证:在关键方法开始处检查参数有效性

  2. 支持更多类型:如BigDecimalLocalDateTime等常见类型

  3. 改进泛型支持:更好地处理嵌套泛型类型

  4. 添加日志:用于调试复杂的参数提取问题

这些改进将显著提升代码的健壮性、可维护性和用户体验。