From 5112a7964a1afb1afa8a5fc039c565a649cd769b Mon Sep 17 00:00:00 2001 From: fankesyooni Date: Wed, 27 Jul 2022 01:38:36 +0800 Subject: [PATCH] Fix ConstructorFinder bug when the params set to nothing will got NoSuchMethodError --- docs/guide/special-feature.md | 41 ++++++++++++++++++- .../hook/core/YukiMemberHookCreater.kt | 4 +- .../hook/factory/ReflectionFactory.kt | 11 +++-- 3 files changed, 48 insertions(+), 8 deletions(-) diff --git a/docs/guide/special-feature.md b/docs/guide/special-feature.md index f47739f0..ca3d11fa 100644 --- a/docs/guide/special-feature.md +++ b/docs/guide/special-feature.md @@ -742,7 +742,7 @@ method { #### 必要的查询条件 -!> 在方法、构造方法查询条件中,**即使是无参的方法也需要设置查询条件**。 +!> 在普通方法查询条件中,**即使是无参的方法也需要设置查询条件**。 假设我们有如下的 `Class`。 @@ -793,7 +793,44 @@ TestFoo::class.java.method { 至此,上述的示例将可以完美地匹配到 `public void foo()` 方法。 -> PS:在较旧的 API 版本中是允许匹配不写默认匹配无参方法的做法的,但是最新版本更正了这一问题,请确保你使用的是最新版本的 API。 +> PS:在较旧的 API 版本中是允许匹配不写默认匹配无参方法的做法的,但是最新版本更正了这一问题,请确保你使用的是最新的 API 版本。 + +#### 可简写查询条件 + +> 在构造方法查询条件中,**无参的构造方法可以不需要填写查询条件**。 + +假设我们有如下的 `Class`。 + +> 示例如下 + +```java +public class TestFoo { + + public TestFoo() { + // ... + } +} +``` + +我们要得到其中的 `public TestFoo()` 构造方法,可以写作如下形式。 + +> 示例如下 + +```kotlin +TestFoo::class.java.constructor { emptyParam() } +``` + +上面的例子可以成功获取到 `public TestFoo()` 构造方法,但是感觉有一些繁琐。 + +与普通方法不同,由于构造方法不需要考虑 `name` 名称,当构造方法没有参数的时候,我们可以省略 `emptyParam` 参数。 + +> 示例如下 + +```kotlin +TestFoo::class.java.constructor() +``` + +!> PS:在旧的 API 版本中构造方法不填写任何查询参数会直接找不到构造方法,**这是一个 BUG,最新版本已经进行修复**,请确保你使用的是最新的 API 版本。 #### 字节码类型 diff --git a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/YukiMemberHookCreater.kt b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/YukiMemberHookCreater.kt index 148e63cf..30560230 100644 --- a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/YukiMemberHookCreater.kt +++ b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/YukiMemberHookCreater.kt @@ -275,7 +275,7 @@ class YukiMemberHookCreater(@PublishedApi internal val packageParam: PackagePara * @param initiate 方法体 * @return [ConstructorFinder.Result] */ - inline fun constructor(initiate: ConstructorFinder.() -> Unit = {}) = try { + inline fun constructor(initiate: ConstructorFinder.() -> Unit = { emptyParam() }) = try { hookMemberMode = HookMemberMode.HOOK_CONVENTIONAL isHookMemberSetup = true ConstructorFinder(hookInstance = this, hookClass.instance).apply(initiate).apply { finder = this }.build(isBind = true) @@ -307,7 +307,7 @@ class YukiMemberHookCreater(@PublishedApi internal val packageParam: PackagePara * @param initiate 方法体 * @return [ConstructorFinder.Result] */ - inline fun HookParam.constructor(initiate: ConstructorFinder.() -> Unit) = + inline fun HookParam.constructor(initiate: ConstructorFinder.() -> Unit = { emptyParam() }) = if (hookClass.instance == null) ConstructorFinder(hookInstance = this@MemberHookCreater).failure(hookClass.throwable) else ConstructorFinder(hookInstance = this@MemberHookCreater, hookClass.instance).apply(initiate).build() diff --git a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/factory/ReflectionFactory.kt b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/factory/ReflectionFactory.kt index d88348b9..b6fa3b50 100644 --- a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/factory/ReflectionFactory.kt +++ b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/factory/ReflectionFactory.kt @@ -123,7 +123,8 @@ inline fun Class<*>.hasMethod(initiate: MethodFinder.() -> Unit) = method(initia * @param initiate 方法体 * @return [Boolean] 是否存在 */ -inline fun Class<*>.hasConstructor(initiate: ConstructorFinder.() -> Unit) = constructor(initiate).ignoredError().isNoSuch.not() +inline fun Class<*>.hasConstructor(initiate: ConstructorFinder.() -> Unit = { emptyParam() }) = + constructor(initiate).ignoredError().isNoSuch.not() /** * 查询 [Member] 中匹配的描述符 @@ -151,7 +152,8 @@ inline fun Class<*>.method(initiate: MethodFinder.() -> Unit) = MethodFinder(cla * @param initiate 查找方法体 * @return [ConstructorFinder.Result] */ -inline fun Class<*>.constructor(initiate: ConstructorFinder.() -> Unit) = ConstructorFinder(classSet = this).apply(initiate).build() +inline fun Class<*>.constructor(initiate: ConstructorFinder.() -> Unit = { emptyParam() }) = + ConstructorFinder(classSet = this).apply(initiate).build() /** * 获得当前实例的类操作对象 @@ -169,7 +171,8 @@ inline fun T.current(initiate: CurrentClass.() -> Unit): T { * @param initiate 查找方法体 * @return [Any] or null */ -inline fun Class<*>.buildOfAny(vararg param: Any?, initiate: ConstructorFinder.() -> Unit = {}) = constructor(initiate).get().call(*param) +inline fun Class<*>.buildOfAny(vararg param: Any?, initiate: ConstructorFinder.() -> Unit = { emptyParam() }) = + constructor(initiate).get().call(*param) /** * 通过构造方法创建新实例 - 指定类型 [T] @@ -177,7 +180,7 @@ inline fun Class<*>.buildOfAny(vararg param: Any?, initiate: ConstructorFinder.( * @param initiate 查找方法体 * @return [T] or null */ -inline fun Class<*>.buildOf(vararg param: Any?, initiate: ConstructorFinder.() -> Unit = {}) = +inline fun Class<*>.buildOf(vararg param: Any?, initiate: ConstructorFinder.() -> Unit = { emptyParam() }) = constructor(initiate).get().newInstance(*param) /**