mirror of
https://github.com/HighCapable/YukiHookAPI.git
synced 2025-09-04 09:45:19 +08:00
Modify move orderIndex, matchIndex in BaseRulesData and move modifiers to BaseRulesData and add objectName in BaseRulesData and make ReflectionTool simplify
This commit is contained in:
@@ -29,6 +29,7 @@ package com.highcapable.yukihookapi.hook.core.finder.base
|
||||
|
||||
import com.highcapable.yukihookapi.annotation.YukiPrivateApi
|
||||
import com.highcapable.yukihookapi.hook.bean.VariousClass
|
||||
import com.highcapable.yukihookapi.hook.core.finder.base.data.BaseRulesData
|
||||
import com.highcapable.yukihookapi.hook.factory.toClass
|
||||
import com.highcapable.yukihookapi.hook.type.defined.UndefinedType
|
||||
import java.lang.reflect.Member
|
||||
@@ -39,18 +40,16 @@ import kotlin.math.abs
|
||||
*/
|
||||
abstract class BaseFinder {
|
||||
|
||||
/** 当前查询条件规则数据 */
|
||||
@PublishedApi
|
||||
internal abstract val rulesData: BaseRulesData
|
||||
|
||||
/**
|
||||
* 字节码、数组下标筛选数据类型
|
||||
*/
|
||||
@PublishedApi
|
||||
internal enum class IndexConfigType { ORDER, MATCH }
|
||||
|
||||
/** 字节码、数组顺序下标 */
|
||||
internal var orderIndex: Pair<Int, Boolean>? = null
|
||||
|
||||
/** 字节码、数组筛选下标 */
|
||||
internal var matchIndex: Pair<Int, Boolean>? = null
|
||||
|
||||
/**
|
||||
* 字节码、数组下标筛选实现类
|
||||
* @param type 类型
|
||||
@@ -66,8 +65,8 @@ abstract class BaseFinder {
|
||||
* @param num 下标
|
||||
*/
|
||||
fun index(num: Int) = when (type) {
|
||||
IndexConfigType.ORDER -> orderIndex = Pair(num, true)
|
||||
IndexConfigType.MATCH -> matchIndex = Pair(num, true)
|
||||
IndexConfigType.ORDER -> rulesData.orderIndex = Pair(num, true)
|
||||
IndexConfigType.MATCH -> rulesData.matchIndex = Pair(num, true)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -88,8 +87,8 @@ abstract class BaseFinder {
|
||||
|
||||
/** 设置满足条件的最后一个*/
|
||||
fun last() = when (type) {
|
||||
IndexConfigType.ORDER -> orderIndex = Pair(0, false)
|
||||
IndexConfigType.MATCH -> matchIndex = Pair(0, false)
|
||||
IndexConfigType.ORDER -> rulesData.orderIndex = Pair(0, false)
|
||||
IndexConfigType.MATCH -> rulesData.matchIndex = Pair(0, false)
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* YukiHookAPI - An efficient Kotlin version of the Xposed Hook API.
|
||||
* Copyright (C) 2019-2022 HighCapable
|
||||
* https://github.com/fankes/YukiHookAPI
|
||||
*
|
||||
* MIT License
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* This file is Created by fankes on 2022/9/8.
|
||||
*/
|
||||
package com.highcapable.yukihookapi.hook.core.finder.base.data
|
||||
|
||||
import com.highcapable.yukihookapi.hook.core.finder.type.ModifierRules
|
||||
import java.lang.reflect.Member
|
||||
|
||||
/**
|
||||
* 这是 [Class] 与 [Member] 规则查询数据基本类实现
|
||||
* @param modifiers 描述符
|
||||
* @param orderIndex 字节码、数组顺序下标
|
||||
* @param matchIndex 字节码、数组筛选下标
|
||||
*/
|
||||
@PublishedApi
|
||||
internal abstract class BaseRulesData internal constructor(
|
||||
var modifiers: ModifierRules? = null,
|
||||
var orderIndex: Pair<Int, Boolean>? = null,
|
||||
var matchIndex: Pair<Int, Boolean>? = null
|
||||
) {
|
||||
|
||||
/**
|
||||
* 获取规则对象名称
|
||||
* @return [String]
|
||||
*/
|
||||
internal abstract val objectName: String
|
||||
|
||||
/**
|
||||
* 判断规则是否已经初始化 (设置了任意一个参数)
|
||||
* @return [Boolean]
|
||||
*/
|
||||
internal open val isInitialize get() = modifiers != null || orderIndex != null || matchIndex != null
|
||||
|
||||
/**
|
||||
* 通过规则数据 [toString] 来得到一个 [Any.hashCode]
|
||||
* @param other 额外的数据 - 可选
|
||||
* @return [Int]
|
||||
*/
|
||||
internal open fun hashCode(other: Any? = null) = "[$other][$modifiers][$orderIndex][$matchIndex]".hashCode()
|
||||
}
|
@@ -61,16 +61,15 @@ class ConstructorFinder @PublishedApi internal constructor(
|
||||
override val classSet: Class<*>? = null
|
||||
) : MemberBaseFinder(tag = "Constructor", hookInstance, classSet) {
|
||||
|
||||
@PublishedApi
|
||||
override var rulesData = ConstructorRulesData()
|
||||
|
||||
/** 当前使用的 [classSet] */
|
||||
private var usedClassSet = classSet
|
||||
|
||||
/** 当前重查找结果回调 */
|
||||
private var remedyPlansCallback: (() -> Unit)? = null
|
||||
|
||||
/** 当前查询条件规则数据 */
|
||||
@PublishedApi
|
||||
internal var rulesData = ConstructorRulesData()
|
||||
|
||||
/**
|
||||
* 设置 [Constructor] 参数个数
|
||||
*
|
||||
@@ -175,7 +174,7 @@ class ConstructorFinder @PublishedApi internal constructor(
|
||||
* @return [HashSet]<[Constructor]>
|
||||
* @throws NoSuchMethodError 如果找不到 [Constructor]
|
||||
*/
|
||||
private val result get() = ReflectionTool.findConstructors(usedClassSet, orderIndex, matchIndex, rulesData)
|
||||
private val result by lazy { ReflectionTool.findConstructors(usedClassSet, rulesData) }
|
||||
|
||||
/**
|
||||
* 设置实例
|
||||
|
@@ -62,16 +62,15 @@ class FieldFinder @PublishedApi internal constructor(
|
||||
override val classSet: Class<*>? = null
|
||||
) : MemberBaseFinder(tag = "Field", hookInstance, classSet) {
|
||||
|
||||
@PublishedApi
|
||||
override var rulesData = FieldRulesData()
|
||||
|
||||
/** 当前使用的 [classSet] */
|
||||
private var usedClassSet = classSet
|
||||
|
||||
/** 当前重查找结果回调 */
|
||||
private var remedyPlansCallback: (() -> Unit)? = null
|
||||
|
||||
/** 当前查询条件规则数据 */
|
||||
@PublishedApi
|
||||
internal var rulesData = FieldRulesData()
|
||||
|
||||
/**
|
||||
* 设置 [Field] 名称
|
||||
*
|
||||
@@ -176,7 +175,7 @@ class FieldFinder @PublishedApi internal constructor(
|
||||
* @return [HashSet]<[Field]>
|
||||
* @throws NoSuchFieldError 如果找不到 [Field]
|
||||
*/
|
||||
private val result get() = ReflectionTool.findFields(usedClassSet, orderIndex, matchIndex, rulesData)
|
||||
private val result get() = ReflectionTool.findFields(usedClassSet, rulesData)
|
||||
|
||||
/**
|
||||
* 设置实例
|
||||
|
@@ -63,16 +63,15 @@ class MethodFinder @PublishedApi internal constructor(
|
||||
override val classSet: Class<*>? = null
|
||||
) : MemberBaseFinder(tag = "Method", hookInstance, classSet) {
|
||||
|
||||
@PublishedApi
|
||||
override var rulesData = MethodRulesData()
|
||||
|
||||
/** 当前使用的 [classSet] */
|
||||
private var usedClassSet = classSet
|
||||
|
||||
/** 当前重查找结果回调 */
|
||||
private var remedyPlansCallback: (() -> Unit)? = null
|
||||
|
||||
/** 当前查询条件规则数据 */
|
||||
@PublishedApi
|
||||
internal var rulesData = MethodRulesData()
|
||||
|
||||
/**
|
||||
* 设置 [Method] 名称
|
||||
*
|
||||
@@ -247,7 +246,7 @@ class MethodFinder @PublishedApi internal constructor(
|
||||
* @return [HashSet]<[Method]>
|
||||
* @throws NoSuchMethodError 如果找不到 [Method]
|
||||
*/
|
||||
private val result get() = ReflectionTool.findMethods(usedClassSet, orderIndex, matchIndex, rulesData)
|
||||
private val result get() = ReflectionTool.findMethods(usedClassSet, rulesData)
|
||||
|
||||
/**
|
||||
* 设置实例
|
||||
|
@@ -40,4 +40,11 @@ internal class ConstructorRulesData internal constructor(
|
||||
var paramTypes: Array<out Class<*>>? = null,
|
||||
var paramCount: Int = -1,
|
||||
var paramCountRange: IntRange = IntRange.EMPTY
|
||||
) : MemberRulesData()
|
||||
) : MemberRulesData() {
|
||||
|
||||
override val objectName get() = "Constructor"
|
||||
|
||||
override val isInitialize get() = super.isInitializeOfSuper || paramTypes != null || paramCount >= 0 || paramCountRange != IntRange.EMPTY
|
||||
|
||||
override fun hashCode(other: Any?) = super.hashCode(other) + "[$paramTypes][$paramCount][$paramCountRange]".hashCode()
|
||||
}
|
@@ -41,4 +41,11 @@ internal class FieldRulesData internal constructor(
|
||||
var name: String = "",
|
||||
var nameConditions: NameConditions? = null,
|
||||
var type: Any? = null
|
||||
) : MemberRulesData()
|
||||
) : MemberRulesData() {
|
||||
|
||||
override val objectName get() = "Field"
|
||||
|
||||
override val isInitialize get() = super.isInitializeOfSuper || name.isNotBlank() || nameConditions != null || type != null
|
||||
|
||||
override fun hashCode(other: Any?) = super.hashCode(other) + "[$name][$nameConditions][$type]".hashCode()
|
||||
}
|
@@ -27,20 +27,31 @@
|
||||
*/
|
||||
package com.highcapable.yukihookapi.hook.core.finder.members.data
|
||||
|
||||
import com.highcapable.yukihookapi.hook.core.finder.type.ModifierRules
|
||||
import com.highcapable.yukihookapi.hook.core.finder.base.data.BaseRulesData
|
||||
import java.lang.reflect.Member
|
||||
|
||||
/**
|
||||
* [Member] 规则查询数据类
|
||||
* @param modifiers 描述符
|
||||
* @param isFindInSuper 是否在未找到后继续在父类中查找
|
||||
* @param matchCount 匹配的字节码个数
|
||||
* @param matchCountRange 匹配的字节码个数范围
|
||||
*/
|
||||
@PublishedApi
|
||||
internal open class MemberRulesData internal constructor(
|
||||
var modifiers: ModifierRules? = null,
|
||||
var isFindInSuper: Boolean = false,
|
||||
var matchCount: Int = -1,
|
||||
var matchCountRange: IntRange = IntRange.EMPTY
|
||||
)
|
||||
) : BaseRulesData() {
|
||||
|
||||
override val objectName get() = "Member"
|
||||
|
||||
/**
|
||||
* 判断 [BaseRulesData] 规则是否已经初始化 (设置了任意一个参数)
|
||||
* @return [Boolean]
|
||||
*/
|
||||
internal val isInitializeOfSuper get() = super.isInitialize
|
||||
|
||||
override val isInitialize get() = isInitializeOfSuper || matchCount >= 0 || matchCountRange != IntRange.EMPTY
|
||||
|
||||
override fun hashCode(other: Any?) = super.hashCode(other) + "[$isFindInSuper][$matchIndex][$matchCountRange]".hashCode()
|
||||
}
|
@@ -47,4 +47,14 @@ internal class MethodRulesData internal constructor(
|
||||
var paramCount: Int = -1,
|
||||
var paramCountRange: IntRange = IntRange.EMPTY,
|
||||
var returnType: Any? = null
|
||||
) : MemberRulesData()
|
||||
) : MemberRulesData() {
|
||||
|
||||
override val objectName get() = "Method"
|
||||
|
||||
override val isInitialize
|
||||
get() = super.isInitializeOfSuper || name.isNotBlank() || nameConditions != null || paramTypes != null ||
|
||||
paramCount >= 0 || paramCountRange != IntRange.EMPTY || returnType != null
|
||||
|
||||
override fun hashCode(other: Any?) =
|
||||
super.hashCode(other) + "[$name][$nameConditions][$paramTypes][$paramCount][$paramCountRange][$returnType]".hashCode()
|
||||
}
|
@@ -27,13 +27,17 @@
|
||||
*/
|
||||
package com.highcapable.yukihookapi.hook.core.reflex.tools
|
||||
|
||||
import com.highcapable.yukihookapi.hook.core.finder.base.data.BaseRulesData
|
||||
import com.highcapable.yukihookapi.hook.core.finder.members.data.ConstructorRulesData
|
||||
import com.highcapable.yukihookapi.hook.core.finder.members.data.FieldRulesData
|
||||
import com.highcapable.yukihookapi.hook.core.finder.members.data.MemberRulesData
|
||||
import com.highcapable.yukihookapi.hook.core.finder.members.data.MethodRulesData
|
||||
import com.highcapable.yukihookapi.hook.factory.hasExtends
|
||||
import com.highcapable.yukihookapi.hook.store.ReflectsCacheStore
|
||||
import com.highcapable.yukihookapi.hook.type.defined.UndefinedType
|
||||
import com.highcapable.yukihookapi.hook.utils.conditions
|
||||
import com.highcapable.yukihookapi.hook.utils.let
|
||||
import com.highcapable.yukihookapi.hook.utils.takeIf
|
||||
import com.highcapable.yukihookapi.hook.xposed.bridge.YukiHookBridge
|
||||
import com.highcapable.yukihookapi.hook.xposed.bridge.factory.YukiHookHelper
|
||||
import com.highcapable.yukihookapi.hook.xposed.parasitic.AppParasitics
|
||||
@@ -84,413 +88,350 @@ internal object ReflectionTool {
|
||||
/**
|
||||
* 查找任意 [Field] 或一组 [Field]
|
||||
* @param classSet [Field] 所在类
|
||||
* @param orderIndex 字节码顺序下标
|
||||
* @param matchIndex 字节码筛选下标
|
||||
* @param rulesData 规则查询数据
|
||||
* @return [HashSet]<[Field]>
|
||||
* @throws IllegalStateException 如果 [classSet] 为 null 或未设置任何条件或 [FieldRulesData.type] 目标类不存在
|
||||
* @throws IllegalStateException 如果未设置任何条件或 [FieldRulesData.type] 目标类不存在
|
||||
* @throws NoSuchFieldError 如果找不到 [Field]
|
||||
*/
|
||||
internal fun findFields(
|
||||
classSet: Class<*>?,
|
||||
orderIndex: Pair<Int, Boolean>?,
|
||||
matchIndex: Pair<Int, Boolean>?,
|
||||
rulesData: FieldRulesData
|
||||
): HashSet<Field> {
|
||||
if (rulesData.type == UndefinedType) error("Field match type class is not found")
|
||||
if (orderIndex == null && matchIndex == null &&
|
||||
rulesData.name.isBlank() && rulesData.nameConditions == null &&
|
||||
rulesData.modifiers == null && rulesData.type == null
|
||||
) error("You must set a condition when finding a Field")
|
||||
val hashCode = ("[$orderIndex][$matchIndex][${rulesData.name}][${rulesData.nameConditions}]" +
|
||||
"[${rulesData.type}][${rulesData.modifiers}][$classSet]").hashCode()
|
||||
return ReflectsCacheStore.findFields(hashCode) ?: let {
|
||||
val fields = HashSet<Field>()
|
||||
classSet?.declaredFields?.apply {
|
||||
var typeIndex = -1
|
||||
var nameIndex = -1
|
||||
var modifyIndex = -1
|
||||
var nameCdsIndex = -1
|
||||
val typeLastIndex =
|
||||
if (rulesData.type != null && matchIndex != null) filter { rulesData.type == it.type }.lastIndex else -1
|
||||
val nameLastIndex =
|
||||
if (rulesData.name.isNotBlank() && matchIndex != null) filter { rulesData.name == it.name }.lastIndex else -1
|
||||
val modifyLastIndex =
|
||||
if (rulesData.modifiers != null && matchIndex != null) filter { rulesData.modifiers!!.contains(it) }.lastIndex else -1
|
||||
val nameCdsLastIndex =
|
||||
if (rulesData.nameConditions != null && matchIndex != null) filter { rulesData.nameConditions!!.contains(it) }.lastIndex else -1
|
||||
forEachIndexed { p, instance ->
|
||||
internal fun findFields(classSet: Class<*>?, rulesData: FieldRulesData) = rulesData.createResult {
|
||||
if (type == UndefinedType) error("Field match type class is not found")
|
||||
if (classSet == null) return@createResult hashSetOf()
|
||||
ReflectsCacheStore.findFields(hashCode(classSet)) ?: hashSetOf<Field>().also { fields ->
|
||||
classSet.declaredFields.also { declares ->
|
||||
var iType = -1
|
||||
var iName = -1
|
||||
var iModify = -1
|
||||
var iNameCds = -1
|
||||
val iLType = type?.let(matchIndex) { e -> declares.filter { e == it.type }.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
|
||||
val iLNameCds = nameConditions?.let(matchIndex) { e -> declares.filter { e.contains(it) }.lastIndex } ?: -1
|
||||
declares.forEachIndexed { index, instance ->
|
||||
var isMatched = false
|
||||
rulesData.conditions {
|
||||
value.type?.also { e ->
|
||||
and((e == instance.type).let {
|
||||
if (it) typeIndex++
|
||||
conditions {
|
||||
type?.also {
|
||||
and((it == instance.type).let { hold ->
|
||||
if (hold) iType++
|
||||
isMatched = true
|
||||
it && (matchIndex == null ||
|
||||
(matchIndex.first >= 0 && matchIndex.first == typeIndex && matchIndex.second) ||
|
||||
(matchIndex.first < 0 &&
|
||||
abs(matchIndex.first) == (typeLastIndex - typeIndex) && matchIndex.second) ||
|
||||
(typeLastIndex == typeIndex && matchIndex.second.not()))
|
||||
hold && matchIndex.compare(iType, iLType)
|
||||
})
|
||||
}
|
||||
value.name.takeIf { it.isNotBlank() }?.also { e ->
|
||||
and((e == instance.name).let {
|
||||
if (it) nameIndex++
|
||||
name.takeIf { it.isNotBlank() }?.also {
|
||||
and((it == instance.name).let { hold ->
|
||||
if (hold) iName++
|
||||
isMatched = true
|
||||
it && (matchIndex == null ||
|
||||
(matchIndex.first >= 0 && matchIndex.first == nameIndex && matchIndex.second) ||
|
||||
(matchIndex.first < 0 &&
|
||||
abs(matchIndex.first) == (nameLastIndex - nameIndex) && matchIndex.second) ||
|
||||
(nameLastIndex == nameIndex && matchIndex.second.not()))
|
||||
hold && matchIndex.compare(iName, iLName)
|
||||
})
|
||||
}
|
||||
value.modifiers?.also { e ->
|
||||
and(e.contains(instance).let {
|
||||
if (it) modifyIndex++
|
||||
modifiers?.also {
|
||||
and(it.contains(instance).let { hold ->
|
||||
if (hold) iModify++
|
||||
isMatched = true
|
||||
it && (matchIndex == null ||
|
||||
(matchIndex.first >= 0 && matchIndex.first == modifyIndex && matchIndex.second) ||
|
||||
(matchIndex.first < 0 &&
|
||||
abs(matchIndex.first) == (modifyLastIndex - modifyIndex) && matchIndex.second) ||
|
||||
(modifyLastIndex == modifyIndex && matchIndex.second.not()))
|
||||
hold && matchIndex.compare(iModify, iLModify)
|
||||
})
|
||||
}
|
||||
value.nameConditions?.also { e ->
|
||||
and(e.contains(instance).let {
|
||||
if (it) nameCdsIndex++
|
||||
nameConditions?.also {
|
||||
and(it.contains(instance).let { hold ->
|
||||
if (hold) iNameCds++
|
||||
isMatched = true
|
||||
it && (matchIndex == null ||
|
||||
(matchIndex.first >= 0 && matchIndex.first == nameCdsIndex && matchIndex.second) ||
|
||||
(matchIndex.first < 0 &&
|
||||
abs(matchIndex.first) == (nameCdsLastIndex - nameCdsIndex) && matchIndex.second) ||
|
||||
(nameCdsLastIndex == nameCdsIndex && matchIndex.second.not()))
|
||||
hold && matchIndex.compare(iNameCds, iLNameCds)
|
||||
})
|
||||
}
|
||||
orderIndex?.also {
|
||||
and(((it.first >= 0 && it.first == p && it.second) ||
|
||||
(it.first < 0 && abs(it.first) == (lastIndex - p) && it.second) ||
|
||||
(lastIndex == p && it.second.not())).also { isMatched = true })
|
||||
}
|
||||
orderIndex.compare(index, declares.lastIndex) { and(it); isMatched = it }
|
||||
}.finally { if (isMatched) fields.add(instance.apply { isAccessible = true }) }
|
||||
}
|
||||
} ?: error("Can't find this Field [${rulesData.name}] because classSet is null")
|
||||
fields.takeIf { it.isNotEmpty() }?.also { ReflectsCacheStore.putFields(hashCode, fields) }
|
||||
?: if (rulesData.isFindInSuper && classSet.hasExtends)
|
||||
findFields(classSet.superclass, orderIndex, matchIndex, rulesData)
|
||||
else throw NoSuchFieldError(
|
||||
"Can't find this Field --> " +
|
||||
when {
|
||||
orderIndex == null -> ""
|
||||
orderIndex.second.not() -> "orderIndex:[last] "
|
||||
else -> "orderIndex:[${orderIndex.first}] "
|
||||
} +
|
||||
when {
|
||||
matchIndex == null -> ""
|
||||
matchIndex.second.not() -> "matchIndex:[last] "
|
||||
else -> "matchIndex:[${matchIndex.first}] "
|
||||
} +
|
||||
when (rulesData.nameConditions) {
|
||||
null -> ""
|
||||
else -> "nameConditions:${rulesData.nameConditions} "
|
||||
} +
|
||||
"name:[${rulesData.name.takeIf { it.isNotBlank() } ?: "unspecified"}] " +
|
||||
"type:[${rulesData.type ?: "unspecified"}] " +
|
||||
"modifiers:${rulesData.modifiers ?: "[]"} " +
|
||||
"in [$classSet] " +
|
||||
"by $TAG"
|
||||
)
|
||||
}
|
||||
}
|
||||
}.takeIf { it.isNotEmpty() }?.also { ReflectsCacheStore.putFields(hashCode(classSet), it) } ?: findSuperOrThrow(classSet)
|
||||
}
|
||||
|
||||
/**
|
||||
* 查找任意 [Method] 或一组 [Method]
|
||||
* @param classSet [Method] 所在类
|
||||
* @param orderIndex 字节码顺序下标
|
||||
* @param matchIndex 字节码筛选下标
|
||||
* @param rulesData 规则查询数据
|
||||
* @return [HashSet]<[Method]>
|
||||
* @throws IllegalStateException 如果 [classSet] 为 null 或未设置任何条件或 [MethodRulesData.paramTypes] 以及 [MethodRulesData.returnType] 目标类不存在
|
||||
* @throws IllegalStateException 如果未设置任何条件或 [MethodRulesData.paramTypes] 以及 [MethodRulesData.returnType] 目标类不存在
|
||||
* @throws NoSuchMethodError 如果找不到 [Method]
|
||||
*/
|
||||
internal fun findMethods(
|
||||
classSet: Class<*>?,
|
||||
orderIndex: Pair<Int, Boolean>?,
|
||||
matchIndex: Pair<Int, Boolean>?,
|
||||
rulesData: MethodRulesData
|
||||
): HashSet<Method> {
|
||||
if (rulesData.returnType == UndefinedType) error("Method match returnType class is not found")
|
||||
rulesData.paramTypes?.takeIf { it.isNotEmpty() }
|
||||
internal fun findMethods(classSet: Class<*>?, rulesData: MethodRulesData) = rulesData.createResult {
|
||||
if (returnType == UndefinedType) error("Method match returnType class is not found")
|
||||
if (classSet == null) return@createResult hashSetOf()
|
||||
paramTypes?.takeIf { it.isNotEmpty() }
|
||||
?.forEachIndexed { p, it -> if (it == UndefinedType) error("Method match paramType[$p] class is not found") }
|
||||
if (orderIndex == null && matchIndex == null &&
|
||||
rulesData.name.isBlank() && rulesData.nameConditions == null &&
|
||||
rulesData.modifiers == null && rulesData.paramCount < 0 &&
|
||||
rulesData.paramCountRange.isEmpty() && rulesData.paramTypes == null &&
|
||||
rulesData.returnType == null
|
||||
) error("You must set a condition when finding a Method")
|
||||
val hashCode = ("[$orderIndex][$matchIndex][${rulesData.name}][${rulesData.nameConditions}][${rulesData.paramCount}]" +
|
||||
"[${rulesData.paramTypes.typeOfString()}][${rulesData.returnType}][${rulesData.modifiers}][$classSet]").hashCode()
|
||||
return ReflectsCacheStore.findMethods(hashCode) ?: let {
|
||||
val methods = HashSet<Method>()
|
||||
classSet?.declaredMethods?.apply {
|
||||
var returnTypeIndex = -1
|
||||
var paramTypeIndex = -1
|
||||
var paramCountIndex = -1
|
||||
var paramCountRangeIndex = -1
|
||||
var nameIndex = -1
|
||||
var modifyIndex = -1
|
||||
var nameCdsIndex = -1
|
||||
val returnTypeLastIndex =
|
||||
if (rulesData.returnType != null && matchIndex != null) filter { rulesData.returnType == it.returnType }.lastIndex else -1
|
||||
val paramCountLastIndex =
|
||||
if (rulesData.paramCount >= 0 && matchIndex != null) filter { rulesData.paramCount == it.parameterTypes.size }.lastIndex else -1
|
||||
val paramCountRangeLastIndex = if (rulesData.paramCountRange.isEmpty().not() && matchIndex != null)
|
||||
filter { it.parameterTypes.size in rulesData.paramCountRange }.lastIndex else -1
|
||||
val paramTypeLastIndex =
|
||||
if (rulesData.paramTypes != null && matchIndex != null)
|
||||
filter { arrayContentsEq(rulesData.paramTypes, it.parameterTypes) }.lastIndex else -1
|
||||
val nameLastIndex =
|
||||
if (rulesData.name.isNotBlank() && matchIndex != null) filter { rulesData.name == it.name }.lastIndex else -1
|
||||
val modifyLastIndex =
|
||||
if (rulesData.modifiers != null && matchIndex != null) filter { rulesData.modifiers!!.contains(it) }.lastIndex else -1
|
||||
val nameCdsLastIndex =
|
||||
if (rulesData.nameConditions != null && matchIndex != null) filter { rulesData.nameConditions!!.contains(it) }.lastIndex else -1
|
||||
forEachIndexed { p, instance ->
|
||||
ReflectsCacheStore.findMethods(hashCode(classSet)) ?: hashSetOf<Method>().also { methods ->
|
||||
classSet.declaredMethods.also { declares ->
|
||||
var iReturnType = -1
|
||||
var iParamTypes = -1
|
||||
var iParamCount = -1
|
||||
var iParamCountRange = -1
|
||||
var iName = -1
|
||||
var iModify = -1
|
||||
var iNameCds = -1
|
||||
val iLReturnType = returnType?.let(matchIndex) { e -> declares.filter { e == it.returnType }.lastIndex } ?: -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 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
|
||||
val iLNameCds = nameConditions?.let(matchIndex) { e -> declares.filter { e.contains(it) }.lastIndex } ?: -1
|
||||
declares.forEachIndexed { index, instance ->
|
||||
var isMatched = false
|
||||
rulesData.conditions {
|
||||
value.name.takeIf { it.isNotBlank() }?.also { e ->
|
||||
and((e == instance.name).let {
|
||||
if (it) nameIndex++
|
||||
conditions {
|
||||
name.takeIf { it.isNotBlank() }?.also {
|
||||
and((it == instance.name).let { hold ->
|
||||
if (hold) iName++
|
||||
isMatched = true
|
||||
it && (matchIndex == null ||
|
||||
(matchIndex.first >= 0 && matchIndex.first == nameIndex && matchIndex.second) ||
|
||||
(matchIndex.first < 0 &&
|
||||
abs(matchIndex.first) == (nameLastIndex - nameIndex) && matchIndex.second) ||
|
||||
(nameLastIndex == nameIndex && matchIndex.second.not()))
|
||||
hold && matchIndex.compare(iName, iLName)
|
||||
})
|
||||
}
|
||||
value.returnType?.also { e ->
|
||||
and((e == instance.returnType).let {
|
||||
if (it) returnTypeIndex++
|
||||
returnType?.also {
|
||||
and((it == instance.returnType).let { hold ->
|
||||
if (hold) iReturnType++
|
||||
isMatched = true
|
||||
it && (matchIndex == null ||
|
||||
(matchIndex.first >= 0 && matchIndex.first == returnTypeIndex && matchIndex.second) ||
|
||||
(matchIndex.first < 0 &&
|
||||
abs(matchIndex.first) == (returnTypeLastIndex - returnTypeIndex) && matchIndex.second) ||
|
||||
(returnTypeLastIndex == returnTypeIndex && matchIndex.second.not()))
|
||||
hold && matchIndex.compare(iReturnType, iLReturnType)
|
||||
})
|
||||
}
|
||||
value.paramCount.takeIf { it >= 0 }?.also { e ->
|
||||
and((instance.parameterTypes.size == e).let {
|
||||
if (it) paramCountIndex++
|
||||
paramCount.takeIf { it >= 0 }?.also {
|
||||
and((instance.parameterTypes.size == it).let { hold ->
|
||||
if (hold) iParamCount++
|
||||
isMatched = true
|
||||
it && (matchIndex == null ||
|
||||
(matchIndex.first >= 0 && matchIndex.first == paramCountIndex && matchIndex.second) ||
|
||||
(matchIndex.first < 0 &&
|
||||
abs(matchIndex.first) == (paramCountLastIndex - paramCountIndex) && matchIndex.second) ||
|
||||
(paramCountLastIndex == paramCountIndex && matchIndex.second.not()))
|
||||
hold && matchIndex.compare(iParamCount, iLParamCount)
|
||||
})
|
||||
}
|
||||
value.paramCountRange.takeIf { it.isEmpty().not() }?.also { e ->
|
||||
and((instance.parameterTypes.size in e).let {
|
||||
if (it) paramCountRangeIndex++
|
||||
paramCountRange.takeIf { it.isEmpty().not() }?.also {
|
||||
and((instance.parameterTypes.size in it).let { hold ->
|
||||
if (hold) iParamCountRange++
|
||||
isMatched = true
|
||||
it && (matchIndex == null ||
|
||||
(matchIndex.first >= 0 && matchIndex.first == paramCountRangeIndex && matchIndex.second) ||
|
||||
(matchIndex.first < 0 &&
|
||||
abs(matchIndex.first) == (paramCountRangeLastIndex - paramCountRangeIndex) && matchIndex.second) ||
|
||||
(paramCountRangeLastIndex == paramCountRangeIndex && matchIndex.second.not()))
|
||||
hold && matchIndex.compare(iParamCountRange, iLParamCountRange)
|
||||
})
|
||||
}
|
||||
value.paramTypes?.also { e ->
|
||||
and(arrayContentsEq(e, instance.parameterTypes).let {
|
||||
if (it) paramTypeIndex++
|
||||
paramTypes?.also {
|
||||
and(arrayContentsEq(it, instance.parameterTypes).let { hold ->
|
||||
if (hold) iParamTypes++
|
||||
isMatched = true
|
||||
it && (matchIndex == null ||
|
||||
(matchIndex.first >= 0 && matchIndex.first == paramTypeIndex && matchIndex.second) ||
|
||||
(matchIndex.first < 0 &&
|
||||
abs(matchIndex.first) == (paramTypeLastIndex - paramTypeIndex) && matchIndex.second) ||
|
||||
(paramTypeLastIndex == paramTypeIndex && matchIndex.second.not()))
|
||||
hold && matchIndex.compare(iParamTypes, iLParamTypes)
|
||||
})
|
||||
}
|
||||
value.modifiers?.also { e ->
|
||||
and(e.contains(instance).let {
|
||||
if (it) modifyIndex++
|
||||
modifiers?.also {
|
||||
and(it.contains(instance).let { hold ->
|
||||
if (hold) iModify++
|
||||
isMatched = true
|
||||
it && (matchIndex == null ||
|
||||
(matchIndex.first >= 0 && matchIndex.first == modifyIndex && matchIndex.second) ||
|
||||
(matchIndex.first < 0 &&
|
||||
abs(matchIndex.first) == (modifyLastIndex - modifyIndex) && matchIndex.second) ||
|
||||
(modifyLastIndex == modifyIndex && matchIndex.second.not()))
|
||||
hold && matchIndex.compare(iModify, iLModify)
|
||||
})
|
||||
}
|
||||
value.nameConditions?.also { e ->
|
||||
and(e.contains(instance).let {
|
||||
if (it) nameCdsIndex++
|
||||
nameConditions?.also {
|
||||
and(it.contains(instance).let { hold ->
|
||||
if (hold) iNameCds++
|
||||
isMatched = true
|
||||
it && (matchIndex == null ||
|
||||
(matchIndex.first >= 0 && matchIndex.first == nameCdsIndex && matchIndex.second) ||
|
||||
(matchIndex.first < 0 &&
|
||||
abs(matchIndex.first) == (nameCdsLastIndex - nameCdsIndex) && matchIndex.second) ||
|
||||
(nameCdsLastIndex == nameCdsIndex && matchIndex.second.not()))
|
||||
hold && matchIndex.compare(iNameCds, iLNameCds)
|
||||
})
|
||||
}
|
||||
orderIndex?.also {
|
||||
and(((it.first >= 0 && it.first == p && it.second) ||
|
||||
(it.first < 0 && abs(it.first) == (lastIndex - p) && it.second) ||
|
||||
(lastIndex == p && it.second.not())).also { isMatched = true })
|
||||
}
|
||||
orderIndex.compare(index, declares.lastIndex) { and(it); isMatched = it }
|
||||
}.finally { if (isMatched) methods.add(instance.apply { isAccessible = true }) }
|
||||
}
|
||||
} ?: error("Can't find this Method [${rulesData.name}] because classSet is null")
|
||||
methods.takeIf { it.isNotEmpty() }?.also { ReflectsCacheStore.putMethods(hashCode, methods) }
|
||||
?: if (rulesData.isFindInSuper && classSet.hasExtends)
|
||||
findMethods(classSet.superclass, orderIndex, matchIndex, rulesData)
|
||||
else throw NoSuchMethodError(
|
||||
"Can't find this Method --> " +
|
||||
when {
|
||||
orderIndex == null -> ""
|
||||
orderIndex.second.not() -> "orderIndex:[last] "
|
||||
else -> "orderIndex:[${orderIndex.first}] "
|
||||
} +
|
||||
when {
|
||||
matchIndex == null -> ""
|
||||
matchIndex.second.not() -> "matchIndex:[last] "
|
||||
else -> "matchIndex:[${matchIndex.first}] "
|
||||
} +
|
||||
when (rulesData.nameConditions) {
|
||||
null -> ""
|
||||
else -> "nameConditions:${rulesData.nameConditions} "
|
||||
} +
|
||||
"name:[${rulesData.name.takeIf { it.isNotBlank() } ?: "unspecified"}] " +
|
||||
"paramCount:[${rulesData.paramCount.takeIf { it >= 0 } ?: "unspecified"}] " +
|
||||
"paramCountRange:[${rulesData.paramCountRange.takeIf { it.isEmpty().not() } ?: "unspecified"}] " +
|
||||
"paramTypes:[${rulesData.paramTypes.typeOfString()}] " +
|
||||
"returnType:[${rulesData.returnType ?: "unspecified"}] " +
|
||||
"modifiers:${rulesData.modifiers ?: "[]"} " +
|
||||
"in [$classSet] " +
|
||||
"by $TAG"
|
||||
)
|
||||
}
|
||||
}
|
||||
}.takeIf { it.isNotEmpty() }?.also { ReflectsCacheStore.putMethods(hashCode(classSet), it) } ?: findSuperOrThrow(classSet)
|
||||
}
|
||||
|
||||
/**
|
||||
* 查找任意 [Constructor] 或一组 [Constructor]
|
||||
* @param classSet [Constructor] 所在类
|
||||
* @param orderIndex 字节码顺序下标
|
||||
* @param matchIndex 字节码筛选下标
|
||||
* @param rulesData 规则查询数据
|
||||
* @return [HashSet]<[Constructor]>
|
||||
* @throws IllegalStateException 如果 [classSet] 为 null 或未设置任何条件或 [ConstructorRulesData.paramTypes] 目标类不存在
|
||||
* @throws IllegalStateException 如果未设置任何条件或 [ConstructorRulesData.paramTypes] 目标类不存在
|
||||
* @throws NoSuchMethodError 如果找不到 [Constructor]
|
||||
*/
|
||||
internal fun findConstructors(
|
||||
classSet: Class<*>?,
|
||||
orderIndex: Pair<Int, Boolean>?,
|
||||
matchIndex: Pair<Int, Boolean>?,
|
||||
rulesData: ConstructorRulesData
|
||||
): HashSet<Constructor<*>> {
|
||||
rulesData.paramTypes?.takeIf { it.isNotEmpty() }
|
||||
internal fun findConstructors(classSet: Class<*>?, rulesData: ConstructorRulesData) = rulesData.createResult {
|
||||
if (classSet == null) return@createResult hashSetOf()
|
||||
paramTypes?.takeIf { it.isNotEmpty() }
|
||||
?.forEachIndexed { p, it -> if (it == UndefinedType) error("Constructor match paramType[$p] class is not found") }
|
||||
if (orderIndex == null && matchIndex == null &&
|
||||
rulesData.modifiers == null && rulesData.paramCount < 0 &&
|
||||
rulesData.paramCountRange.isEmpty() && rulesData.paramTypes == null
|
||||
) error("You must set a condition when finding a Constructor")
|
||||
val hashCode = ("[$orderIndex][$matchIndex][${rulesData.paramCount}][${rulesData.paramTypes.typeOfString()}]" +
|
||||
"[${rulesData.modifiers}][$classSet]").hashCode()
|
||||
return ReflectsCacheStore.findConstructors(hashCode) ?: let {
|
||||
val constructors = HashSet<Constructor<*>>()
|
||||
classSet?.declaredConstructors?.apply {
|
||||
var paramTypeIndex = -1
|
||||
var paramCountIndex = -1
|
||||
var paramCountRangeIndex = -1
|
||||
var modifyIndex = -1
|
||||
val paramCountLastIndex =
|
||||
if (rulesData.paramCount >= 0 && matchIndex != null) filter { rulesData.paramCount == it.parameterTypes.size }.lastIndex else -1
|
||||
val paramCountRangeLastIndex = if (rulesData.paramCountRange.isEmpty().not() && matchIndex != null)
|
||||
filter { it.parameterTypes.size in rulesData.paramCountRange }.lastIndex else -1
|
||||
val paramTypeLastIndex =
|
||||
if (rulesData.paramTypes != null && matchIndex != null)
|
||||
filter { arrayContentsEq(rulesData.paramTypes, it.parameterTypes) }.lastIndex else -1
|
||||
val modifyLastIndex =
|
||||
if (rulesData.modifiers != null && matchIndex != null) filter { rulesData.modifiers!!.contains(it) }.lastIndex else -1
|
||||
forEachIndexed { p, instance ->
|
||||
ReflectsCacheStore.findConstructors(hashCode(classSet)) ?: hashSetOf<Constructor<*>>().also { constructors ->
|
||||
classSet.declaredConstructors.also { declares ->
|
||||
var iParamTypes = -1
|
||||
var iParamCount = -1
|
||||
var iParamCountRange = -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 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 ->
|
||||
var isMatched = false
|
||||
rulesData.conditions {
|
||||
value.paramCount.takeIf { it >= 0 }?.also { e ->
|
||||
and((instance.parameterTypes.size == e).let {
|
||||
if (it) paramCountIndex++
|
||||
conditions {
|
||||
paramCount.takeIf { it >= 0 }?.also {
|
||||
and((instance.parameterTypes.size == it).let { hold ->
|
||||
if (hold) iParamCount++
|
||||
isMatched = true
|
||||
it && (matchIndex == null ||
|
||||
(matchIndex.first >= 0 && matchIndex.first == paramCountIndex && matchIndex.second) ||
|
||||
(matchIndex.first < 0 &&
|
||||
abs(matchIndex.first) == (paramCountLastIndex - paramCountIndex) && matchIndex.second) ||
|
||||
(paramCountLastIndex == paramCountIndex && matchIndex.second.not()))
|
||||
hold && matchIndex.compare(iParamCount, iLParamCount)
|
||||
})
|
||||
}
|
||||
value.paramCountRange.takeIf { it.isEmpty().not() }?.also { e ->
|
||||
and((instance.parameterTypes.size in e).let {
|
||||
if (it) paramCountRangeIndex++
|
||||
paramCountRange.takeIf { it.isEmpty().not() }?.also {
|
||||
and((instance.parameterTypes.size in it).let { hold ->
|
||||
if (hold) iParamCountRange++
|
||||
isMatched = true
|
||||
it && (matchIndex == null ||
|
||||
(matchIndex.first >= 0 && matchIndex.first == paramCountRangeIndex && matchIndex.second) ||
|
||||
(matchIndex.first < 0 &&
|
||||
abs(matchIndex.first) == (paramCountRangeLastIndex - paramCountRangeIndex) && matchIndex.second) ||
|
||||
(paramCountRangeLastIndex == paramCountRangeIndex && matchIndex.second.not()))
|
||||
hold && matchIndex.compare(iParamCountRange, iLParamCountRange)
|
||||
})
|
||||
}
|
||||
value.paramTypes?.also { e ->
|
||||
and(arrayContentsEq(e, instance.parameterTypes).let {
|
||||
if (it) paramTypeIndex++
|
||||
paramTypes?.also {
|
||||
and(arrayContentsEq(it, instance.parameterTypes).let { hold ->
|
||||
if (hold) iParamTypes++
|
||||
isMatched = true
|
||||
it && (matchIndex == null ||
|
||||
(matchIndex.first >= 0 && matchIndex.first == paramTypeIndex && matchIndex.second) ||
|
||||
(matchIndex.first < 0 &&
|
||||
abs(matchIndex.first) == (paramTypeLastIndex - paramTypeIndex) && matchIndex.second) ||
|
||||
(paramTypeLastIndex == paramTypeIndex && matchIndex.second.not()))
|
||||
hold && matchIndex.compare(iParamTypes, iLParamTypes)
|
||||
})
|
||||
}
|
||||
value.modifiers?.also { e ->
|
||||
and(e.contains(instance).let {
|
||||
if (it) modifyIndex++
|
||||
modifiers?.also {
|
||||
and(it.contains(instance).let { hold ->
|
||||
if (hold) iModify++
|
||||
isMatched = true
|
||||
it && (matchIndex == null ||
|
||||
(matchIndex.first >= 0 && matchIndex.first == modifyIndex && matchIndex.second) ||
|
||||
(matchIndex.first < 0 &&
|
||||
abs(matchIndex.first) == (modifyLastIndex - modifyIndex) && matchIndex.second) ||
|
||||
(modifyLastIndex == modifyIndex && matchIndex.second.not()))
|
||||
hold && matchIndex.compare(iModify, iLModify)
|
||||
})
|
||||
}
|
||||
orderIndex?.also {
|
||||
and(((it.first >= 0 && it.first == p && it.second) ||
|
||||
(it.first < 0 && abs(it.first) == (lastIndex - p) && it.second) ||
|
||||
(lastIndex == p && it.second.not())).also { isMatched = true })
|
||||
}
|
||||
orderIndex.compare(index, declares.lastIndex) { and(it); isMatched = it }
|
||||
}.finally { if (isMatched) constructors.add(instance.apply { isAccessible = true }) }
|
||||
}
|
||||
} ?: error("Can't find this Constructor because classSet is null")
|
||||
return constructors.takeIf { it.isNotEmpty() }?.also { ReflectsCacheStore.putConstructors(hashCode, constructors) }
|
||||
?: if (rulesData.isFindInSuper && classSet.hasExtends)
|
||||
findConstructors(classSet.superclass, orderIndex, matchIndex, rulesData)
|
||||
else throw NoSuchMethodError(
|
||||
"Can't find this Constructor --> " +
|
||||
when {
|
||||
orderIndex == null -> ""
|
||||
orderIndex.second.not() -> "orderIndex:[last] "
|
||||
else -> "orderIndex:[${orderIndex.first}] "
|
||||
} +
|
||||
when {
|
||||
matchIndex == null -> ""
|
||||
matchIndex.second.not() -> "matchIndex:[last] "
|
||||
else -> "matchIndex:[${matchIndex.first}] "
|
||||
} +
|
||||
"paramCount:[${rulesData.paramCount.takeIf { it >= 0 } ?: "unspecified"}] " +
|
||||
"paramCountRange:[${rulesData.paramCountRange.takeIf { it.isEmpty().not() } ?: "unspecified"}] " +
|
||||
"paramTypes:[${rulesData.paramTypes.typeOfString()}] " +
|
||||
"modifiers:${rulesData.modifiers ?: "[]"} " +
|
||||
"in [$classSet] " +
|
||||
"by $TAG"
|
||||
)
|
||||
}
|
||||
}
|
||||
}.takeIf { it.isNotEmpty() }?.also { ReflectsCacheStore.putConstructors(hashCode(classSet), it) } ?: findSuperOrThrow(classSet)
|
||||
}
|
||||
|
||||
/**
|
||||
* 比较位置下标的前后顺序
|
||||
* @param need 当前位置
|
||||
* @param last 最后位置
|
||||
* @return [Boolean] 返回是否成立
|
||||
*/
|
||||
private fun Pair<Int, Boolean>?.compare(need: Int, last: Int) = this == null || ((first >= 0 && first == need && second) ||
|
||||
(first < 0 && abs(first) == (last - need) && second) || (last == need && second.not()))
|
||||
|
||||
/**
|
||||
* 比较位置下标的前后顺序
|
||||
* @param need 当前位置
|
||||
* @param last 最后位置
|
||||
* @param result 回调是否成立
|
||||
*/
|
||||
private fun Pair<Int, Boolean>?.compare(need: Int, last: Int, result: (Boolean) -> Unit) {
|
||||
if (this == null) return
|
||||
((first >= 0 && first == need && second) ||
|
||||
(first < 0 && abs(first) == (last - need) && second) ||
|
||||
(last == need && second.not())).also(result)
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建查找结果方法体
|
||||
* @param result 回调方法体
|
||||
* @return [T]
|
||||
* @throws IllegalStateException 如果没有 [BaseRulesData.isInitialize]
|
||||
*/
|
||||
private inline fun <reified T, R : BaseRulesData> R.createResult(result: R.() -> T): T {
|
||||
when (this) {
|
||||
is FieldRulesData -> isInitialize.not()
|
||||
is MethodRulesData -> isInitialize.not()
|
||||
is ConstructorRulesData -> isInitialize.not()
|
||||
is MemberRulesData -> isInitialize.not()
|
||||
else -> true
|
||||
}.takeIf { it }?.also { error("You must set a condition when finding a $objectName") }
|
||||
return result(this)
|
||||
}
|
||||
|
||||
/**
|
||||
* 在 [Class.getSuperclass] 中查找或抛出异常
|
||||
* @param classSet 所在类
|
||||
* @return [T]
|
||||
* @throws NoSuchFieldError 继承于方法 [throwNotFoundError] 的异常
|
||||
* @throws NoSuchMethodError 继承于方法 [throwNotFoundError] 的异常
|
||||
* @throws IllegalStateException 如果 [R] 的类型错误
|
||||
*/
|
||||
private inline fun <reified T, R : MemberRulesData> R.findSuperOrThrow(classSet: Class<*>): T = when (this) {
|
||||
is FieldRulesData ->
|
||||
if (isFindInSuper && classSet.hasExtends)
|
||||
findFields(classSet.superclass, rulesData = this) as T
|
||||
else throwNotFoundError(classSet)
|
||||
is MethodRulesData ->
|
||||
if (isFindInSuper && classSet.hasExtends)
|
||||
findMethods(classSet.superclass, rulesData = this) as T
|
||||
else throwNotFoundError(classSet)
|
||||
is ConstructorRulesData ->
|
||||
if (isFindInSuper && classSet.hasExtends)
|
||||
findConstructors(classSet.superclass, rulesData = this) as T
|
||||
else throwNotFoundError(classSet)
|
||||
else -> error("Type [$this] not allowed")
|
||||
}
|
||||
|
||||
/**
|
||||
* 抛出找不到 [Class]、[Member] 的异常
|
||||
* @param instanceSet 所在 [ClassLoader] or [Class]
|
||||
* @throws NoClassDefFoundError 如果找不到 [Class]
|
||||
* @throws NoSuchFieldError 如果找不到 [Field]
|
||||
* @throws NoSuchMethodError 如果找不到 [Method] or [Constructor]
|
||||
* @throws IllegalStateException 如果 [BaseRulesData] 的类型错误
|
||||
*/
|
||||
private fun BaseRulesData.throwNotFoundError(instanceSet: Any?): Nothing = when (this) {
|
||||
is FieldRulesData -> throw NoSuchFieldError(
|
||||
"Can't find this Field --> " +
|
||||
when {
|
||||
orderIndex == null -> ""
|
||||
orderIndex!!.second.not() -> "orderIndex:[last] "
|
||||
else -> "orderIndex:[${orderIndex!!.first}] "
|
||||
} +
|
||||
when {
|
||||
matchIndex == null -> ""
|
||||
matchIndex!!.second.not() -> "matchIndex:[last] "
|
||||
else -> "matchIndex:[${matchIndex!!.first}] "
|
||||
} +
|
||||
when (nameConditions) {
|
||||
null -> ""
|
||||
else -> "nameConditions:${nameConditions} "
|
||||
} +
|
||||
"name:[${name.takeIf { it.isNotBlank() } ?: "unspecified"}] " +
|
||||
"type:[${type ?: "unspecified"}] " +
|
||||
"modifiers:${modifiers ?: "[]"} " +
|
||||
"in [$instanceSet] by $TAG"
|
||||
)
|
||||
is MethodRulesData -> throw NoSuchMethodError(
|
||||
"Can't find this Method --> " +
|
||||
when {
|
||||
orderIndex == null -> ""
|
||||
orderIndex!!.second.not() -> "orderIndex:[last] "
|
||||
else -> "orderIndex:[${orderIndex!!.first}] "
|
||||
} +
|
||||
when {
|
||||
matchIndex == null -> ""
|
||||
matchIndex!!.second.not() -> "matchIndex:[last] "
|
||||
else -> "matchIndex:[${matchIndex!!.first}] "
|
||||
} +
|
||||
when (nameConditions) {
|
||||
null -> ""
|
||||
else -> "nameConditions:${nameConditions} "
|
||||
} +
|
||||
"name:[${name.takeIf { it.isNotBlank() } ?: "unspecified"}] " +
|
||||
"paramCount:[${paramCount.takeIf { it >= 0 } ?: "unspecified"}] " +
|
||||
"paramCountRange:[${paramCountRange.takeIf { it.isEmpty().not() } ?: "unspecified"}] " +
|
||||
"paramTypes:[${paramTypes.typeOfString()}] " +
|
||||
"returnType:[${returnType ?: "unspecified"}] " +
|
||||
"modifiers:${modifiers ?: "[]"} " +
|
||||
"in [$instanceSet] by $TAG"
|
||||
)
|
||||
is ConstructorRulesData -> throw NoSuchMethodError(
|
||||
"Can't find this Constructor --> " +
|
||||
when {
|
||||
orderIndex == null -> ""
|
||||
orderIndex!!.second.not() -> "orderIndex:[last] "
|
||||
else -> "orderIndex:[${orderIndex!!.first}] "
|
||||
} +
|
||||
when {
|
||||
matchIndex == null -> ""
|
||||
matchIndex!!.second.not() -> "matchIndex:[last] "
|
||||
else -> "matchIndex:[${matchIndex!!.first}] "
|
||||
} +
|
||||
"paramCount:[${paramCount.takeIf { it >= 0 } ?: "unspecified"}] " +
|
||||
"paramCountRange:[${paramCountRange.takeIf { it.isEmpty().not() } ?: "unspecified"}] " +
|
||||
"paramTypes:[${paramTypes.typeOfString()}] " +
|
||||
"modifiers:${modifiers ?: "[]"} " +
|
||||
"in [$instanceSet] by $TAG"
|
||||
)
|
||||
else -> error("Type [$this] not allowed")
|
||||
}
|
||||
|
||||
/**
|
||||
|
Reference in New Issue
Block a user