From 57aba63e907e4f4deb4fd71dd78e4aa7a1dc8979 Mon Sep 17 00:00:00 2001 From: fankesyooni Date: Fri, 9 Sep 2022 03:39:57 +0800 Subject: [PATCH] Modify move orderIndex, matchIndex in BaseRulesData and move modifiers to BaseRulesData and add objectName in BaseRulesData and make ReflectionTool simplify --- .../hook/core/finder/base/BaseFinder.kt | 19 +- .../core/finder/base/data/BaseRulesData.kt | 64 ++ .../core/finder/members/ConstructorFinder.kt | 9 +- .../hook/core/finder/members/FieldFinder.kt | 9 +- .../hook/core/finder/members/MethodFinder.kt | 9 +- .../members/data/ConstructorRulesData.kt | 9 +- .../finder/members/data/FieldRulesData.kt | 9 +- .../finder/members/data/MemberRulesData.kt | 19 +- .../finder/members/data/MethodRulesData.kt | 12 +- .../hook/core/reflex/tools/ReflectionTool.kt | 599 ++++++++---------- 10 files changed, 397 insertions(+), 361 deletions(-) create mode 100644 yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/finder/base/data/BaseRulesData.kt diff --git a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/finder/base/BaseFinder.kt b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/finder/base/BaseFinder.kt index 24250125..af7477fb 100644 --- a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/finder/base/BaseFinder.kt +++ b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/finder/base/BaseFinder.kt @@ -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? = null - - /** 字节码、数组筛选下标 */ - internal var matchIndex: Pair? = 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) } /** diff --git a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/finder/base/data/BaseRulesData.kt b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/finder/base/data/BaseRulesData.kt new file mode 100644 index 00000000..e7223ea7 --- /dev/null +++ b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/finder/base/data/BaseRulesData.kt @@ -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? = null, + var matchIndex: Pair? = 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() +} \ No newline at end of file diff --git a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/finder/members/ConstructorFinder.kt b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/finder/members/ConstructorFinder.kt index a1c0e647..92550d5e 100644 --- a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/finder/members/ConstructorFinder.kt +++ b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/finder/members/ConstructorFinder.kt @@ -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) } /** * 设置实例 diff --git a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/finder/members/FieldFinder.kt b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/finder/members/FieldFinder.kt index ce420dfc..e58b64c4 100644 --- a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/finder/members/FieldFinder.kt +++ b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/finder/members/FieldFinder.kt @@ -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) /** * 设置实例 diff --git a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/finder/members/MethodFinder.kt b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/finder/members/MethodFinder.kt index 83bacd48..577ab3fa 100644 --- a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/finder/members/MethodFinder.kt +++ b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/finder/members/MethodFinder.kt @@ -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) /** * 设置实例 diff --git a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/finder/members/data/ConstructorRulesData.kt b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/finder/members/data/ConstructorRulesData.kt index 2c9f4f6a..a9f3321a 100644 --- a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/finder/members/data/ConstructorRulesData.kt +++ b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/finder/members/data/ConstructorRulesData.kt @@ -40,4 +40,11 @@ internal class ConstructorRulesData internal constructor( var paramTypes: Array>? = null, var paramCount: Int = -1, var paramCountRange: IntRange = IntRange.EMPTY -) : MemberRulesData() \ No newline at end of file +) : 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() +} \ No newline at end of file diff --git a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/finder/members/data/FieldRulesData.kt b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/finder/members/data/FieldRulesData.kt index 17c371eb..7c0746fd 100644 --- a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/finder/members/data/FieldRulesData.kt +++ b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/finder/members/data/FieldRulesData.kt @@ -41,4 +41,11 @@ internal class FieldRulesData internal constructor( var name: String = "", var nameConditions: NameConditions? = null, var type: Any? = null -) : MemberRulesData() \ No newline at end of file +) : 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() +} \ No newline at end of file diff --git a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/finder/members/data/MemberRulesData.kt b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/finder/members/data/MemberRulesData.kt index 021bd2fe..076b4021 100644 --- a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/finder/members/data/MemberRulesData.kt +++ b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/finder/members/data/MemberRulesData.kt @@ -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 -) \ No newline at end of file +) : 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() +} \ No newline at end of file diff --git a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/finder/members/data/MethodRulesData.kt b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/finder/members/data/MethodRulesData.kt index 16209d68..e370ed55 100644 --- a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/finder/members/data/MethodRulesData.kt +++ b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/finder/members/data/MethodRulesData.kt @@ -47,4 +47,14 @@ internal class MethodRulesData internal constructor( var paramCount: Int = -1, var paramCountRange: IntRange = IntRange.EMPTY, var returnType: Any? = null -) : MemberRulesData() \ No newline at end of file +) : 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() +} \ No newline at end of file diff --git a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/reflex/tools/ReflectionTool.kt b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/reflex/tools/ReflectionTool.kt index 87f8fead..1571edaa 100644 --- a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/reflex/tools/ReflectionTool.kt +++ b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/reflex/tools/ReflectionTool.kt @@ -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?, - matchIndex: Pair?, - rulesData: FieldRulesData - ): HashSet { - 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() - 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().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?, - matchIndex: Pair?, - rulesData: MethodRulesData - ): HashSet { - 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() - 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().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?, - matchIndex: Pair?, - rulesData: ConstructorRulesData - ): HashSet> { - 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>() - 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>().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?.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?.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 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 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") } /**