refactor: change T.resolve() to T.asResolver in KavaRef

This commit is contained in:
2025-07-06 19:42:55 +08:00
parent 770f253861
commit 3714ea56d5
5 changed files with 103 additions and 48 deletions

View File

@@ -31,8 +31,10 @@ public class World {
``` ```
```kotlin ```kotlin
World().resolve().firstMethod { val myWorld = World()
World::class.resolve().firstMethod {
name = "sayHello" name = "sayHello"
parameters(String::class) parameters(String::class)
}.invoke("KavaRef") }.of(myWorld).invoke("KavaRef")
``` ```

View File

@@ -70,7 +70,7 @@ The relationship diagram is as follows.
``` :no-line-numbers ``` :no-line-numbers
KavaRef KavaRef
└── KClass/Class/Any.resolve() └── KClass/Class.resolve()
├── method() ├── method()
├── constructor() ├── constructor()
└── field() └── field()
@@ -199,7 +199,7 @@ you can use this instance to create KavaRef reflections directly.
```kotlin ```kotlin
// Here, the test instance test will be passed to // Here, the test instance test will be passed to
// KavaRef and get test::class.java. // KavaRef and get test::class.java.
test.resolve() test.asResolver()
.firstMethod { .firstMethod {
name = "doTask" name = "doTask"
parameters(String::class) parameters(String::class)
@@ -215,7 +215,7 @@ Next, we need to get the `isTaskRunning` variable, which can be written in the f
// Suppose this is an example of this Class. // Suppose this is an example of this Class.
val test: Test val test: Test
// Call and execute with KavaRef. // Call and execute with KavaRef.
val isTaskRunning = test.resolve() val isTaskRunning = test.asResolver()
.firstField { .firstField {
name = "isTaskRunning" name = "isTaskRunning"
type = Boolean::class type = Boolean::class
@@ -258,6 +258,12 @@ To set the current instance, if the reflection is static (static) member, you do
::: :::
::: warning
The `Any.resolve()` function has been deprecated in `1.0.1` version because it pollutes the namespace (for example `File.resolve("/path/to/file")`), and now use `Any.asResolver()` instead.
:::
::: danger ::: danger
In `MemberResolver` inherited from `InstanceAwareResolver`, the type of `of(instance)` requires the same type as the currently reflected `Class` instance generic type. In `MemberResolver` inherited from `InstanceAwareResolver`, the type of `of(instance)` requires the same type as the currently reflected `Class` instance generic type.
@@ -295,7 +301,7 @@ At this point, you can use the `parameters(...)` condition to use `VagueType` to
// Suppose this is an example of this Class. // Suppose this is an example of this Class.
val test: Test val test: Test
// Call and execute with KavaRef. // Call and execute with KavaRef.
test.resolve() Test::class.resolve()
.firstMethod { .firstMethod {
name = "release" name = "release"
// Use VagueType to fill in the types you don't want to fill in, // Use VagueType to fill in the types you don't want to fill in,
@@ -325,7 +331,7 @@ Suppose we want to get the `doTask` method in `Test`, we can use the following i
// Suppose this is an example of this Class. // Suppose this is an example of this Class.
val test: Test val test: Test
// Call and execute with KavaRef. // Call and execute with KavaRef.
test.resolve() Test::class.resolve()
.firstMethod { .firstMethod {
// Use lambda to set the method name. // Use lambda to set the method name.
name { name {
@@ -334,7 +340,7 @@ test.resolve()
} }
// Set parameter type. // Set parameter type.
parameters(String::class) parameters(String::class)
}.invoke("task_name") }.of(test).invoke("task_name")
``` ```
### Generic Conditions ### Generic Conditions
@@ -349,7 +355,7 @@ Suppose we need to filter the `print` method in `Box<String>`.
// Suppose this is an example of this Class. // Suppose this is an example of this Class.
val box: Box<String> val box: Box<String>
// Call and execute with KavaRef. // Call and execute with KavaRef.
box.resolve() box.asResolver()
.firstMethod { .firstMethod {
name = "print" name = "print"
// Set generic parameter conditions. // Set generic parameter conditions.
@@ -374,13 +380,13 @@ Without knowing the superclass name, we only need to add `superclass()` to the f
// Suppose this is an example of this Class. // Suppose this is an example of this Class.
val test: Test val test: Test
// Call and execute with KavaRef. // Call and execute with KavaRef.
test.resolve() Test::class.resolve()
.firstMethod { .firstMethod {
name = "doBaseTask" name = "doBaseTask"
parameters(String::class) parameters(String::class)
// Just add this condition. // Just add this condition.
superclass() superclass()
}.invoke("task_name") }.of(test).invoke("task_name")
``` ```
At this time, we can get this method in the superclass. At this time, we can get this method in the superclass.
@@ -432,12 +438,12 @@ You can also use string types to pass in full class names in conditions such as
// Suppose this is an example of this Class. // Suppose this is an example of this Class.
val test: Test val test: Test
// Call and execute with KavaRef. // Call and execute with KavaRef.
test.resolve() Test::class.resolve()
.firstMethod { .firstMethod {
name = "doTask" name = "doTask"
// Pass the full class name using string type. // Pass the full class name using string type.
parameters("java.lang.String") parameters("java.lang.String")
}.invoke("task_name") }.of(test).invoke("task_name")
``` ```
### Exception Handling ### Exception Handling
@@ -568,12 +574,13 @@ If you don't like the Kotlin lambda writing, you can create chained calls manual
// Suppose this is an example of this Class. // Suppose this is an example of this Class.
val test: Test val test: Test
// Call and execute with KavaRef. // Call and execute with KavaRef.
test.resolve() Test::class.resolve()
.method() // Conditions begin. .method() // Conditions begin.
.name("doTask") .name("doTask")
.parameters(String::class) .parameters(String::class)
.build() // Conditions ends (executes) .build() // Conditions ends (executes)
.first() .first()
.of(test) // Setting up instance.
.invoke("task_name") .invoke("task_name")
``` ```
@@ -705,13 +712,13 @@ val myResolver = MyMemberProcessorResolver()
// Suppose this is an instance of this Class. // Suppose this is an instance of this Class.
val test: Test val test: Test
// Call and execute using KavaRef. // Call and execute using KavaRef.
test.resolve() Test::class.resolve()
// Set custom resolver. // Set custom resolver.
.processor(myResolver) .processor(myResolver)
.firstMethod { .firstMethod {
name = "doTask" name = "doTask"
parameters(String::class) parameters(String::class)
}.invoke("task_name") }.of(test).invoke("task_name")
``` ```
::: tip ::: tip

View File

@@ -31,8 +31,10 @@ public class World {
``` ```
```kotlin ```kotlin
World().resolve().firstMethod { val myWorld = World()
World::class.resolve().firstMethod {
name = "sayHello" name = "sayHello"
parameters(String::class) parameters(String::class)
}.invoke("KavaRef") }.of(myWorld).invoke("KavaRef")
``` ```

View File

@@ -69,7 +69,7 @@ KavaRef 采用链式调用的设计方案,它对可用的 Java 反射 API (例
``` :no-line-numbers ``` :no-line-numbers
KavaRef KavaRef
└── KClass/Class/Any.resolve() └── KClass/Class.resolve()
├── method() ├── method()
├── constructor() ├── constructor()
└── field() └── field()
@@ -192,7 +192,7 @@ Test::class
```kotlin ```kotlin
// 在这里Test 的实例 test 会被传给 KavaRef 并获取 test::class.java // 在这里Test 的实例 test 会被传给 KavaRef 并获取 test::class.java
test.resolve() test.asResolver()
.firstMethod { .firstMethod {
name = "doTask" name = "doTask"
parameters(String::class) parameters(String::class)
@@ -208,7 +208,7 @@ test.resolve()
// 假设这就是这个 Class 的实例 // 假设这就是这个 Class 的实例
val test: Test val test: Test
// 使用 KavaRef 调用并执行 // 使用 KavaRef 调用并执行
val isTaskRunning = test.resolve() val isTaskRunning = test.asResolver()
.firstField { .firstField {
name = "isTaskRunning" name = "isTaskRunning"
type = Boolean::class type = Boolean::class
@@ -250,6 +250,12 @@ val test = Test::class.resolve()
::: :::
::: warning
`Any.resolve()` 方法已在 `1.0.1` 版本被弃用,因为它会污染命名空间 (例如 `File.resolve("/path/to/file")`),现在请使用 `Any.asResolver()` 来代替。
:::
::: danger ::: danger
在继承于 `InstanceAwareResolver` 的 `MemberResolver` 中,`of(instance)` 的类型要求与当前反射的 `Class` 实例泛型类型相同, 在继承于 `InstanceAwareResolver` 的 `MemberResolver` 中,`of(instance)` 的类型要求与当前反射的 `Class` 实例泛型类型相同,
@@ -286,7 +292,7 @@ myClass.resolve()
// 假设这就是这个 Class 的实例 // 假设这就是这个 Class 的实例
val test: Test val test: Test
// 使用 KavaRef 调用并执行 // 使用 KavaRef 调用并执行
test.resolve() Test::class.resolve()
.firstMethod { .firstMethod {
name = "release" name = "release"
// 使用 VagueType 来填充不想填写的类型,同时保证其它类型能够匹配 // 使用 VagueType 来填充不想填写的类型,同时保证其它类型能够匹配
@@ -314,7 +320,7 @@ test.resolve()
// 假设这就是这个 Class 的实例 // 假设这就是这个 Class 的实例
val test: Test val test: Test
// 使用 KavaRef 调用并执行 // 使用 KavaRef 调用并执行
test.resolve() Test::class.resolve()
.firstMethod { .firstMethod {
// 使用 lambda 来设置方法名 // 使用 lambda 来设置方法名
name { name {
@@ -323,7 +329,7 @@ test.resolve()
} }
// 设置参数类型 // 设置参数类型
parameters(String::class) parameters(String::class)
}.invoke("task_name") }.of(test).invoke("task_name")
``` ```
### 泛型条件 ### 泛型条件
@@ -338,7 +344,7 @@ KavaRef 支持添加泛型过滤条件,你可以使用 `TypeMatcher` 提供的
// 假设这就是这个 Class 的实例 // 假设这就是这个 Class 的实例
val box: Box<String> val box: Box<String>
// 使用 KavaRef 调用并执行 // 使用 KavaRef 调用并执行
box.resolve() box.asResolver()
.firstMethod { .firstMethod {
name = "print" name = "print"
// 设置泛型参数条件 // 设置泛型参数条件
@@ -363,13 +369,13 @@ box.resolve()
// 假设这就是这个 Class 的实例 // 假设这就是这个 Class 的实例
val test: Test val test: Test
// 使用 KavaRef 调用并执行 // 使用 KavaRef 调用并执行
test.resolve() Test::class.resolve()
.firstMethod { .firstMethod {
name = "doBaseTask" name = "doBaseTask"
parameters(String::class) parameters(String::class)
// 只需要添加这个条件 // 只需要添加这个条件
superclass() superclass()
}.invoke("task_name") }.of(test).invoke("task_name")
``` ```
这个时候我们就可以在超类中获取到这个方法了。 这个时候我们就可以在超类中获取到这个方法了。
@@ -419,12 +425,12 @@ val tag = Test::class.resolve()
// 假设这就是这个 Class 的实例 // 假设这就是这个 Class 的实例
val test: Test val test: Test
// 使用 KavaRef 调用并执行 // 使用 KavaRef 调用并执行
test.resolve() Test::class.resolve()
.firstMethod { .firstMethod {
name = "doTask" name = "doTask"
// 使用字符串类型传入完整类名 // 使用字符串类型传入完整类名
parameters("java.lang.String") parameters("java.lang.String")
}.invoke("task_name") }.of(test).invoke("task_name")
``` ```
### 异常处理 ### 异常处理
@@ -548,12 +554,13 @@ KavaRef.setLogger(MyLogger())
// 假设这就是这个 Class 的实例 // 假设这就是这个 Class 的实例
val test: Test val test: Test
// 使用 KavaRef 调用并执行 // 使用 KavaRef 调用并执行
test.resolve() Test::class.resolve()
.method() // 条件开始 .method() // 条件开始
.name("doTask") .name("doTask")
.parameters(String::class) .parameters(String::class)
.build() // 条件结束 (执行) .build() // 条件结束 (执行)
.first() .first()
.of(test) // 设置实例
.invoke("task_name") .invoke("task_name")
``` ```
@@ -684,13 +691,13 @@ val myResolver = MyMemberProcessorResolver()
// 假设这就是这个 Class 的实例 // 假设这就是这个 Class 的实例
val test: Test val test: Test
// 使用 KavaRef 调用并执行 // 使用 KavaRef 调用并执行
test.resolve() Test::class.resolve()
// 设置自定义解析器 // 设置自定义解析器
.processor(myResolver) .processor(myResolver)
.firstMethod { .firstMethod {
name = "doTask" name = "doTask"
parameters(String::class) parameters(String::class)
}.invoke("task_name") }.of(test).invoke("task_name")
``` ```
::: tip ::: tip

View File

@@ -83,6 +83,15 @@ class KavaRef private constructor() {
@JvmName("resolveClass") @JvmName("resolveClass")
fun <T : Any> Class<T>.resolve() = MemberScope(createConfiguration()) fun <T : Any> Class<T>.resolve() = MemberScope(createConfiguration())
/**
* Create a [MemberScope] instance to start a new reflection.
*
* This function has been deprecated due to naming pollution, use [asResolver] instead.
* @return [MemberScope]
*/
@Deprecated(message = "Use asResolver() instead.", replaceWith = ReplaceWith("this.asResolver()"))
fun <T : Any> T.resolve() = asResolver()
/** /**
* Create a [MemberScope] instance to start a new reflection. * Create a [MemberScope] instance to start a new reflection.
* @see KClass.resolve * @see KClass.resolve
@@ -91,44 +100,72 @@ class KavaRef private constructor() {
*/ */
@JvmStatic @JvmStatic
@JvmName("resolveObject") @JvmName("resolveObject")
fun <T : Any> T.resolve() = when (this) { fun <T : Any> T.asResolver() = when (this) {
is KClass<*> -> MemberScope((this as KClass<T>).java.createConfiguration(memberInstance = this)) is KClass<*> -> MemberScope((this as KClass<T>).java.createConfiguration(memberInstance = this))
is Class<*> -> MemberScope((this as Class<T>).createConfiguration(memberInstance = this)) is Class<*> -> MemberScope((this as Class<T>).createConfiguration(memberInstance = this))
else -> MemberScope(javaClass.createConfiguration(memberInstance = this)) else -> MemberScope(javaClass.createConfiguration(memberInstance = this))
} }
// Below are deprecated functions to prevent recursive calls. // Below are deprecated functions to prevent internal calls.
private const val RECURSIVELY_CALL_DEPRECATED_MESSAGE = "You are calling resolve() recursively, it's an error and should delete it." private const val DEPRECATED_MESSAGE = "You are calling asResolver() in KavaRef internal component, it's an error and should delete it."
private const val RECURSIVELY_CALL_EXCEPTION_MESSAGE = "Not allowed to call resolve() recursively, please delete it." private const val EXCEPTION_MESSAGE = "Not allowed to call asResolver() in KavaRef internal component, please delete it."
/** /**
* This is a fake function call chains to avoid recursive calls to themselves. * This is a fake function call chains to avoid internal calls to themselves.
*/ */
@Deprecated(message = RECURSIVELY_CALL_DEPRECATED_MESSAGE, level = DeprecationLevel.ERROR) @Deprecated(message = DEPRECATED_MESSAGE, level = DeprecationLevel.ERROR)
@JvmSynthetic @JvmSynthetic
fun MemberScope<*>.resolve(): MemberScope<*> = error(RECURSIVELY_CALL_EXCEPTION_MESSAGE) fun MemberScope<*>.asResolver(): MemberScope<*> = error(EXCEPTION_MESSAGE)
/** /**
* This is a fake function call chains to avoid recursive calls to themselves. * This is a fake function call chains to avoid internal calls to themselves.
*/ */
@Deprecated(message = RECURSIVELY_CALL_DEPRECATED_MESSAGE, level = DeprecationLevel.ERROR) @Deprecated(message = DEPRECATED_MESSAGE, level = DeprecationLevel.ERROR)
@JvmSynthetic @JvmSynthetic
fun MemberCondition<*, *, *>.resolve(): MemberCondition<*, *, *> = error(RECURSIVELY_CALL_EXCEPTION_MESSAGE) fun MemberScope<*>.resolve(): MemberScope<*> = error(EXCEPTION_MESSAGE)
/** /**
* This is a fake function call chains to avoid recursive calls to themselves. * This is a fake function call chains to avoid internal calls to themselves.
*/ */
@Deprecated(message = RECURSIVELY_CALL_DEPRECATED_MESSAGE, level = DeprecationLevel.ERROR) @Deprecated(message = DEPRECATED_MESSAGE, level = DeprecationLevel.ERROR)
@JvmSynthetic @JvmSynthetic
fun MemberResolver<*, *>.resolve(): MemberResolver<*, *> = error(RECURSIVELY_CALL_EXCEPTION_MESSAGE) fun MemberCondition<*, *, *>.asResolver(): MemberCondition<*, *, *> = error(EXCEPTION_MESSAGE)
/** /**
* This is a fake function call chains to avoid recursive calls to themselves. * This is a fake function call chains to avoid internal calls to themselves.
*/ */
@Deprecated(message = RECURSIVELY_CALL_DEPRECATED_MESSAGE, level = DeprecationLevel.ERROR) @Deprecated(message = DEPRECATED_MESSAGE, level = DeprecationLevel.ERROR)
@JvmSynthetic @JvmSynthetic
fun List<MemberResolver<*, *>>.resolve(): List<MemberResolver<*, *>> = error(RECURSIVELY_CALL_EXCEPTION_MESSAGE) fun MemberCondition<*, *, *>.resolve(): MemberCondition<*, *, *> = error(EXCEPTION_MESSAGE)
/**
* This is a fake function call chains to avoid internal calls to themselves.
*/
@Deprecated(message = DEPRECATED_MESSAGE, level = DeprecationLevel.ERROR)
@JvmSynthetic
fun MemberResolver<*, *>.asResolver(): MemberResolver<*, *> = error(EXCEPTION_MESSAGE)
/**
* This is a fake function call chains to avoid internal calls to themselves.
*/
@Deprecated(message = DEPRECATED_MESSAGE, level = DeprecationLevel.ERROR)
@JvmSynthetic
fun MemberResolver<*, *>.resolve(): MemberResolver<*, *> = error(EXCEPTION_MESSAGE)
/**
* This is a fake function call chains to avoid internal calls to themselves.
*/
@Deprecated(message = DEPRECATED_MESSAGE, level = DeprecationLevel.ERROR)
@JvmSynthetic
fun List<MemberResolver<*, *>>.asResolver(): List<MemberResolver<*, *>> = error(EXCEPTION_MESSAGE)
/**
* This is a fake function call chains to avoid internal calls to themselves.
*/
@Deprecated(message = DEPRECATED_MESSAGE, level = DeprecationLevel.ERROR)
@JvmSynthetic
fun List<MemberResolver<*, *>>.resolve(): List<MemberResolver<*, *>> = error(EXCEPTION_MESSAGE)
} }
/** /**