Added paramCount { ... } function in MethodFinder and ConstructorFinder

This commit is contained in:
2022-09-11 23:37:45 +08:00
parent 42462938c3
commit bc03f14ba5
7 changed files with 109 additions and 3 deletions

View File

@@ -42,6 +42,7 @@ import com.highcapable.yukihookapi.hook.factory.checkingInternal
import com.highcapable.yukihookapi.hook.factory.hasExtends
import com.highcapable.yukihookapi.hook.log.yLoggerW
import com.highcapable.yukihookapi.hook.type.defined.UndefinedType
import com.highcapable.yukihookapi.hook.utils.IntConditions
import com.highcapable.yukihookapi.hook.utils.runBlocking
import com.highcapable.yukihookapi.hook.utils.unit
import java.lang.reflect.Constructor
@@ -164,6 +165,26 @@ class ConstructorFinder @PublishedApi internal constructor(
return IndexTypeCondition(IndexConfigType.MATCH)
}
/**
* 设置 [Constructor] 参数个数条件
*
* 你可以不使用 [param] 指定参数类型而是仅使用此方法指定参数个数条件
*
* 使用示例如下 ↓
*
* ```kotlin
* paramCount { it > 5 && it != 0 }
* ```
*
* - ❗存在多个 [BaseFinder.IndexTypeCondition] 时除了 [order] 只会生效最后一个
* @param conditions 条件方法体
* @return [BaseFinder.IndexTypeCondition]
*/
fun paramCount(conditions: IntConditions): IndexTypeCondition {
rulesData.paramCountConditions = conditions
return IndexTypeCondition(IndexConfigType.MATCH)
}
/**
* 设置在 [classSet] 的所有父类中查找当前 [Constructor]
*

View File

@@ -43,6 +43,7 @@ import com.highcapable.yukihookapi.hook.factory.checkingInternal
import com.highcapable.yukihookapi.hook.factory.hasExtends
import com.highcapable.yukihookapi.hook.log.yLoggerW
import com.highcapable.yukihookapi.hook.type.defined.UndefinedType
import com.highcapable.yukihookapi.hook.utils.IntConditions
import com.highcapable.yukihookapi.hook.utils.runBlocking
import com.highcapable.yukihookapi.hook.utils.unit
import com.highcapable.yukihookapi.hook.xposed.bridge.factory.YukiHookHelper
@@ -222,6 +223,26 @@ class MethodFinder @PublishedApi internal constructor(
return IndexTypeCondition(IndexConfigType.MATCH)
}
/**
* 设置 [Method] 参数个数条件
*
* 你可以不使用 [param] 指定参数类型而是仅使用此方法指定参数个数条件
*
* 使用示例如下 ↓
*
* ```kotlin
* paramCount { it > 5 && it != 0 }
* ```
*
* - ❗存在多个 [BaseFinder.IndexTypeCondition] 时除了 [order] 只会生效最后一个
* @param conditions 条件方法体
* @return [BaseFinder.IndexTypeCondition]
*/
fun paramCount(conditions: IntConditions): IndexTypeCondition {
rulesData.paramCountConditions = conditions
return IndexTypeCondition(IndexConfigType.MATCH)
}
/**
* 设置 [Method] 返回值
*

View File

@@ -27,6 +27,7 @@
*/
package com.highcapable.yukihookapi.hook.core.finder.members.data
import com.highcapable.yukihookapi.hook.utils.IntConditions
import java.lang.reflect.Constructor
/**
@@ -34,17 +35,21 @@ import java.lang.reflect.Constructor
* @param paramTypes 参数类型数组
* @param paramCount 参数个数
* @param paramCountRange 参数个数范围
* @param paramCountConditions 参数个数条件
*/
@PublishedApi
internal class ConstructorRulesData internal constructor(
var paramTypes: Array<out Class<*>>? = null,
var paramCount: Int = -1,
var paramCountRange: IntRange = IntRange.EMPTY
var paramCountRange: IntRange = IntRange.EMPTY,
var paramCountConditions: IntConditions? = null
) : MemberRulesData() {
override val objectName get() = "Constructor"
override val isInitialize get() = super.isInitializeOfSuper || paramTypes != null || paramCount >= 0 || paramCountRange != IntRange.EMPTY
override val isInitialize
get() = super.isInitializeOfSuper || paramTypes != null || paramCount >= 0 ||
paramCountRange != IntRange.EMPTY || paramCountConditions != null
override fun hashCode(other: Any?) = super.hashCode(other) + "[$paramTypes][$paramCount][$paramCountRange]".hashCode()
}

View File

@@ -28,6 +28,7 @@
package com.highcapable.yukihookapi.hook.core.finder.members.data
import com.highcapable.yukihookapi.hook.core.finder.type.NameConditions
import com.highcapable.yukihookapi.hook.utils.IntConditions
import java.lang.reflect.Method
/**
@@ -37,6 +38,7 @@ import java.lang.reflect.Method
* @param paramTypes 参数类型数组
* @param paramCount 参数个数
* @param paramCountRange 参数个数范围
* @param paramCountConditions 参数个数条件
* @param returnType 返回值类型
*/
@PublishedApi
@@ -46,6 +48,7 @@ internal class MethodRulesData internal constructor(
var paramTypes: Array<out Class<*>>? = null,
var paramCount: Int = -1,
var paramCountRange: IntRange = IntRange.EMPTY,
var paramCountConditions: IntConditions? = null,
var returnType: Any? = null
) : MemberRulesData() {
@@ -53,7 +56,7 @@ internal class MethodRulesData internal constructor(
override val isInitialize
get() = super.isInitializeOfSuper || name.isNotBlank() || nameConditions != null || paramTypes != null ||
paramCount >= 0 || paramCountRange != IntRange.EMPTY || returnType != null
paramCount >= 0 || paramCountRange != IntRange.EMPTY || paramCountConditions != null || returnType != null
override fun hashCode(other: Any?) =
super.hashCode(other) + "[$name][$nameConditions][$paramTypes][$paramCount][$paramCountRange][$returnType]".hashCode()

View File

@@ -159,6 +159,7 @@ internal object ReflectionTool {
var iParamTypes = -1
var iParamCount = -1
var iParamCountRange = -1
var iParamCountCds = -1
var iName = -1
var iModify = -1
var iNameCds = -1
@@ -167,6 +168,8 @@ internal object ReflectionTool {
?.let { e -> declares.filter { e == it.parameterTypes.size }.lastIndex } ?: -1
val iLParamCountRange = paramCountRange.takeIf(matchIndex) { it.isEmpty().not() }
?.let { e -> declares.filter { it.parameterTypes.size in e }.lastIndex } ?: -1
val iLParamCountCds = paramCountConditions
?.let(matchIndex) { e -> declares.filter { e(it.parameterTypes.size) }.lastIndex } ?: -1
val iLParamTypes = paramTypes?.let(matchIndex) { e -> declares.filter { arrayContentsEq(e, it.parameterTypes) }.lastIndex } ?: -1
val iLName = name.takeIf(matchIndex) { it.isNotBlank() }?.let { e -> declares.filter { e == it.name }.lastIndex } ?: -1
val iLModify = modifiers?.let(matchIndex) { e -> declares.filter { e.contains(it) }.lastIndex } ?: -1
@@ -197,6 +200,12 @@ internal object ReflectionTool {
hold && matchIndex.compare(iParamCountRange, iLParamCountRange)
})
}
paramCountConditions?.also {
and(it(instance.parameterTypes.size).let { hold ->
if (hold) iParamCountCds++
hold && matchIndex.compare(iParamCountCds, iLParamCountCds)
})
}
paramTypes?.also {
and(arrayContentsEq(it, instance.parameterTypes).let { hold ->
if (hold) iParamTypes++
@@ -239,11 +248,14 @@ internal object ReflectionTool {
var iParamTypes = -1
var iParamCount = -1
var iParamCountRange = -1
var iParamCountCds = -1
var iModify = -1
val iLParamCount = paramCount.takeIf(matchIndex) { it >= 0 }
?.let { e -> declares.filter { e == it.parameterTypes.size }.lastIndex } ?: -1
val iLParamCountRange = paramCountRange.takeIf(matchIndex) { it.isEmpty().not() }
?.let { e -> declares.filter { it.parameterTypes.size in e }.lastIndex } ?: -1
val iLParamCountCds = paramCountConditions
?.let(matchIndex) { e -> declares.filter { e(it.parameterTypes.size) }.lastIndex } ?: -1
val iLParamTypes = paramTypes?.let(matchIndex) { e -> declares.filter { arrayContentsEq(e, it.parameterTypes) }.lastIndex } ?: -1
val iLModify = modifiers?.let(matchIndex) { e -> declares.filter { e.contains(it) }.lastIndex } ?: -1
declares.forEachIndexed { index, instance ->
@@ -260,6 +272,12 @@ internal object ReflectionTool {
hold && matchIndex.compare(iParamCountRange, iLParamCountRange)
})
}
paramCountConditions?.also {
and(it(instance.parameterTypes.size).let { hold ->
if (hold) iParamCountCds++
hold && matchIndex.compare(iParamCountCds, iLParamCountCds)
})
}
paramTypes?.also {
and(arrayContentsEq(it, instance.parameterTypes).let { hold ->
if (hold) iParamTypes++
@@ -367,6 +385,7 @@ internal object ReflectionTool {
nameConditions?.let { "nameConditions:$it" } ?: "",
"paramCount:[${paramCount.takeIf { it >= 0 } ?: "unspecified"}]",
"paramCountRange:[${paramCountRange.takeIf { it.isEmpty().not() } ?: "unspecified"}]",
"paramCountConditions:[${paramCountConditions?.let { "existed" } ?: "unspecified"}]",
"paramTypes:[${paramTypes.typeOfString()}]",
"returnType:[${returnType ?: "unspecified"}]",
"modifiers:${modifiers ?: "[]"}",
@@ -377,6 +396,7 @@ internal object ReflectionTool {
instanceSet, name = "Constructor",
"paramCount:[${paramCount.takeIf { it >= 0 } ?: "unspecified"}]",
"paramCountRange:[${paramCountRange.takeIf { it.isEmpty().not() } ?: "unspecified"}]",
"paramCountConditions:[${paramCountConditions?.let { "existed" } ?: "unspecified"}]",
"paramTypes:[${paramTypes.typeOfString()}]",
"modifiers:${modifiers ?: "[]"}",
orderIndex?.let { it.takeIf { it.second }?.let { e -> "orderIndex:[${e.first}]" } ?: "orderIndex:[last]" } ?: "",