feat: lots of changes

- move demo-app to samples and rename demo-android
- rename yukireflection to yukireflection-core
- add demo-jvm in samples
- convert yukireflection-core from android to java-library
- optimize code
- other small changes
This commit is contained in:
2023-09-22 17:00:54 +08:00
parent d02a5f8282
commit 1c205afd37
83 changed files with 337 additions and 96 deletions

1
yukireflection-core/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
/build

Binary file not shown.

View File

@@ -0,0 +1,97 @@
/*
* YukiReflection - An efficient Reflection API for Java and Android built in Kotlin
* Copyright (C) 2019-2023 HighCapable
* https://github.com/fankes/YukiReflection
*
* 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 2023/1/21.
*/
@file:Suppress("unused")
package com.highcapable.yukireflection
import com.highcapable.yukireflection.YukiReflection.Configs
import com.highcapable.yukireflection.generated.YukiReflectionProperties
import java.lang.reflect.Member
/**
* [YukiReflection] 的装载调用类
*
* 你可以使用 [Configs] 对 [YukiReflection] 进行配置
*/
object YukiReflection {
/** 版本名称 */
const val API_VERSION_NAME = YukiReflectionProperties.PROJECT_YUKIREFLECTION_CORE_VERSION
/** 版本号 */
const val API_VERSION_CODE = 3
/**
* 配置 [YukiReflection]
*/
object Configs {
/**
* 这是一个调试日志的全局标识
*
* 默认文案为 YukiReflection
*
* 你可以修改为你自己的文案
*/
var debugTag = "YukiReflection"
/**
* 是否开启调试模式 - 默认不启用
*
* 启用后将交由日志输出管理器打印详细日志 (例如反射查找功能的耗时) 到控制台
*
* 请过滤 [debugTag] 即可找到每条日志
*/
var isDebug = false
/**
* 是否启用调试日志的输出功能
*
* - ❗关闭后将会停用 [YukiReflection] 对全部日志的输出
*/
var isAllowPrintingLogs = true
/**
* 是否启用 [Member] 缓存功能
*
* - ❗此方法及功能已被移除 - 在之后的版本中将直接被删除
*
* - ❗[Member] 的直接缓存功能已被移除 - 因为其存在内存溢出 (OOM) 问题
*/
@Deprecated(message = "此方法及功能已被移除,请删除此方法")
var isEnableMemberCache = false
}
/**
* 配置 [YukiReflection] 相关参数
* @param initiate 方法体
*/
inline fun configs(initiate: Configs.() -> Unit) {
Configs.apply(initiate)
}
}

View File

@@ -0,0 +1,56 @@
/*
* YukiReflection - An efficient Reflection API for Java and Android built in Kotlin
* Copyright (C) 2019-2023 HighCapable
* https://github.com/fankes/YukiReflection
*
* 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/4/3.
* This file is Modified by fankes on 2023/1/21.
*/
@file:Suppress("OPT_IN_IS_NOT_ENABLED", "EXPERIMENTAL_IS_NOT_ENABLED", "unused")
package com.highcapable.yukireflection.annotation
@RequiresOptIn(level = RequiresOptIn.Level.WARNING)
@MustBeDocumented
@Target(
AnnotationTarget.CLASS,
AnnotationTarget.CONSTRUCTOR,
AnnotationTarget.FUNCTION,
AnnotationTarget.ANNOTATION_CLASS,
AnnotationTarget.PROPERTY,
AnnotationTarget.FIELD,
AnnotationTarget.LOCAL_VARIABLE,
AnnotationTarget.VALUE_PARAMETER,
AnnotationTarget.PROPERTY_GETTER,
AnnotationTarget.PROPERTY_SETTER,
AnnotationTarget.TYPEALIAS
)
@Retention(AnnotationRetention.BINARY)
/**
* - ❗标记为不规范使用可能会引发问题的 API
*
* 此功能用于规范代码调用域 - 非调用域内的 API 将会在 IDE 中显示警告
*
* 此功能除继承和接口外不应该在这里被调用
*/
annotation class CauseProblemsApi

View File

@@ -0,0 +1,54 @@
/*
* YukiReflection - An efficient Reflection API for Java and Android built in Kotlin
* Copyright (C) 2019-2023 HighCapable
* https://github.com/fankes/YukiReflection
*
* 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/4/3.
* This file is Modified by fankes on 2023/1/21.
*/
@file:Suppress("OPT_IN_IS_NOT_ENABLED", "EXPERIMENTAL_IS_NOT_ENABLED")
package com.highcapable.yukireflection.annotation
@RequiresOptIn(level = RequiresOptIn.Level.ERROR)
@MustBeDocumented
@Target(
AnnotationTarget.CLASS,
AnnotationTarget.CONSTRUCTOR,
AnnotationTarget.FUNCTION,
AnnotationTarget.ANNOTATION_CLASS,
AnnotationTarget.PROPERTY,
AnnotationTarget.FIELD,
AnnotationTarget.LOCAL_VARIABLE,
AnnotationTarget.VALUE_PARAMETER,
AnnotationTarget.PROPERTY_GETTER,
AnnotationTarget.PROPERTY_SETTER,
AnnotationTarget.TYPEALIAS
)
@Retention(AnnotationRetention.BINARY)
/**
* - ❗标记功能为私有功能性 API
*
* 此功能除继承和接口外不应该在这里被调用
*/
internal annotation class YukiPrivateApi

View File

@@ -0,0 +1,157 @@
/*
* YukiReflection - An efficient Reflection API for Java and Android built in Kotlin
* Copyright (C) 2019-2023 HighCapable
* https://github.com/fankes/YukiReflection
*
* 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/4/4.
* This file is Modified by fankes on 2023/1/21.
*/
@file:Suppress("unused")
package com.highcapable.yukireflection.bean
import com.highcapable.yukireflection.factory.field
import com.highcapable.yukireflection.factory.generic
import com.highcapable.yukireflection.factory.method
import com.highcapable.yukireflection.finder.members.FieldFinder
import com.highcapable.yukireflection.finder.members.MethodFinder
import com.highcapable.yukireflection.finder.type.factory.FieldConditions
import com.highcapable.yukireflection.finder.type.factory.MethodConditions
/**
* 当前实例的类操作对象
* @param classSet 当前实例的 [Class]
* @param instance 当前实例本身
*/
class CurrentClass @PublishedApi internal constructor(@PublishedApi internal val classSet: Class<*>, @PublishedApi internal val instance: Any) {
/** 是否开启忽略错误警告功能 */
@PublishedApi
internal var isShutErrorPrinting = false
/**
* 获得当前 [classSet] 的 [Class.getName]
* @return [String]
*/
val name get() = classSet.name ?: instance.javaClass.name ?: ""
/**
* 获得当前 [classSet] 的 [Class.getSimpleName]
* @return [String]
*/
val simpleName get() = classSet.simpleName ?: instance.javaClass.simpleName ?: ""
/**
* 获得当前实例中的泛型父类
*
* 如果当前实例不存在泛型将返回 null
* @return [GenericClass] or null
*/
fun generic() = classSet.generic()
/**
* 获得当前实例中的泛型父类
*
* 如果当前实例不存在泛型将返回 null
* @param initiate 实例方法体
* @return [GenericClass] or null
*/
inline fun generic(initiate: GenericClass.() -> Unit) = classSet.generic(initiate)
/**
* 调用父类实例
* @return [SuperClass]
*/
fun superClass() = SuperClass(classSet.superclass)
/**
* 调用当前实例中的变量
* @param initiate 查找方法体
* @return [FieldFinder.Result.Instance]
*/
inline fun field(initiate: FieldConditions) = classSet.field(initiate).result { if (isShutErrorPrinting) ignored() }.get(instance)
/**
* 调用当前实例中的方法
* @param initiate 查找方法体
* @return [MethodFinder.Result.Instance]
*/
inline fun method(initiate: MethodConditions) = classSet.method(initiate).result { if (isShutErrorPrinting) ignored() }.get(instance)
/**
* 当前类的父类实例的类操作对象
*
* - ❗请使用 [superClass] 方法来获取 [SuperClass]
* @param superClassSet 父类 [Class] 对象
*/
inner class SuperClass internal constructor(@PublishedApi internal val superClassSet: Class<*>) {
/**
* 获得当前 [classSet] 中父类的 [Class.getName]
* @return [String]
*/
val name get() = superClassSet.name ?: ""
/**
* 获得当前 [classSet] 中父类的 [Class.getSimpleName]
* @return [String]
*/
val simpleName get() = superClassSet.simpleName ?: ""
/**
* 获得当前实例父类中的泛型父类
*
* 如果当前实例不存在泛型将返回 null
* @return [GenericClass] or null
*/
fun generic() = superClassSet.generic()
/**
* 获得当前实例父类中的泛型父类
*
* 如果当前实例不存在泛型将返回 null
* @param initiate 实例方法体
* @return [GenericClass] or null
*/
inline fun generic(initiate: GenericClass.() -> Unit) = superClassSet.generic(initiate)
/**
* 调用父类实例中的变量
* @param initiate 查找方法体
* @return [FieldFinder.Result.Instance]
*/
inline fun field(initiate: FieldConditions) = superClassSet.field(initiate).result { if (isShutErrorPrinting) ignored() }.get(instance)
/**
* 调用父类实例中的方法
* @param initiate 查找方法体
* @return [MethodFinder.Result.Instance]
*/
inline fun method(initiate: MethodConditions) =
superClassSet.method(initiate).result { if (isShutErrorPrinting) ignored() }.get(instance)
override fun toString() = "CurrentClass super [${superClassSet}]"
}
override fun toString() = "CurrentClass [$classSet]"
}

View File

@@ -0,0 +1,57 @@
/*
* YukiReflection - An efficient Reflection API for Java and Android built in Kotlin
* Copyright (C) 2019-2023 HighCapable
* https://github.com/fankes/YukiReflection
*
* 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/20.
* This file is Modified by fankes on 2023/1/21.
*/
@file:Suppress("unused", "UNCHECKED_CAST")
package com.highcapable.yukireflection.bean
import java.lang.reflect.ParameterizedType
/**
* 当前 [Class] 的泛型父类操作对象
* @param type 类型声明实例
*/
class GenericClass internal constructor(@PublishedApi internal val type: ParameterizedType) {
/**
* 获得泛型参数数组下标的 [Class] 实例
* @param index 数组下标 - 默认 0
* @return [Class]
*/
fun argument(index: Int = 0) = type.actualTypeArguments[index] as Class<*>
/**
* 获得泛型参数数组下标的 [Class] 实例
* @param index 数组下标 - 默认 0
* @return [Class]<[T]>
* @throws IllegalStateException 如果 [Class] 的类型不为 [T]
*/
@JvmName("argument_Generics")
inline fun <reified T> argument(index: Int = 0) =
type.actualTypeArguments[index] as? Class<T> ?: error("Target Class type cannot cast to ${T::class.java}")
}

View File

@@ -0,0 +1,80 @@
/*
* YukiReflection - An efficient Reflection API for Java and Android built in Kotlin
* Copyright (C) 2019-2023 HighCapable
* https://github.com/fankes/YukiReflection
*
* 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/2/10.
* This file is Modified by fankes on 2023/1/21.
*/
@file:Suppress("unused")
package com.highcapable.yukireflection.bean
import com.highcapable.yukireflection.factory.toClassOrNull
/**
* 这是一个不确定性 [Class] 类名装载器
* @param name 可指定多个类名 - 将会自动匹配存在的第一个类名
*/
class VariousClass(private vararg val name: String) {
/**
* 获取匹配的实体类
*
* - 使用当前 [loader] 装载目标 [Class]
* @param loader 当前 [ClassLoader] - 若留空使用默认 [ClassLoader]
* @param initialize 是否初始化 [Class] 的静态方法块 - 默认否
* @return [Class]
* @throws IllegalStateException 如果任何 [Class] 都没有匹配到
*/
fun get(loader: ClassLoader? = null, initialize: Boolean = false): Class<*> {
var finalClass: Class<*>? = null
if (name.isNotEmpty()) run {
name.forEach {
finalClass = it.toClassOrNull(loader, initialize)
if (finalClass != null) return@run
}
}
return finalClass ?: error("VariousClass match failed of those $this")
}
/**
* 获取匹配的实体类
*
* - 使用当前 [loader] 装载目标 [Class]
*
* 匹配不到 [Class] 会返回 null - 不会抛出异常
* @param loader 当前 [ClassLoader] - 若留空使用默认 [ClassLoader]
* @param initialize 是否初始化 [Class] 的静态方法块 - 默认否
* @return [Class] or null
*/
fun getOrNull(loader: ClassLoader? = null, initialize: Boolean = false) = runCatching { get(loader, initialize) }.getOrNull()
override fun toString(): String {
var result = ""
return if (name.isNotEmpty()) {
name.forEach { result += "\"$it\"," }
"[${result.substring(0, result.lastIndex)}]"
} else "[]"
}
}

View File

@@ -0,0 +1,369 @@
/*
* YukiReflection - An efficient Reflection API for Java and Android built in Kotlin
* Copyright (C) 2019-2023 HighCapable
* https://github.com/fankes/YukiReflection
*
* 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/2/2.
* This file is Modified by fankes on 2023/1/21.
*/
@file:Suppress("unused", "UNCHECKED_CAST")
package com.highcapable.yukireflection.factory
import android.content.Context
import com.highcapable.yukireflection.bean.CurrentClass
import com.highcapable.yukireflection.bean.GenericClass
import com.highcapable.yukireflection.finder.base.rules.ModifierRules
import com.highcapable.yukireflection.finder.classes.DexClassFinder
import com.highcapable.yukireflection.finder.members.ConstructorFinder
import com.highcapable.yukireflection.finder.members.FieldFinder
import com.highcapable.yukireflection.finder.members.MethodFinder
import com.highcapable.yukireflection.finder.tools.ReflectionTool
import com.highcapable.yukireflection.finder.type.factory.*
import com.highcapable.yukireflection.type.java.*
import dalvik.system.BaseDexClassLoader
import java.lang.reflect.*
/**
* 写出当前 [ClassLoader] 下所有 [Class] 名称数组
*
* - ❗此方法在 [Class] 数量过多时会非常耗时
*
* - ❗若要按指定规则查找一个 [Class] - 请使用 [searchClass] 方法
* @return [List]<[String]>
* @throws IllegalStateException 如果当前 [ClassLoader] 不是 [BaseDexClassLoader]
*/
fun ClassLoader.listOfClasses() = ReflectionTool.findDexClassList(loader = this)
/**
* 通过当前 [ClassLoader] 按指定条件查找并得到 Dex 中的 [Class]
*
* - ❗此方法在 [Class] 数量过多及查找条件复杂时会非常耗时
*
* - ❗建议启用 [async] 或设置 [name] 参数 - [name] 参数将在当前 APP 不同版本中自动进行本地缓存以提升效率
*
* - ❗如果使用了 [async] 或 [name] 参数 - 则必须填写 [context] 参数
*
* - ❗此功能尚在试验阶段 - 性能与稳定性可能仍然存在问题 - 使用过程遇到问题请向我们报告并帮助我们改进
* @param context 当前 [Context] - 默认空
* @param name 标识当前 [Class] 缓存的名称 - 不设置将不启用缓存 - 启用缓存自动启用 [async]
* @param async 是否启用异步 - 默认否
* @param initiate 方法体
* @return [DexClassFinder.Result]
*/
inline fun ClassLoader.searchClass(context: Context? = null, name: String = "", async: Boolean = false, initiate: ClassConditions) =
DexClassFinder(context, name, async = async || name.isNotBlank(), loaderSet = this).apply(initiate).build()
/**
* 当前 [Class] 是否有继承关系 - 父类是 [Any] 将被认为没有继承关系
* @return [Boolean]
*/
val Class<*>.hasExtends get() = superclass != null && superclass != AnyClass
/**
* 当前 [Class] 是否继承于 [other]
*
* 如果当前 [Class] 就是 [other] 也会返回 true
*
* 如果当前 [Class] 为 null 或 [other] 为 null 会返回 false
* @param other 需要判断的 [Class]
* @return [Boolean]
*/
infix fun Class<*>?.extends(other: Class<*>?): Boolean {
if (this == null || other == null) return false
var isMatched = false
/**
* 查找是否存在父类
* @param current 当前 [Class]
*/
fun findSuperClass(current: Class<*>) {
if (current == other)
isMatched = true
else if (current != AnyClass && current.superclass != null) findSuperClass(current.superclass)
}
findSuperClass(current = this)
return isMatched
}
/**
* 当前 [Class] 是否不继承于 [other]
*
* 此方法相当于 [extends] 的反向判断
* @param other 需要判断的 [Class]
* @return [Boolean]
*/
infix fun Class<*>?.notExtends(other: Class<*>?) = extends(other).not()
/**
* 当前 [Class] 是否实现了 [other] 接口类
*
* 如果当前 [Class] 为 null 或 [other] 为 null 会返回 false
* @param other 需要判断的 [Class]
* @return [Boolean]
*/
infix fun Class<*>?.implements(other: Class<*>?): Boolean {
if (this == null || other == null) return false
/**
* 获取当前 [Class] 实现的所有接口类
* @return [Set]<[Class]>
*/
fun Class<*>.findAllInterfaces(): Set<Class<*>> = mutableSetOf(*interfaces).apply { superclass?.also { addAll(it.findAllInterfaces()) } }
return findAllInterfaces().takeIf { it.isNotEmpty() }?.any { it.name == other.name } ?: false
}
/**
* 当前 [Class] 是否未实现 [other] 接口类
*
* 此方法相当于 [implements] 的反向判断
* @param other 需要判断的 [Class]
* @return [Boolean]
*/
infix fun Class<*>?.notImplements(other: Class<*>?) = implements(other).not()
/**
* 自动转换当前 [Class] 为 Java 原始类型 (Primitive Type)
*
* 如果当前 [Class] 为 Java 或 Kotlin 基本类型将自动执行类型转换
*
* 当前能够自动转换的基本类型如下 ↓
*
* - [kotlin.Unit]
* - [java.lang.Void]
* - [java.lang.Boolean]
* - [java.lang.Integer]
* - [java.lang.Float]
* - [java.lang.Double]
* - [java.lang.Long]
* - [java.lang.Short]
* - [java.lang.Character]
* - [java.lang.Byte]
* @return [Class]
*/
fun Class<*>.toJavaPrimitiveType() = when (this) {
classOf<Unit>(), UnitClass, UnitType -> UnitType
BooleanClass, BooleanType -> BooleanType
IntClass, IntType -> IntType
FloatClass, FloatType -> FloatType
DoubleClass, DoubleType -> DoubleType
LongClass, LongType -> LongType
ShortClass, ShortType -> ShortType
CharClass, CharType -> CharType
ByteClass, ByteType -> ByteType
else -> this
}
/**
* 通过字符串类名转换为 [loader] 中的实体类
* @param loader [Class] 所在的 [ClassLoader] - 默认空 - 不填使用默认 [ClassLoader]
* @param initialize 是否初始化 [Class] 的静态方法块 - 默认否
* @return [Class]
* @throws NoClassDefFoundError 如果找不到 [Class] 或设置了错误的 [ClassLoader]
*/
fun String.toClass(loader: ClassLoader? = null, initialize: Boolean = false) = ReflectionTool.findClassByName(name = this, loader, initialize)
/**
* 通过字符串类名转换为 [loader] 中的实体类
* @param loader [Class] 所在的 [ClassLoader] - 默认空 - 不填使用默认 [ClassLoader]
* @param initialize 是否初始化 [Class] 的静态方法块 - 默认否
* @return [Class]<[T]>
* @throws NoClassDefFoundError 如果找不到 [Class] 或设置了错误的 [ClassLoader]
* @throws IllegalStateException 如果 [Class] 的类型不为 [T]
*/
@JvmName("toClass_Generics")
inline fun <reified T> String.toClass(loader: ClassLoader? = null, initialize: Boolean = false) =
ReflectionTool.findClassByName(name = this, loader, initialize) as? Class<T>? ?: error("Target Class type cannot cast to ${T::class.java}")
/**
* 通过字符串类名转换为 [loader] 中的实体类
*
* 找不到 [Class] 会返回 null - 不会抛出异常
* @param loader [Class] 所在的 [ClassLoader] - 默认空 - 不填使用默认 [ClassLoader]
* @param initialize 是否初始化 [Class] 的静态方法块 - 默认否
* @return [Class] or null
*/
fun String.toClassOrNull(loader: ClassLoader? = null, initialize: Boolean = false) = runCatching { toClass(loader, initialize) }.getOrNull()
/**
* 通过字符串类名转换为 [loader] 中的实体类
*
* 找不到 [Class] 会返回 null - 不会抛出异常
* @param loader [Class] 所在的 [ClassLoader] - 默认空 - 不填使用默认 [ClassLoader]
* @param initialize 是否初始化 [Class] 的静态方法块 - 默认否
* @return [Class]<[T]> or null
*/
@JvmName("toClassOrNull_Generics")
inline fun <reified T> String.toClassOrNull(loader: ClassLoader? = null, initialize: Boolean = false) =
runCatching { toClass<T>(loader, initialize) }.getOrNull()
/**
* 通过 [T] 得到其 [Class] 实例并转换为实体类
* @param loader [Class] 所在的 [ClassLoader] - 默认空 - 可不填
* @param initialize 是否初始化 [Class] 的静态方法块 - 如果未设置 [loader] (为 null) 时将不会生效 - 默认否
* @return [Class]<[T]>
* @throws NoClassDefFoundError 如果找不到 [Class] 或设置了错误的 [ClassLoader]
*/
inline fun <reified T> classOf(loader: ClassLoader? = null, initialize: Boolean = false) =
loader?.let { T::class.java.name.toClass(loader, initialize) as Class<T> } ?: T::class.java
/**
* 通过字符串类名使用指定的 [ClassLoader] 查找是否存在
* @param loader [Class] 所在的 [ClassLoader] - 不填使用默认 [ClassLoader]
* @return [Boolean] 是否存在
*/
fun String.hasClass(loader: ClassLoader? = null) = ReflectionTool.hasClassByName(name = this, loader)
/**
* 查找变量是否存在
* @param initiate 方法体
* @return [Boolean] 是否存在
*/
inline fun Class<*>.hasField(initiate: FieldConditions) = field(initiate).ignored().isNoSuch.not()
/**
* 查找方法是否存在
* @param initiate 方法体
* @return [Boolean] 是否存在
*/
inline fun Class<*>.hasMethod(initiate: MethodConditions) = method(initiate).ignored().isNoSuch.not()
/**
* 查找构造方法是否存在
* @param initiate 方法体
* @return [Boolean] 是否存在
*/
inline fun Class<*>.hasConstructor(initiate: ConstructorConditions = { emptyParam() }) = constructor(initiate).ignored().isNoSuch.not()
/**
* 查找 [Member] 中匹配的描述符
* @param conditions 条件方法体
* @return [Boolean] 是否存在
*/
inline fun Member.hasModifiers(conditions: ModifierConditions) = conditions(ModifierRules.with(instance = this))
/**
* 查找 [Class] 中匹配的描述符
* @param conditions 条件方法体
* @return [Boolean] 是否存在
*/
inline fun Class<*>.hasModifiers(conditions: ModifierConditions) = conditions(ModifierRules.with(instance = this))
/**
* 查找并得到变量
* @param initiate 查找方法体
* @return [FieldFinder.Result]
*/
inline fun Class<*>.field(initiate: FieldConditions) = FieldFinder(classSet = this).apply(initiate).build()
/**
* 查找并得到方法
* @param initiate 查找方法体
* @return [MethodFinder.Result]
*/
inline fun Class<*>.method(initiate: MethodConditions) = MethodFinder(classSet = this).apply(initiate).build()
/**
* 查找并得到构造方法
* @param initiate 查找方法体
* @return [ConstructorFinder.Result]
*/
inline fun Class<*>.constructor(initiate: ConstructorConditions = { emptyParam() }) = ConstructorFinder(classSet = this).apply(initiate).build()
/**
* 获得当前 [Class] 的泛型父类
*
* 如果当前实例不存在泛型将返回 null
* @return [GenericClass] or null
*/
fun Class<*>.generic() = genericSuperclass?.let { (it as? ParameterizedType?)?.let { e -> GenericClass(e) } }
/**
* 获得当前 [Class] 的泛型父类
*
* 如果当前实例不存在泛型将返回 null
* @param initiate 实例方法体
* @return [GenericClass] or null
*/
inline fun Class<*>.generic(initiate: GenericClass.() -> Unit) = generic()?.apply(initiate)
/**
* 获得当前实例的类操作对象
* @param ignored 是否开启忽略错误警告功能 - 默认否
* @return [CurrentClass]
*/
inline fun <reified T : Any> T.current(ignored: Boolean = false) =
CurrentClass(javaClass, instance = this).apply { isShutErrorPrinting = ignored }
/**
* 获得当前实例的类操作对象
* @param ignored 是否开启忽略错误警告功能 - 默认否
* @param initiate 方法体
* @return [T]
*/
inline fun <reified T : Any> T.current(ignored: Boolean = false, initiate: CurrentClass.() -> Unit): T {
current(ignored).apply(initiate)
return this
}
/**
* 通过构造方法创建新实例 - 任意类型 [Any]
* @param args 方法参数
* @param initiate 查找方法体
* @return [Any] or null
*/
inline fun Class<*>.buildOf(vararg args: Any?, initiate: ConstructorConditions = { emptyParam() }) =
constructor(initiate).get().call(*args)
/**
* 通过构造方法创建新实例 - 指定类型 [T]
* @param args 方法参数
* @param initiate 查找方法体
* @return [T] or null
*/
@JvmName(name = "buildOf_Generics")
inline fun <T> Class<*>.buildOf(vararg args: Any?, initiate: ConstructorConditions = { emptyParam() }) =
constructor(initiate).get().newInstance<T>(*args)
/**
* 遍历当前类中的所有方法
* @param isAccessible 是否强制设置成员为可访问类型 - 默认是
* @param result 回调 - ([Int] 下标,[Method] 实例)
*/
inline fun Class<*>.allMethods(isAccessible: Boolean = true, result: (index: Int, method: Method) -> Unit) =
declaredMethods.forEachIndexed { p, it -> result(p, it.also { e -> e.isAccessible = isAccessible }) }
/**
* 遍历当前类中的所有构造方法
* @param isAccessible 是否强制设置成员为可访问类型 - 默认是
* @param result 回调 - ([Int] 下标,[Constructor] 实例)
*/
inline fun Class<*>.allConstructors(isAccessible: Boolean = true, result: (index: Int, constructor: Constructor<*>) -> Unit) =
declaredConstructors.forEachIndexed { p, it -> result(p, it.also { e -> e.isAccessible = isAccessible }) }
/**
* 遍历当前类中的所有变量
* @param isAccessible 是否强制设置成员为可访问类型 - 默认是
* @param result 回调 - ([Int] 下标,[Field] 实例)
*/
inline fun Class<*>.allFields(isAccessible: Boolean = true, result: (index: Int, field: Field) -> Unit) =
declaredFields.forEachIndexed { p, it -> result(p, it.also { e -> e.isAccessible = isAccessible }) }

View File

@@ -0,0 +1,147 @@
/*
* YukiReflection - An efficient Reflection API for Java and Android built in Kotlin
* Copyright (C) 2019-2023 HighCapable
* https://github.com/fankes/YukiReflection
*
* 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/4.
* This file is Modified by fankes on 2023/1/21.
*/
package com.highcapable.yukireflection.finder.base
import com.highcapable.yukireflection.annotation.YukiPrivateApi
import com.highcapable.yukireflection.bean.VariousClass
import com.highcapable.yukireflection.factory.toClass
import com.highcapable.yukireflection.finder.base.data.BaseRulesData
import com.highcapable.yukireflection.type.defined.UndefinedType
import java.lang.reflect.Member
import kotlin.math.abs
/**
* 这是 [Class] 与 [Member] 查找类功能的基本类实现
*/
abstract class BaseFinder {
/** 当前查找条件规则数据 */
@PublishedApi
internal abstract val rulesData: BaseRulesData
/**
* 字节码、数组下标筛选数据类型
*/
@PublishedApi
internal enum class IndexConfigType { ORDER, MATCH }
/**
* 字节码、数组下标筛选实现类
* @param type 类型
*/
inner class IndexTypeCondition @PublishedApi internal constructor(private val type: IndexConfigType) {
/**
* 设置下标
*
* 若 index 小于零则为倒序 - 此时可以使用 [IndexTypeConditionSort.reverse] 方法实现
*
* 可使用 [IndexTypeConditionSort.first] 和 [IndexTypeConditionSort.last] 设置首位和末位筛选条件
* @param num 下标
*/
fun index(num: Int) = when (type) {
IndexConfigType.ORDER -> rulesData.orderIndex = Pair(num, true)
IndexConfigType.MATCH -> rulesData.matchIndex = Pair(num, true)
}
/**
* 得到下标
* @return [IndexTypeConditionSort]
*/
fun index() = IndexTypeConditionSort()
/**
* 字节码、数组下标排序实现类
*
* - ❗请使用 [index] 方法来获取 [IndexTypeConditionSort]
*/
inner class IndexTypeConditionSort internal constructor() {
/** 设置满足条件的第一个*/
fun first() = index(num = 0)
/** 设置满足条件的最后一个*/
fun last() = when (type) {
IndexConfigType.ORDER -> rulesData.orderIndex = Pair(0, false)
IndexConfigType.MATCH -> rulesData.matchIndex = Pair(0, false)
}
/**
* 设置倒序下标
* @param num 下标
*/
fun reverse(num: Int) = when {
num < 0 -> index(abs(num))
num == 0 -> index().last()
else -> index(-num)
}
}
}
/**
* 将目标类型转换为可识别的兼容类型
* @param tag 当前查找类的标识
* @param loader 使用的 [ClassLoader]
* @return [Class] or null
*/
internal fun Any?.compat(tag: String, loader: ClassLoader?) = when (this) {
null -> null
is Class<*> -> this
is String -> runCatching { toClass(loader) }.getOrNull() ?: UndefinedType
is VariousClass -> runCatching { get(loader) }.getOrNull() ?: UndefinedType
else -> error("$tag match type \"$javaClass\" not allowed")
} as Class<*>?
/**
* 返回结果实现类
*
* - ❗此功能交由方法体自动完成 - 你不应该手动调用此方法
* @return [BaseResult]
*/
@YukiPrivateApi
abstract fun build(): BaseResult
/**
* 返回只有异常的结果实现类
*
* - ❗此功能交由方法体自动完成 - 你不应该手动调用此方法
* @param throwable 异常
* @return [BaseResult]
*/
@YukiPrivateApi
abstract fun failure(throwable: Throwable?): BaseResult
/**
* 查找结果实现、处理类接口
*
* - ❗此功能交由方法体自动完成 - 你不应该手动继承此接口
*/
@YukiPrivateApi
interface BaseResult
}

View File

@@ -0,0 +1,83 @@
/*
* YukiReflection - An efficient Reflection API for Java and Android built in Kotlin
* Copyright (C) 2019-2023 HighCapable
* https://github.com/fankes/YukiReflection
*
* 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/4.
* This file is Modified by fankes on 2023/1/25.
*/
package com.highcapable.yukireflection.finder.base
import com.highcapable.yukireflection.YukiReflection
import com.highcapable.yukireflection.annotation.YukiPrivateApi
import com.highcapable.yukireflection.log.yLoggerE
import com.highcapable.yukireflection.log.yLoggerI
/**
* 这是 [Class] 查找类功能的基本类实现
* @param loaderSet 当前使用的 [ClassLoader] 实例
*/
abstract class ClassBaseFinder internal constructor(internal open val loaderSet: ClassLoader? = null) : BaseFinder() {
internal companion object {
/** [loaderSet] 为 null 的提示 */
internal const val LOADERSET_IS_NULL = "loaderSet is null"
}
/** 当前找到的 [Class] 数组 */
internal var classInstances = HashSet<Class<*>>()
/** 是否开启忽略错误警告功能 */
internal var isShutErrorPrinting = false
/**
* 将目标类型转换为可识别的兼容类型
* @param any 当前需要转换的实例
* @param tag 当前查找类的标识
* @return [Class] or null
*/
internal fun compatType(any: Any?, tag: String) = any?.compat(tag, loaderSet)
/**
* 在开启 [YukiReflection.Configs.isDebug] 的情况下输出调试信息
* @param msg 调试日志内容
*/
internal fun onDebuggingMsg(msg: String) {
if (YukiReflection.Configs.isDebug) yLoggerI(msg)
}
/**
* 发生错误时输出日志
* @param throwable 错误
*/
internal fun onFailureMsg(throwable: Throwable? = null) {
if (isShutErrorPrinting) return
/** 判断是否为 [LOADERSET_IS_NULL] */
if (throwable?.message == LOADERSET_IS_NULL) return
yLoggerE(msg = "NoClassDefFound happend in [$loaderSet]", e = throwable)
}
@YukiPrivateApi
override fun failure(throwable: Throwable?) = error("DexClassFinder does not contain this usage")
}

View File

@@ -0,0 +1,133 @@
/*
* YukiReflection - An efficient Reflection API for Java and Android built in Kotlin
* Copyright (C) 2019-2023 HighCapable
* https://github.com/fankes/YukiReflection
*
* 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/2/18.
* This file is Modified by fankes on 2023/1/21.
*/
@file:Suppress("MemberVisibilityCanBePrivate")
package com.highcapable.yukireflection.finder.base
import com.highcapable.yukireflection.YukiReflection
import com.highcapable.yukireflection.log.yLoggerE
import com.highcapable.yukireflection.log.yLoggerI
import com.highcapable.yukireflection.utils.await
import java.lang.reflect.Constructor
import java.lang.reflect.Field
import java.lang.reflect.Member
import java.lang.reflect.Method
/**
* 这是 [Member] 查找类功能的基本类实现
* @param tag 当前查找类的标识
* @param classSet 当前需要查找的 [Class] 实例
*/
abstract class MemberBaseFinder internal constructor(
private val tag: String,
@PublishedApi internal open val classSet: Class<*>? = null
) : BaseFinder() {
internal companion object {
/** [classSet] 为 null 的提示 */
internal const val CLASSSET_IS_NULL = "classSet is null"
}
/** 是否使用了重查找功能 */
@PublishedApi
internal var isUsingRemedyPlan = false
/** 是否开启忽略错误警告功能 */
internal var isShutErrorPrinting = false
/** 当前找到的 [Member] 数组 */
internal var memberInstances = HashSet<Member>()
/** 需要输出的日志内容 */
private var loggingContent: Pair<String, Throwable?>? = null
/**
* 将 [HashSet]<[Member]> 转换为 [HashSet]<[Field]>
* @return [HashSet]<[Field]>
*/
internal fun HashSet<Member>.fields() =
hashSetOf<Field>().also { takeIf { e -> e.isNotEmpty() }?.forEach { e -> (e as? Field?)?.also { f -> it.add(f) } } }
/**
* 将 [HashSet]<[Member]> 转换为 [HashSet]<[Method]>
* @return [HashSet]<[Method]>
*/
internal fun HashSet<Member>.methods() =
hashSetOf<Method>().also { takeIf { e -> e.isNotEmpty() }?.forEach { e -> (e as? Method?)?.also { m -> it.add(m) } } }
/**
* 将 [HashSet]<[Member]> 转换为 [HashSet]<[Constructor]>
* @return [HashSet]<[Constructor]>
*/
internal fun HashSet<Member>.constructors() =
hashSetOf<Constructor<*>>().also { takeIf { e -> e.isNotEmpty() }?.forEach { e -> (e as? Constructor<*>?)?.also { c -> it.add(c) } } }
/**
* 将目标类型转换为可识别的兼容类型
* @return [Class] or null
*/
internal fun Any?.compat() = compat(tag, classSet?.classLoader)
/**
* 发生错误时输出日志
* @param msg 消息日志
* @param throwable 错误
* @param isAlwaysPrint 忽略条件每次都打印错误
*/
internal fun onFailureMsg(msg: String = "", throwable: Throwable? = null, isAlwaysPrint: Boolean = false) {
/** 创建日志 */
fun build() {
if (isUsingRemedyPlan.not() && isShutErrorPrinting.not()) loggingContent = Pair(msg, throwable)
}
/** 判断是否为 [CLASSSET_IS_NULL] */
if (throwable?.message == CLASSSET_IS_NULL) return
/** 判断始终输出日志或等待结果后输出日志 */
if (isAlwaysPrint) build().run { printLogIfExist() }
else await { build().run { printLogIfExist() } }
}
/** 存在日志时输出日志 */
internal fun printLogIfExist() {
if (loggingContent != null) yLoggerE(
msg = "NoSuch$tag happend in [$classSet] ${loggingContent?.first}",
e = loggingContent?.second
)
/** 仅输出一次 - 然后清掉日志 */
loggingContent = null
}
/**
* 在开启 [YukiReflection.Configs.isDebug] 的情况下输出调试信息
* @param msg 调试日志内容
*/
internal fun onDebuggingMsg(msg: String) {
if (YukiReflection.Configs.isDebug) yLoggerI(msg)
}
}

View File

@@ -0,0 +1,144 @@
/*
* YukiReflection - An efficient Reflection API for Java and Android built in Kotlin
* Copyright (C) 2019-2023 HighCapable
* https://github.com/fankes/YukiReflection
*
* 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.
* This file is Modified by fankes on 2023/1/21.
*/
package com.highcapable.yukireflection.finder.base.data
import com.highcapable.yukireflection.finder.base.rules.CountRules
import com.highcapable.yukireflection.finder.base.rules.ModifierRules
import com.highcapable.yukireflection.finder.base.rules.NameRules
import com.highcapable.yukireflection.finder.base.rules.ObjectRules
import com.highcapable.yukireflection.finder.type.factory.ModifierConditions
import com.highcapable.yukireflection.type.defined.VagueType
import java.lang.reflect.Constructor
import java.lang.reflect.Field
import java.lang.reflect.Member
import java.lang.reflect.Method
/**
* 这是 [Class] 与 [Member] 规则查找数据基本类实现
* @param modifiers 描述符条件
* @param orderIndex 字节码、数组顺序下标
* @param matchIndex 字节码、数组筛选下标
*/
@PublishedApi
internal abstract class BaseRulesData internal constructor(
var modifiers: ModifierConditions? = null,
var orderIndex: Pair<Int, Boolean>? = null,
var matchIndex: Pair<Int, Boolean>? = null
) {
/** 当前类唯一标识值 */
internal var uniqueValue = 0L
init {
uniqueValue = System.currentTimeMillis()
}
/**
* [String] 转换为 [NameRules]
* @return [NameRules]
*/
internal fun String.cast() = NameRules.with(this)
/**
* [Int] 转换为 [CountRules]
* @return [CountRules]
*/
internal fun Int.cast() = CountRules.with(this)
/**
* [Class] 转换为 [ModifierRules]
* @return [ModifierRules]
*/
internal fun Class<*>.cast() = ModifierRules.with(instance = this, uniqueValue)
/**
* [Member] 转换为 [ModifierRules]
* @return [ModifierRules]
*/
internal fun Member.cast() = ModifierRules.with(instance = this, uniqueValue)
/**
* [Field.getType] 转换为 [ObjectRules]
* @return [ObjectRules]
*/
internal fun Field.type() = ObjectRules.with(type)
/**
* [Method.getParameterTypes] 转换为 [ObjectRules]
* @return [ObjectRules]
*/
internal fun Method.paramTypes() = ObjectRules.with(parameterTypes)
/**
* [Method.getReturnType] 转换为 [ObjectRules]
* @return [ObjectRules]
*/
internal fun Method.returnType() = ObjectRules.with(returnType)
/**
* [Constructor.getParameterTypes] 转换为 [ObjectRules]
* @return [ObjectRules]
*/
internal fun Constructor<*>.paramTypes() = ObjectRules.with(parameterTypes)
/**
* 获取参数数组文本化内容
* @return [String]
*/
internal fun Array<out Class<*>>?.typeOfString() =
StringBuilder("(").also { sb ->
var isFirst = true
if (this == null || isEmpty()) return "()"
forEach {
if (isFirst) isFirst = false else sb.append(", ")
sb.append(it.takeIf { it.canonicalName != VagueType.canonicalName }?.canonicalName ?: "*vague*")
}
sb.append(")")
}.toString()
/**
* 获取规则对象模板字符串数组
* @return [Array]<[String]>
*/
internal abstract val templates: Array<String>
/**
* 获取规则对象名称
* @return [String]
*/
internal abstract val objectName: String
/**
* 判断规则是否已经初始化 (设置了任意一个参数)
* @return [Boolean]
*/
internal open val isInitialize get() = modifiers != null || orderIndex != null || matchIndex != null
override fun toString() = "[$modifiers][$orderIndex][$matchIndex]"
}

View File

@@ -0,0 +1,83 @@
/*
* YukiReflection - An efficient Reflection API for Java and Android built in Kotlin
* Copyright (C) 2019-2023 HighCapable
* https://github.com/fankes/YukiReflection
*
* 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/14.
* This file is Modified by fankes on 2023/1/21.
*/
@file:Suppress("unused")
package com.highcapable.yukireflection.finder.base.rules
import java.lang.reflect.Member
/**
* 这是一个模糊 [Class]、[Member] 数组 (下标) 个数条件实现类
*
* 可对 R8 混淆后的 [Class]、[Member] 进行更加详细的定位
* @param instance 当前实例对象
*/
class CountRules private constructor(private val instance: Int) {
@PublishedApi
internal companion object {
/**
* 创建实例
* @param instance 实例对象
* @return [CountRules]
*/
@PublishedApi
internal fun with(instance: Int) = CountRules(instance)
}
/**
* 是否为 0
* @return [Boolean]
*/
fun Int.isZero() = this == 0
/**
* 大于 [count]
* @param count 目标对象
* @return [Boolean]
*/
fun Int.moreThan(count: Int) = this > count
/**
* 小于 [count]
* @param count 目标对象
* @return [Boolean]
*/
fun Int.lessThan(count: Int) = this < count
/**
* 在 [countRange] 区间 A ≤ this ≤ B
* @param countRange 区间
* @return [Boolean]
*/
fun Int.inInterval(countRange: IntRange) = this in countRange
override fun toString() = "CountRules [$instance]"
}

View File

@@ -0,0 +1,240 @@
/*
* YukiReflection - An efficient Reflection API for Java and Android built in Kotlin
* Copyright (C) 2019-2023 HighCapable
* https://github.com/fankes/YukiReflection
*
* 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/3/27.
* This file is Modified by fankes on 2022/9/14.
* This file is Modified by fankes on 2023/1/21.
*/
@file:Suppress("unused")
package com.highcapable.yukireflection.finder.base.rules
import android.util.ArrayMap
import java.lang.reflect.Field
import java.lang.reflect.Member
import java.lang.reflect.Method
import java.lang.reflect.Modifier
/**
* 这是一个 [Class]、[Member] 描述符条件实现类
*
* 可对 R8 混淆后的 [Class]、[Member] 进行更加详细的定位
* @param instance 当前实例对象
*/
class ModifierRules private constructor(private val instance: Any) {
@PublishedApi
internal companion object {
/** 当前实例数组 */
private val instances = ArrayMap<Long, ModifierRules>()
/**
* 获取模板字符串数组
* @param value 唯一标识值
* @return [ArrayList]<[String]>
*/
internal fun templates(value: Long) = instances[value]?.templates ?: arrayListOf()
/**
* 创建实例
* @param instance 实例对象
* @param value 唯一标识值 - 默认 0
* @return [ModifierRules]
*/
@PublishedApi
internal fun with(instance: Any, value: Long = 0) = ModifierRules(instance).apply { instances[value] = this }
}
/** 当前模板字符串数组 */
private val templates = ArrayList<String>()
/**
* [Class]、[Member] 类型是否包含 public
*
* 如下所示 ↓
*
* public class/void/int/String...
*
* ^^^
* @return [Boolean]
*/
val isPublic get() = Modifier.isPublic(modifiers).also { templates.add("<isPublic> ($it)") }
/**
* [Class]、[Member] 类型是否包含 private
*
* 如下所示 ↓
*
* private class/void/int/String...
*
* ^^^
* @return [Boolean]
*/
val isPrivate get() = Modifier.isPrivate(modifiers).also { templates.add("<isPrivate> ($it)") }
/**
* [Class]、[Member] 类型是否包含 protected
*
* 如下所示 ↓
*
* protected class/void/int/String...
*
* ^^^
* @return [Boolean]
*/
val isProtected get() = Modifier.isProtected(modifiers).also { templates.add("<isProtected> ($it)") }
/**
* [Class]、[Member] 类型是否包含 static
*
* 对于任意的静态 [Class]、[Member] 可添加此描述进行确定
*
* 如下所示 ↓
*
* static class/void/int/String...
*
* ^^^
*
* - ❗注意 Kotlin → Jvm 后的 object 类中的方法并不是静态的
* @return [Boolean]
*/
val isStatic get() = Modifier.isStatic(modifiers).also { templates.add("<isStatic> ($it)") }
/**
* [Class]、[Member] 类型是否包含 final
*
* 如下所示 ↓
*
* final class/void/int/String...
*
* ^^^
*
* - ❗注意 Kotlin → Jvm 后没有 open 标识的 [Class]、[Member] 和没有任何关联的 [Class]、[Member] 都将为 final
* @return [Boolean]
*/
val isFinal get() = Modifier.isFinal(modifiers).also { templates.add("<isFinal> ($it)") }
/**
* [Class]、[Member] 类型是否包含 synchronized
*
* 如下所示 ↓
*
* synchronized class/void/int/String...
*
* ^^^
* @return [Boolean]
*/
val isSynchronized get() = Modifier.isSynchronized(modifiers).also { templates.add("<isSynchronized> ($it)") }
/**
* [Field] 类型是否包含 volatile
*
* 如下所示 ↓
*
* volatile int/String...
*
* ^^^
* @return [Boolean]
*/
val isVolatile get() = Modifier.isVolatile(modifiers).also { templates.add("<isVolatile> ($it)") }
/**
* [Field] 类型是否包含 transient
*
* 如下所示 ↓
*
* transient int/String...
*
* ^^^
* @return [Boolean]
*/
val isTransient get() = Modifier.isTransient(modifiers).also { templates.add("<isTransient> ($it)") }
/**
* [Method] 类型是否包含 native
*
* 对于任意 JNI 对接的 [Method] 可添加此描述进行确定
*
* 如下所示 ↓
*
* native void/int/String...
*
* ^^^
* @return [Boolean]
*/
val isNative get() = Modifier.isNative(modifiers).also { templates.add("<isNative> ($it)") }
/**
* [Class] 类型是否包含 interface
*
* 如下所示 ↓
*
* interface ...
*
* ^^^
* @return [Boolean]
*/
val isInterface get() = Modifier.isInterface(modifiers).also { templates.add("<isInterface> ($it)") }
/**
* [Class]、[Member] 类型是否包含 abstract
*
* 对于任意的抽象 [Class]、[Member] 可添加此描述进行确定
*
* 如下所示 ↓
*
* abstract class/void/int/String...
*
* ^^^
* @return [Boolean]
*/
val isAbstract get() = Modifier.isAbstract(modifiers).also { templates.add("<isAbstract> ($it)") }
/**
* [Class]、[Member] 类型是否包含 strictfp
*
* 如下所示 ↓
*
* strictfp class/void/int/String...
*
* ^^^
* @return [Boolean]
*/
val isStrict get() = Modifier.isStrict(modifiers).also { templates.add("<isStrict> ($it)") }
/**
* 获取当前对象的类型描述符
* @return [Int]
*/
private val modifiers
get() = when (instance) {
is Member -> instance.modifiers
is Class<*> -> instance.modifiers
else -> 0
}
override fun toString() = "ModifierRules [$instance]"
}

View File

@@ -0,0 +1,126 @@
/*
* YukiReflection - An efficient Reflection API for Java and Android built in Kotlin
* Copyright (C) 2019-2023 HighCapable
* https://github.com/fankes/YukiReflection
*
* 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/5/16.
* This file is Modified by fankes on 2022/9/14.
* This file is Modified by fankes on 2023/1/21.
*/
@file:Suppress("unused", "MemberVisibilityCanBePrivate")
package com.highcapable.yukireflection.finder.base.rules
import java.lang.reflect.Member
/**
* 这是一个模糊 [Class]、[Member] 名称条件实现类
*
* 可对 R8 混淆后的 [Class]、[Member] 进行更加详细的定位
* @param instance 当前实例对象
*/
class NameRules private constructor(private val instance: String) {
@PublishedApi
internal companion object {
/**
* 创建实例
* @param instance 实例对象
* @return [NameRules]
*/
@PublishedApi
internal fun with(instance: String) = NameRules(instance)
}
/**
* 是否为匿名类的主类调用对象名称
*
* 它的名称形态通常为this$[index]
* @param index 下标 - 默认 0
* @return [Boolean]
*/
fun String.isSynthetic(index: Int = 0) = this == "this$$index"
/**
* 是否只有符号
*
* 筛选仅包含 _、-、?、!、,、.、<、> 等符号以及特殊符号
*
* 你可以使用 [matches] 方法进行更详细的正则匹配
* @return [Boolean]
*/
fun String.isOnlySymbols() = matches("[*,.:~`'\"|/\\\\?!^()\\[\\]{}%@#$&\\-_+=<>]+".toRegex())
/**
* 是否只有字母
*
* 在没有 [isOnlyLowercase] 以及 [isOnlyUppercase] 的条件下筛选仅包含 26 个大小写英文字母
*
* 你可以使用 [matches] 方法进行更详细的正则匹配
* @return [Boolean]
*/
fun String.isOnlyLetters() = matches("[a-zA-Z]+".toRegex())
/**
* 是否只有数字
*
* 筛选仅包含 0-9 阿拉伯数字
*
* 你可以使用 [matches] 方法进行更详细的正则匹配
* @return [Boolean]
*/
fun String.isOnlyNumbers() = matches("\\d+".toRegex())
/**
* 是否只有字母或数字
*
* 融合条件 [isOnlyLetters] 和 [isOnlyNumbers]
*
* 你可以使用 [matches] 方法进行更详细的正则匹配
* @return [Boolean]
*/
fun String.isOnlyLettersNumbers() = matches("[a-zA-Z\\d]+".toRegex())
/**
* 是否只有小写字母
*
* 在没有其它条件的情况下设置此条件允许判断对象存在字母以外的字符
*
* 你可以使用 [matches] 方法进行更详细的正则匹配
* @return [Boolean]
*/
fun String.isOnlyLowercase() = matches("[a-z]+".toRegex())
/**
* 是否只有大写字母
*
* 在没有其它条件的情况下设置此条件允许判断对象存在字母以外的字符
*
* 你可以使用 [matches] 方法进行更详细的正则匹配
* @return [Boolean]
*/
fun String.isOnlyUppercase() = matches("[A-Z]+".toRegex())
override fun toString() = "NameRules [$instance]"
}

View File

@@ -0,0 +1,56 @@
/*
* YukiReflection - An efficient Reflection API for Java and Android built in Kotlin
* Copyright (C) 2019-2023 HighCapable
* https://github.com/fankes/YukiReflection
*
* 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/12/30.
* This file is Modified by fankes on 2023/1/21.
*/
@file:Suppress("unused")
package com.highcapable.yukireflection.finder.base.rules
import java.lang.reflect.Member
/**
* 这是一个任意对象条件实现类
*
* 可对 R8 混淆后的 [Class]、[Member] 进行更加详细的定位
* @param instance 当前实例对象
*/
class ObjectRules private constructor(private val instance: Any) {
@PublishedApi
internal companion object {
/**
* 创建实例
* @param instance 实例对象
* @return [ObjectRules]
*/
@PublishedApi
internal fun with(instance: Any) = ObjectRules(instance)
}
override fun toString() = "ObjectRules [$instance]"
}

View File

@@ -0,0 +1,618 @@
/*
* YukiReflection - An efficient Reflection API for Java and Android built in Kotlin
* Copyright (C) 2019-2023 HighCapable
* https://github.com/fankes/YukiReflection
*
* 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/4.
* This file is Modified by fankes on 2023/1/25.
*/
@file:Suppress("unused", "MemberVisibilityCanBePrivate")
package com.highcapable.yukireflection.finder.classes
import android.content.Context
import android.content.SharedPreferences
import android.content.pm.PackageManager
import com.highcapable.yukireflection.annotation.YukiPrivateApi
import com.highcapable.yukireflection.factory.hasClass
import com.highcapable.yukireflection.factory.searchClass
import com.highcapable.yukireflection.factory.toClass
import com.highcapable.yukireflection.finder.base.ClassBaseFinder
import com.highcapable.yukireflection.finder.classes.data.ClassRulesData
import com.highcapable.yukireflection.finder.classes.rules.ConstructorRules
import com.highcapable.yukireflection.finder.classes.rules.FieldRules
import com.highcapable.yukireflection.finder.classes.rules.MemberRules
import com.highcapable.yukireflection.finder.classes.rules.MethodRules
import com.highcapable.yukireflection.finder.classes.rules.base.BaseRules
import com.highcapable.yukireflection.finder.classes.rules.result.MemberRulesResult
import com.highcapable.yukireflection.finder.tools.ReflectionTool
import com.highcapable.yukireflection.finder.type.factory.ModifierConditions
import com.highcapable.yukireflection.finder.type.factory.NameConditions
import com.highcapable.yukireflection.log.yLoggerW
import com.highcapable.yukireflection.utils.await
import com.highcapable.yukireflection.utils.runBlocking
import com.highcapable.yukireflection.utils.toStackTrace
import dalvik.system.BaseDexClassLoader
import java.lang.reflect.Constructor
import java.lang.reflect.Field
import java.lang.reflect.Member
import java.lang.reflect.Method
/**
* [Class] 查找类
*
* 可使用 [BaseDexClassLoader] 通过指定条件查找指定 [Class] 或一组 [Class]
*
* - ❗此功能尚在试验阶段 - 性能与稳定性可能仍然存在问题 - 使用过程遇到问题请向我们报告并帮助我们改进
* @param context 当前 [Context]
* @param name 标识当前 [Class] 缓存的名称 - 不设置将不启用缓存 - 启用缓存必须启用 [async]
* @param async 是否启用异步
* @param loaderSet 当前使用的 [ClassLoader] 实例
*/
class DexClassFinder @PublishedApi internal constructor(
private val context: Context?,
internal var name: String,
internal var async: Boolean,
override val loaderSet: ClassLoader?
) : ClassBaseFinder(loaderSet) {
companion object {
/** 缓存的存储文件名 */
private const val CACHE_FILE_NAME = "config_yukireflection_cache_obfuscate_classes"
/**
* 通过 [Context] 获取当前 [SharedPreferences]
* @param versionName 版本名称 - 默认空
* @param versionCode 版本号 - 默认空
* @return [SharedPreferences] or null
*/
private fun Context.currentSp(versionName: String? = null, versionCode: Long? = null) = runCatching {
@Suppress("NewApi", "DEPRECATION", "KotlinRedundantDiagnosticSuppress")
getSharedPreferences(packageManager?.getPackageInfo(packageName, PackageManager.GET_META_DATA)
?.let { "${CACHE_FILE_NAME}_${versionName ?: it.versionName}_${versionCode ?: runCatching { it.longVersionCode }.getOrNull() ?: it.versionCode}" }
?: "${CACHE_FILE_NAME}_unknown",
Context.MODE_PRIVATE)
}.onFailure { yLoggerW(msg = "Failed to read app's SharedPreferences when using DexClassFinder\n${it.toStackTrace()}") }.getOrNull()
/**
* 清除当前 [DexClassFinder] 的 [Class] 缓存
*
* 适用于全部通过 [ClassLoader.searchClass] 获取的 [DexClassFinder]
* @param context 当前 [Context]
* @param versionName 版本名称 - 默认空
* @param versionCode 版本号 - 默认空
*/
fun clearCache(context: Context, versionName: String? = null, versionCode: Long? = null) =
context.currentSp(versionName, versionCode)?.edit()?.clear()?.apply() ?: yLoggerW(msg = "Failed to clear DexClassFinder's cache")
}
@PublishedApi
override var rulesData = ClassRulesData()
/**
* 设置 [Class] 完整名称
*
* 只会查找匹配到的 [Class.getName]
*
* 例如 com.demo.Test 需要填写 com.demo.Test
* @return [String]
*/
var fullName
get() = rulesData.fullName?.name ?: ""
set(value) {
rulesData.fullName = rulesData.createNameRulesData(value)
}
/**
* 设置 [Class] 简单名称
*
* 只会查找匹配到的 [Class.getSimpleName]
*
* 例如 com.demo.Test 只需要填写 Test
*
* 对于匿名类例如 com.demo.Test$InnerTest 会为空 - 此时你可以使用 [singleName]
* @return [String]
*/
var simpleName
get() = rulesData.simpleName?.name ?: ""
set(value) {
rulesData.simpleName = rulesData.createNameRulesData(value)
}
/**
* 设置 [Class] 独立名称
*
* 设置后将首先使用 [Class.getSimpleName] - 若为空则会使用 [Class.getName] 进行处理
*
* 例如 com.demo.Test 只需要填写 Test
*
* 对于匿名类例如 com.demo.Test$InnerTest 只需要填写 Test$InnerTest
* @return [String]
*/
var singleName
get() = rulesData.singleName?.name ?: ""
set(value) {
rulesData.singleName = rulesData.createNameRulesData(value)
}
/**
* 设置在指定包名范围查找当前 [Class]
*
* 设置后仅会在当前 [name] 开头匹配的包名路径下进行查找 - 可提升查找速度
*
* 例如 ↓
*
* com.demo.test
*
* com.demo.test.demo
*
* - ❗建议设置此参数指定查找范围 - 否则 [Class] 过多时将会非常慢
* @param name 指定包名
* @return [FromPackageRules] 可设置 [FromPackageRules.absolute] 标识包名绝对匹配
*/
fun from(vararg name: String) = FromPackageRules(arrayListOf<ClassRulesData.PackageRulesData>().also {
name.takeIf { e -> e.isNotEmpty() }?.forEach { e -> it.add(rulesData.createPackageRulesData(e)) }
if (it.isNotEmpty()) rulesData.fromPackages.addAll(it)
})
/**
* 设置 [Class] 标识符筛选条件
*
* - 可不设置筛选条件
* @param conditions 条件方法体
*/
fun modifiers(conditions: ModifierConditions) {
rulesData.modifiers = conditions
}
/**
* 设置 [Class] 完整名称
*
* 只会查找匹配到的 [Class.getName]
*
* 例如 com.demo.Test 需要填写 com.demo.Test
* @param value 名称
* @return [ClassNameRules] 可设置 [ClassNameRules.optional] 标识类名可选
*/
fun fullName(value: String) = rulesData.createNameRulesData(value).let {
rulesData.fullName = it
ClassNameRules(it)
}
/**
* 设置 [Class] 简单名称
*
* 只会查找匹配到的 [Class.getSimpleName]
*
* 例如 com.demo.Test 只需要填写 Test
*
* 对于匿名类例如 com.demo.Test$InnerTest 会为空 - 此时你可以使用 [singleName]
* @param value 名称
* @return [ClassNameRules] 可设置 [ClassNameRules.optional] 标识类名可选
*/
fun simpleName(value: String) = rulesData.createNameRulesData(value).let {
rulesData.simpleName = it
ClassNameRules(it)
}
/**
* 设置 [Class] 独立名称
*
* 设置后将首先使用 [Class.getSimpleName] - 若为空则会使用 [Class.getName] 进行处理
*
* 例如 com.demo.Test 只需要填写 Test
*
* 对于匿名类例如 com.demo.Test$InnerTest 只需要填写 Test$InnerTest
* @param value 名称
* @return [ClassNameRules] 可设置 [ClassNameRules.optional] 标识类名可选
*/
fun singleName(value: String) = rulesData.createNameRulesData(value).let {
rulesData.singleName = it
ClassNameRules(it)
}
/**
* 设置 [Class] 完整名称条件
*
* 只会查找匹配到的 [Class.getName]
* @param conditions 条件方法体
*/
fun fullName(conditions: NameConditions) {
rulesData.fullNameConditions = conditions
}
/**
* 设置 [Class] 简单名称条件
*
* 只会查找匹配到的 [Class.getSimpleName]
* @param conditions 条件方法体
*/
fun simpleName(conditions: NameConditions) {
rulesData.simpleNameConditions = conditions
}
/**
* 设置 [Class] 独立名称条件
*
* 设置后将首先使用 [Class.getSimpleName] - 若为空则会使用 [Class.getName] 进行处理
* @param conditions 条件方法体
*/
fun singleName(conditions: NameConditions) {
rulesData.singleNameConditions = conditions
}
/** 设置 [Class] 继承的父类 */
inline fun <reified T> extends() {
rulesData.extendsClass.add(T::class.java.name)
}
/**
* 设置 [Class] 继承的父类
*
* 会同时查找 [name] 中所有匹配的父类
* @param name [Class] 完整名称
*/
fun extends(vararg name: String) {
rulesData.extendsClass.addAll(name.toList())
}
/** 设置 [Class] 实现的接口类 */
inline fun <reified T> implements() {
rulesData.implementsClass.add(T::class.java.name)
}
/**
* 设置 [Class] 实现的接口类
*
* 会同时查找 [name] 中所有匹配的接口类
* @param name [Class] 完整名称
*/
fun implements(vararg name: String) {
rulesData.implementsClass.addAll(name.toList())
}
/**
* 标识 [Class] 为匿名类
*
* 例如 com.demo.Test$1 或 com.demo.Test$InnerTest
*
* 标识后你可以使用 [enclosing] 来进一步指定匿名类的 (封闭类) 主类
*/
fun anonymous() {
rulesData.isAnonymousClass = true
}
/**
* 设置 [Class] 没有任何继承
*
* 此时 [Class] 只应该继承于 [Any]
*
* - ❗设置此条件后 [extends] 将失效
*/
fun noExtends() {
rulesData.isNoExtendsClass = true
}
/**
* 设置 [Class] 没有任何接口
*
* - ❗设置此条件后 [implements] 将失效
*/
fun noImplements() {
rulesData.isNoImplementsClass = true
}
/**
* 设置 [Class] 没有任何继承与接口
*
* 此时 [Class] 只应该继承于 [Any]
*
* - ❗设置此条件后 [extends] 与 [implements] 将失效
*/
fun noSuper() {
noExtends()
noImplements()
}
/** 设置 [Class] 匿名类的 (封闭类) 主类 */
inline fun <reified T> enclosing() {
rulesData.enclosingClass.add(T::class.java.name)
}
/**
* 设置 [Class] 匿名类的 (封闭类) 主类
*
* 会同时查找 [name] 中所有匹配的 (封闭类) 主类
* @param name [Class] 完整名称
*/
fun enclosing(vararg name: String) {
rulesData.enclosingClass.addAll(name.toList())
}
/**
* 包名范围名称过滤匹配条件实现类
* @param packages 包名数组
*/
inner class FromPackageRules internal constructor(private val packages: ArrayList<ClassRulesData.PackageRulesData>) {
/**
* 设置包名绝对匹配
*
* 例如有如下包名 ↓
*
* com.demo.test.a
*
* com.demo.test.a.b
*
* com.demo.test.active
*
* 若包名条件为 "com.demo.test.a" 则绝对匹配仅能匹配到第一个
*
* 相反地 - 不设置以上示例会全部匹配
*/
fun absolute() = packages.takeIf { it.isNotEmpty() }?.forEach { it.isAbsolute = true }
}
/**
* 类名匹配条件实现类
* @param name 类名匹配实例
*/
inner class ClassNameRules internal constructor(private val name: ClassRulesData.NameRulesData) {
/**
* 设置类名可选
*
* 例如有如下类名 ↓
*
* com.demo.Test (fullName) / Test (simpleName)
*
* defpackage.a (fullName) / a (simpleName)
*
* 这两个类名都是同一个类 - 但是在有些版本中被混淆有些版本没有
*
* 此时可设置类名为 "com.demo.Test" (fullName) / "Test" (simpleName)
*
* 这样就可在完全匹配类名情况下使用类名而忽略其它查找条件 - 否则忽略此条件继续使用其它查找条件
*/
fun optional() {
name.isOptional = true
}
}
/**
* 设置 [Class] 满足的 [Member] 条件
* @param initiate 条件方法体
* @return [MemberRulesResult]
*/
inline fun member(initiate: MemberRules.() -> Unit = {}) = BaseRules.createMemberRules(this).apply(initiate).build()
/**
* 设置 [Class] 满足的 [Field] 条件
* @param initiate 条件方法体
* @return [MemberRulesResult]
*/
inline fun field(initiate: FieldRules.() -> Unit = {}) = BaseRules.createFieldRules(this).apply(initiate).build()
/**
* 设置 [Class] 满足的 [Method] 条件
* @param initiate 条件方法体
* @return [MemberRulesResult]
*/
inline fun method(initiate: MethodRules.() -> Unit = {}) = BaseRules.createMethodRules(this).apply(initiate).build()
/**
* 设置 [Class] 满足的 [Constructor] 条件
* @param initiate 查找方法体
* @return [MemberRulesResult]
*/
inline fun constructor(initiate: ConstructorRules.() -> Unit = {}) = BaseRules.createConstructorRules(this).apply(initiate).build()
/**
* 得到 [Class] 或一组 [Class]
* @return [HashSet]<[Class]>
* @throws NoClassDefFoundError 如果找不到 [Class]
*/
private val result get() = ReflectionTool.findClasses(loaderSet, rulesData)
/**
* 从本地缓存读取 [Class] 数据
* @return [HashSet]<[Class]>
*/
private fun readFromCache(): HashSet<Class<*>> =
if (async && name.isNotBlank()) hashSetOf<Class<*>>().also { classes ->
context?.currentSp()?.getStringSet(name, emptySet())?.takeIf { it.isNotEmpty() }
?.forEach { className -> if (className.hasClass(loaderSet)) classes.add(className.toClass(loaderSet)) }
} else hashSetOf()
/**
* 将当前 [Class] 数组名称保存到本地缓存
* @throws IllegalStateException 如果当前包名为 "android"
*/
private fun HashSet<Class<*>>.saveToCache() {
if (name.isNotBlank() && isNotEmpty()) hashSetOf<String>().also { names ->
takeIf { it.isNotEmpty() }?.forEach { names.add(it.name) }
context?.also {
if (it.packageName == "android") error("Cannot create classes cache for \"android\", please remove \"name\" param")
it.currentSp()?.edit()?.apply { putStringSet(name, names) }?.apply() ?: yLoggerW(msg = "Failed to use caching in DexClassFinder")
}
}
}
/**
* 设置实例
* @param classes 当前找到的 [Class] 数组
*/
private fun setInstance(classes: HashSet<Class<*>>) {
classInstances.clear()
classes.takeIf { it.isNotEmpty() }?.forEach { classInstances.add(it) }
}
@YukiPrivateApi
override fun build() = runCatching {
if (loaderSet != null) {
/** 开始任务 */
fun startProcess() {
runBlocking {
setInstance(readFromCache().takeIf { it.isNotEmpty() } ?: result)
}.result { ms -> classInstances.takeIf { it.isNotEmpty() }?.forEach { onDebuggingMsg(msg = "Find Class [$it] takes ${ms}ms") } }
}
Result().also { e ->
if (async) e.await {
runCatching {
startProcess()
it.waitResultCallback?.invoke(it.get())
it.waitAllResultCallback?.invoke(it.all())
classInstances.saveToCache()
}.onFailure { e ->
it.isNotFound = true
it.throwable = e
it.noClassDefFoundErrorCallback?.invoke()
onFailureMsg(throwable = e)
}
} else startProcess()
}
} else Result(isNotFound = true, Throwable(LOADERSET_IS_NULL)).await { onFailureMsg() }
}.getOrElse { e -> Result(isNotFound = true, e).await { onFailureMsg(throwable = e) } }
/**
* [Class] 查找结果实现类
* @param isNotFound 是否没有找到 [Class] - 默认否
* @param throwable 错误信息
*/
inner class Result internal constructor(
@PublishedApi internal var isNotFound: Boolean = false,
@PublishedApi internal var throwable: Throwable? = null
) : BaseResult {
/** 异步方法体回调结果 */
internal var waitResultCallback: ((Class<*>?) -> Unit)? = null
/** 异步方法体回调数组结果 */
internal var waitAllResultCallback: ((HashSet<Class<*>>) -> Unit)? = null
/** 异常结果重新回调方法体 */
internal var noClassDefFoundErrorCallback: (() -> Unit)? = null
/**
* 创建监听结果事件方法体
* @param initiate 方法体
* @return [Result] 可继续向下监听
*/
inline fun result(initiate: Result.() -> Unit) = apply(initiate)
/**
* 得到 [Class] 本身
*
* - 若有多个 [Class] 结果只会返回第一个
*
* - 在查找条件找不到任何结果的时候将返回 null
*
* - ❗若你设置了 [async] 请使用 [wait] 方法
* @return [Class] or null
*/
fun get() = all().takeIf { it.isNotEmpty() }?.first()
/**
* 得到 [Class] 本身数组
*
* - 返回全部查找条件匹配的多个 [Class] 实例
*
* - 在查找条件找不到任何结果的时候将返回空的 [HashSet]
*
* - ❗若你设置了 [async] 请使用 [waitAll] 方法
* @return [HashSet]<[Class]>
*/
fun all() = classInstances
/**
* 得到 [Class] 本身数组 (依次遍历)
*
* - 回调全部查找条件匹配的多个 [Class] 实例
*
* - 在查找条件找不到任何结果的时候将不会执行
*
* - ❗若你设置了 [async] 请使用 [waitAll] 方法
* @param result 回调每个结果
* @return [Result] 可继续向下监听
*/
fun all(result: (Class<*>) -> Unit): Result {
all().takeIf { it.isNotEmpty() }?.forEach(result)
return this
}
/**
* 得到 [Class] 本身 (异步)
*
* - 若有多个 [Class] 结果只会回调第一个
*
* - 在查找条件找不到任何结果的时候将回调 null
*
* - ❗你需要设置 [async] 后此方法才会被回调 - 否则请使用 [get] 方法
* @param result 回调 - ([Class] or null)
* @return [Result] 可继续向下监听
*/
fun wait(result: (Class<*>?) -> Unit): Result {
waitResultCallback = result
return this
}
/**
* 得到 [Class] 本身数组 (异步)
*
* - 回调全部查找条件匹配的多个 [Class] 实例
*
* - 在查找条件找不到任何结果的时候将回调空的 [HashSet]
*
* - ❗你需要设置 [async] 后此方法才会被回调 - 否则请使用 [all] 方法
* @param result 回调 - ([HashSet]<[Class]>)
* @return [Result] 可继续向下监听
*/
fun waitAll(result: (HashSet<Class<*>>) -> Unit): Result {
waitAllResultCallback = result
return this
}
/**
* 监听找不到 [Class] 时
* @param result 回调错误
* @return [Result] 可继续向下监听
*/
fun onNoClassDefFoundError(result: (Throwable) -> Unit): Result {
noClassDefFoundErrorCallback = { if (isNotFound) result(throwable ?: Throwable("Initialization Error")) }
noClassDefFoundErrorCallback?.invoke()
return this
}
/**
* 忽略异常并停止打印任何错误日志
*
* - ❗此时若要监听异常结果 - 你需要手动实现 [onNoClassDefFoundError] 方法
* @return [Result] 可继续向下监听
*/
fun ignored(): Result {
isShutErrorPrinting = true
return this
}
}
}

View File

@@ -0,0 +1,182 @@
/*
* YukiReflection - An efficient Reflection API for Java and Android built in Kotlin
* Copyright (C) 2019-2023 HighCapable
* https://github.com/fankes/YukiReflection
*
* 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/5.
* This file is Modified by fankes on 2023/1/25.
*/
@file:Suppress("PropertyName")
package com.highcapable.yukireflection.finder.classes.data
import com.highcapable.yukireflection.finder.base.data.BaseRulesData
import com.highcapable.yukireflection.finder.base.rules.ModifierRules
import com.highcapable.yukireflection.finder.members.data.ConstructorRulesData
import com.highcapable.yukireflection.finder.members.data.FieldRulesData
import com.highcapable.yukireflection.finder.members.data.MemberRulesData
import com.highcapable.yukireflection.finder.members.data.MethodRulesData
import com.highcapable.yukireflection.finder.type.factory.NameConditions
import java.lang.reflect.Constructor
import java.lang.reflect.Field
import java.lang.reflect.Member
import java.lang.reflect.Method
/**
* [Class] 规则查找数据类
* @param fromPackages 指定包名范围名称数组
* @param fullName 完整名称
* @param simpleName 简单名称
* @param singleName 独立名称
* @param fullNameConditions 完整名称规则
* @param simpleNameConditions 简单名称规则
* @param singleNameConditions 独立名称规则
* @param isAnonymousClass 匿名类
* @param isNoExtendsClass 无继承的父类
* @param isNoImplementsClass 无继承的实现的接口类
* @param extendsClass 继承的父类名称数组
* @param implementsClass 实现的接口类名称数组
* @param enclosingClass 包含的封闭类 (主类) 名称数组
* @param memberRules [Member] 查找条件数据数组
* @param fieldRules [Field] 查找条件数据数组
* @param methodRules [Method] 查找条件数据数组
* @param constroctorRules [Constructor] 查找条件数据数组
*/
@PublishedApi
internal class ClassRulesData internal constructor(
var fromPackages: ArrayList<PackageRulesData> = arrayListOf(),
var fullName: NameRulesData? = null,
var simpleName: NameRulesData? = null,
var singleName: NameRulesData? = null,
var fullNameConditions: NameConditions? = null,
var simpleNameConditions: NameConditions? = null,
var singleNameConditions: NameConditions? = null,
var isAnonymousClass: Boolean? = null,
var isNoExtendsClass: Boolean? = null,
var isNoImplementsClass: Boolean? = null,
var extendsClass: ArrayList<String> = arrayListOf(),
var implementsClass: ArrayList<String> = arrayListOf(),
var enclosingClass: ArrayList<String> = arrayListOf(),
var memberRules: ArrayList<MemberRulesData> = arrayListOf(),
var fieldRules: ArrayList<FieldRulesData> = arrayListOf(),
var methodRules: ArrayList<MethodRulesData> = arrayListOf(),
var constroctorRules: ArrayList<ConstructorRulesData> = arrayListOf()
) : BaseRulesData() {
/**
* 创建类名匹配条件查找数据类
* @param name 包名
* @return [NameRulesData]
*/
internal fun createNameRulesData(name: String) = NameRulesData(name)
/**
* 创建包名范围名称过滤匹配条件查找数据类
* @param name 包名
* @return [PackageRulesData]
*/
internal fun createPackageRulesData(name: String) = PackageRulesData(name)
/**
* 获取 [Class.getSimpleName] 与 [Class.getName] 的独立名称
* @param instance 当前 [Class] 实例
* @return [String]
*/
internal fun classSingleName(instance: Class<*>) = instance.simpleName.takeIf { it.isNotBlank() }
?: instance.enclosingClass?.let { it.simpleName + instance.name.replace(it.name, newValue = "") } ?: ""
/**
* 类名匹配条件查找数据类
* @param name 包名
* @param isOptional 是否可选 - 默认否
*/
inner class NameRulesData internal constructor(var name: String, var isOptional: Boolean = false) {
/** [Class.getName] */
internal val TYPE_NAME = 0
/** [Class.getSimpleName] */
internal val TYPE_SIMPLE_NAME = 1
/** [Class.getSimpleName] or [Class.getName] */
internal val TYPE_SINGLE_NAME = 2
/**
* 匹配当前 [Class] 实例
* @param instance 当前 [Class] 实例
* @param type 判断类型
* @return [Boolean]
*/
internal fun equals(instance: Class<*>, type: Int) = when (type) {
TYPE_NAME -> instance.name == name
TYPE_SIMPLE_NAME -> instance.simpleName == name
TYPE_SINGLE_NAME -> classSingleName(instance) == name
else -> false
}
override fun toString() = "$name optional($isOptional)"
}
/**
* 包名范围名称过滤匹配条件查找数据类
* @param name 包名
* @param isAbsolute 是否绝对匹配 - 默认否
*/
inner class PackageRulesData internal constructor(var name: String, var isAbsolute: Boolean = false) {
override fun toString() = "$name absolute($isAbsolute)"
}
override val templates
get() = arrayOf(
fromPackages.takeIf { it.isNotEmpty() }?.let { "from:$it" } ?: "",
fullName?.let { "fullName:[$it]" } ?: "",
simpleName?.let { "simpleName:[$it]" } ?: "",
singleName?.let { "singleName:[$it]" } ?: "",
fullNameConditions?.let { "fullNameConditions:[existed]" } ?: "",
simpleNameConditions?.let { "simpleNameConditions:[existed]" } ?: "",
singleNameConditions?.let { "singleNameConditions:[existed]" } ?: "",
modifiers?.let { "modifiers:${ModifierRules.templates(uniqueValue)}" } ?: "",
isAnonymousClass?.let { "isAnonymousClass:[$it]" } ?: "",
isNoExtendsClass?.let { "isNoExtendsClass:[$it]" } ?: "",
isNoImplementsClass?.let { "isNoImplementsClass:[$it]" } ?: "",
extendsClass.takeIf { it.isNotEmpty() }?.let { "extendsClass:$it" } ?: "",
implementsClass.takeIf { it.isNotEmpty() }?.let { "implementsClass:$it" } ?: "",
enclosingClass.takeIf { it.isNotEmpty() }?.let { "enclosingClass:$it" } ?: "",
memberRules.takeIf { it.isNotEmpty() }?.let { "memberRules:[${it.size} existed]" } ?: "",
fieldRules.takeIf { it.isNotEmpty() }?.let { "fieldRules:[${it.size} existed]" } ?: "",
methodRules.takeIf { it.isNotEmpty() }?.let { "methodRules:[${it.size} existed]" } ?: "",
constroctorRules.takeIf { it.isNotEmpty() }?.let { "constroctorRules:[${it.size} existed]" } ?: ""
)
override val objectName get() = "Class"
override val isInitialize
get() = super.isInitialize || fromPackages.isNotEmpty() || fullName != null || simpleName != null || singleName != null ||
fullNameConditions != null || simpleNameConditions != null || singleNameConditions != null || isAnonymousClass != null ||
isNoExtendsClass != null || isNoImplementsClass != null || extendsClass.isNotEmpty() || enclosingClass.isNotEmpty() ||
memberRules.isNotEmpty() || fieldRules.isNotEmpty() || methodRules.isNotEmpty() || constroctorRules.isNotEmpty()
override fun toString() = "[$fromPackages][$fullName][$simpleName][$singleName][$fullNameConditions][$simpleNameConditions]" +
"[$singleNameConditions][$modifiers][$isAnonymousClass][$isNoExtendsClass][$isNoImplementsClass][$extendsClass][$implementsClass]" +
"[$enclosingClass][$memberRules][$fieldRules][$methodRules][$constroctorRules]" + super.toString()
}

View File

@@ -0,0 +1,165 @@
/*
* YukiReflection - An efficient Reflection API for Java and Android built in Kotlin
* Copyright (C) 2019-2023 HighCapable
* https://github.com/fankes/YukiReflection
*
* 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/12.
* This file is Modified by fankes on 2023/1/25.
*/
@file:Suppress("MemberVisibilityCanBePrivate")
package com.highcapable.yukireflection.finder.classes.rules
import com.highcapable.yukireflection.bean.VariousClass
import com.highcapable.yukireflection.finder.classes.rules.base.BaseRules
import com.highcapable.yukireflection.finder.classes.rules.result.MemberRulesResult
import com.highcapable.yukireflection.finder.members.data.ConstructorRulesData
import com.highcapable.yukireflection.finder.type.factory.CountConditions
import com.highcapable.yukireflection.finder.type.factory.ModifierConditions
import com.highcapable.yukireflection.finder.type.factory.ObjectsConditions
import com.highcapable.yukireflection.type.defined.UndefinedType
import com.highcapable.yukireflection.type.defined.VagueType
import java.lang.reflect.Constructor
/**
* [Constructor] 查找条件实现类
* @param rulesData 当前查找条件规则数据
*/
class ConstructorRules internal constructor(@PublishedApi internal val rulesData: ConstructorRulesData) : BaseRules() {
/**
* 设置 [Constructor] 参数个数
*
* 你可以不使用 [param] 指定参数类型而是仅使用此变量指定参数个数
*
* 若参数个数小于零则忽略并使用 [param]
* @return [Int]
*/
var paramCount
get() = rulesData.paramCount
set(value) {
rulesData.paramCount = value
}
/**
* 设置 [Constructor] 标识符筛选条件
*
* - 可不设置筛选条件
* @param conditions 条件方法体
*/
fun modifiers(conditions: ModifierConditions) {
rulesData.modifiers = conditions
}
/** 设置 [Constructor] 空参数、无参数 */
fun emptyParam() {
rulesData.paramCount = 0
}
/**
* 设置 [Constructor] 参数
*
* 如果同时使用了 [paramCount] 则 [paramType] 的数量必须与 [paramCount] 完全匹配
*
* 如果 [Constructor] 中存在一些无意义又很长的类型 - 你可以使用 [VagueType] 来替代它
*
* 例如下面这个参数结构 ↓
*
* ```java
* Foo(String var1, boolean var2, com.demo.Test var3, int var4)
* ```
*
* 此时就可以简单地写作 ↓
*
* ```kotlin
* param(StringType, BooleanType, VagueType, IntType)
* ```
*
* - ❗无参 [Constructor] 请使用 [emptyParam] 设置查找条件
*
* - ❗有参 [Constructor] 必须使用此方法设定参数或使用 [paramCount] 指定个数
* @param paramType 参数类型数组 - ❗只能是 [Class]、[String]、[VariousClass]
*/
fun param(vararg paramType: Any) {
if (paramType.isEmpty()) error("paramTypes is empty, please use emptyParam() instead")
rulesData.paramTypes =
arrayListOf<Class<*>>().apply { paramType.forEach { add(it.compat(tag = "Constructor") ?: UndefinedType) } }.toTypedArray()
}
/**
* 设置 [Constructor] 参数条件
*
* 使用示例如下 ↓
*
* ```kotlin
* param { it[1] == StringClass || it[2].name == "java.lang.String" }
* ```
*
* - ❗无参 [Constructor] 请使用 [emptyParam] 设置查找条件
*
* - ❗有参 [Constructor] 必须使用此方法设定参数或使用 [paramCount] 指定个数
* @param conditions 条件方法体
*/
fun param(conditions: ObjectsConditions) {
rulesData.paramTypesConditions = conditions
}
/**
* 设置 [Constructor] 参数个数范围
*
* 你可以不使用 [param] 指定参数类型而是仅使用此方法指定参数个数范围
*
* 使用示例如下 ↓
*
* ```kotlin
* paramCount(1..5)
* ```
* @param numRange 个数范围
*/
fun paramCount(numRange: IntRange) {
rulesData.paramCountRange = numRange
}
/**
* 设置 [Constructor] 参数个数条件
*
* 你可以不使用 [param] 指定参数类型而是仅使用此方法指定参数个数条件
*
* 使用示例如下 ↓
*
* ```kotlin
* paramCount { it >= 5 || it.isZero() }
* ```
* @param conditions 条件方法体
*/
fun paramCount(conditions: CountConditions) {
rulesData.paramCountConditions = conditions
}
/**
* 返回结果实现类
* @return [MemberRulesResult]
*/
@PublishedApi
internal fun build() = MemberRulesResult(rulesData)
}

View File

@@ -0,0 +1,110 @@
/*
* YukiReflection - An efficient Reflection API for Java and Android built in Kotlin
* Copyright (C) 2019-2023 HighCapable
* https://github.com/fankes/YukiReflection
*
* 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/12.
* This file is Modified by fankes on 2023/1/25.
*/
package com.highcapable.yukireflection.finder.classes.rules
import com.highcapable.yukireflection.bean.VariousClass
import com.highcapable.yukireflection.finder.classes.rules.base.BaseRules
import com.highcapable.yukireflection.finder.classes.rules.result.MemberRulesResult
import com.highcapable.yukireflection.finder.members.data.FieldRulesData
import com.highcapable.yukireflection.finder.type.factory.ModifierConditions
import com.highcapable.yukireflection.finder.type.factory.NameConditions
import com.highcapable.yukireflection.finder.type.factory.ObjectConditions
import java.lang.reflect.Field
/**
* [Field] 查找条件实现类
* @param rulesData 当前查找条件规则数据
*/
class FieldRules internal constructor(@PublishedApi internal val rulesData: FieldRulesData) : BaseRules() {
/**
* 设置 [Field] 名称
* @return [String]
*/
var name
get() = rulesData.name
set(value) {
rulesData.name = value
}
/**
* 设置 [Field] 类型
*
* - ❗只能是 [Class]、[String]、[VariousClass]
*
* - 可不填写类型
* @return [Any] or null
*/
var type
get() = rulesData.type
set(value) {
rulesData.type = value?.compat(tag = "Field")
}
/**
* 设置 [Field] 标识符筛选条件
*
* - 可不设置筛选条件
* @param conditions 条件方法体
*/
fun modifiers(conditions: ModifierConditions) {
rulesData.modifiers = conditions
}
/**
* 设置 [Field] 名称条件
* @param conditions 条件方法体
*/
fun name(conditions: NameConditions) {
rulesData.nameConditions = conditions
}
/**
* 设置 [Field] 类型条件
*
* - 可不填写类型
*
* 使用示例如下 ↓
*
* ```kotlin
* type { it == StringClass || it.name == "java.lang.String" }
* ```
* @param conditions 条件方法体
*/
fun type(conditions: ObjectConditions) {
rulesData.typeConditions = conditions
}
/**
* 返回结果实现类
* @return [MemberRulesResult]
*/
@PublishedApi
internal fun build() = MemberRulesResult(rulesData)
}

View File

@@ -0,0 +1,59 @@
/*
* YukiReflection - An efficient Reflection API for Java and Android built in Kotlin
* Copyright (C) 2019-2023 HighCapable
* https://github.com/fankes/YukiReflection
*
* 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/12.
* This file is Modified by fankes on 2023/1/25.
*/
package com.highcapable.yukireflection.finder.classes.rules
import com.highcapable.yukireflection.finder.classes.rules.base.BaseRules
import com.highcapable.yukireflection.finder.classes.rules.result.MemberRulesResult
import com.highcapable.yukireflection.finder.members.data.MemberRulesData
import com.highcapable.yukireflection.finder.type.factory.ModifierConditions
import java.lang.reflect.Member
/**
* [Member] 查找条件实现类
* @param rulesData 当前查找条件规则数据
*/
class MemberRules internal constructor(@PublishedApi internal val rulesData: MemberRulesData) : BaseRules() {
/**
* 设置 [Member] 标识符筛选条件
*
* - 可不设置筛选条件
* @param conditions 条件方法体
*/
fun modifiers(conditions: ModifierConditions) {
rulesData.modifiers = conditions
}
/**
* 返回结果实现类
* @return [MemberRulesResult]
*/
@PublishedApi
internal fun build() = MemberRulesResult(rulesData)
}

View File

@@ -0,0 +1,211 @@
/*
* YukiReflection - An efficient Reflection API for Java and Android built in Kotlin
* Copyright (C) 2019-2023 HighCapable
* https://github.com/fankes/YukiReflection
*
* 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/12.
* This file is Modified by fankes on 2023/1/25.
*/
@file:Suppress("unused", "MemberVisibilityCanBePrivate")
package com.highcapable.yukireflection.finder.classes.rules
import com.highcapable.yukireflection.bean.VariousClass
import com.highcapable.yukireflection.finder.classes.rules.base.BaseRules
import com.highcapable.yukireflection.finder.classes.rules.result.MemberRulesResult
import com.highcapable.yukireflection.finder.members.data.MethodRulesData
import com.highcapable.yukireflection.finder.type.factory.*
import com.highcapable.yukireflection.type.defined.UndefinedType
import com.highcapable.yukireflection.type.defined.VagueType
import java.lang.reflect.Method
/**
* [Method] 查找条件实现类
* @param rulesData 当前查找条件规则数据
*/
class MethodRules internal constructor(@PublishedApi internal val rulesData: MethodRulesData) : BaseRules() {
/**
* 设置 [Method] 名称
* @return [String]
*/
var name
get() = rulesData.name
set(value) {
rulesData.name = value
}
/**
* 设置 [Method] 参数个数
*
* 你可以不使用 [param] 指定参数类型而是仅使用此变量指定参数个数
*
* 若参数个数小于零则忽略并使用 [param]
* @return [Int]
*/
var paramCount
get() = rulesData.paramCount
set(value) {
rulesData.paramCount = value
}
/**
* 设置 [Method] 返回值
*
* - ❗只能是 [Class]、[String]、[VariousClass]
*
* - 可不填写返回值
* @return [Any] or null
*/
var returnType
get() = rulesData.returnType
set(value) {
rulesData.returnType = value.compat(tag = "Method")
}
/**
* 设置 [Method] 标识符筛选条件
*
* - 可不设置筛选条件
* @param conditions 条件方法体
*/
fun modifiers(conditions: ModifierConditions) {
rulesData.modifiers = conditions
}
/** 设置 [Method] 空参数、无参数 */
fun emptyParam() {
rulesData.paramCount = 0
}
/**
* 设置 [Method] 参数
*
* 如果同时使用了 [paramCount] 则 [paramType] 的数量必须与 [paramCount] 完全匹配
*
* 如果 [Method] 中存在一些无意义又很长的类型 - 你可以使用 [VagueType] 来替代它
*
* 例如下面这个参数结构 ↓
*
* ```java
* void foo(String var1, boolean var2, com.demo.Test var3, int var4)
* ```
*
* 此时就可以简单地写作 ↓
*
* ```kotlin
* param(StringType, BooleanType, VagueType, IntType)
* ```
*
* - ❗无参 [Method] 请使用 [emptyParam] 设置查找条件
*
* - ❗有参 [Method] 必须使用此方法设定参数或使用 [paramCount] 指定个数
* @param paramType 参数类型数组 - ❗只能是 [Class]、[String]、[VariousClass]
*/
fun param(vararg paramType: Any) {
if (paramType.isEmpty()) error("paramTypes is empty, please use emptyParam() instead")
rulesData.paramTypes =
arrayListOf<Class<*>>().apply { paramType.forEach { add(it.compat(tag = "Method") ?: UndefinedType) } }.toTypedArray()
}
/**
* 设置 [Method] 参数条件
*
* 使用示例如下 ↓
*
* ```kotlin
* param { it[1] == StringClass || it[2].name == "java.lang.String" }
* ```
*
* - ❗无参 [Method] 请使用 [emptyParam] 设置查找条件
*
* - ❗有参 [Method] 必须使用此方法设定参数或使用 [paramCount] 指定个数
* @param conditions 条件方法体
*/
fun param(conditions: ObjectsConditions) {
rulesData.paramTypesConditions = conditions
}
/**
* 设置 [Method] 名称条件
* @param conditions 条件方法体
*/
fun name(conditions: NameConditions) {
rulesData.nameConditions = conditions
}
/**
* 设置 [Method] 参数个数范围
*
* 你可以不使用 [param] 指定参数类型而是仅使用此方法指定参数个数范围
*
* 使用示例如下 ↓
*
* ```kotlin
* paramCount(1..5)
* ```
* @param numRange 个数范围
*/
fun paramCount(numRange: IntRange) {
rulesData.paramCountRange = numRange
}
/**
* 设置 [Method] 参数个数条件
*
* 你可以不使用 [param] 指定参数类型而是仅使用此方法指定参数个数条件
*
* 使用示例如下 ↓
*
* ```kotlin
* paramCount { it >= 5 || it.isZero() }
* ```
* @param conditions 条件方法体
*/
fun paramCount(conditions: CountConditions) {
rulesData.paramCountConditions = conditions
}
/**
* 设置 [Method] 返回值条件
*
* - 可不填写返回值
*
* 使用示例如下 ↓
*
* ```kotlin
* returnType { it == StringClass || it.name == "java.lang.String" }
* ```
* @param conditions 条件方法体
*/
fun returnType(conditions: ObjectConditions) {
rulesData.returnTypeConditions = conditions
}
/**
* 返回结果实现类
* @return [MemberRulesResult]
*/
@PublishedApi
internal fun build() = MemberRulesResult(rulesData)
}

View File

@@ -0,0 +1,91 @@
/*
* YukiReflection - An efficient Reflection API for Java and Android built in Kotlin
* Copyright (C) 2019-2023 HighCapable
* https://github.com/fankes/YukiReflection
*
* 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/12.
* This file is Modified by fankes on 2023/1/25.
*/
package com.highcapable.yukireflection.finder.classes.rules.base
import com.highcapable.yukireflection.finder.classes.DexClassFinder
import com.highcapable.yukireflection.finder.classes.rules.ConstructorRules
import com.highcapable.yukireflection.finder.classes.rules.FieldRules
import com.highcapable.yukireflection.finder.classes.rules.MemberRules
import com.highcapable.yukireflection.finder.classes.rules.MethodRules
import com.highcapable.yukireflection.finder.members.data.ConstructorRulesData
import com.highcapable.yukireflection.finder.members.data.FieldRulesData
import com.highcapable.yukireflection.finder.members.data.MemberRulesData
import com.highcapable.yukireflection.finder.members.data.MethodRulesData
import java.lang.reflect.Member
/**
* [Member] 查找条件实现父类
* @param instance 当前查找类实例
*/
open class BaseRules internal constructor(internal var instance: DexClassFinder? = null) {
@PublishedApi
internal companion object {
/**
* 创建查找条件规则数据
* @param instance 当前查找类实例
* @return [MemberRulesData]
*/
@PublishedApi
internal fun createMemberRules(instance: DexClassFinder) =
MemberRules(MemberRulesData().apply { instance.rulesData.memberRules.add(this) }).apply { this.instance = instance }
/**
* 创建查找条件规则数据
* @return [FieldRulesData]
*/
@PublishedApi
internal fun createFieldRules(instance: DexClassFinder) =
FieldRules(FieldRulesData().apply { instance.rulesData.fieldRules.add(this) }).apply { this.instance = instance }
/**
* 创建查找条件规则数据
* @return [MethodRulesData]
*/
@PublishedApi
internal fun createMethodRules(instance: DexClassFinder) =
MethodRules(MethodRulesData().apply { instance.rulesData.methodRules.add(this) }).apply { this.instance = instance }
/**
* 创建查找条件规则数据
* @return [ConstructorRulesData]
*/
@PublishedApi
internal fun createConstructorRules(instance: DexClassFinder) =
ConstructorRules(ConstructorRulesData().apply { instance.rulesData.constroctorRules.add(this) }).apply { this.instance = instance }
}
/**
* 将目标类型转换为可识别的兼容类型
* @param tag 当前查找类的标识
* @return [Class] or null
*/
internal fun Any?.compat(tag: String) = instance?.compatType(any = this, tag)
}

View File

@@ -0,0 +1,90 @@
/*
* YukiReflection - An efficient Reflection API for Java and Android built in Kotlin
* Copyright (C) 2019-2023 HighCapable
* https://github.com/fankes/YukiReflection
*
* 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/12.
* This file is Modified by fankes on 2023/1/25.
*/
@file:Suppress("unused", "MemberVisibilityCanBePrivate")
package com.highcapable.yukireflection.finder.classes.rules.result
import com.highcapable.yukireflection.finder.members.data.MemberRulesData
import com.highcapable.yukireflection.finder.type.factory.CountConditions
import java.lang.reflect.Member
/**
* 当前 [Member] 查找条件结果实现类
* @param rulesData 当前查找条件规则数据
*/
class MemberRulesResult internal constructor(private val rulesData: MemberRulesData) {
/**
* 设置当前 [Member] 在查找条件中个数为 0
* @return [MemberRulesResult] 可继续向下监听
*/
fun none() = count(num = 0)
/**
* 设置当前 [Member] 在查找条件中需要全部匹配的个数
* @param num 个数
* @return [MemberRulesResult] 可继续向下监听
*/
fun count(num: Int): MemberRulesResult {
rulesData.matchCount = num
return this
}
/**
* 设置当前 [Member] 在查找条件中需要全部匹配的个数范围
*
* 使用示例如下 ↓
*
* ```kotlin
* count(1..5)
* ```
* @param numRange 个数范围
* @return [MemberRulesResult] 可继续向下监听
*/
fun count(numRange: IntRange): MemberRulesResult {
rulesData.matchCountRange = numRange
return this
}
/**
* 设置当前 [Member] 在查找条件中需要全部匹配的个数条件
*
* 使用示例如下 ↓
*
* ```kotlin
* count { it >= 5 || it.isZero() }
* ```
* @param conditions 条件方法体
* @return [MemberRulesResult] 可继续向下监听
*/
fun count(conditions: CountConditions): MemberRulesResult {
rulesData.matchCountConditions = conditions
return this
}
}

View File

@@ -0,0 +1,508 @@
/*
* YukiReflection - An efficient Reflection API for Java and Android built in Kotlin
* Copyright (C) 2019-2023 HighCapable
* https://github.com/fankes/YukiReflection
*
* 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/2/4.
* This file is Modified by fankes on 2023/1/21.
*/
@file:Suppress("unused", "MemberVisibilityCanBePrivate", "UNCHECKED_CAST", "KotlinConstantConditions")
package com.highcapable.yukireflection.finder.members
import com.highcapable.yukireflection.annotation.YukiPrivateApi
import com.highcapable.yukireflection.bean.VariousClass
import com.highcapable.yukireflection.factory.hasExtends
import com.highcapable.yukireflection.finder.base.BaseFinder
import com.highcapable.yukireflection.finder.base.MemberBaseFinder
import com.highcapable.yukireflection.finder.members.data.ConstructorRulesData
import com.highcapable.yukireflection.finder.tools.ReflectionTool
import com.highcapable.yukireflection.finder.type.factory.ConstructorConditions
import com.highcapable.yukireflection.finder.type.factory.CountConditions
import com.highcapable.yukireflection.finder.type.factory.ModifierConditions
import com.highcapable.yukireflection.finder.type.factory.ObjectsConditions
import com.highcapable.yukireflection.log.yLoggerW
import com.highcapable.yukireflection.type.defined.UndefinedType
import com.highcapable.yukireflection.type.defined.VagueType
import com.highcapable.yukireflection.utils.runBlocking
import java.lang.reflect.Constructor
/**
* [Constructor] 查找类
*
* 可通过指定类型查找指定 [Constructor] 或一组 [Constructor]
* @param classSet 当前需要查找的 [Class] 实例
*/
class ConstructorFinder @PublishedApi internal constructor(@PublishedApi override val classSet: Class<*>? = null) :
MemberBaseFinder(tag = "Constructor", classSet) {
@PublishedApi
override var rulesData = ConstructorRulesData()
/** 当前使用的 [classSet] */
private var usedClassSet = classSet
/** 当前重查找结果回调 */
private var remedyPlansCallback: (() -> Unit)? = null
/**
* 设置 [Constructor] 参数个数
*
* 你可以不使用 [param] 指定参数类型而是仅使用此变量指定参数个数
*
* 若参数个数小于零则忽略并使用 [param]
* @return [Int]
*/
var paramCount
get() = rulesData.paramCount
set(value) {
rulesData.paramCount = value
}
/**
* 设置 [Constructor] 标识符筛选条件
*
* - ❗存在多个 [BaseFinder.IndexTypeCondition] 时除了 [order] 只会生效最后一个
* @param conditions 条件方法体
* @return [BaseFinder.IndexTypeCondition]
*/
fun modifiers(conditions: ModifierConditions): IndexTypeCondition {
rulesData.modifiers = conditions
return IndexTypeCondition(IndexConfigType.MATCH)
}
/**
* 设置 [Constructor] 空参数、无参数
*
* @return [BaseFinder.IndexTypeCondition]
*/
fun emptyParam() = paramCount(num = 0)
/**
* 设置 [Constructor] 参数
*
* 如果同时使用了 [paramCount] 则 [paramType] 的数量必须与 [paramCount] 完全匹配
*
* 如果 [Constructor] 中存在一些无意义又很长的类型 - 你可以使用 [VagueType] 来替代它
*
* 例如下面这个参数结构 ↓
*
* ```java
* Foo(String var1, boolean var2, com.demo.Test var3, int var4)
* ```
*
* 此时就可以简单地写作 ↓
*
* ```kotlin
* param(StringType, BooleanType, VagueType, IntType)
* ```
*
* - ❗无参 [Constructor] 请使用 [emptyParam] 设置查找条件
*
* - ❗有参 [Constructor] 必须使用此方法设定参数或使用 [paramCount] 指定个数
*
* - ❗存在多个 [BaseFinder.IndexTypeCondition] 时除了 [order] 只会生效最后一个
* @param paramType 参数类型数组 - ❗只能是 [Class]、[String]、[VariousClass]
* @return [BaseFinder.IndexTypeCondition]
*/
fun param(vararg paramType: Any): IndexTypeCondition {
if (paramType.isEmpty()) error("paramTypes is empty, please use emptyParam() instead")
rulesData.paramTypes = arrayListOf<Class<*>>().apply { paramType.forEach { add(it.compat() ?: UndefinedType) } }.toTypedArray()
return IndexTypeCondition(IndexConfigType.MATCH)
}
/**
* 设置 [Constructor] 参数条件
*
* 使用示例如下 ↓
*
* ```kotlin
* param { it[1] == StringClass || it[2].name == "java.lang.String" }
* ```
*
* - ❗无参 [Constructor] 请使用 [emptyParam] 设置查找条件
*
* - ❗有参 [Constructor] 必须使用此方法设定参数或使用 [paramCount] 指定个数
*
* - ❗存在多个 [BaseFinder.IndexTypeCondition] 时除了 [order] 只会生效最后一个
* @param conditions 条件方法体
* @return [BaseFinder.IndexTypeCondition]
*/
fun param(conditions: ObjectsConditions): IndexTypeCondition {
rulesData.paramTypesConditions = conditions
return IndexTypeCondition(IndexConfigType.MATCH)
}
/**
* 顺序筛选字节码的下标
* @return [BaseFinder.IndexTypeCondition]
*/
fun order() = IndexTypeCondition(IndexConfigType.ORDER)
/**
* 设置 [Constructor] 参数个数
*
* 你可以不使用 [param] 指定参数类型而是仅使用此方法指定参数个数
*
* 若参数个数小于零则忽略并使用 [param]
*
* - ❗存在多个 [BaseFinder.IndexTypeCondition] 时除了 [order] 只会生效最后一个
* @param num 个数
* @return [BaseFinder.IndexTypeCondition]
*/
fun paramCount(num: Int): IndexTypeCondition {
rulesData.paramCount = num
return IndexTypeCondition(IndexConfigType.MATCH)
}
/**
* 设置 [Constructor] 参数个数范围
*
* 你可以不使用 [param] 指定参数类型而是仅使用此方法指定参数个数范围
*
* 使用示例如下 ↓
*
* ```kotlin
* paramCount(1..5)
* ```
*
* - ❗存在多个 [BaseFinder.IndexTypeCondition] 时除了 [order] 只会生效最后一个
* @param numRange 个数范围
* @return [BaseFinder.IndexTypeCondition]
*/
fun paramCount(numRange: IntRange): IndexTypeCondition {
rulesData.paramCountRange = numRange
return IndexTypeCondition(IndexConfigType.MATCH)
}
/**
* 设置 [Constructor] 参数个数条件
*
* 你可以不使用 [param] 指定参数类型而是仅使用此方法指定参数个数条件
*
* 使用示例如下 ↓
*
* ```kotlin
* paramCount { it >= 5 || it.isZero() }
* ```
*
* - ❗存在多个 [BaseFinder.IndexTypeCondition] 时除了 [order] 只会生效最后一个
* @param conditions 条件方法体
* @return [BaseFinder.IndexTypeCondition]
*/
fun paramCount(conditions: CountConditions): IndexTypeCondition {
rulesData.paramCountConditions = conditions
return IndexTypeCondition(IndexConfigType.MATCH)
}
/**
* 设置在 [classSet] 的所有父类中查找当前 [Constructor]
*
* - ❗若当前 [classSet] 的父类较多可能会耗时 - API 会自动循环到父类继承是 [Any] 前的最后一个类
* @param isOnlySuperClass 是否仅在当前 [classSet] 的父类中查找 - 若父类是 [Any] 则不会生效
*/
fun superClass(isOnlySuperClass: Boolean = false) {
rulesData.isFindInSuper = true
if (isOnlySuperClass && classSet?.hasExtends == true) usedClassSet = classSet.superclass
}
/**
* 得到 [Constructor] 或一组 [Constructor]
* @return [HashSet]<[Constructor]>
* @throws NoSuchMethodError 如果找不到 [Constructor]
*/
private val result by lazy { ReflectionTool.findConstructors(usedClassSet, rulesData) }
/**
* 设置实例
* @param constructors 当前找到的 [Constructor] 数组
*/
private fun setInstance(constructors: HashSet<Constructor<*>>) {
memberInstances.clear()
constructors.takeIf { it.isNotEmpty() }?.forEach { memberInstances.add(it) }
}
/** 得到 [Constructor] 结果 */
private fun internalBuild() {
if (classSet == null) error(CLASSSET_IS_NULL)
runBlocking {
setInstance(result)
}.result { ms ->
memberInstances.takeIf { it.isNotEmpty() }?.forEach { onDebuggingMsg(msg = "Find Constructor [$it] takes ${ms}ms") }
}
}
@YukiPrivateApi
override fun build() = runCatching {
internalBuild()
Result()
}.getOrElse {
onFailureMsg(throwable = it)
Result(isNoSuch = true, it)
}
@YukiPrivateApi
override fun failure(throwable: Throwable?) = Result(isNoSuch = true, throwable)
/**
* [Constructor] 重查找实现类
*
* 可累计失败次数直到查找成功
*/
inner class RemedyPlan @PublishedApi internal constructor() {
/** 失败尝试次数数组 */
@PublishedApi
internal val remedyPlans = HashSet<Pair<ConstructorFinder, Result>>()
/**
* 创建需要重新查找的 [Constructor]
*
* 你可以添加多个备选 [Constructor] - 直到成功为止
*
* 若最后依然失败 - 将停止查找并输出错误日志
* @param initiate 方法体
*/
inline fun constructor(initiate: ConstructorConditions) =
Result().apply { remedyPlans.add(Pair(ConstructorFinder(classSet).apply(initiate), this)) }
/** 开始重查找 */
@PublishedApi
internal fun build() {
if (classSet == null) return
if (remedyPlans.isNotEmpty()) run {
var isFindSuccess = false
var lastError: Throwable? = null
remedyPlans.forEachIndexed { p, it ->
runCatching {
runBlocking {
setInstance(it.first.result)
}.result { ms ->
memberInstances.takeIf { it.isNotEmpty() }?.forEach { onDebuggingMsg(msg = "Find Constructor [$it] takes ${ms}ms") }
}
isFindSuccess = true
it.second.onFindCallback?.invoke(memberInstances.constructors())
remedyPlansCallback?.invoke()
memberInstances.takeIf { it.isNotEmpty() }
?.forEach { onDebuggingMsg(msg = "Constructor [$it] trying ${p + 1} times success by RemedyPlan") }
return@run
}.onFailure {
lastError = it
onFailureMsg(msg = "Trying ${p + 1} times by RemedyPlan --> $it", isAlwaysPrint = true)
}
}
if (isFindSuccess.not()) {
onFailureMsg(
msg = "Trying ${remedyPlans.size} times and all failure by RemedyPlan",
throwable = lastError,
isAlwaysPrint = true
)
remedyPlans.clear()
}
} else yLoggerW(msg = "RemedyPlan is empty, forgot it?")
}
/**
* [RemedyPlan] 结果实现类
*
* 可在这里处理是否成功的回调
*/
inner class Result @PublishedApi internal constructor() {
/** 找到结果时的回调 */
internal var onFindCallback: (HashSet<Constructor<*>>.() -> Unit)? = null
/**
* 当找到结果时
* @param initiate 回调
*/
fun onFind(initiate: HashSet<Constructor<*>>.() -> Unit) {
onFindCallback = initiate
}
}
}
/**
* [Constructor] 查找结果实现类
* @param isNoSuch 是否没有找到 [Constructor] - 默认否
* @param throwable 错误信息
*/
inner class Result internal constructor(
@PublishedApi internal val isNoSuch: Boolean = false,
@PublishedApi internal val throwable: Throwable? = null
) : BaseResult {
/**
* 创建监听结果事件方法体
* @param initiate 方法体
* @return [Result] 可继续向下监听
*/
inline fun result(initiate: Result.() -> Unit) = apply(initiate)
/**
* 获得 [Constructor] 实例处理类
*
* - 若有多个 [Constructor] 结果只会返回第一个
*
* - ❗在 [memberInstances] 结果为空时使用此方法将无法获得对象
*
* - ❗若你设置了 [remedys] 请使用 [wait] 回调结果方法
* @return [Instance]
*/
fun get() = Instance(give())
/**
* 获得 [Constructor] 实例处理类数组
*
* - 返回全部查找条件匹配的多个 [Constructor] 实例结果
*
* - ❗在 [memberInstances] 结果为空时使用此方法将无法获得对象
*
* - ❗若你设置了 [remedys] 请使用 [waitAll] 回调结果方法
* @return [ArrayList]<[Instance]>
*/
fun all() = arrayListOf<Instance>().apply { giveAll().takeIf { it.isNotEmpty() }?.forEach { add(Instance(it)) } }
/**
* 得到 [Constructor] 本身
*
* - 若有多个 [Constructor] 结果只会返回第一个
*
* - 在查找条件找不到任何结果的时候将返回 null
* @return [Constructor] or null
*/
fun give() = giveAll().takeIf { it.isNotEmpty() }?.first()
/**
* 得到 [Constructor] 本身数组
*
* - 返回全部查找条件匹配的多个 [Constructor] 实例
*
* - 在查找条件找不到任何结果的时候将返回空的 [HashSet]
* @return [HashSet]<[Constructor]>
*/
fun giveAll() = memberInstances.takeIf { it.isNotEmpty() }?.constructors() ?: HashSet()
/**
* 获得 [Constructor] 实例处理类
*
* - 若有多个 [Constructor] 结果只会返回第一个
*
* - ❗若你设置了 [remedys] 必须使用此方法才能获得结果
*
* - ❗若你没有设置 [remedys] 此方法将不会被回调
* @param initiate 回调 [Instance]
*/
fun wait(initiate: Instance.() -> Unit) {
if (memberInstances.isNotEmpty()) initiate(get())
else remedyPlansCallback = { initiate(get()) }
}
/**
* 获得 [Constructor] 实例处理类数组
*
* - 返回全部查找条件匹配的多个 [Constructor] 实例结果
*
* - ❗若你设置了 [remedys] 必须使用此方法才能获得结果
*
* - ❗若你没有设置 [remedys] 此方法将不会被回调
* @param initiate 回调 [ArrayList]<[Instance]>
*/
fun waitAll(initiate: ArrayList<Instance>.() -> Unit) {
if (memberInstances.isNotEmpty()) initiate(all())
else remedyPlansCallback = { initiate(all()) }
}
/**
* 创建 [Constructor] 重查找功能
*
* 当你遇到一种 [Constructor] 可能存在不同形式的存在时
*
* 可以使用 [RemedyPlan] 重新查找它 - 而没有必要使用 [onNoSuchConstructor] 捕获异常二次查找 [Constructor]
* @param initiate 方法体
* @return [Result] 可继续向下监听
*/
inline fun remedys(initiate: RemedyPlan.() -> Unit): Result {
isUsingRemedyPlan = true
if (isNoSuch) RemedyPlan().apply(initiate).build()
return this
}
/**
* 监听找不到 [Constructor] 时
*
* - 只会返回第一次的错误信息 - 不会返回 [RemedyPlan] 的错误信息
* @param result 回调错误
* @return [Result] 可继续向下监听
*/
inline fun onNoSuchConstructor(result: (Throwable) -> Unit): Result {
if (isNoSuch) result(throwable ?: Throwable("Initialization Error"))
return this
}
/**
* 忽略异常并停止打印任何错误日志
*
* - ❗此时若要监听异常结果 - 你需要手动实现 [onNoSuchConstructor] 方法
* @return [Result] 可继续向下监听
*/
fun ignored(): Result {
isShutErrorPrinting = true
return this
}
/**
* [Constructor] 实例处理类
*
* 调用与创建目标实例类对象
*
* - ❗请使用 [get]、[wait]、[all]、[waitAll] 方法来获取 [Instance]
* @param constructor 当前 [Constructor] 实例对象
*/
inner class Instance internal constructor(private val constructor: Constructor<*>?) {
/**
* 执行 [Constructor] 创建目标实例
* @param args [Constructor] 参数
* @return [Any] or null
*/
private fun baseCall(vararg args: Any?) = constructor?.newInstance(*args)
/**
* 执行 [Constructor] 创建目标实例 - 不指定目标实例类型
* @param args [Constructor] 参数
* @return [Any] or null
*/
fun call(vararg args: Any?) = baseCall(*args)
/**
* 执行 [Constructor] 创建目标实例 - 指定 [T] 目标实例类型
* @param args [Constructor] 参数
* @return [T] or null
*/
fun <T> newInstance(vararg args: Any?) = baseCall(*args) as? T?
override fun toString() = "[${constructor?.name ?: "<empty>"}]"
}
}
}

View File

@@ -0,0 +1,605 @@
/*
* YukiReflection - An efficient Reflection API for Java and Android built in Kotlin
* Copyright (C) 2019-2023 HighCapable
* https://github.com/fankes/YukiReflection
*
* 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/2/4.
* This file is Modified by fankes on 2023/1/21.
*/
@file:Suppress("unused", "UNCHECKED_CAST", "MemberVisibilityCanBePrivate", "KotlinConstantConditions")
package com.highcapable.yukireflection.finder.members
import com.highcapable.yukireflection.annotation.YukiPrivateApi
import com.highcapable.yukireflection.bean.CurrentClass
import com.highcapable.yukireflection.bean.VariousClass
import com.highcapable.yukireflection.factory.current
import com.highcapable.yukireflection.factory.hasExtends
import com.highcapable.yukireflection.finder.base.BaseFinder
import com.highcapable.yukireflection.finder.base.MemberBaseFinder
import com.highcapable.yukireflection.finder.members.data.FieldRulesData
import com.highcapable.yukireflection.finder.tools.ReflectionTool
import com.highcapable.yukireflection.finder.type.factory.FieldConditions
import com.highcapable.yukireflection.finder.type.factory.ModifierConditions
import com.highcapable.yukireflection.finder.type.factory.NameConditions
import com.highcapable.yukireflection.finder.type.factory.ObjectConditions
import com.highcapable.yukireflection.log.yLoggerW
import com.highcapable.yukireflection.utils.runBlocking
import java.lang.reflect.Field
/**
* [Field] 查找类
*
* 可通过指定类型查找指定 [Field] 或一组 [Field]
* @param classSet 当前需要查找的 [Class] 实例
*/
class FieldFinder @PublishedApi internal constructor(@PublishedApi override val classSet: Class<*>? = null) :
MemberBaseFinder(tag = "Field", classSet) {
@PublishedApi
override var rulesData = FieldRulesData()
/** 当前使用的 [classSet] */
private var usedClassSet = classSet
/** 当前重查找结果回调 */
private var remedyPlansCallback: (() -> Unit)? = null
/**
* 设置 [Field] 名称
*
* - ❗若不填写名称则必须存在一个其它条件
* @return [String]
*/
var name
get() = rulesData.name
set(value) {
rulesData.name = value
}
/**
* 设置 [Field] 类型
*
* - ❗只能是 [Class]、[String]、[VariousClass]
*
* - 可不填写类型
* @return [Any] or null
*/
var type
get() = rulesData.type
set(value) {
rulesData.type = value.compat()
}
/**
* 设置 [Field] 标识符筛选条件
*
* - 可不设置筛选条件
*
* - ❗存在多个 [BaseFinder.IndexTypeCondition] 时除了 [order] 只会生效最后一个
* @param conditions 条件方法体
* @return [BaseFinder.IndexTypeCondition]
*/
fun modifiers(conditions: ModifierConditions): IndexTypeCondition {
rulesData.modifiers = conditions
return IndexTypeCondition(IndexConfigType.MATCH)
}
/**
* 顺序筛选字节码的下标
* @return [BaseFinder.IndexTypeCondition]
*/
fun order() = IndexTypeCondition(IndexConfigType.ORDER)
/**
* 设置 [Field] 名称
*
* - ❗若不填写名称则必须存在一个其它条件
*
* - ❗存在多个 [BaseFinder.IndexTypeCondition] 时除了 [order] 只会生效最后一个
* @param value 名称
* @return [BaseFinder.IndexTypeCondition]
*/
fun name(value: String): IndexTypeCondition {
rulesData.name = value
return IndexTypeCondition(IndexConfigType.MATCH)
}
/**
* 设置 [Field] 名称条件
*
* - ❗若不填写名称则必须存在一个其它条件
*
* - ❗存在多个 [BaseFinder.IndexTypeCondition] 时除了 [order] 只会生效最后一个
* @param conditions 条件方法体
* @return [BaseFinder.IndexTypeCondition]
*/
fun name(conditions: NameConditions): IndexTypeCondition {
rulesData.nameConditions = conditions
return IndexTypeCondition(IndexConfigType.MATCH)
}
/**
* 设置 [Field] 类型
*
* - 可不填写类型
*
* - ❗存在多个 [BaseFinder.IndexTypeCondition] 时除了 [order] 只会生效最后一个
* @param value 类型 - ❗只能是 [Class]、[String]、[VariousClass]
* @return [BaseFinder.IndexTypeCondition]
*/
fun type(value: Any): IndexTypeCondition {
rulesData.type = value.compat()
return IndexTypeCondition(IndexConfigType.MATCH)
}
/**
* 设置 [Field] 类型条件
*
* - 可不填写类型
*
* 使用示例如下 ↓
*
* ```kotlin
* type { it == StringClass || it.name == "java.lang.String" }
* ```
*
* - ❗存在多个 [BaseFinder.IndexTypeCondition] 时除了 [order] 只会生效最后一个
* @param conditions 条件方法体
* @return [BaseFinder.IndexTypeCondition]
*/
fun type(conditions: ObjectConditions): IndexTypeCondition {
rulesData.typeConditions = conditions
return IndexTypeCondition(IndexConfigType.MATCH)
}
/**
* 设置在 [classSet] 的所有父类中查找当前 [Field]
*
* - ❗若当前 [classSet] 的父类较多可能会耗时 - API 会自动循环到父类继承是 [Any] 前的最后一个类
* @param isOnlySuperClass 是否仅在当前 [classSet] 的父类中查找 - 若父类是 [Any] 则不会生效
*/
fun superClass(isOnlySuperClass: Boolean = false) {
rulesData.isFindInSuper = true
if (isOnlySuperClass && classSet?.hasExtends == true) usedClassSet = classSet.superclass
}
/**
* 得到 [Field] 或一组 [Field]
* @return [HashSet]<[Field]>
* @throws NoSuchFieldError 如果找不到 [Field]
*/
private val result get() = ReflectionTool.findFields(usedClassSet, rulesData)
/**
* 设置实例
* @param fields 当前找到的 [Field] 数组
*/
private fun setInstance(fields: HashSet<Field>) {
memberInstances.clear()
fields.takeIf { it.isNotEmpty() }?.forEach { memberInstances.add(it) }
}
/** 得到 [Field] 结果 */
private fun internalBuild() {
if (classSet == null) error(CLASSSET_IS_NULL)
runBlocking {
setInstance(result)
}.result { ms ->
memberInstances.takeIf { it.isNotEmpty() }?.forEach { onDebuggingMsg(msg = "Find Field [$it] takes ${ms}ms") }
}
}
@YukiPrivateApi
override fun build() = runCatching {
internalBuild()
Result()
}.getOrElse {
onFailureMsg(throwable = it)
Result(isNoSuch = true, it)
}
@YukiPrivateApi
override fun failure(throwable: Throwable?) = Result(isNoSuch = true, throwable)
/**
* [Field] 重查找实现类
*
* 可累计失败次数直到查找成功
*/
inner class RemedyPlan @PublishedApi internal constructor() {
/** 失败尝试次数数组 */
@PublishedApi
internal val remedyPlans = HashSet<Pair<FieldFinder, Result>>()
/**
* 创建需要重新查找的 [Field]
*
* 你可以添加多个备选 [Field] - 直到成功为止
*
* 若最后依然失败 - 将停止查找并输出错误日志
* @param initiate 方法体
* @return [Result] 结果
*/
inline fun field(initiate: FieldConditions) = Result().apply { remedyPlans.add(Pair(FieldFinder(classSet).apply(initiate), this)) }
/** 开始重查找 */
@PublishedApi
internal fun build() {
if (classSet == null) return
if (remedyPlans.isNotEmpty()) run {
var isFindSuccess = false
var lastError: Throwable? = null
remedyPlans.forEachIndexed { p, it ->
runCatching {
runBlocking {
setInstance(it.first.result)
}.result { ms ->
memberInstances.takeIf { it.isNotEmpty() }?.forEach { onDebuggingMsg(msg = "Find Field [$it] takes ${ms}ms") }
}
isFindSuccess = true
it.second.onFindCallback?.invoke(memberInstances.fields())
remedyPlansCallback?.invoke()
memberInstances.takeIf { it.isNotEmpty() }
?.forEach { onDebuggingMsg(msg = "Field [$it] trying ${p + 1} times success by RemedyPlan") }
return@run
}.onFailure {
lastError = it
onFailureMsg(msg = "Trying ${p + 1} times by RemedyPlan --> $it", isAlwaysPrint = true)
}
}
if (isFindSuccess.not()) {
onFailureMsg(
msg = "Trying ${remedyPlans.size} times and all failure by RemedyPlan",
throwable = lastError,
isAlwaysPrint = true
)
remedyPlans.clear()
}
} else yLoggerW(msg = "RemedyPlan is empty, forgot it?")
}
/**
* [RemedyPlan] 结果实现类
*
* 可在这里处理是否成功的回调
*/
inner class Result @PublishedApi internal constructor() {
/** 找到结果时的回调 */
internal var onFindCallback: (HashSet<Field>.() -> Unit)? = null
/**
* 当找到结果时
* @param initiate 回调
*/
fun onFind(initiate: HashSet<Field>.() -> Unit) {
onFindCallback = initiate
}
}
}
/**
* [Field] 查找结果实现类
*
* @param isNoSuch 是否没有找到 [Field] - 默认否
* @param throwable 错误信息
*/
inner class Result internal constructor(
@PublishedApi internal val isNoSuch: Boolean = false,
private val throwable: Throwable? = null
) : BaseResult {
/**
* 创建监听结果事件方法体
* @param initiate 方法体
* @return [Result] 可继续向下监听
*/
inline fun result(initiate: Result.() -> Unit) = apply(initiate)
/**
* 获得 [Field] 实例处理类
*
* - 若有多个 [Field] 结果只会返回第一个
*
* - ❗在 [memberInstances] 结果为空时使用此方法将无法获得对象
*
* - ❗如果目标对象不是静态 - 你必须设置 [instance]
*
* - ❗若你设置了 [remedys] 请使用 [wait] 回调结果方法
* @param instance [Field] 所在的实例对象 - 如果是静态可不填 - 默认 null
* @return [Instance]
*/
fun get(instance: Any? = null) = Instance(instance, give())
/**
* 获得 [Field] 实例处理类数组
*
* - 返回全部查找条件匹配的多个 [Field] 实例结果
*
* - ❗在 [memberInstances] 结果为空时使用此方法将无法获得对象
*
* - ❗如果目标对象不是静态 - 你必须设置 [instance]
*
* - ❗若你设置了 [remedys] 请使用 [waitAll] 回调结果方法
* @param instance [Field] 所在的实例对象 - 如果是静态可不填 - 默认 null
* @return [ArrayList]<[Instance]>
*/
fun all(instance: Any? = null) =
arrayListOf<Instance>().apply { giveAll().takeIf { it.isNotEmpty() }?.forEach { add(Instance(instance, it)) } }
/**
* 得到 [Field] 本身
*
* - 若有多个 [Field] 结果只会返回第一个
*
* - 在查找条件找不到任何结果的时候将返回 null
* @return [Field] or null
*/
fun give() = giveAll().takeIf { it.isNotEmpty() }?.first()
/**
* 得到 [Field] 本身数组
*
* - 返回全部查找条件匹配的多个 [Field] 实例
*
* - 在查找条件找不到任何结果的时候将返回空的 [HashSet]
* @return [HashSet]<[Field]>
*/
fun giveAll() = memberInstances.takeIf { it.isNotEmpty() }?.fields() ?: HashSet()
/**
* 获得 [Field] 实例处理类
*
* - 若有多个 [Field] 结果只会返回第一个
*
* - ❗若你设置了 [remedys] 必须使用此方法才能获得结果
*
* - ❗若你没有设置 [remedys] 此方法将不会被回调
* @param instance 所在实例
* @param initiate 回调 [Instance]
*/
fun wait(instance: Any? = null, initiate: Instance.() -> Unit) {
if (memberInstances.isNotEmpty()) initiate(get(instance))
else remedyPlansCallback = { initiate(get(instance)) }
}
/**
* 获得 [Field] 实例处理类数组
*
* - 返回全部查找条件匹配的多个 [Field] 实例结果
*
* - ❗若你设置了 [remedys] 必须使用此方法才能获得结果
*
* - ❗若你没有设置 [remedys] 此方法将不会被回调
* @param instance 所在实例
* @param initiate 回调 [ArrayList]<[Instance]>
*/
fun waitAll(instance: Any? = null, initiate: ArrayList<Instance>.() -> Unit) {
if (memberInstances.isNotEmpty()) initiate(all(instance))
else remedyPlansCallback = { initiate(all(instance)) }
}
/**
* 创建 [Field] 重查找功能
*
* 当你遇到一种方法可能存在不同形式的存在时
*
* 可以使用 [RemedyPlan] 重新查找它 - 而没有必要使用 [onNoSuchField] 捕获异常二次查找 [Field]
*
* 若第一次查找失败了 - 你还可以在这里继续添加此方法体直到成功为止
* @param initiate 方法体
* @return [Result] 可继续向下监听
*/
inline fun remedys(initiate: RemedyPlan.() -> Unit): Result {
isUsingRemedyPlan = true
if (isNoSuch) RemedyPlan().apply(initiate).build()
return this
}
/**
* 监听找不到 [Field] 时
*
* - 只会返回第一次的错误信息 - 不会返回 [RemedyPlan] 的错误信息
* @param result 回调错误
* @return [Result] 可继续向下监听
*/
fun onNoSuchField(result: (Throwable) -> Unit): Result {
if (isNoSuch) result(throwable ?: Throwable("Initialization Error"))
return this
}
/**
* 忽略异常并停止打印任何错误日志
*
* - ❗此时若要监听异常结果 - 你需要手动实现 [onNoSuchField] 方法
* @return [Result] 可继续向下监听
*/
fun ignored(): Result {
isShutErrorPrinting = true
return this
}
/**
* [Field] 实例处理类
*
* - ❗请使用 [get]、[all] 方法来获取 [Instance]
* @param instance 当前 [Field] 所在类的实例对象
* @param field 当前 [Field] 实例对象
*/
inner class Instance internal constructor(private val instance: Any?, private val field: Field?) {
/**
* 获取当前 [Field] 自身的实例化对象
*
* - 若要直接获取不确定的实例对象 - 请调用 [any] 方法
* @return [Any] or null
*/
@PublishedApi
internal val self
get() = field?.get(instance)
/**
* 获得当前 [Field] 自身 [self] 实例的类操作对象
* @param ignored 是否开启忽略错误警告功能 - 默认否
* @return [CurrentClass] or null
*/
fun current(ignored: Boolean = false) = self?.current(ignored)
/**
* 获得当前 [Field] 自身 [self] 实例的类操作对象
* @param ignored 是否开启忽略错误警告功能 - 默认否
* @param initiate 方法体
* @return [Any] or null
*/
inline fun current(ignored: Boolean = false, initiate: CurrentClass.() -> Unit) = self?.current(ignored, initiate)
/**
* 得到当前 [Field] 实例
* @return [T] or null
*/
fun <T> cast() = self as? T?
/**
* 得到当前 [Field] 的 [Byte] 实例
*
* - ❗请确认目标 [Field] 的类型 - 发生错误会返回 null
* @return [Byte] or null
*/
fun byte() = cast<Byte?>()
/**
* 得到当前 [Field] 的 [Int] 实例
*
* - ❗请确认目标 [Field] 的类型 - 发生错误会返回默认值
* @return [Int] 取不到返回 0
*/
fun int() = cast() ?: 0
/**
* 得到当前 [Field] 的 [Long] 实例
*
* - ❗请确认目标 [Field] 的类型 - 发生错误会返回默认值
* @return [Long] 取不到返回 0L
*/
fun long() = cast() ?: 0L
/**
* 得到当前 [Field] 的 [Short] 实例
*
* - ❗请确认目标 [Field] 的类型 - 发生错误会返回默认值
* @return [Short] 取不到返回 0
*/
fun short() = cast<Short?>() ?: 0
/**
* 得到当前 [Field] 的 [Double] 实例
*
* - ❗请确认目标 [Field] 的类型 - 发生错误会返回默认值
* @return [Double] 取不到返回 0.0
*/
fun double() = cast() ?: 0.0
/**
* 得到当前 [Field] 的 [Float] 实例
*
* - ❗请确认目标 [Field] 的类型 - 发生错误会返回默认值
* @return [Float] 取不到返回 0f
*/
fun float() = cast() ?: 0f
/**
* 得到当前 [Field] 的 [String] 实例
*
* - ❗请确认目标 [Field] 的类型 - 发生错误会返回默认值
* @return [String] 取不到返回 ""
*/
fun string() = cast() ?: ""
/**
* 得到当前 [Field] 的 [Char] 实例
*
* - ❗请确认目标 [Field] 的类型 - 发生错误会返回默认值
* @return [Char] 取不到返回 ' '
*/
fun char() = cast() ?: ' '
/**
* 得到当前 [Field] 的 [Boolean] 实例
*
* - ❗请确认目标 [Field] 的类型 - 发生错误会返回默认值
* @return [Boolean] 取不到返回 false
*/
fun boolean() = cast() ?: false
/**
* 得到当前 [Field] 的 [Any] 实例
* @return [Any] or null
*/
fun any() = self
/**
* 得到当前 [Field] 的 [Array] 实例 - 每项类型 [T]
*
* - ❗请确认目标 [Field] 的类型 - 发生错误会返回空数组
* @return [Array] 取不到返回空数组
*/
inline fun <reified T> array() = cast() ?: arrayOf<T>()
/**
* 得到当前 [Field] 的 [List] 实例 - 每项类型 [T]
*
* - ❗请确认目标 [Field] 的类型 - 发生错误会返回空数组
* @return [List] 取不到返回空数组
*/
inline fun <reified T> list() = cast() ?: listOf<T>()
/**
* 设置当前 [Field] 实例
* @param any 设置的实例内容
*/
fun set(any: Any?) = field?.set(instance, any)
/**
* 设置当前 [Field] 实例为 true
*
* - ❗请确保示例对象类型为 [Boolean]
*/
fun setTrue() = set(true)
/**
* 设置当前 [Field] 实例为 true
*
* - ❗请确保示例对象类型为 [Boolean]
*/
fun setFalse() = set(false)
/** 设置当前 [Field] 实例为 null */
fun setNull() = set(null)
override fun toString() =
"[${self?.javaClass?.name ?: "<empty>"}] in [${instance?.javaClass?.name ?: "<empty>"}] value \"$self\""
}
}
}

View File

@@ -0,0 +1,694 @@
/*
* YukiReflection - An efficient Reflection API for Java and Android built in Kotlin
* Copyright (C) 2019-2023 HighCapable
* https://github.com/fankes/YukiReflection
*
* 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/2/4.
* This file is Modified by fankes on 2023/1/21.
*/
@file:Suppress("unused", "MemberVisibilityCanBePrivate", "UNCHECKED_CAST", "KotlinConstantConditions")
package com.highcapable.yukireflection.finder.members
import com.highcapable.yukireflection.annotation.YukiPrivateApi
import com.highcapable.yukireflection.bean.VariousClass
import com.highcapable.yukireflection.factory.hasExtends
import com.highcapable.yukireflection.finder.base.BaseFinder
import com.highcapable.yukireflection.finder.base.MemberBaseFinder
import com.highcapable.yukireflection.finder.members.data.MethodRulesData
import com.highcapable.yukireflection.finder.tools.ReflectionTool
import com.highcapable.yukireflection.finder.type.factory.*
import com.highcapable.yukireflection.log.yLoggerW
import com.highcapable.yukireflection.type.defined.UndefinedType
import com.highcapable.yukireflection.type.defined.VagueType
import com.highcapable.yukireflection.utils.runBlocking
import java.lang.reflect.Method
/**
* [Method] 查找类
*
* 可通过指定类型查找指定 [Method] 或一组 [Method]
* @param classSet 当前需要查找的 [Class] 实例
*/
class MethodFinder @PublishedApi internal constructor(@PublishedApi override val classSet: Class<*>? = null) :
MemberBaseFinder(tag = "Method", classSet) {
@PublishedApi
override var rulesData = MethodRulesData()
/** 当前使用的 [classSet] */
private var usedClassSet = classSet
/** 当前重查找结果回调 */
private var remedyPlansCallback: (() -> Unit)? = null
/**
* 设置 [Method] 名称
*
* - ❗若不填写名称则必须存在一个其它条件
* @return [String]
*/
var name
get() = rulesData.name
set(value) {
rulesData.name = value
}
/**
* 设置 [Method] 参数个数
*
* 你可以不使用 [param] 指定参数类型而是仅使用此变量指定参数个数
*
* 若参数个数小于零则忽略并使用 [param]
* @return [Int]
*/
var paramCount
get() = rulesData.paramCount
set(value) {
rulesData.paramCount = value
}
/**
* 设置 [Method] 返回值
*
* - ❗只能是 [Class]、[String]、[VariousClass]
*
* - 可不填写返回值
* @return [Any] or null
*/
var returnType
get() = rulesData.returnType
set(value) {
rulesData.returnType = value.compat()
}
/**
* 设置 [Method] 标识符筛选条件
*
* - 可不设置筛选条件
*
* - ❗存在多个 [BaseFinder.IndexTypeCondition] 时除了 [order] 只会生效最后一个
* @param conditions 条件方法体
* @return [BaseFinder.IndexTypeCondition]
*/
fun modifiers(conditions: ModifierConditions): IndexTypeCondition {
rulesData.modifiers = conditions
return IndexTypeCondition(IndexConfigType.MATCH)
}
/**
* 设置 [Method] 空参数、无参数
*
* @return [BaseFinder.IndexTypeCondition]
*/
fun emptyParam() = paramCount(num = 0)
/**
* 设置 [Method] 参数
*
* 如果同时使用了 [paramCount] 则 [paramType] 的数量必须与 [paramCount] 完全匹配
*
* 如果 [Method] 中存在一些无意义又很长的类型 - 你可以使用 [VagueType] 来替代它
*
* 例如下面这个参数结构 ↓
*
* ```java
* void foo(String var1, boolean var2, com.demo.Test var3, int var4)
* ```
*
* 此时就可以简单地写作 ↓
*
* ```kotlin
* param(StringType, BooleanType, VagueType, IntType)
* ```
*
* - ❗无参 [Method] 请使用 [emptyParam] 设置查找条件
*
* - ❗有参 [Method] 必须使用此方法设定参数或使用 [paramCount] 指定个数
*
* - ❗存在多个 [BaseFinder.IndexTypeCondition] 时除了 [order] 只会生效最后一个
* @param paramType 参数类型数组 - ❗只能是 [Class]、[String]、[VariousClass]
* @return [BaseFinder.IndexTypeCondition]
*/
fun param(vararg paramType: Any): IndexTypeCondition {
if (paramType.isEmpty()) error("paramTypes is empty, please use emptyParam() instead")
rulesData.paramTypes = arrayListOf<Class<*>>().apply { paramType.forEach { add(it.compat() ?: UndefinedType) } }.toTypedArray()
return IndexTypeCondition(IndexConfigType.MATCH)
}
/**
* 设置 [Method] 参数条件
*
* 使用示例如下 ↓
*
* ```kotlin
* param { it[1] == StringClass || it[2].name == "java.lang.String" }
* ```
*
* - ❗无参 [Method] 请使用 [emptyParam] 设置查找条件
*
* - ❗有参 [Method] 必须使用此方法设定参数或使用 [paramCount] 指定个数
*
* - ❗存在多个 [BaseFinder.IndexTypeCondition] 时除了 [order] 只会生效最后一个
* @param conditions 条件方法体
* @return [BaseFinder.IndexTypeCondition]
*/
fun param(conditions: ObjectsConditions): IndexTypeCondition {
rulesData.paramTypesConditions = conditions
return IndexTypeCondition(IndexConfigType.MATCH)
}
/**
* 顺序筛选字节码的下标
* @return [BaseFinder.IndexTypeCondition]
*/
fun order() = IndexTypeCondition(IndexConfigType.ORDER)
/**
* 设置 [Method] 名称
*
* - ❗若不填写名称则必须存在一个其它条件
*
* - ❗存在多个 [BaseFinder.IndexTypeCondition] 时除了 [order] 只会生效最后一个
* @param value 名称
* @return [BaseFinder.IndexTypeCondition]
*/
fun name(value: String): IndexTypeCondition {
rulesData.name = value
return IndexTypeCondition(IndexConfigType.MATCH)
}
/**
* 设置 [Method] 名称条件
*
* - ❗若不填写名称则必须存在一个其它条件
*
* - ❗存在多个 [BaseFinder.IndexTypeCondition] 时除了 [order] 只会生效最后一个
* @param conditions 条件方法体
* @return [BaseFinder.IndexTypeCondition]
*/
fun name(conditions: NameConditions): IndexTypeCondition {
rulesData.nameConditions = conditions
return IndexTypeCondition(IndexConfigType.MATCH)
}
/**
* 设置 [Method] 参数个数
*
* 你可以不使用 [param] 指定参数类型而是仅使用此方法指定参数个数
*
* 若参数个数小于零则忽略并使用 [param]
*
* - ❗存在多个 [BaseFinder.IndexTypeCondition] 时除了 [order] 只会生效最后一个
* @param num 个数
* @return [BaseFinder.IndexTypeCondition]
*/
fun paramCount(num: Int): IndexTypeCondition {
rulesData.paramCount = num
return IndexTypeCondition(IndexConfigType.MATCH)
}
/**
* 设置 [Method] 参数个数范围
*
* 你可以不使用 [param] 指定参数类型而是仅使用此方法指定参数个数范围
*
* 使用示例如下 ↓
*
* ```kotlin
* paramCount(1..5)
* ```
*
* - ❗存在多个 [BaseFinder.IndexTypeCondition] 时除了 [order] 只会生效最后一个
* @param numRange 个数范围
* @return [BaseFinder.IndexTypeCondition]
*/
fun paramCount(numRange: IntRange): IndexTypeCondition {
rulesData.paramCountRange = numRange
return IndexTypeCondition(IndexConfigType.MATCH)
}
/**
* 设置 [Method] 参数个数条件
*
* 你可以不使用 [param] 指定参数类型而是仅使用此方法指定参数个数条件
*
* 使用示例如下 ↓
*
* ```kotlin
* paramCount { it >= 5 || it.isZero() }
* ```
*
* - ❗存在多个 [BaseFinder.IndexTypeCondition] 时除了 [order] 只会生效最后一个
* @param conditions 条件方法体
* @return [BaseFinder.IndexTypeCondition]
*/
fun paramCount(conditions: CountConditions): IndexTypeCondition {
rulesData.paramCountConditions = conditions
return IndexTypeCondition(IndexConfigType.MATCH)
}
/**
* 设置 [Method] 返回值
*
* - 可不填写返回值
*
* - ❗存在多个 [BaseFinder.IndexTypeCondition] 时除了 [order] 只会生效最后一个
* @param value 个数
* @return [BaseFinder.IndexTypeCondition]
*/
fun returnType(value: Any): IndexTypeCondition {
rulesData.returnType = value.compat()
return IndexTypeCondition(IndexConfigType.MATCH)
}
/**
* 设置 [Method] 返回值条件
*
* - 可不填写返回值
*
* 使用示例如下 ↓
*
* ```kotlin
* returnType { it == StringClass || it.name == "java.lang.String" }
* ```
*
* - ❗存在多个 [BaseFinder.IndexTypeCondition] 时除了 [order] 只会生效最后一个
* @param conditions 条件方法体
* @return [BaseFinder.IndexTypeCondition]
*/
fun returnType(conditions: ObjectConditions): IndexTypeCondition {
rulesData.returnTypeConditions = conditions
return IndexTypeCondition(IndexConfigType.MATCH)
}
/**
* 设置在 [classSet] 的所有父类中查找当前 [Method]
*
* - ❗若当前 [classSet] 的父类较多可能会耗时 - API 会自动循环到父类继承是 [Any] 前的最后一个类
* @param isOnlySuperClass 是否仅在当前 [classSet] 的父类中查找 - 若父类是 [Any] 则不会生效
*/
fun superClass(isOnlySuperClass: Boolean = false) {
rulesData.isFindInSuper = true
if (isOnlySuperClass && classSet?.hasExtends == true) usedClassSet = classSet.superclass
}
/**
* 得到 [Method] 或一组 [Method]
* @return [HashSet]<[Method]>
* @throws NoSuchMethodError 如果找不到 [Method]
*/
private val result get() = ReflectionTool.findMethods(usedClassSet, rulesData)
/**
* 设置实例
* @param methods 当前找到的 [Method] 数组
*/
private fun setInstance(methods: HashSet<Method>) {
memberInstances.clear()
methods.takeIf { it.isNotEmpty() }?.forEach { memberInstances.add(it) }
}
/** 得到 [Method] 结果 */
private fun internalBuild() {
if (classSet == null) error(CLASSSET_IS_NULL)
runBlocking {
setInstance(result)
}.result { ms ->
memberInstances.takeIf { it.isNotEmpty() }?.forEach { onDebuggingMsg(msg = "Find Method [$it] takes ${ms}ms") }
}
}
@YukiPrivateApi
override fun build() = runCatching {
internalBuild()
Result()
}.getOrElse {
onFailureMsg(throwable = it)
Result(isNoSuch = true, it)
}
@YukiPrivateApi
override fun failure(throwable: Throwable?) = Result(isNoSuch = true, throwable)
/**
* [Method] 重查找实现类
*
* 可累计失败次数直到查找成功
*/
inner class RemedyPlan @PublishedApi internal constructor() {
/** 失败尝试次数数组 */
@PublishedApi
internal val remedyPlans = HashSet<Pair<MethodFinder, Result>>()
/**
* 创建需要重新查找的 [Method]
*
* 你可以添加多个备选 [Method] - 直到成功为止
*
* 若最后依然失败 - 将停止查找并输出错误日志
* @param initiate 方法体
* @return [Result] 结果
*/
inline fun method(initiate: MethodConditions) = Result().apply { remedyPlans.add(Pair(MethodFinder(classSet).apply(initiate), this)) }
/** 开始重查找 */
@PublishedApi
internal fun build() {
if (classSet == null) return
if (remedyPlans.isNotEmpty()) run {
var isFindSuccess = false
var lastError: Throwable? = null
remedyPlans.forEachIndexed { p, it ->
runCatching {
runBlocking {
setInstance(it.first.result)
}.result { ms ->
memberInstances.takeIf { it.isNotEmpty() }?.forEach { onDebuggingMsg(msg = "Find Method [$it] takes ${ms}ms") }
}
isFindSuccess = true
it.second.onFindCallback?.invoke(memberInstances.methods())
remedyPlansCallback?.invoke()
memberInstances.takeIf { it.isNotEmpty() }
?.forEach { onDebuggingMsg(msg = "Method [$it] trying ${p + 1} times success by RemedyPlan") }
return@run
}.onFailure {
lastError = it
onFailureMsg(msg = "Trying ${p + 1} times by RemedyPlan --> $it", isAlwaysPrint = true)
}
}
if (isFindSuccess.not()) {
onFailureMsg(
msg = "Trying ${remedyPlans.size} times and all failure by RemedyPlan",
throwable = lastError,
isAlwaysPrint = true
)
remedyPlans.clear()
}
} else yLoggerW(msg = "RemedyPlan is empty, forgot it?")
}
/**
* [RemedyPlan] 结果实现类
*
* 可在这里处理是否成功的回调
*/
inner class Result @PublishedApi internal constructor() {
/** 找到结果时的回调 */
internal var onFindCallback: (HashSet<Method>.() -> Unit)? = null
/**
* 当找到结果时
* @param initiate 回调
*/
fun onFind(initiate: HashSet<Method>.() -> Unit) {
onFindCallback = initiate
}
}
}
/**
* [Method] 查找结果实现类
* @param isNoSuch 是否没有找到 [Method] - 默认否
* @param throwable 错误信息
*/
inner class Result internal constructor(
@PublishedApi internal val isNoSuch: Boolean = false,
@PublishedApi internal val throwable: Throwable? = null
) : BaseResult {
/**
* 创建监听结果事件方法体
* @param initiate 方法体
* @return [Result] 可继续向下监听
*/
inline fun result(initiate: Result.() -> Unit) = apply(initiate)
/**
* 获得 [Method] 实例处理类
*
* - 若有多个 [Method] 结果只会返回第一个
*
* - ❗在 [memberInstances] 结果为空时使用此方法将无法获得对象
*
* - ❗若你设置了 [remedys] 请使用 [wait] 回调结果方法
* @param instance 所在实例
* @return [Instance]
*/
fun get(instance: Any? = null) = Instance(instance, give())
/**
* 获得 [Method] 实例处理类数组
*
* - 返回全部查找条件匹配的多个 [Method] 实例结果
*
* - ❗在 [memberInstances] 结果为空时使用此方法将无法获得对象
*
* - ❗若你设置了 [remedys] 请使用 [waitAll] 回调结果方法
* @param instance 所在实例
* @return [ArrayList]<[Instance]>
*/
fun all(instance: Any? = null) =
arrayListOf<Instance>().apply { giveAll().takeIf { it.isNotEmpty() }?.forEach { add(Instance(instance, it)) } }
/**
* 得到 [Method] 本身
*
* - 若有多个 [Method] 结果只会返回第一个
*
* - 在查找条件找不到任何结果的时候将返回 null
* @return [Method] or null
*/
fun give() = giveAll().takeIf { it.isNotEmpty() }?.first()
/**
* 得到 [Method] 本身数组
*
* - 返回全部查找条件匹配的多个 [Method] 实例
*
* - 在查找条件找不到任何结果的时候将返回空的 [HashSet]
* @return [HashSet]<[Method]>
*/
fun giveAll() = memberInstances.takeIf { it.isNotEmpty() }?.methods() ?: HashSet()
/**
* 获得 [Method] 实例处理类
*
* - 若有多个 [Method] 结果只会返回第一个
*
* - ❗若你设置了 [remedys] 必须使用此方法才能获得结果
*
* - ❗若你没有设置 [remedys] 此方法将不会被回调
* @param instance 所在实例
* @param initiate 回调 [Instance]
*/
fun wait(instance: Any? = null, initiate: Instance.() -> Unit) {
if (memberInstances.isNotEmpty()) initiate(get(instance))
else remedyPlansCallback = { initiate(get(instance)) }
}
/**
* 获得 [Method] 实例处理类数组
*
* - 返回全部查找条件匹配的多个 [Method] 实例结果
*
* - ❗若你设置了 [remedys] 必须使用此方法才能获得结果
*
* - ❗若你没有设置 [remedys] 此方法将不会被回调
* @param instance 所在实例
* @param initiate 回调 [ArrayList]<[Instance]>
*/
fun waitAll(instance: Any? = null, initiate: ArrayList<Instance>.() -> Unit) {
if (memberInstances.isNotEmpty()) initiate(all(instance))
else remedyPlansCallback = { initiate(all(instance)) }
}
/**
* 创建 [Method] 重查找功能
*
* 当你遇到一种 [Method] 可能存在不同形式的存在时
*
* 可以使用 [RemedyPlan] 重新查找它 - 而没有必要使用 [onNoSuchMethod] 捕获异常二次查找 [Method]
*
* 若第一次查找失败了 - 你还可以在这里继续添加此方法体直到成功为止
* @param initiate 方法体
* @return [Result] 可继续向下监听
*/
inline fun remedys(initiate: RemedyPlan.() -> Unit): Result {
isUsingRemedyPlan = true
if (isNoSuch) RemedyPlan().apply(initiate).build()
return this
}
/**
* 监听找不到 [Method] 时
*
* - 只会返回第一次的错误信息 - 不会返回 [RemedyPlan] 的错误信息
* @param result 回调错误
* @return [Result] 可继续向下监听
*/
inline fun onNoSuchMethod(result: (Throwable) -> Unit): Result {
if (isNoSuch) result(throwable ?: Throwable("Initialization Error"))
return this
}
/**
* 忽略异常并停止打印任何错误日志
*
* - ❗此时若要监听异常结果 - 你需要手动实现 [onNoSuchMethod] 方法
* @return [Result] 可继续向下监听
*/
fun ignored(): Result {
isShutErrorPrinting = true
return this
}
/**
* [Method] 实例处理类
*
* - ❗请使用 [get]、[wait]、[all]、[waitAll] 方法来获取 [Instance]
* @param instance 当前 [Method] 所在类的实例对象
* @param method 当前 [Method] 实例对象
*/
inner class Instance internal constructor(private val instance: Any?, private val method: Method?) {
/**
* 执行 [Method]
* @param args 方法参数
* @return [Any] or null
*/
private fun baseCall(vararg args: Any?) = method?.invoke(instance, *args)
/**
* 执行 [Method] - 不指定返回值类型
* @param args 方法参数
* @return [Any] or null
*/
fun call(vararg args: Any?) = baseCall(*args)
/**
* 执行 [Method] - 指定 [T] 返回值类型
* @param args 方法参数
* @return [T] or null
*/
fun <T> invoke(vararg args: Any?) = baseCall(*args) as? T?
/**
* 执行 [Method] - 指定 [Byte] 返回值类型
*
* - ❗请确认目标变量的类型 - 发生错误会返回 null
* @param args 方法参数
* @return [Byte] or null
*/
fun byte(vararg args: Any?) = invoke<Byte?>(*args)
/**
* 执行 [Method] - 指定 [Int] 返回值类型
*
* - ❗请确认目标 [Method] 的返回值 - 发生错误会返回默认值
* @param args 方法参数
* @return [Int] 取不到返回 0
*/
fun int(vararg args: Any?) = invoke(*args) ?: 0
/**
* 执行 [Method] - 指定 [Long] 返回值类型
*
* - ❗请确认目标 [Method] 的返回值 - 发生错误会返回默认值
* @param args 方法参数
* @return [Long] 取不到返回 0L
*/
fun long(vararg args: Any?) = invoke(*args) ?: 0L
/**
* 执行 [Method] - 指定 [Short] 返回值类型
*
* - ❗请确认目标 [Method] 的返回值 - 发生错误会返回默认值
* @param args 方法参数
* @return [Short] 取不到返回 0
*/
fun short(vararg args: Any?) = invoke<Short?>(*args) ?: 0
/**
* 执行 [Method] - 指定 [Double] 返回值类型
*
* - ❗请确认目标 [Method] 的返回值 - 发生错误会返回默认值
* @param args 方法参数
* @return [Double] 取不到返回 0.0
*/
fun double(vararg args: Any?) = invoke(*args) ?: 0.0
/**
* 执行 [Method] - 指定 [Float] 返回值类型
*
* - ❗请确认目标 [Method] 的返回值 - 发生错误会返回默认值
* @param args 方法参数
* @return [Float] 取不到返回 0f
*/
fun float(vararg args: Any?) = invoke(*args) ?: 0f
/**
* 执行 [Method] - 指定 [String] 返回值类型
* @param args 方法参数
* @return [String] 取不到返回 ""
*/
fun string(vararg args: Any?) = invoke(*args) ?: ""
/**
* 执行 [Method] - 指定 [Char] 返回值类型
* @param args 方法参数
* @return [Char] 取不到返回 ' '
*/
fun char(vararg args: Any?) = invoke(*args) ?: ' '
/**
* 执行 [Method] - 指定 [Boolean] 返回值类型
*
* - ❗请确认目标 [Method] 的返回值 - 发生错误会返回默认值
* @param args 方法参数
* @return [Boolean] 取不到返回 false
*/
fun boolean(vararg args: Any?) = invoke(*args) ?: false
/**
* 执行 [Method] - 指定 [Array] 返回值类型 - 每项类型 [T]
*
* - ❗请确认目标 [Method] 的返回值 - 发生错误会返回空数组
* @return [Array] 取不到返回空数组
*/
inline fun <reified T> array(vararg args: Any?) = invoke(*args) ?: arrayOf<T>()
/**
* 执行 [Method] - 指定 [List] 返回值类型 - 每项类型 [T]
*
* - ❗请确认目标 [Method] 的返回值 - 发生错误会返回空数组
* @return [List] 取不到返回空数组
*/
inline fun <reified T> list(vararg args: Any?) = invoke(*args) ?: listOf<T>()
override fun toString() = "[${method?.name ?: "<empty>"}] in [${instance?.javaClass?.name ?: "<empty>"}]"
}
}
}

View File

@@ -0,0 +1,68 @@
/*
* YukiReflection - An efficient Reflection API for Java and Android built in Kotlin
* Copyright (C) 2019-2023 HighCapable
* https://github.com/fankes/YukiReflection
*
* 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/4.
* This file is Modified by fankes on 2023/1/21.
*/
package com.highcapable.yukireflection.finder.members.data
import com.highcapable.yukireflection.finder.type.factory.CountConditions
import com.highcapable.yukireflection.finder.type.factory.ObjectsConditions
import java.lang.reflect.Constructor
/**
* [Constructor] 规则查找数据类
* @param paramTypes 参数类型数组
* @param paramTypesConditions 参数类型条件
* @param paramCount 参数个数
* @param paramCountRange 参数个数范围
* @param paramCountConditions 参数个数条件
*/
@PublishedApi
internal class ConstructorRulesData internal constructor(
var paramTypes: Array<out Class<*>>? = null,
var paramTypesConditions: ObjectsConditions? = null,
var paramCount: Int = -1,
var paramCountRange: IntRange = IntRange.EMPTY,
var paramCountConditions: CountConditions? = null
) : MemberRulesData() {
override val templates
get() = arrayOf(
paramCount.takeIf { it >= 0 }?.let { "paramCount:[$it]" } ?: "",
paramCountRange.takeIf { it.isEmpty().not() }?.let { "paramCountRange:[$it]" } ?: "",
paramCountConditions?.let { "paramCountConditions:[existed]" } ?: "",
paramTypes?.typeOfString()?.let { "paramTypes:[$it]" } ?: "",
paramTypesConditions?.let { "paramTypesConditions:[existed]" } ?: "", *super.templates
)
override val objectName get() = "Constructor"
override val isInitialize
get() = super.isInitializeOfSuper || paramTypes != null || paramTypesConditions != null || paramCount >= 0 ||
paramCountRange.isEmpty().not() || paramCountConditions != null
override fun toString() = "[$paramTypes][$paramTypesConditions][$paramCount][$paramCountRange]" + super.toString()
}

View File

@@ -0,0 +1,64 @@
/*
* YukiReflection - An efficient Reflection API for Java and Android built in Kotlin
* Copyright (C) 2019-2023 HighCapable
* https://github.com/fankes/YukiReflection
*
* 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/4.
* This file is Modified by fankes on 2023/1/21.
*/
package com.highcapable.yukireflection.finder.members.data
import com.highcapable.yukireflection.finder.type.factory.NameConditions
import com.highcapable.yukireflection.finder.type.factory.ObjectConditions
import java.lang.reflect.Field
/**
* [Field] 规则查找数据类
* @param name 名称
* @param nameConditions 名称规则
* @param type 类型
* @param typeConditions 类型条件
*/
@PublishedApi
internal class FieldRulesData internal constructor(
var name: String = "",
var nameConditions: NameConditions? = null,
var type: Any? = null,
var typeConditions: ObjectConditions? = null
) : MemberRulesData() {
override val templates
get() = arrayOf(
name.takeIf { it.isNotBlank() }?.let { "name:[$it]" } ?: "",
nameConditions?.let { "nameConditions:[existed]" } ?: "",
type?.let { "type:[$it]" } ?: "",
typeConditions?.let { "typeConditions:[existed]" } ?: "", *super.templates
)
override val objectName get() = "Field"
override val isInitialize
get() = super.isInitializeOfSuper || name.isNotBlank() || nameConditions != null || type != null || typeConditions != null
override fun toString() = "[$name][$nameConditions][$type][$typeConditions]" + super.toString()
}

View File

@@ -0,0 +1,75 @@
/*
* YukiReflection - An efficient Reflection API for Java and Android built in Kotlin
* Copyright (C) 2019-2023 HighCapable
* https://github.com/fankes/YukiReflection
*
* 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/4.
* This file is Modified by fankes on 2023/1/21.
*/
package com.highcapable.yukireflection.finder.members.data
import com.highcapable.yukireflection.finder.base.data.BaseRulesData
import com.highcapable.yukireflection.finder.base.rules.ModifierRules
import com.highcapable.yukireflection.finder.type.factory.CountConditions
import java.lang.reflect.Member
/**
* [Member] 规则查找数据类
* @param isFindInSuper 是否在未找到后继续在父类中查找
* @param matchCount 匹配的字节码个数
* @param matchCountRange 匹配的字节码个数范围
* @param matchCountConditions 匹配的字节码个数条件
*/
@PublishedApi
internal open class MemberRulesData internal constructor(
var isFindInSuper: Boolean = false,
var matchCount: Int = -1,
var matchCountRange: IntRange = IntRange.EMPTY,
var matchCountConditions: CountConditions? = null
) : BaseRulesData() {
override val templates
get() = arrayOf(
modifiers?.let { "modifiers:${ModifierRules.templates(uniqueValue)}" } ?: "",
orderIndex?.let { it.takeIf { it.second }?.let { e -> "orderIndex:[${e.first}]" } ?: "orderIndex:[last]" } ?: "",
matchIndex?.let { it.takeIf { it.second }?.let { e -> "matchIndex:[${e.first}]" } ?: "matchIndex:[last]" } ?: ""
)
override val objectName get() = "Member"
/**
* 判断 [matchCount]、[matchCountRange] 规则是否已经初始化 (设置了任意一个参数)
* @return [Boolean]
*/
internal val isInitializeOfMatch get() = matchCount >= 0 || matchCountRange.isEmpty().not() || matchCountConditions != null
/**
* 判断 [BaseRulesData] 规则是否已经初始化 (设置了任意一个参数)
* @return [Boolean]
*/
internal val isInitializeOfSuper get() = super.isInitialize
override val isInitialize get() = isInitializeOfSuper || isInitializeOfMatch
override fun toString() = "[$isFindInSuper][$matchIndex][$matchCountRange][$matchCountConditions]" + super.toString()
}

View File

@@ -0,0 +1,84 @@
/*
* YukiReflection - An efficient Reflection API for Java and Android built in Kotlin
* Copyright (C) 2019-2023 HighCapable
* https://github.com/fankes/YukiReflection
*
* 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/4.
* This file is Modified by fankes on 2023/1/21.
*/
package com.highcapable.yukireflection.finder.members.data
import com.highcapable.yukireflection.finder.type.factory.CountConditions
import com.highcapable.yukireflection.finder.type.factory.NameConditions
import com.highcapable.yukireflection.finder.type.factory.ObjectConditions
import com.highcapable.yukireflection.finder.type.factory.ObjectsConditions
import java.lang.reflect.Method
/**
* [Method] 规则查找数据类
* @param name 名称
* @param nameConditions 名称规则
* @param paramTypes 参数类型数组
* @param paramTypesConditions 参数类型条件
* @param paramCount 参数个数
* @param paramCountRange 参数个数范围
* @param paramCountConditions 参数个数条件
* @param returnType 返回值类型
* @param returnTypeConditions 返回值类型条件
*/
@PublishedApi
internal class MethodRulesData internal constructor(
var name: String = "",
var nameConditions: NameConditions? = null,
var paramTypes: Array<out Class<*>>? = null,
var paramTypesConditions: ObjectsConditions? = null,
var paramCount: Int = -1,
var paramCountRange: IntRange = IntRange.EMPTY,
var paramCountConditions: CountConditions? = null,
var returnType: Any? = null,
var returnTypeConditions: ObjectConditions? = null
) : MemberRulesData() {
override val templates
get() = arrayOf(
name.takeIf { it.isNotBlank() }?.let { "name:[$it]" } ?: "",
nameConditions?.let { "nameConditions:[existed]" } ?: "",
paramCount.takeIf { it >= 0 }?.let { "paramCount:[$it]" } ?: "",
paramCountRange.takeIf { it.isEmpty().not() }?.let { "paramCountRange:[$it]" } ?: "",
paramCountConditions?.let { "paramCountConditions:[existed]" } ?: "",
paramTypes?.typeOfString()?.let { "paramTypes:[$it]" } ?: "",
paramTypesConditions?.let { "paramTypesConditions:[existed]" } ?: "",
returnType?.let { "returnType:[$it]" } ?: "",
returnTypeConditions?.let { "returnTypeConditions:[existed]" } ?: "", *super.templates
)
override val objectName get() = "Method"
override val isInitialize
get() = super.isInitializeOfSuper || name.isNotBlank() || nameConditions != null || paramTypes != null || paramTypesConditions != null ||
paramCount >= 0 || paramCountRange.isEmpty().not() || paramCountConditions != null ||
returnType != null || returnTypeConditions != null
override fun toString() = "[$name][$nameConditions][$paramTypes][$paramTypesConditions][$paramCount]" +
"[$paramCountRange][$returnType][$returnTypeConditions]" + super.toString()
}

View File

@@ -0,0 +1,712 @@
/*
* YukiReflection - An efficient Reflection API for Java and Android built in Kotlin
* Copyright (C) 2019-2023 HighCapable
* https://github.com/fankes/YukiReflection
*
* 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/3/27.
* This file is Modified by fankes on 2023/1/21.
*/
@file:Suppress("KotlinConstantConditions", "KDocUnresolvedReference")
package com.highcapable.yukireflection.finder.tools
import android.util.ArrayMap
import com.highcapable.yukireflection.YukiReflection
import com.highcapable.yukireflection.factory.*
import com.highcapable.yukireflection.finder.base.data.BaseRulesData
import com.highcapable.yukireflection.finder.classes.data.ClassRulesData
import com.highcapable.yukireflection.finder.members.data.ConstructorRulesData
import com.highcapable.yukireflection.finder.members.data.FieldRulesData
import com.highcapable.yukireflection.finder.members.data.MemberRulesData
import com.highcapable.yukireflection.finder.members.data.MethodRulesData
import com.highcapable.yukireflection.log.yLoggerW
import com.highcapable.yukireflection.type.defined.UndefinedType
import com.highcapable.yukireflection.type.defined.VagueType
import com.highcapable.yukireflection.type.java.DalvikBaseDexClassLoader
import com.highcapable.yukireflection.type.java.NoClassDefFoundErrorClass
import com.highcapable.yukireflection.type.java.NoSuchFieldErrorClass
import com.highcapable.yukireflection.type.java.NoSuchMethodErrorClass
import com.highcapable.yukireflection.utils.*
import dalvik.system.BaseDexClassLoader
import java.lang.reflect.Constructor
import java.lang.reflect.Field
import java.lang.reflect.Member
import java.lang.reflect.Method
import java.util.*
import kotlin.math.abs
/**
* 这是一个对 [Class]、[Member] 查找的工具实现类
*/
@PublishedApi
internal object ReflectionTool {
/** 当前工具类的标签 */
private const val TAG = "YukiReflection#ReflectionTool"
/**
* 当前工具类的 [ClassLoader]
* @return [ClassLoader]
*/
private val currentClassLoader get() = classOf<YukiReflection>().classLoader ?: error("Operating system not supported")
/**
* 内存缓存实例实现
*/
private object MemoryCache {
/** 缓存的 [Class] 列表数组 */
val dexClassListData = ArrayMap<String, List<String>>()
/** 缓存的 [Class] 对象数组 */
val classData = ArrayMap<String, Class<*>?>()
}
/**
* 写出当前 [ClassLoader] 下所有 [Class] 名称数组
* @param loader 当前使用的 [ClassLoader]
* @return [List]<[String]>
* @throws IllegalStateException 如果 [loader] 不是 [BaseDexClassLoader]
*/
internal fun findDexClassList(loader: ClassLoader?) = MemoryCache.dexClassListData[loader.toString()]
?: DalvikBaseDexClassLoader.field { name = "pathList" }.ignored().get(loader.value().let {
while (it.value !is BaseDexClassLoader) {
if (it.value?.parent != null) it.value = it.value?.parent
else error("ClassLoader [$loader] is not a DexClassLoader")
}; it.value ?: error("ClassLoader [$loader] load failed")
}).current(ignored = true)?.field { name = "dexElements" }?.array<Any>()?.flatMap { element ->
element.current(ignored = true).field { name = "dexFile" }.current(ignored = true)
?.method { name = "entries" }?.invoke<Enumeration<String>>()?.toList().orEmpty()
}.orEmpty().also { if (it.isNotEmpty()) MemoryCache.dexClassListData[loader.toString()] = it }
/**
* 使用字符串类名查找 [Class] 是否存在
* @param name [Class] 完整名称
* @param loader [Class] 所在的 [ClassLoader]
* @return [Boolean]
*/
internal fun hasClassByName(name: String, loader: ClassLoader?) = runCatching { findClassByName(name, loader); true }.getOrNull() ?: false
/**
* 使用字符串类名获取 [Class]
* @param name [Class] 完整名称
* @param loader [Class] 所在的 [ClassLoader]
* @param initialize 是否初始化 [Class] 的静态方法块 - 默认否
* @return [Class]
* @throws NoClassDefFoundError 如果找不到 [Class] 或设置了错误的 [ClassLoader]
*/
@PublishedApi
internal fun findClassByName(name: String, loader: ClassLoader?, initialize: Boolean = false): Class<*> {
val uniqueCode = "[$name][$loader]"
/**
* 获取 [Class.forName] 的 [Class] 对象
* @param name [Class] 完整名称
* @param initialize 是否初始化 [Class] 的静态方法块
* @param loader [Class] 所在的 [ClassLoader] - 默认为 [currentClassLoader]
* @return [Class]
*/
fun classForName(name: String, initialize: Boolean, loader: ClassLoader? = currentClassLoader) =
Class.forName(name, initialize, loader)
/**
* 使用默认方式和 [ClassLoader] 装载 [Class]
* @return [Class] or null
*/
fun loadWithDefaultClassLoader() = if (initialize.not()) loader?.loadClass(name) else classForName(name, initialize, loader)
return MemoryCache.classData[uniqueCode] ?: runCatching {
(loadWithDefaultClassLoader() ?: classForName(name, initialize)).also { MemoryCache.classData[uniqueCode] = it }
}.getOrNull() ?: throw createException(loader ?: currentClassLoader, name = "Class", "name:[$name]")
}
/**
* 查找任意 [Class] 或一组 [Class]
* @param loaderSet 类所在 [ClassLoader]
* @param rulesData 规则查找数据
* @return [HashSet]<[Class]>
* @throws IllegalStateException 如果 [loaderSet] 为 null 或未设置任何条件
* @throws NoClassDefFoundError 如果找不到 [Class]
*/
internal fun findClasses(loaderSet: ClassLoader?, rulesData: ClassRulesData) = rulesData.createResult {
hashSetOf<Class<*>>().also { classes ->
/**
* 开始查找作业
* @param instance 当前 [Class] 实例
*/
fun startProcess(instance: Class<*>) {
conditions {
fromPackages.takeIf { it.isNotEmpty() }?.also { and(true) }
fullName?.also { it.equals(instance, it.TYPE_NAME).also { e -> if (it.isOptional) opt(e) else and(e) } }
simpleName?.also { it.equals(instance, it.TYPE_SIMPLE_NAME).also { e -> if (it.isOptional) opt(e) else and(e) } }
singleName?.also { it.equals(instance, it.TYPE_SINGLE_NAME).also { e -> if (it.isOptional) opt(e) else and(e) } }
fullNameConditions?.also { instance.name.also { n -> runCatching { and(it(n.cast(), n)) } } }
simpleNameConditions?.also { instance.simpleName.also { n -> runCatching { and(it(n.cast(), n)) } } }
singleNameConditions?.also { classSingleName(instance).also { n -> runCatching { and(it(n.cast(), n)) } } }
modifiers?.also { runCatching { and(it(instance.cast())) } }
extendsClass.takeIf { it.isNotEmpty() }?.also { and(instance.hasExtends && it.contains(instance.superclass.name)) }
implementsClass.takeIf { it.isNotEmpty() }
?.also { and(instance.interfaces.isNotEmpty() && instance.interfaces.any { e -> it.contains(e.name) }) }
enclosingClass.takeIf { it.isNotEmpty() }
?.also { and(instance.enclosingClass != null && it.contains(instance.enclosingClass.name)) }
isAnonymousClass?.also { and(instance.isAnonymousClass && it) }
isNoExtendsClass?.also { and(instance.hasExtends.not() && it) }
isNoImplementsClass?.also { and(instance.interfaces.isEmpty() && it) }
/**
* 匹配 [MemberRulesData]
* @param size [Member] 个数
* @param result 回调是否匹配
*/
fun MemberRulesData.matchCount(size: Int, result: (Boolean) -> Unit) {
takeIf { it.isInitializeOfMatch }?.also { rule ->
rule.conditions {
value.matchCount.takeIf { it >= 0 }?.also { and(it == size) }
value.matchCountRange.takeIf { it.isEmpty().not() }?.also { and(size in it) }
value.matchCountConditions?.also { runCatching { and(it(size.cast(), size)) } }
}.finally { result(true) }.without { result(false) }
} ?: result(true)
}
/**
* 检查类型中的 [Class] 是否存在 - 即不存在 [UndefinedType]
* @param type 类型
* @return [Boolean]
*/
fun MemberRulesData.exists(vararg type: Any?): Boolean {
if (type.isEmpty()) return true
for (i in type.indices) if (type[i] == UndefinedType) {
yLoggerW(msg = "$objectName type[$i] mistake, it will be ignored in current conditions")
return false
}
return true
}
memberRules.takeIf { it.isNotEmpty() }?.forEach { rule ->
instance.existMembers?.apply {
var numberOfFound = 0
if (rule.isInitializeOfSuper) forEach { member ->
rule.conditions {
value.modifiers?.also { runCatching { and(it(member.cast())) } }
}.finally { numberOfFound++ }
}.run { rule.matchCount(numberOfFound) { and(it && numberOfFound > 0) } }
else rule.matchCount(count()) { and(it) }
}
}
fieldRules.takeIf { it.isNotEmpty() }?.forEach { rule ->
instance.existFields?.apply {
var numberOfFound = 0
if (rule.isInitialize) forEach { field ->
rule.conditions {
value.type?.takeIf { value.exists(it) }?.also { and(it == field.type) }
value.name.takeIf { it.isNotBlank() }?.also { and(it == field.name) }
value.modifiers?.also { runCatching { and(it(field.cast())) } }
value.nameConditions?.also { field.name.also { n -> runCatching { and(it(n.cast(), n)) } } }
value.typeConditions?.also { field.also { t -> runCatching { and(it(t.type(), t.type)) } } }
}.finally { numberOfFound++ }
}.run { rule.matchCount(numberOfFound) { and(it && numberOfFound > 0) } }
else rule.matchCount(count()) { and(it) }
}
}
methodRules.takeIf { it.isNotEmpty() }?.forEach { rule ->
instance.existMethods?.apply {
var numberOfFound = 0
if (rule.isInitialize) forEach { method ->
rule.conditions {
value.name.takeIf { it.isNotBlank() }?.also { and(it == method.name) }
value.returnType?.takeIf { value.exists(it) }?.also { and(it == method.returnType) }
value.returnTypeConditions
?.also { method.also { r -> runCatching { and(it(r.returnType(), r.returnType)) } } }
value.paramCount.takeIf { it >= 0 }?.also { and(method.parameterTypes.size == it) }
value.paramCountRange.takeIf { it.isEmpty().not() }?.also { and(method.parameterTypes.size in it) }
value.paramCountConditions
?.also { method.parameterTypes.size.also { s -> runCatching { and(it(s.cast(), s)) } } }
value.paramTypes?.takeIf { value.exists(*it) }?.also { and(paramTypesEq(it, method.parameterTypes)) }
value.paramTypesConditions
?.also { method.also { t -> runCatching { and(it(t.paramTypes(), t.parameterTypes)) } } }
value.modifiers?.also { runCatching { and(it(method.cast())) } }
value.nameConditions?.also { method.name.also { n -> runCatching { and(it(n.cast(), n)) } } }
}.finally { numberOfFound++ }
}.run { rule.matchCount(numberOfFound) { and(it && numberOfFound > 0) } }
else rule.matchCount(count()) { and(it) }
}
}
constroctorRules.takeIf { it.isNotEmpty() }?.forEach { rule ->
instance.existConstructors?.apply {
var numberOfFound = 0
if (rule.isInitialize) forEach { constructor ->
rule.conditions {
value.paramCount.takeIf { it >= 0 }?.also { and(constructor.parameterTypes.size == it) }
value.paramCountRange.takeIf { it.isEmpty().not() }?.also { and(constructor.parameterTypes.size in it) }
value.paramCountConditions
?.also { constructor.parameterTypes.size.also { s -> runCatching { and(it(s.cast(), s)) } } }
value.paramTypes?.takeIf { value.exists(*it) }?.also { and(paramTypesEq(it, constructor.parameterTypes)) }
value.paramTypesConditions
?.also { constructor.also { t -> runCatching { and(it(t.paramTypes(), t.parameterTypes)) } } }
value.modifiers?.also { runCatching { and(it(constructor.cast())) } }
}.finally { numberOfFound++ }
}.run { rule.matchCount(numberOfFound) { and(it && numberOfFound > 0) } }
else rule.matchCount(count()) { and(it) }
}
}
}.finally { classes.add(instance) }
}
findDexClassList(loaderSet).takeIf { it.isNotEmpty() }?.forEach { className ->
/** 分离包名 → com.demo.Test → com.demo (获取最后一个 "." + 简单类名的长度) → 由于末位存在 "." 最后要去掉 1 个长度 */
(if (className.contains("."))
className.substring(0, className.length - className.split(".").let { it[it.lastIndex] }.length - 1)
else className).also { packageName ->
if ((fromPackages.isEmpty() || fromPackages.any {
if (it.isAbsolute) packageName == it.name else packageName.startsWith(it.name)
}) && className.hasClass(loaderSet)
) startProcess(className.toClass(loaderSet))
}
}
}.takeIf { it.isNotEmpty() } ?: throwNotFoundError(loaderSet)
}
/**
* 查找任意 [Field] 或一组 [Field]
* @param classSet [Field] 所在类
* @param rulesData 规则查找数据
* @return [HashSet]<[Field]>
* @throws IllegalStateException 如果未设置任何条件或 [FieldRulesData.type] 目标类不存在
* @throws NoSuchFieldError 如果找不到 [Field]
*/
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()
hashSetOf<Field>().also { fields ->
classSet.existFields?.also { declares ->
var iType = -1
var iName = -1
var iModify = -1
var iNameCds = -1
var iTypeCds = -1
val iLType = type?.let(matchIndex) { e -> declares.findLastIndex { e == it.type } } ?: -1
val iLName = name.takeIf(matchIndex) { it.isNotBlank() }?.let { e -> declares.findLastIndex { e == it.name } } ?: -1
val iLModify = modifiers?.let(matchIndex) { e -> declares.findLastIndex { runOrFalse { e(it.cast()) } } } ?: -1
val iLNameCds = nameConditions
?.let(matchIndex) { e -> declares.findLastIndex { it.name.let { n -> runOrFalse { e(n.cast(), n) } } } } ?: -1
val iLTypeCds = typeConditions?.let(matchIndex) { e -> declares.findLastIndex { runOrFalse { e(it.type(), it.type) } } } ?: -1
declares.forEachIndexed { index, instance ->
conditions {
type?.also {
and((it == instance.type).let { hold ->
if (hold) iType++
hold && matchIndex.compare(iType, iLType)
})
}
name.takeIf { it.isNotBlank() }?.also {
and((it == instance.name).let { hold ->
if (hold) iName++
hold && matchIndex.compare(iName, iLName)
})
}
modifiers?.also {
and(runOrFalse { it(instance.cast()) }.let { hold ->
if (hold) iModify++
hold && matchIndex.compare(iModify, iLModify)
})
}
nameConditions?.also {
and(instance.name.let { n -> runOrFalse { it(n.cast(), n) } }.let { hold ->
if (hold) iNameCds++
hold && matchIndex.compare(iNameCds, iLNameCds)
})
}
typeConditions?.also {
and(instance.let { t -> runOrFalse { it(t.type(), t.type) } }.let { hold ->
if (hold) iTypeCds++
hold && matchIndex.compare(iTypeCds, iLTypeCds)
})
}
orderIndex.compare(index, declares.lastIndex()) { and(it) }
}.finally { fields.add(instance.apply { isAccessible = true }) }
}
}
}.takeIf { it.isNotEmpty() } ?: findSuperOrThrow(classSet)
}
/**
* 查找任意 [Method] 或一组 [Method]
* @param classSet [Method] 所在类
* @param rulesData 规则查找数据
* @return [HashSet]<[Method]>
* @throws IllegalStateException 如果未设置任何条件或 [MethodRulesData.paramTypes] 以及 [MethodRulesData.returnType] 目标类不存在
* @throws NoSuchMethodError 如果找不到 [Method]
*/
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") }
hashSetOf<Method>().also { methods ->
classSet.existMethods?.also { declares ->
var iReturnType = -1
var iReturnTypeCds = -1
var iParamTypes = -1
var iParamTypesCds = -1
var iParamCount = -1
var iParamCountRange = -1
var iParamCountCds = -1
var iName = -1
var iModify = -1
var iNameCds = -1
val iLReturnType = returnType?.let(matchIndex) { e -> declares.findLastIndex { e == it.returnType } } ?: -1
val iLReturnTypeCds = returnTypeConditions
?.let(matchIndex) { e -> declares.findLastIndex { runOrFalse { e(it.returnType(), it.returnType) } } } ?: -1
val iLParamCount = paramCount.takeIf(matchIndex) { it >= 0 }
?.let { e -> declares.findLastIndex { e == it.parameterTypes.size } } ?: -1
val iLParamCountRange = paramCountRange.takeIf(matchIndex) { it.isEmpty().not() }
?.let { e -> declares.findLastIndex { it.parameterTypes.size in e } } ?: -1
val iLParamCountCds = paramCountConditions?.let(matchIndex) { e ->
declares.findLastIndex { it.parameterTypes.size.let { s -> runOrFalse { e(s.cast(), s) } } }
} ?: -1
val iLParamTypes = paramTypes?.let(matchIndex) { e -> declares.findLastIndex { paramTypesEq(e, it.parameterTypes) } } ?: -1
val iLParamTypesCds = paramTypesConditions
?.let(matchIndex) { e -> declares.findLastIndex { runOrFalse { e(it.paramTypes(), it.parameterTypes) } } } ?: -1
val iLName = name.takeIf(matchIndex) { it.isNotBlank() }?.let { e -> declares.findLastIndex { e == it.name } } ?: -1
val iLModify = modifiers?.let(matchIndex) { e -> declares.findLastIndex { runOrFalse { e(it.cast()) } } } ?: -1
val iLNameCds = nameConditions
?.let(matchIndex) { e -> declares.findLastIndex { it.name.let { n -> runOrFalse { e(n.cast(), n) } } } } ?: -1
declares.forEachIndexed { index, instance ->
conditions {
name.takeIf { it.isNotBlank() }?.also {
and((it == instance.name).let { hold ->
if (hold) iName++
hold && matchIndex.compare(iName, iLName)
})
}
returnType?.also {
and((it == instance.returnType).let { hold ->
if (hold) iReturnType++
hold && matchIndex.compare(iReturnType, iLReturnType)
})
}
returnTypeConditions?.also {
and(instance.let { r -> runOrFalse { it(r.returnType(), r.returnType) } }.let { hold ->
if (hold) iReturnTypeCds++
hold && matchIndex.compare(iReturnTypeCds, iLReturnTypeCds)
})
}
paramCount.takeIf { it >= 0 }?.also {
and((instance.parameterTypes.size == it).let { hold ->
if (hold) iParamCount++
hold && matchIndex.compare(iParamCount, iLParamCount)
})
}
paramCountRange.takeIf { it.isEmpty().not() }?.also {
and((instance.parameterTypes.size in it).let { hold ->
if (hold) iParamCountRange++
hold && matchIndex.compare(iParamCountRange, iLParamCountRange)
})
}
paramCountConditions?.also {
and(instance.parameterTypes.size.let { s -> runOrFalse { it(s.cast(), s) } }.let { hold ->
if (hold) iParamCountCds++
hold && matchIndex.compare(iParamCountCds, iLParamCountCds)
})
}
paramTypes?.also {
and(paramTypesEq(it, instance.parameterTypes).let { hold ->
if (hold) iParamTypes++
hold && matchIndex.compare(iParamTypes, iLParamTypes)
})
}
paramTypesConditions?.also {
and(instance.let { t -> runOrFalse { it(t.paramTypes(), t.parameterTypes) } }.let { hold ->
if (hold) iParamTypesCds++
hold && matchIndex.compare(iParamTypesCds, iLParamTypesCds)
})
}
modifiers?.also {
and(runOrFalse { it(instance.cast()) }.let { hold ->
if (hold) iModify++
hold && matchIndex.compare(iModify, iLModify)
})
}
nameConditions?.also {
and(instance.name.let { n -> runOrFalse { it(n.cast(), n) } }.let { hold ->
if (hold) iNameCds++
hold && matchIndex.compare(iNameCds, iLNameCds)
})
}
orderIndex.compare(index, declares.lastIndex()) { and(it) }
}.finally { methods.add(instance.apply { isAccessible = true }) }
}
}
}.takeIf { it.isNotEmpty() } ?: findSuperOrThrow(classSet)
}
/**
* 查找任意 [Constructor] 或一组 [Constructor]
* @param classSet [Constructor] 所在类
* @param rulesData 规则查找数据
* @return [HashSet]<[Constructor]>
* @throws IllegalStateException 如果未设置任何条件或 [ConstructorRulesData.paramTypes] 目标类不存在
* @throws NoSuchMethodError 如果找不到 [Constructor]
*/
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") }
hashSetOf<Constructor<*>>().also { constructors ->
classSet.existConstructors?.also { declares ->
var iParamTypes = -1
var iParamTypesCds = -1
var iParamCount = -1
var iParamCountRange = -1
var iParamCountCds = -1
var iModify = -1
val iLParamCount = paramCount.takeIf(matchIndex) { it >= 0 }
?.let { e -> declares.findLastIndex { e == it.parameterTypes.size } } ?: -1
val iLParamCountRange = paramCountRange.takeIf(matchIndex) { it.isEmpty().not() }
?.let { e -> declares.findLastIndex { it.parameterTypes.size in e } } ?: -1
val iLParamCountCds = paramCountConditions?.let(matchIndex) { e ->
declares.findLastIndex { it.parameterTypes.size.let { s -> runOrFalse { e(s.cast(), s) } } }
} ?: -1
val iLParamTypes = paramTypes?.let(matchIndex) { e -> declares.findLastIndex { paramTypesEq(e, it.parameterTypes) } } ?: -1
val iLParamTypesCds = paramTypesConditions
?.let(matchIndex) { e -> declares.findLastIndex { runOrFalse { e(it.paramTypes(), it.parameterTypes) } } } ?: -1
val iLModify = modifiers?.let(matchIndex) { e -> declares.findLastIndex { runOrFalse { e(it.cast()) } } } ?: -1
declares.forEachIndexed { index, instance ->
conditions {
paramCount.takeIf { it >= 0 }?.also {
and((instance.parameterTypes.size == it).let { hold ->
if (hold) iParamCount++
hold && matchIndex.compare(iParamCount, iLParamCount)
})
}
paramCountRange.takeIf { it.isEmpty().not() }?.also {
and((instance.parameterTypes.size in it).let { hold ->
if (hold) iParamCountRange++
hold && matchIndex.compare(iParamCountRange, iLParamCountRange)
})
}
paramCountConditions?.also {
and(instance.parameterTypes.size.let { s -> runOrFalse { it(s.cast(), s) } }.let { hold ->
if (hold) iParamCountCds++
hold && matchIndex.compare(iParamCountCds, iLParamCountCds)
})
}
paramTypes?.also {
and(paramTypesEq(it, instance.parameterTypes).let { hold ->
if (hold) iParamTypes++
hold && matchIndex.compare(iParamTypes, iLParamTypes)
})
}
paramTypesConditions?.also {
and(instance.let { t -> runOrFalse { it(t.paramTypes(), t.parameterTypes) } }.let { hold ->
if (hold) iParamTypesCds++
hold && matchIndex.compare(iParamTypesCds, iLParamTypesCds)
})
}
modifiers?.also {
and(runOrFalse { it(instance.cast()) }.let { hold ->
if (hold) iModify++
hold && matchIndex.compare(iModify, iLModify)
})
}
orderIndex.compare(index, declares.lastIndex()) { and(it) }
}.finally { constructors.add(instance.apply { isAccessible = true }) }
}
}
}.takeIf { it.isNotEmpty() } ?: 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 ClassRulesData -> 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 createException(instanceSet, objectName, *templates)
is MethodRulesData -> throw createException(instanceSet, objectName, *templates)
is ConstructorRulesData -> throw createException(instanceSet, objectName, *templates)
is ClassRulesData -> throw createException(instanceSet ?: currentClassLoader, objectName, *templates)
else -> error("Type [$this] not allowed")
}
/**
* 创建一个异常
* @param instanceSet 所在 [ClassLoader] or [Class]
* @param name 实例名称
* @param content 异常内容
* @return [Throwable]
*/
private fun createException(instanceSet: Any?, name: String, vararg content: String): Throwable {
/**
* 获取 [Class.getName] 长度的空格数量并使用 "->" 拼接
* @return [String]
*/
fun Class<*>.space(): String {
var space = ""
for (i in 0..this.name.length) space += " "
return "$space -> "
}
if (content.isEmpty()) return IllegalStateException("Exception content is null")
val space = when (name) {
"Class" -> NoClassDefFoundErrorClass.space()
"Field" -> NoSuchFieldErrorClass.space()
"Method", "Constructor" -> NoSuchMethodErrorClass.space()
else -> error("Invalid Exception type")
}
var splicing = ""
content.forEach { if (it.isNotBlank()) splicing += "$space$it\n" }
val template = "Can't find this $name in [$instanceSet]:\n${splicing}Generated by $TAG"
return when (name) {
"Class" -> NoClassDefFoundError(template)
"Field" -> NoSuchFieldError(template)
"Method", "Constructor" -> NoSuchMethodError(template)
else -> error("Invalid Exception type")
}
}
/**
* 获取当前 [Class] 中存在的 [Member] 数组
* @return [Sequence]<[Member]> or null
*/
private val Class<*>.existMembers
get() = runCatching {
arrayListOf<Member>().apply {
addAll(declaredFields.toList())
addAll(declaredMethods.toList())
addAll(declaredConstructors.toList())
}.asSequence()
}.onFailure {
yLoggerW(msg = "Failed to get the declared Members in [$this] because got an exception\n$it")
}.getOrNull()
/**
* 获取当前 [Class] 中存在的 [Field] 数组
* @return [Sequence]<[Field]> or null
*/
private val Class<*>.existFields
get() = runCatching { declaredFields.asSequence() }.onFailure {
yLoggerW(msg = "Failed to get the declared Fields in [$this] because got an exception\n$it")
}.getOrNull()
/**
* 获取当前 [Class] 中存在的 [Method] 数组
* @return [Sequence]<[Method]> or null
*/
private val Class<*>.existMethods
get() = runCatching { declaredMethods.asSequence() }.onFailure {
yLoggerW(msg = "Failed to get the declared Methods in [$this] because got an exception\n$it")
}.getOrNull()
/**
* 获取当前 [Class] 中存在的 [Constructor] 数组
* @return [Sequence]<[Constructor]> or null
*/
private val Class<*>.existConstructors
get() = runCatching { declaredConstructors.asSequence() }.onFailure {
yLoggerW(msg = "Failed to get the declared Constructors in [$this] because got an exception\n$it")
}.getOrNull()
/**
* 判断两个方法、构造方法类型数组是否相等
*
* 复制自 [Class] 中的 [Class.arrayContentsEq]
* @param compare 用于比较的数组
* @param original 方法、构造方法原始数组
* @return [Boolean] 是否相等
* @throws IllegalStateException 如果 [VagueType] 配置不正确
*/
private fun paramTypesEq(compare: Array<out Any>?, original: Array<out Any>?): Boolean {
return when {
(compare == null && original == null) || (compare?.isEmpty() == true && original?.isEmpty() == true) -> true
(compare == null && original != null) || (compare != null && original == null) || (compare?.size != original?.size) -> false
else -> {
if (compare == null || original == null) return false
if (compare.all { it == VagueType }) error("The number of VagueType must be at least less than the count of paramTypes")
for (i in compare.indices) if ((compare[i] !== VagueType) && (compare[i] !== original[i])) return false
true
}
}
}
}

View File

@@ -0,0 +1,65 @@
/*
* YukiReflection - An efficient Reflection API for Java and Android built in Kotlin
* Copyright (C) 2019-2023 HighCapable
* https://github.com/fankes/YukiReflection
*
* 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/14.
* This file is Modified by fankes on 2023/1/21.
*/
package com.highcapable.yukireflection.finder.type.factory
import com.highcapable.yukireflection.finder.base.rules.CountRules
import com.highcapable.yukireflection.finder.base.rules.ModifierRules
import com.highcapable.yukireflection.finder.base.rules.NameRules
import com.highcapable.yukireflection.finder.base.rules.ObjectRules
import com.highcapable.yukireflection.finder.classes.DexClassFinder
import com.highcapable.yukireflection.finder.members.ConstructorFinder
import com.highcapable.yukireflection.finder.members.FieldFinder
import com.highcapable.yukireflection.finder.members.MethodFinder
/** 定义 [DexClassFinder] 方法体类型 */
internal typealias ClassConditions = DexClassFinder.() -> Unit
/** 定义 [FieldFinder] 方法体类型 */
internal typealias FieldConditions = FieldFinder.() -> Unit
/** 定义 [MethodFinder] 方法体类型 */
internal typealias MethodConditions = MethodFinder.() -> Unit
/** 定义 [ConstructorFinder] 方法体类型 */
internal typealias ConstructorConditions = ConstructorFinder.() -> Unit
/** 定义 [NameRules] 方法体类型 */
internal typealias NameConditions = NameRules.(String) -> Boolean
/** 定义 [CountRules] 方法体类型 */
internal typealias CountConditions = CountRules.(Int) -> Boolean
/** 定义 [ModifierRules] 方法体类型 */
internal typealias ModifierConditions = ModifierRules.() -> Boolean
/** 定义 [ObjectRules] 方法体类型 */
internal typealias ObjectConditions = ObjectRules.(Class<*>) -> Boolean
/** 定义 [ObjectRules] 方法体类型 */
internal typealias ObjectsConditions = ObjectRules.(Array<Class<*>>) -> Boolean

View File

@@ -0,0 +1,67 @@
/*
* YukiReflection - An efficient Reflection API for Java and Android built in Kotlin
* Copyright (C) 2019-2023 HighCapable
* https://github.com/fankes/YukiReflection
*
* 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/2/3.
* This file is Modified by fankes on 2023/1/21.
*/
@file:Suppress("unused", "MemberVisibilityCanBePrivate")
package com.highcapable.yukireflection.log
import android.util.Log
import com.highcapable.yukireflection.YukiReflection
/**
* 向控制台打印日志 - D
* @param msg 日志打印的内容
*/
internal fun yLoggerD(msg: String) {
if (YukiReflection.Configs.isAllowPrintingLogs) Log.d(YukiReflection.Configs.debugTag, msg)
}
/**
* 向控制台打印日志 - I
* @param msg 日志打印的内容
*/
internal fun yLoggerI(msg: String) {
if (YukiReflection.Configs.isAllowPrintingLogs) Log.i(YukiReflection.Configs.debugTag, msg)
}
/**
* 向控制台打印日志 - W
* @param msg 日志打印的内容
*/
internal fun yLoggerW(msg: String) {
if (YukiReflection.Configs.isAllowPrintingLogs) Log.w(YukiReflection.Configs.debugTag, msg)
}
/**
* 向控制台打印日志 - E
* @param msg 日志打印的内容
* @param e 可填入异常堆栈信息 - 将自动完整打印到控制台
*/
internal fun yLoggerE(msg: String, e: Throwable? = null) {
if (YukiReflection.Configs.isAllowPrintingLogs) Log.e(YukiReflection.Configs.debugTag, msg, e)
}

View File

@@ -0,0 +1,824 @@
/*
* YukiReflection - An efficient Reflection API for Java and Android built in Kotlin
* Copyright (C) 2019-2023 HighCapable
* https://github.com/fankes/YukiReflection
*
* 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/2/2.
* This file is Modified by fankes on 2023/1/21.
*/
@file:Suppress("unused", "KDocUnresolvedReference", "DEPRECATION")
package com.highcapable.yukireflection.type.android
import android.app.*
import android.appwidget.AppWidgetHost
import android.appwidget.AppWidgetManager
import android.appwidget.AppWidgetProvider
import android.appwidget.AppWidgetProviderInfo
import android.content.*
import android.content.Intent.ShortcutIconResource
import android.content.pm.*
import android.content.pm.LauncherApps.ShortcutQuery
import android.content.res.*
import android.database.sqlite.SQLiteDatabase
import android.graphics.drawable.*
import android.icu.text.SimpleDateFormat
import android.media.MediaPlayer
import android.os.*
import android.provider.Settings
import android.service.notification.StatusBarNotification
import android.util.*
import android.view.*
import android.view.accessibility.AccessibilityEvent
import android.view.accessibility.AccessibilityManager
import android.view.accessibility.AccessibilityNodeInfo
import android.widget.Toast
import com.highcapable.yukireflection.factory.classOf
import com.highcapable.yukireflection.factory.toClass
import com.highcapable.yukireflection.factory.toClassOrNull
/**
* 获得 [android.R] 类型
* @return [Class]<[android.R]>
*/
val AndroidRClass get() = classOf<android.R>()
/**
* 获得 [Context] 类型
* @return [Class]<[Context]>
*/
val ContextClass get() = classOf<Context>()
/**
* 获得 [ContextImpl] 类型
* @return [Class]
*/
val ContextImplClass get() = "android.app.ContextImpl".toClass()
/**
* 获得 [ContextWrapper] 类型
* @return [Class]<[ContextWrapper]>
*/
val ContextWrapperClass get() = classOf<ContextWrapper>()
/**
* 获得 [Application] 类型
* @return [Class]<[Application]>
*/
val ApplicationClass get() = classOf<Application>()
/**
* 获得 [ApplicationInfo] 类型
* @return [Class]<[ApplicationInfo]>
*/
val ApplicationInfoClass get() = classOf<ApplicationInfo>()
/**
* 获得 [Instrumentation] 类型
* @return [Class]<[Instrumentation]>
*/
val InstrumentationClass get() = classOf<Instrumentation>()
/**
* 获得 [PackageInfo] 类型
* @return [Class]<[PackageInfo]>
*/
val PackageInfoClass get() = classOf<PackageInfo>()
/**
* 获得 [ApplicationPackageManager] 类型
* @return [Class]
*/
val ApplicationPackageManagerClass get() = "android.app.ApplicationPackageManager".toClass()
/**
* 获得 [ActivityThread] 类型
* @return [Class]
*/
val ActivityThreadClass get() = "android.app.ActivityThread".toClass()
/**
* 获得 [ActivityManager] 类型
* @return [Class]<[ActivityManager]>
*/
val ActivityManagerClass get() = classOf<ActivityManager>()
/**
* 获得 [IActivityManager] 类型
* @return [Class]
*/
val IActivityManagerClass get() = "android.app.IActivityManager".toClass()
/**
* 获得 [ActivityManagerNative] 类型
* @return [Class]
*/
val ActivityManagerNativeClass get() = "android.app.ActivityManagerNative".toClass()
/**
* 获得 [IActivityTaskManager] 类型
*
* - ❗在 Android O (26) 及以上系统加入
* @return [Class] or null
*/
val IActivityTaskManagerClass get() = "android.app.IActivityTaskManager".toClassOrNull()
/**
* 获得 [ActivityTaskManager] 类型
*
* - ❗在 Android O (26) 及以上系统加入
* @return [Class] or null
*/
val ActivityTaskManagerClass get() = "android.app.ActivityTaskManager".toClassOrNull()
/**
* 获得 [IPackageManager] 类型
* @return [Class]
*/
val IPackageManagerClass get() = "android.content.pm.IPackageManager".toClass()
/**
* 获得 [ClientTransaction] 类型
* @return [Class]
*/
val ClientTransactionClass get() = "android.app.servertransaction.ClientTransaction".toClass()
/**
* 获得 [LoadedApk] 类型
* @return [Class]
*/
val LoadedApkClass get() = "android.app.LoadedApk".toClass()
/**
* 获得 [Singleton] 类型
* @return [Class]
*/
val SingletonClass get() = "android.util.Singleton".toClass()
/**
* 获得 [Activity] 类型
* @return [Class]<[Activity]>
*/
val ActivityClass get() = classOf<Activity>()
/**
* 获得 [Looper] 类型
* @return [Class]<[Looper]>
*/
val LooperClass get() = classOf<Looper>()
/**
* 获得 [Fragment] 类型 - Support
* @return [Class]
*/
val FragmentClass_AndroidSupport get() = "android.support.v4.app.Fragment".toClass()
/**
* 获得 [Fragment] 类型 - AndroidX
* @return [Class]
*/
val FragmentClass_AndroidX get() = "androidx.fragment.app.Fragment".toClass()
/**
* 获得 [FragmentActivity] 类型 - Support
* @return [Class]
*/
val FragmentActivityClass_AndroidSupport get() = "android.support.v4.app.FragmentActivity".toClass()
/**
* 获得 [FragmentActivity] 类型 - AndroidX
* @return [Class]
*/
val FragmentActivityClass_AndroidX get() = "androidx.fragment.app.FragmentActivity".toClass()
/**
* 获得 [DocumentFile] 类型 - AndroidX
* @return [Class]
*/
val DocumentFileClass get() = "androidx.documentfile.provider.DocumentFile".toClass()
/**
* 获得 [Service] 类型
* @return [Class]<[Service]>
*/
val ServiceClass get() = classOf<Service>()
/**
* 获得 [Binder] 类型
* @return [Class]<[Binder]>
*/
val BinderClass get() = classOf<Binder>()
/**
* 获得 [IBinder] 类型
* @return [Class]<[IBinder]>
*/
val IBinderClass get() = classOf<IBinder>()
/**
* 获得 [BroadcastReceiver] 类型
* @return [Class]<[BroadcastReceiver]>
*/
val BroadcastReceiverClass get() = classOf<BroadcastReceiver>()
/**
* 获得 [Bundle] 类型
* @return [Class]<[Bundle]>
*/
val BundleClass get() = classOf<Bundle>()
/**
* 获得 [BaseBundle] 类型
* @return [Class]<[BaseBundle]>
*/
val BaseBundleClass get() = classOf<BaseBundle>()
/**
* 获得 [Resources] 类型
* @return [Class]<[Resources]>
*/
val ResourcesClass get() = classOf<Resources>()
/**
* 获得 [Configuration] 类型
* @return [Class]<[Configuration]>
*/
val ConfigurationClass get() = classOf<Configuration>()
/**
* 获得 [ConfigurationInfo] 类型
* @return [Class]<[ConfigurationInfo]>
*/
val ConfigurationInfoClass get() = classOf<ConfigurationInfo>()
/**
* 获得 [ContentResolver] 类型
* @return [Class]<[ContentResolver]>
*/
val ContentResolverClass get() = classOf<ContentResolver>()
/**
* 获得 [ContentProvider] 类型
* @return [Class]<[ContentProvider]>
*/
val ContentProviderClass get() = classOf<ContentProvider>()
/**
* 获得 [Settings] 类型
* @return [Class]<[Settings]>
*/
val SettingsClass get() = classOf<Settings>()
/**
* 获得 [Settings.System] 类型
* @return [Class]<[Settings.System]>
*/
val Settings_SystemClass get() = classOf<Settings.System>()
/**
* 获得 [Settings.Secure] 类型
* @return [Class]<[Settings.Secure]>
*/
val Settings_SecureClass get() = classOf<Settings.Secure>()
/**
* 获得 [TypedArray] 类型
* @return [Class]<[TypedArray]>
*/
val TypedArrayClass get() = classOf<TypedArray>()
/**
* 获得 [TypedValue] 类型
* @return [Class]<[TypedValue]>
*/
val TypedValueClass get() = classOf<TypedValue>()
/**
* 获得 [SparseArray] 类型
* @return [Class]<[SparseArray]>
*/
val SparseArrayClass get() = classOf<SparseArray<*>>()
/**
* 获得 [SparseIntArray] 类型
* @return [Class]<[SparseIntArray]>
*/
val SparseIntArrayClass get() = classOf<SparseIntArray>()
/**
* 获得 [SparseBooleanArray] 类型
* @return [Class]<[SparseBooleanArray]>
*/
val SparseBooleanArrayClass get() = classOf<SparseBooleanArray>()
/**
* 获得 [SparseLongArray] 类型
* @return [Class]<[SparseLongArray]>
*/
val SparseLongArrayClass get() = classOf<SparseLongArray>()
/**
* 获得 [LongSparseArray] 类型
* @return [Class]<[LongSparseArray]>
*/
val LongSparseArrayClass get() = classOf<LongSparseArray<*>>()
/**
* 获得 [ArrayMap] 类型
* @return [Class]<[ArrayMap]>
*/
val ArrayMapClass get() = classOf<ArrayMap<*, *>>()
/**
* 获得 [ArraySet] 类型
*
* - ❗在 Android M (23) 及以上系统加入
* @return [Class]<[ArraySet]> or null
*/
val ArraySetClass get() = if (Build.VERSION.SDK_INT >= 23) classOf<ArraySet<*>>() else null
/**
* 获得 [Handler] 类型
* @return [Class]<[Handler]>
*/
val HandlerClass get() = classOf<Handler>()
/**
* 获得 [Handler.Callback] 类型
* @return [Class]<[Handler.Callback]>
*/
val Handler_CallbackClass get() = classOf<Handler.Callback>()
/**
* 获得 [Message] 类型
* @return [Class]<[Message]>
*/
val MessageClass get() = classOf<Message>()
/**
* 获得 [MessageQueue] 类型
* @return [Class]<[MessageQueue]>
*/
val MessageQueueClass get() = classOf<MessageQueue>()
/**
* 获得 [Messenger] 类型
* @return [Class]<[Messenger]>
*/
val MessengerClass get() = classOf<Messenger>()
/**
* 获得 [AsyncTask] 类型
* @return [Class]<[AsyncTask]>
*/
val AsyncTaskClass get() = classOf<AsyncTask<*, *, *>>()
/**
* 获得 [SimpleDateFormat] 类型
*
* - ❗在 Android N (24) 及以上系统加入
* @return [Class]<[SimpleDateFormat]> or null
*/
val SimpleDateFormatClass_Android get() = if (Build.VERSION.SDK_INT >= 24) classOf<SimpleDateFormat>() else null
/**
* 获得 [Base64] 类型
* @return [Class]<[Base64]>
*/
val Base64Class_Android get() = classOf<Base64>()
/**
* 获得 [Window] 类型
* @return [Class]<[Window]>
*/
val WindowClass get() = classOf<Window>()
/**
* 获得 [WindowMetrics] 类型
*
* - ❗在 Android R (30) 及以上系统加入
* @return [Class]<[WindowMetrics]> or null
*/
val WindowMetricsClass get() = if (Build.VERSION.SDK_INT >= 30) classOf<WindowMetrics>() else null
/**
* 获得 [WindowInsets] 类型
* @return [Class]<[WindowInsets]>
*/
val WindowInsetsClass get() = classOf<WindowInsets>()
/**
* 获得 [WindowInsets.Type] 类型
*
* - ❗在 Android R (30) 及以上系统加入
* @return [Class]<[WindowInsets.Type]> or null
*/
val WindowInsets_TypeClass get() = if (Build.VERSION.SDK_INT >= 30) classOf<WindowInsets.Type>() else null
/**
* 获得 [WindowManager] 类型
* @return [Class]<[WindowManager]>
*/
val WindowManagerClass get() = classOf<WindowManager>()
/**
* 获得 [WindowManager.LayoutParams] 类型
* @return [Class]<[WindowManager.LayoutParams]>
*/
val WindowManager_LayoutParamsClass get() = classOf<WindowManager.LayoutParams>()
/**
* 获得 [ViewManager] 类型
* @return [Class]<[ViewManager]>
*/
val ViewManagerClass get() = classOf<ViewManager>()
/**
* 获得 [Parcel] 类型
* @return [Class]<[Parcel]>
*/
val ParcelClass get() = classOf<Parcel>()
/**
* 获得 [Parcelable] 类型
* @return [Class]<[Parcelable]>
*/
val ParcelableClass get() = classOf<Parcelable>()
/**
* 获得 [Parcelable.Creator] 类型
* @return [Class]<[Parcelable.Creator]>
*/
val Parcelable_CreatorClass get() = classOf<Parcelable.Creator<*>>()
/**
* 获得 [Dialog] 类型
* @return [Class]<[Dialog]>
*/
val DialogClass get() = classOf<Dialog>()
/**
* 获得 [AlertDialog] 类型
* @return [Class]<[AlertDialog]>
*/
val AlertDialogClass get() = classOf<AlertDialog>()
/**
* 获得 [DisplayMetrics] 类型
* @return [Class]<[DisplayMetrics]>
*/
val DisplayMetricsClass get() = classOf<DisplayMetrics>()
/**
* 获得 [Display] 类型
* @return [Class]<[Display]>
*/
val DisplayClass get() = classOf<Display>()
/**
* 获得 [Toast] 类型
* @return [Class]<[Toast]>
*/
val ToastClass get() = classOf<Toast>()
/**
* 获得 [Intent] 类型
* @return [Class]<[Intent]>
*/
val IntentClass get() = classOf<Intent>()
/**
* 获得 [ComponentInfo] 类型
* @return [Class]<[ComponentInfo]>
*/
val ComponentInfoClass get() = classOf<ComponentInfo>()
/**
* 获得 [ComponentName] 类型
* @return [Class]<[ComponentName]>
*/
val ComponentNameClass get() = classOf<ComponentName>()
/**
* 获得 [PendingIntent] 类型
* @return [Class]<[PendingIntent]>
*/
val PendingIntentClass get() = classOf<PendingIntent>()
/**
* 获得 [ColorStateList] 类型
* @return [Class]<[ColorStateList]>
*/
val ColorStateListClass get() = classOf<ColorStateList>()
/**
* 获得 [ContentValues] 类型
* @return [Class]<[ContentValues]>
*/
val ContentValuesClass get() = classOf<ContentValues>()
/**
* 获得 [SharedPreferences] 类型
* @return [Class]<[SharedPreferences]>
*/
val SharedPreferencesClass get() = classOf<SharedPreferences>()
/**
* 获得 [MediaPlayer] 类型
* @return [Class]<[MediaPlayer]>
*/
val MediaPlayerClass get() = classOf<MediaPlayer>()
/**
* 获得 [ProgressDialog] 类型
* @return [Class]<[ProgressDialog]>
*/
val ProgressDialogClass get() = classOf<ProgressDialog>()
/**
* 获得 [Log] 类型
* @return [Class]<[Log]>
*/
val LogClass get() = classOf<Log>()
/**
* 获得 [Build] 类型
* @return [Class]<[Build]>
*/
val BuildClass get() = classOf<Build>()
/**
* 获得 [Xml] 类型
* @return [Class]<[Xml]>
*/
val XmlClass get() = classOf<Xml>()
/**
* 获得 [ContrastColorUtil] 类型
* @return [Class]
*/
val ContrastColorUtilClass get() = "com.android.internal.util.ContrastColorUtil".toClass()
/**
* 获得 [StatusBarNotification] 类型
* @return [Class]<[StatusBarNotification]>
*/
val StatusBarNotificationClass get() = classOf<StatusBarNotification>()
/**
* 获得 [Notification] 类型
* @return [Class]<[Notification]>
*/
val NotificationClass get() = classOf<Notification>()
/**
* 获得 [Notification.Builder] 类型
* @return [Class]<[Notification.Builder]>
*/
val Notification_BuilderClass get() = classOf<Notification.Builder>()
/**
* 获得 [Notification.Action] 类型
* @return [Class]<[Notification.Action]>
*/
val Notification_ActionClass get() = classOf<Notification.Action>()
/**
* 获得 [DialogInterface] 类型
* @return [Class]<[DialogInterface]>
*/
val DialogInterfaceClass get() = classOf<DialogInterface>()
/**
* 获得 [DialogInterface.OnClickListener] 类型
* @return [Class]<[DialogInterface.OnClickListener]>
*/
val DialogInterface_OnClickListenerClass get() = classOf<DialogInterface.OnClickListener>()
/**
* 获得 [DialogInterface.OnCancelListener] 类型
* @return [Class]<[DialogInterface.OnCancelListener]>
*/
val DialogInterface_OnCancelListenerClass get() = classOf<DialogInterface.OnCancelListener>()
/**
* 获得 [DialogInterface.OnDismissListener] 类型
* @return [Class]<[DialogInterface.OnDismissListener]>
*/
val DialogInterface_OnDismissListenerClass get() = classOf<DialogInterface.OnDismissListener>()
/**
* 获得 [Environment] 类型
* @return [Class]<[Environment]>
*/
val EnvironmentClass get() = classOf<Environment>()
/**
* 获得 [Process] 类型
* @return [Class]<[Process]>
*/
val ProcessClass get() = classOf<Process>()
/**
* 获得 [Vibrator] 类型
* @return [Class]<[Vibrator]>
*/
val VibratorClass get() = classOf<Vibrator>()
/**
* 获得 [VibrationEffect] 类型
*
* - ❗在 Android O (26) 及以上系统加入
* @return [Class]<[VibrationEffect]> or null
*/
val VibrationEffectClass get() = if (Build.VERSION.SDK_INT >= 26) classOf<VibrationEffect>() else null
/**
* 获得 [VibrationAttributes] 类型
*
* - ❗在 Android R (30) 及以上系统加入
* @return [Class]<[VibrationAttributes]> or null
*/
val VibrationAttributesClass get() = if (Build.VERSION.SDK_INT >= 30) classOf<VibrationAttributes>() else null
/**
* 获得 [SystemClock] 类型
* @return [Class]<[SystemClock]>
*/
val SystemClockClass get() = classOf<SystemClock>()
/**
* 获得 [PowerManager] 类型
* @return [Class]<[PowerManager]>
*/
val PowerManagerClass get() = classOf<PowerManager>()
/**
* 获得 [PowerManager.WakeLock] 类型
* @return [Class]<[PowerManager.WakeLock]>
*/
val PowerManager_WakeLockClass get() = classOf<PowerManager.WakeLock>()
/**
* 获得 [UserHandle] 类型
* @return [Class]<[UserHandle]>
*/
val UserHandleClass get() = classOf<UserHandle>()
/**
* 获得 [ShortcutInfo] 类型
*
* - ❗在 Android N_MR1 (25) 及以上系统加入
* @return [Class]<[ShortcutInfo]> or null
*/
val ShortcutInfoClass get() = if (Build.VERSION.SDK_INT >= 25) classOf<ShortcutInfo>() else null
/**
* 获得 [ShortcutManager] 类型
*
* - ❗在 Android R (30) 及以上系统加入
* @return [Class]<[ShortcutManager]> or null
*/
val ShortcutManagerClass get() = if (Build.VERSION.SDK_INT >= 30) classOf<ShortcutManager>() else null
/**
* 获得 [ShortcutQuery] 类型
*
* - ❗在 Android N_MR1 (25) 及以上系统加入
* @return [Class]<[ShortcutQuery]> or null
*/
val ShortcutQueryClass get() = if (Build.VERSION.SDK_INT >= 25) classOf<ShortcutQuery>() else null
/**
* 获得 [KeyboardShortcutInfo] 类型
* @return [Class]<[KeyboardShortcutInfo]>
*/
val KeyboardShortcutInfoClass get() = classOf<KeyboardShortcutInfo>()
/**
* 获得 [KeyboardShortcutGroup] 类型
* @return [Class]<[KeyboardShortcutGroup]>
*/
val KeyboardShortcutGroupClass get() = classOf<KeyboardShortcutGroup>()
/**
* 获得 [ShortcutIconResource] 类型
* @return [Class]<[ShortcutIconResource]>
*/
val ShortcutIconResourceClass get() = classOf<ShortcutIconResource>()
/**
* 获得 [AssetManager] 类型
* @return [Class]<[AssetManager]>
*/
val AssetManagerClass get() = classOf<AssetManager>()
/**
* 获得 [AppWidgetManager] 类型
* @return [Class]<[AppWidgetManager]>
*/
val AppWidgetManagerClass get() = classOf<AppWidgetManager>()
/**
* 获得 [AppWidgetProvider] 类型
* @return [Class]<[AppWidgetProvider]>
*/
val AppWidgetProviderClass get() = classOf<AppWidgetProvider>()
/**
* 获得 [AppWidgetProviderInfo] 类型
* @return [Class]<[AppWidgetProviderInfo]>
*/
val AppWidgetProviderInfoClass get() = classOf<AppWidgetProviderInfo>()
/**
* 获得 [AppWidgetHost] 类型
* @return [Class]<[AppWidgetHost]>
*/
val AppWidgetHostClass get() = classOf<AppWidgetHost>()
/**
* 获得 [ActivityInfo] 类型
* @return [Class]<[ActivityInfo]>
*/
val ActivityInfoClass get() = classOf<ActivityInfo>()
/**
* 获得 [ResolveInfo] 类型
* @return [Class]<[ResolveInfo]>
*/
val ResolveInfoClass get() = classOf<ResolveInfo>()
/**
* 获得 [Property] 类型
* @return [Class]<[Property]>
*/
val PropertyClass get() = classOf<Property<*, *>>()
/**
* 获得 [IntProperty] 类型
* @return [Class]<[IntProperty]>
*/
val IntPropertyClass get() = classOf<IntProperty<*>>()
/**
* 获得 [FloatProperty] 类型
* @return [Class]<[FloatProperty]>
*/
val FloatPropertyClass get() = classOf<FloatProperty<*>>()
/**
* 获得 [SQLiteDatabase] 类型
* @return [Class]<[SQLiteDatabase]>
*/
val SQLiteDatabaseClass get() = classOf<SQLiteDatabase>()
/**
* 获得 [StrictMode] 类型
* @return [Class]<[StrictMode]>
*/
val StrictModeClass get() = classOf<StrictMode>()
/**
* 获得 [AccessibilityManager] 类型
* @return [Class]<[AccessibilityManager]>
*/
val AccessibilityManagerClass get() = classOf<AccessibilityManager>()
/**
* 获得 [AccessibilityEvent] 类型
* @return [Class]<[AccessibilityEvent]>
*/
val AccessibilityEventClass get() = classOf<AccessibilityEvent>()
/**
* 获得 [AccessibilityNodeInfo] 类型
* @return [Class]<[AccessibilityNodeInfo]>
*/
val AccessibilityNodeInfoClass get() = classOf<AccessibilityNodeInfo>()
/**
* 获得 [IInterface] 类型
* @return [Class]<[IInterface]>
*/
val IInterfaceClass get() = classOf<IInterface>()

View File

@@ -0,0 +1,221 @@
/*
* YukiReflection - An efficient Reflection API for Java and Android built in Kotlin
* Copyright (C) 2019-2023 HighCapable
* https://github.com/fankes/YukiReflection
*
* 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/2/13.
* This file is Modified by fankes on 2023/1/21.
*/
@file:Suppress("unused", "KDocUnresolvedReference")
package com.highcapable.yukireflection.type.android
import android.graphics.*
import android.graphics.drawable.*
import android.os.Build
import android.text.*
import android.util.Size
import android.util.SizeF
import com.highcapable.yukireflection.factory.classOf
/**
* 获得 [Typeface] 类型
* @return [Class]<[Typeface]>
*/
val TypefaceClass get() = classOf<Typeface>()
/**
* 获得 [Bitmap] 类型
* @return [Class]<[Bitmap]>
*/
val BitmapClass get() = classOf<Bitmap>()
/**
* 获得 [Icon] 类型
*
* - ❗在 Android M (23) 及以上系统加入
* @return [Class]<[Icon]> or null
*/
val IconClass get() = if (Build.VERSION.SDK_INT >= 23) classOf<Icon>() else null
/**
* 获得 [Outline] 类型
* @return [Class]<[Outline]>
*/
val OutlineClass get() = classOf<Outline>()
/**
* 获得 [Drawable] 类型
* @return [Class]<[Drawable]>
*/
val DrawableClass get() = classOf<Drawable>()
/**
* 获得 [GradientDrawable] 类型
* @return [Class]<[GradientDrawable]>
*/
val GradientDrawableClass get() = classOf<GradientDrawable>()
/**
* 获得 [ColorDrawable] 类型
* @return [Class]<[ColorDrawable]>
*/
val ColorDrawableClass get() = classOf<ColorDrawable>()
/**
* 获得 [BitmapDrawable] 类型
* @return [Class]<[BitmapDrawable]>
*/
val BitmapDrawableClass get() = classOf<BitmapDrawable>()
/**
* 获得 [Size] 类型
* @return [Class]<[Size]>
*/
val SizeClass get() = classOf<Size>()
/**
* 获得 [SizeF] 类型
* @return [Class]<[SizeF]>
*/
val SizeFClass get() = classOf<SizeF>()
/**
* 获得 [Rect] 类型
* @return [Class]<[Rect]>
*/
val RectClass get() = classOf<Rect>()
/**
* 获得 [RectF] 类型
* @return [Class]<[RectF]>
*/
val RectFClass get() = classOf<RectF>()
/**
* 获得 [NinePatch] 类型
* @return [Class]<[NinePatch]>
*/
val NinePatchClass get() = classOf<NinePatch>()
/**
* 获得 [Paint] 类型
* @return [Class]<[Paint]>
*/
val PaintClass get() = classOf<Paint>()
/**
* 获得 [TextPaint] 类型
* @return [Class]<[TextPaint]>
*/
val TextPaintClass get() = classOf<TextPaint>()
/**
* 获得 [Canvas] 类型
* @return [Class]<[Canvas]>
*/
val CanvasClass get() = classOf<Canvas>()
/**
* 获得 [Point] 类型
* @return [Class]<[Point]>
*/
val PointClass get() = classOf<Point>()
/**
* 获得 [PointF] 类型
* @return [Class]<[PointF]>
*/
val PointFClass get() = classOf<PointF>()
/**
* 获得 [Matrix] 类型
* @return [Class]<[Matrix]>
*/
val MatrixClass get() = classOf<Matrix>()
/**
* 获得 [ColorMatrix] 类型
* @return [Class]<[ColorMatrix]>
*/
val ColorMatrixClass get() = classOf<ColorMatrix>()
/**
* 获得 [ColorMatrixColorFilter] 类型
* @return [Class]<[ColorMatrixColorFilter]>
*/
val ColorMatrixColorFilterClass get() = classOf<ColorMatrixColorFilter>()
/**
* 获得 [TextUtils] 类型
* @return [Class]<[TextUtils]>
*/
val TextUtilsClass get() = classOf<TextUtils>()
/**
* 获得 [Editable] 类型
* @return [Class]<[Editable]>
*/
val EditableClass get() = classOf<Editable>()
/**
* 获得 [TextWatcher] 类型
* @return [Class]<[TextWatcher]>
*/
val TextWatcherClass get() = classOf<TextWatcher>()
/**
* 获得 [Editable.Factory] 类型
* @return [Class]<[Editable.Factory]>
*/
val Editable_FactoryClass get() = classOf<Editable.Factory>()
/**
* 获得 [GetChars] 类型
* @return [Class]<[GetChars]>
*/
val GetCharsClass get() = classOf<GetChars>()
/**
* 获得 [Spannable] 类型
* @return [Class]<[Spannable]>
*/
val SpannableClass get() = classOf<Spannable>()
/**
* 获得 [SpannableStringBuilder] 类型
* @return [Class]<[SpannableStringBuilder]>
*/
val SpannableStringBuilderClass get() = classOf<SpannableStringBuilder>()
/**
* 获得 [BitmapFactory] 类型
* @return [Class]<[BitmapFactory]>
*/
val BitmapFactoryClass get() = classOf<BitmapFactory>()
/**
* 获得 [BitmapFactory.Options] 类型
* @return [Class]<[BitmapFactory.Options]>
*/
val BitmapFactory_OptionsClass get() = classOf<BitmapFactory.Options>()

View File

@@ -0,0 +1,416 @@
/*
* YukiReflection - An efficient Reflection API for Java and Android built in Kotlin
* Copyright (C) 2019-2023 HighCapable
* https://github.com/fankes/YukiReflection
*
* 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/2/2.
* This file is Modified by fankes on 2023/1/21.
*/
@file:Suppress("unused")
package com.highcapable.yukireflection.type.android
import android.animation.*
import android.appwidget.AppWidgetHostView
import android.util.AttributeSet
import android.view.*
import android.view.animation.AlphaAnimation
import android.view.animation.Animation
import android.view.animation.TranslateAnimation
import android.webkit.WebView
import android.webkit.WebViewClient
import android.widget.*
import android.widget.RemoteViews.RemoteView
import com.highcapable.yukireflection.factory.classOf
/**
* 获得 [View] 类型
* @return [Class]<[View]>
*/
val ViewClass get() = classOf<View>()
/**
* 获得 [Surface] 类型
* @return [Class]<[Surface]>
*/
val SurfaceClass get() = classOf<Surface>()
/**
* 获得 [SurfaceView] 类型
* @return [Class]<[SurfaceView]>
*/
val SurfaceViewClass get() = classOf<SurfaceView>()
/**
* 获得 [TextureView] 类型
* @return [Class]<[TextureView]>
*/
val TextureViewClass get() = classOf<TextureView>()
/**
* 获得 [WebView] 类型
* @return [Class]<[WebView]>
*/
val WebViewClass get() = classOf<WebView>()
/**
* 获得 [WebViewClient] 类型
* @return [Class]<[WebViewClient]>
*/
val WebViewClientClass get() = classOf<WebViewClient>()
/**
* 获得 [ViewStructure] 类型
* @return [Class]<[ViewStructure]>
*/
val ViewStructureClass get() = classOf<ViewStructure>()
/**
* 获得 [ViewGroup] 类型
* @return [Class]<[ViewGroup]>
*/
val ViewGroupClass get() = classOf<ViewGroup>()
/**
* 获得 [ViewParent] 类型
* @return [Class]<[ViewParent]>
*/
val ViewParentClass get() = classOf<ViewParent>()
/**
* 获得 [AppWidgetHostView] 类型
* @return [Class]<[AppWidgetHostView]>
*/
val AppWidgetHostViewClass get() = classOf<AppWidgetHostView>()
/**
* 获得 [RemoteViews] 类型
* @return [Class]<[RemoteViews]>
*/
val RemoteViewsClass get() = classOf<RemoteViews>()
/**
* 获得 [RemoteView] 类型
* @return [Class]<[RemoteView]>
*/
val RemoteViewClass get() = classOf<RemoteView>()
/**
* 获得 [TextView] 类型
* @return [Class]<[TextView]>
*/
val TextViewClass get() = classOf<TextView>()
/**
* 获得 [ImageView] 类型
* @return [Class]<[ImageView]>
*/
val ImageViewClass get() = classOf<ImageView>()
/**
* 获得 [ImageButton] 类型
* @return [Class]<[ImageButton]>
*/
val ImageButtonClass get() = classOf<ImageButton>()
/**
* 获得 [EditText] 类型
* @return [Class]<[EditText]>
*/
val EditTextClass get() = classOf<EditText>()
/**
* 获得 [Button] 类型
* @return [Class]<[Button]>
*/
val ButtonClass get() = classOf<Button>()
/**
* 获得 [CheckBox] 类型
* @return [Class]<[CheckBox]>
*/
val CheckBoxClass get() = classOf<CheckBox>()
/**
* 获得 [CompoundButton] 类型
* @return [Class]<[CompoundButton]>
*/
val CompoundButtonClass get() = classOf<CompoundButton>()
/**
* 获得 [VideoView] 类型
* @return [Class]<[VideoView]>
*/
val VideoViewClass get() = classOf<VideoView>()
/**
* 获得 [ListView] 类型
* @return [Class]<[ListView]>
*/
val ListViewClass get() = classOf<ListView>()
/**
* 获得 [LayoutInflater] 类型
* @return [Class]<[LayoutInflater]>
*/
val LayoutInflaterClass get() = classOf<LayoutInflater>()
/**
* 获得 [LayoutInflater.Filter] 类型
* @return [Class]<[LayoutInflater.Filter]>
*/
val LayoutInflater_FilterClass get() = classOf<LayoutInflater.Filter>()
/**
* 获得 [LayoutInflater.Factory] 类型
* @return [Class]<[LayoutInflater.Factory]>
*/
val LayoutInflater_FactoryClass get() = classOf<LayoutInflater.Factory>()
/**
* 获得 [LayoutInflater.Factory2] 类型
* @return [Class]<[LayoutInflater.Factory2]>
*/
val LayoutInflater_Factory2Class get() = classOf<LayoutInflater.Factory2>()
/**
* 获得 [ListAdapter] 类型
* @return [Class]<[ListAdapter]>
*/
val ListAdapterClass get() = classOf<ListAdapter>()
/**
* 获得 [ArrayAdapter] 类型
* @return [Class]<[ArrayAdapter]>
*/
val ArrayAdapterClass get() = classOf<ArrayAdapter<*>>()
/**
* 获得 [BaseAdapter] 类型
* @return [Class]<[BaseAdapter]>
*/
val BaseAdapterClass get() = classOf<BaseAdapter>()
/**
* 获得 [RelativeLayout] 类型
* @return [Class]<[RelativeLayout]>
*/
val RelativeLayoutClass get() = classOf<RelativeLayout>()
/**
* 获得 [FrameLayout] 类型
* @return [Class]<[FrameLayout]>
*/
val FrameLayoutClass get() = classOf<FrameLayout>()
/**
* 获得 [LinearLayout] 类型
* @return [Class]<[LinearLayout]>
*/
val LinearLayoutClass get() = classOf<LinearLayout>()
/**
* 获得 [ViewGroup.LayoutParams] 类型
* @return [Class]<[ViewGroup.LayoutParams]>
*/
val ViewGroup_LayoutParamsClass get() = classOf<ViewGroup.LayoutParams>()
/**
* 获得 [RelativeLayout.LayoutParams] 类型
* @return [Class]<[RelativeLayout.LayoutParams]>
*/
val RelativeLayout_LayoutParamsClass get() = classOf<RelativeLayout.LayoutParams>()
/**
* 获得 [LinearLayout.LayoutParams] 类型
* @return [Class]<[LinearLayout.LayoutParams]>
*/
val LinearLayout_LayoutParamsClass get() = classOf<LinearLayout.LayoutParams>()
/**
* 获得 [FrameLayout.LayoutParams] 类型
* @return [Class]<[FrameLayout.LayoutParams]>
*/
val FrameLayout_LayoutParamsClass get() = classOf<FrameLayout.LayoutParams>()
/**
* 获得 [TextClock] 类型
* @return [Class]<[TextClock]>
*/
val TextClockClass get() = classOf<TextClock>()
/**
* 获得 [MotionEvent] 类型
* @return [Class]<[MotionEvent]>
*/
val MotionEventClass get() = classOf<MotionEvent>()
/**
* 获得 [View.OnClickListener] 类型
* @return [Class]<[View.OnClickListener]>
*/
val View_OnClickListenerClass get() = classOf<View.OnClickListener>()
/**
* 获得 [View.OnLongClickListener] 类型
* @return [Class]<[View.OnLongClickListener]>
*/
val View_OnLongClickListenerClass get() = classOf<View.OnLongClickListener>()
/**
* 获得 [View.OnTouchListener] 类型
* @return [Class]<[View.OnTouchListener]>
*/
val View_OnTouchListenerClass get() = classOf<View.OnTouchListener>()
/**
* 获得 [AutoCompleteTextView] 类型
* @return [Class]<[AutoCompleteTextView]>
*/
val AutoCompleteTextViewClass get() = classOf<AutoCompleteTextView>()
/**
* 获得 [ViewStub] 类型
* @return [Class]<[ViewStub]>
*/
val ViewStubClass get() = classOf<ViewStub>()
/**
* 获得 [ViewStub.OnInflateListener] 类型
* @return [Class]<[ViewStub.OnInflateListener]>
*/
val ViewStub_OnInflateListenerClass get() = classOf<ViewStub.OnInflateListener>()
/**
* 获得 [GestureDetector] 类型
* @return [Class]<[GestureDetector]>
*/
val GestureDetectorClass get() = classOf<GestureDetector>()
/**
* 获得 [GestureDetector.SimpleOnGestureListener] 类型
* @return [Class]<[GestureDetector.SimpleOnGestureListener]>
*/
val GestureDetector_SimpleOnGestureListenerClass get() = classOf<GestureDetector.SimpleOnGestureListener>()
/**
* 获得 [ProgressBar] 类型
* @return [Class]<[ProgressBar]>
*/
val ProgressBarClass get() = classOf<ProgressBar>()
/**
* 获得 [AttributeSet] 类型
* @return [Class]<[AttributeSet]>
*/
val AttributeSetClass get() = classOf<AttributeSet>()
/**
* 获得 [Animation] 类型
* @return [Class]<[Animation]>
*/
val AnimationClass get() = classOf<Animation>()
/**
* 获得 [Animation.AnimationListener] 类型
* @return [Class]<[Animation.AnimationListener]>
*/
val Animation_AnimationListenerClass get() = classOf<Animation.AnimationListener>()
/**
* 获得 [TranslateAnimation] 类型
* @return [Class]<[TranslateAnimation]>
*/
val TranslateAnimationClass get() = classOf<TranslateAnimation>()
/**
* 获得 [AlphaAnimation] 类型
* @return [Class]<[AlphaAnimation]>
*/
val AlphaAnimationClass get() = classOf<AlphaAnimation>()
/**
* 获得 [Animator] 类型
* @return [Class]<[Animator]>
*/
val AnimatorClass get() = classOf<Animator>()
/**
* 获得 [Animator.AnimatorListener] 类型
* @return [Class]<[Animator.AnimatorListener]>
*/
val Animator_AnimatorListenerClass get() = classOf<Animator.AnimatorListener>()
/**
* 获得 [ObjectAnimator] 类型
* @return [Class]<[ObjectAnimator]>
*/
val ObjectAnimatorClass get() = classOf<ObjectAnimator>()
/**
* 获得 [ValueAnimator] 类型
* @return [Class]<[ValueAnimator]>
*/
val ValueAnimatorClass get() = classOf<ValueAnimator>()
/**
* 获得 [ValueAnimator.AnimatorUpdateListener] 类型
* @return [Class]<[ValueAnimator.AnimatorUpdateListener]>
*/
val ValueAnimator_AnimatorUpdateListenerClass get() = classOf<ValueAnimator.AnimatorUpdateListener>()
/**
* 获得 [ViewAnimator] 类型
* @return [Class]<[ViewAnimator]>
*/
val ViewAnimatorClass get() = classOf<ViewAnimator>()
/**
* 获得 [AnimatorSet] 类型
* @return [Class]<[AnimatorSet]>
*/
val AnimatorSetClass get() = classOf<AnimatorSet>()
/**
* 获得 [AnimatorSet.Builder] 类型
* @return [Class]<[AnimatorSet.Builder]>
*/
val AnimatorSet_BuilderClass get() = classOf<AnimatorSet.Builder>()
/**
* 获得 [PropertyValuesHolder] 类型
* @return [Class]<[PropertyValuesHolder]>
*/
val PropertyValuesHolderClass get() = classOf<PropertyValuesHolder>()
/**
* 获得 [ViewPropertyAnimator] 类型
* @return [Class]<[ViewPropertyAnimator]>
*/
val ViewPropertyAnimatorClass get() = classOf<ViewPropertyAnimator>()
/**
* 获得 [View.MeasureSpec] 类型
* @return [Class]<[View.MeasureSpec]>
*/
val View_MeasureSpecClass get() = classOf<View.MeasureSpec>()

View File

@@ -0,0 +1,57 @@
/*
* YukiReflection - An efficient Reflection API for Java and Android built in Kotlin
* Copyright (C) 2019-2023 HighCapable
* https://github.com/fankes/YukiReflection
*
* 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/4/3.
* This file is Modified by fankes on 2023/1/21.
*/
package com.highcapable.yukireflection.type.defined
import com.highcapable.yukireflection.factory.classOf
/**
* 未定义类型实例
*
* 请使用 [UndefinedType] 来调用它
*/
internal class UndefinedClass private constructor()
/**
* 模糊类型实例
*
* 请使用 [VagueType] 来调用它
*/
class VagueClass private constructor()
/**
* 得到未定义类型
* @return [Class]<[UndefinedClass]>
*/
internal val UndefinedType get() = classOf<UndefinedClass>()
/**
* 得到模糊类型
* @return [Class]<[VagueClass]>
*/
val VagueType get() = classOf<VagueClass>()

View File

@@ -0,0 +1,835 @@
/*
* YukiReflection - An efficient Reflection API for Java and Android built in Kotlin
* Copyright (C) 2019-2023 HighCapable
* https://github.com/fankes/YukiReflection
*
* 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/2/2.
* This file is Modified by fankes on 2023/1/21.
*/
@file:Suppress("unused", "KDocUnresolvedReference", "DEPRECATION", "FunctionName", "UNCHECKED_CAST")
package com.highcapable.yukireflection.type.java
import android.os.Build
import com.highcapable.yukireflection.factory.classOf
import com.highcapable.yukireflection.factory.toClass
import com.highcapable.yukireflection.factory.toClassOrNull
import dalvik.system.BaseDexClassLoader
import dalvik.system.DexClassLoader
import dalvik.system.InMemoryDexClassLoader
import dalvik.system.PathClassLoader
import org.json.JSONArray
import org.json.JSONObject
import java.io.*
import java.lang.ref.Reference
import java.lang.ref.WeakReference
import java.lang.reflect.Constructor
import java.lang.reflect.Field
import java.lang.reflect.Member
import java.lang.reflect.Method
import java.net.HttpCookie
import java.net.HttpURLConnection
import java.text.SimpleDateFormat
import java.util.*
import java.util.concurrent.atomic.AtomicBoolean
import java.util.function.Supplier
import java.util.zip.ZipEntry
import java.util.zip.ZipFile
import java.util.zip.ZipInputStream
import java.util.zip.ZipOutputStream
import java.lang.reflect.Array as JavaArray
import java.util.function.Function as JavaFunction
/**
* 获得任意类型的数组
*
* 它在 Java 中表示为:([type])[]
* @param type 类型
* @return [Class]<[JavaArray]>
*/
fun ArrayClass(type: Class<*>) = JavaArray.newInstance(type, 0).javaClass as Class<JavaArray>
/**
* 获得 [Boolean] 类型
*
* 这是 Java 原始类型 (Primitive Type) - 它在字节码中的关键字为 "boolean"
* @return [Class]
*/
val BooleanType get() = Boolean::class.javaPrimitiveType ?: "boolean".toClass()
/**
* 获得 [Char] 类型
*
* 这是 Java 原始类型 (Primitive Type) - 它在字节码中的关键字为 "char"
* @return [Class]
*/
val CharType get() = Char::class.javaPrimitiveType ?: "char".toClass()
/**
* 获得 [Byte] 类型
*
* 这是 Java 原始类型 (Primitive Type) - 它在字节码中的关键字为 "byte"
* @return [Class]
*/
val ByteType get() = Byte::class.javaPrimitiveType ?: "byte".toClass()
/**
* 获得 [Short] 类型
*
* 这是 Java 原始类型 (Primitive Type) - 它在字节码中的关键字为 "short"
* @return [Class]
*/
val ShortType get() = Short::class.javaPrimitiveType ?: "short".toClass()
/**
* 获得 [Int] 类型
*
* 这是 Java 原始类型 (Primitive Type) - 它在字节码中的关键字为 "int"
* @return [Class]
*/
val IntType get() = Int::class.javaPrimitiveType ?: "int".toClass()
/**
* 获得 [Float] 类型
*
* 这是 Java 原始类型 (Primitive Type) - 它在字节码中的关键字为 "float"
* @return [Class]
*/
val FloatType get() = Float::class.javaPrimitiveType ?: "float".toClass()
/**
* 获得 [Long] 类型
*
* 这是 Java 原始类型 (Primitive Type) - 它在字节码中的关键字为 "long"
* @return [Class]
*/
val LongType get() = Long::class.javaPrimitiveType ?: "long".toClass()
/**
* 获得 [Double] 类型
*
* 这是 Java 原始类型 (Primitive Type) - 它在字节码中的关键字为 "double"
* @return [Class]
*/
val DoubleType get() = Double::class.javaPrimitiveType ?: "double".toClass()
/**
* 获得 [Unit] 类型
*
* 这是 Java 原始类型 (Primitive Type) - 它在字节码中的关键字为 "void"
* @return [Class]
*/
val UnitType get() = Void.TYPE ?: "void".toClass()
/**
* 获得 [Any] 类型
*
* 它等价于 Java 中的 [java.lang.Object]
* @return [Class]<[Any]>
*/
val AnyClass get() = classOf<Any>()
/**
* 获得 [Boolean] 类型
*
* 它等价于 Java 中的 [java.lang.Boolean]
* @return [Class]<[Boolean]>
*/
val BooleanClass get() = classOf<Boolean>()
/**
* 获得 [Char] 类型
*
* 它等价于 Java 中的 [java.lang.Character]
* @return [Class]<[Char]>
*/
val CharClass get() = classOf<Char>()
/**
* 获得 [Byte] 类型
*
* 它等价于 Java 中的 [java.lang.Byte]
* @return [Class]<[Byte]>
*/
val ByteClass get() = classOf<Byte>()
/**
* 获得 [Short] 类型
*
* 它等价于 Java 中的 [java.lang.Short]
* @return [Class]<[Short]>
*/
val ShortClass get() = classOf<Short>()
/**
* 获得 [Int] 类型
*
* 它等价于 Java 中的 [java.lang.Integer]
* @return [Class]<[Int]>
*/
val IntClass get() = classOf<Int>()
/**
* 获得 [Float] 类型
*
* 它等价于 Java 中的 [java.lang.Float]
* @return [Class]<[Float]>
*/
val FloatClass get() = classOf<Float>()
/**
* 获得 [Long] 类型
*
* 它等价于 Java 中的 [java.lang.Long]
* @return [Class]<[Long]>
*/
val LongClass get() = classOf<Long>()
/**
* 获得 [Double] 类型
*
* 它等价于 Java 中的 [java.lang.Double]
* @return [Class]<[Double]>
*/
val DoubleClass get() = classOf<Double>()
/**
* 获得 [Number] 类型
*
* 它等价于 Java 中的 [java.lang.Number]
* @return [Class]<[Number]>
*/
val NumberClass get() = classOf<Number>()
/**
* 获得 [Unit] 类型
*
* 它等价于 Java 中的 [java.lang.Void]
* @return [Class]<[Void]>
*/
val UnitClass get() = classOf<Void>()
/**
* 获得 [String] 类型
*
* 它等价于 Java 中的 [java.lang.String]
* @return [Class]<[String]>
*/
val StringClass get() = classOf<String>()
/**
* 获得 [CharSequence] 类型
*
* 它等价于 Java 中的 [java.lang.CharSequence]
* @return [Class]<[CharSequence]>
*/
val CharSequenceClass get() = classOf<CharSequence>()
/**
* 获得 [Serializable] 类型
* @return [Class]<[Serializable]>
*/
val SerializableClass get() = classOf<Serializable>()
/**
* 获得 [Array] 类型
*
* 它等价于 Java 中的 [java.lang.reflect.Array]
* @return [Class]<[JavaArray]>
*/
val ArrayClass get() = classOf<JavaArray>()
/**
* 获得 [Boolean] - [Array] 类型
*
* 这是 Java 原始类型 (Primitive Type) 数组 - 它在字节码中的关键字为 "boolean[]"
* @return [Class]<[JavaArray]>
*/
val BooleanArrayType get() = ArrayClass(BooleanType)
/**
* 获得 [Char] - [Array] 类型
*
* 这是 Java 原始类型 (Primitive Type) 数组 - 它在字节码中的关键字为 "char[]"
* @return [Class]<[JavaArray]>
*/
val CharArrayType get() = ArrayClass(CharType)
/**
* 获得 [Byte] - [Array] 类型
*
* 这是 Java 原始类型 (Primitive Type) 数组 - 它在字节码中的关键字为 "byte[]"
* @return [Class]<[JavaArray]>
*/
val ByteArrayType get() = ArrayClass(ByteType)
/**
* 获得 [Short] - [Array] 类型
*
* 这是 Java 原始类型 (Primitive Type) 数组 - 它在字节码中的关键字为 "short[]"
* @return [Class]<[JavaArray]>
*/
val ShortArrayType get() = ArrayClass(ShortType)
/**
* 获得 [Short] - [Array] 类型
*
* - ❗此方法已弃用 - 在之后的版本中将直接被删除
*
* - ❗请现在转移到 [ShortArrayType]
* @return [Class]<[JavaArray]>
*/
@Deprecated(message = "请使用修复后的命名方法", ReplaceWith("ShortArrayType"))
val ShortArraytType get() = ShortArrayType
/**
* 获得 [Int] - [Array] 类型
*
* 这是 Java 原始类型 (Primitive Type) 数组 - 它在字节码中的关键字为 "int[]"
* @return [Class]<[JavaArray]>
*/
val IntArrayType get() = ArrayClass(IntType)
/**
* 获得 [Float] - [Array] 类型
*
* 这是 Java 原始类型 (Primitive Type) 数组 - 它在字节码中的关键字为 "float[]"
* @return [Class]<[JavaArray]>
*/
val FloatArrayType get() = ArrayClass(FloatType)
/**
* 获得 [Long] - [Array] 类型
*
* 这是 Java 原始类型 (Primitive Type) 数组 - 它在字节码中的关键字为 "long[]"
* @return [Class]<[JavaArray]>
*/
val LongArrayType get() = ArrayClass(LongType)
/**
* 获得 [Double] - [Array] 类型
*
* 这是 Java 原始类型 (Primitive Type) 数组 - 它在字节码中的关键字为 "double[]"
* @return [Class]<[JavaArray]>
*/
val DoubleArrayType get() = ArrayClass(DoubleType)
/**
* 获得 [Any] - [Array] 类型
*
* 它在 Java 中表示为Object[]
* @return [Class]<[JavaArray]>
*/
val AnyArrayClass get() = ArrayClass(AnyClass)
/**
* 获得 [Boolean] - [Array] 类型
*
* 它在 Java 中表示为Boolean[]
* @return [Class]<[JavaArray]>
*/
val BooleanArrayClass get() = ArrayClass(BooleanClass)
/**
* 获得 [Char] - [Array] 类型
*
* 它在 Java 中表示为Character[]
* @return [Class]<[JavaArray]>
*/
val CharArrayClass get() = ArrayClass(CharClass)
/**
* 获得 [Byte] - [Array] 类型
*
* 它在 Java 中表示为Byte[]
* @return [Class]<[JavaArray]>
*/
val ByteArrayClass get() = ArrayClass(ByteClass)
/**
* 获得 [Short] - [Array] 类型
*
* 它在 Java 中表示为Short[]
* @return [Class]<[JavaArray]>
*/
val ShortArrayClass get() = ArrayClass(ShortClass)
/**
* 获得 [Int] - [Array] 类型
*
* 它在 Java 中表示为Integer[]
* @return [Class]<[JavaArray]>
*/
val IntArrayClass get() = ArrayClass(IntClass)
/**
* 获得 [Float] - [Array] 类型
*
* 它在 Java 中表示为Float[]
* @return [Class]<[JavaArray]>
*/
val FloatArrayClass get() = ArrayClass(FloatClass)
/**
* 获得 [Long] - [Array] 类型
*
* 它在 Java 中表示为Long[]
* @return [Class]<[JavaArray]>
*/
val LongArrayClass get() = ArrayClass(LongClass)
/**
* 获得 [Double] - [Array] 类型
*
* 它在 Java 中表示为Double[]
* @return [Class]<[JavaArray]>
*/
val DoubleArrayClass get() = ArrayClass(DoubleClass)
/**
* 获得 [Number] - [Array] 类型
*
* 它在 Java 中表示为Number[]
* @return [Class]<[JavaArray]>
*/
val NumberArrayClass get() = ArrayClass(NumberClass)
/**
* 获得 [String] - [Array] 类型
*
* 它在 Java 中表示为String[]
* @return [Class]<[JavaArray]>
*/
val StringArrayClass get() = ArrayClass(StringClass)
/**
* 获得 [CharSequence] - [Array] 类型
*
* 它在 Java 中表示为CharSequence[]
* @return [Class]<[JavaArray]>
*/
val CharSequenceArrayClass get() = ArrayClass(CharSequenceClass)
/**
* 获得 [Cloneable] 类型
* @return [Class]<[Cloneable]>
*/
val CloneableClass get() = classOf<Cloneable>()
/**
* 获得 [List] 类型
* @return [Class]<[List]>
*/
val ListClass get() = classOf<List<*>>()
/**
* 获得 [ArrayList] 类型
* @return [Class]<[ArrayList]>
*/
val ArrayListClass get() = classOf<ArrayList<*>>()
/**
* 获得 [HashMap] 类型
* @return [Class]<[HashMap]>
*/
val HashMapClass get() = classOf<HashMap<*, *>>()
/**
* 获得 [HashSet] 类型
* @return [Class]<[HashSet]>
*/
val HashSetClass get() = classOf<HashSet<*>>()
/**
* 获得 [WeakHashMap] 类型
* @return [Class]<[WeakHashMap]>
*/
val WeakHashMapClass get() = classOf<WeakHashMap<*, *>>()
/**
* 获得 [WeakReference] 类型
* @return [Class]<[WeakReference]>
*/
val WeakReferenceClass get() = classOf<WeakReference<*>>()
/**
* 获得 [Enum] 类型
* @return [Class]<[Enum]>
*/
val EnumClass get() = classOf<Enum<*>>()
/**
* 获得 [Map] 类型
* @return [Class]<[Map]>
*/
val MapClass get() = classOf<Map<*, *>>()
/**
* 获得 [Map.Entry] 类型
* @return [Class]<[Map.Entry]>
*/
val Map_EntryClass get() = classOf<Map.Entry<*, *>>()
/**
* 获得 [Reference] 类型
* @return [Class]<[Reference]>
*/
val ReferenceClass get() = classOf<Reference<*>>()
/**
* 获得 [Vector] 类型
* @return [Class]<[Vector]>
*/
val VectorClass get() = classOf<Vector<*>>()
/**
* 获得 [File] 类型
* @return [Class]<[File]>
*/
val FileClass get() = classOf<File>()
/**
* 获得 [InputStream] 类型
* @return [Class]<[InputStream]>
*/
val InputStreamClass get() = classOf<InputStream>()
/**
* 获得 [OutputStream] 类型
* @return [Class]<[OutputStream]>
*/
val OutputStreamClass get() = classOf<OutputStream>()
/**
* 获得 [BufferedReader] 类型
* @return [Class]<[BufferedReader]>
*/
val BufferedReaderClass get() = classOf<BufferedReader>()
/**
* 获得 [Date] 类型
* @return [Class]<[Date]>
*/
val DateClass get() = classOf<Date>()
/**
* 获得 [TimeZone] 类型
* @return [Class]<[TimeZone]>
*/
val TimeZoneClass get() = classOf<TimeZone>()
/**
* 获得 [SimpleDateFormat] 类型
* @return [Class]<[SimpleDateFormat]>
*/
val SimpleDateFormatClass_Java get() = classOf<SimpleDateFormat>()
/**
* 获得 [Timer] 类型
* @return [Class]<[Timer]>
*/
val TimerClass get() = classOf<Timer>()
/**
* 获得 [TimerTask] 类型
* @return [Class]<[TimerTask]>
*/
val TimerTaskClass get() = classOf<TimerTask>()
/**
* 获得 [Thread] 类型
* @return [Class]<[Thread]>
*/
val ThreadClass get() = classOf<Thread>()
/**
* 获得 [Base64] 类型
*
* - ❗在 Android O (26) 及以上系统加入
* @return [Class]<[Base64]> or null
*/
val Base64Class_Java get() = if (Build.VERSION.SDK_INT >= 26) classOf<Base64>() else null
/**
* 获得 [Observer] 类型
* @return [Class]<[Observer]>
*/
val ObserverClass get() = classOf<Observer>()
/**
* 获得 [Set] 类型
* @return [Class]<[Set]>
*/
val SetClass get() = classOf<Set<*>>()
/**
* 获得 [JSONObject] 类型
* @return [Class]<[JSONObject]>
*/
val JSONObjectClass get() = classOf<JSONObject>()
/**
* 获得 [JSONArray] 类型
* @return [Class]<[JSONArray]>
*/
val JSONArrayClass get() = classOf<JSONArray>()
/**
* 获得 [StringBuilder] 类型
* @return [Class]<[StringBuilder]>
*/
val StringBuilderClass get() = classOf<StringBuilder>()
/**
* 获得 [StringBuffer] 类型
* @return [Class]<[StringBuffer]>
*/
val StringBufferClass get() = classOf<StringBuffer>()
/**
* 获得 [ZipEntry] 类型
* @return [Class]<[ZipEntry]>
*/
val ZipEntryClass get() = classOf<ZipEntry>()
/**
* 获得 [ZipFile] 类型
* @return [Class]<[ZipFile]>
*/
val ZipFileClass get() = classOf<ZipFile>()
/**
* 获得 [ZipInputStream] 类型
* @return [Class]<[ZipInputStream]>
*/
val ZipInputStreamClass get() = classOf<ZipInputStream>()
/**
* 获得 [ZipOutputStream] 类型
* @return [Class]<[ZipOutputStream]>
*/
val ZipOutputStreamClass get() = classOf<ZipOutputStream>()
/**
* 获得 [HttpURLConnection] 类型
* @return [Class]<[HttpURLConnection]>
*/
val HttpURLConnectionClass get() = classOf<HttpURLConnection>()
/**
* 获得 [HttpCookie] 类型
* @return [Class]<[HttpCookie]>
*/
val HttpCookieClass get() = classOf<HttpCookie>()
/**
* 获得 [HttpClient] 类型
* @return [Class] or null
*/
val HttpClientClass get() = "java.net.http.HttpClient".toClassOrNull()
/**
* 获得 [AtomicBoolean] 类型
* @return [Class]<[AtomicBoolean]>
*/
val AtomicBooleanClass get() = classOf<AtomicBoolean>()
/**
* 获得 [Supplier] 类型
* @return [Class]<[Supplier]>
*/
val SupplierClass get() = classOf<Supplier<*>>()
/**
* 获得 [Class] 类型
* @return [Class]<[Class]>
*/
val JavaClass get() = classOf<Class<*>>()
/**
* 获得 [ClassLoader] 类型
* @return [Class]<[ClassLoader]>
*/
val JavaClassLoader get() = classOf<ClassLoader>()
/**
* 获得 [BaseDexClassLoader] 类型
* @return [Class]<[BaseDexClassLoader]>
*/
val DalvikBaseDexClassLoader get() = classOf<BaseDexClassLoader>()
/**
* 获得 [DexClassLoader] 类型
* @return [Class]<[DexClassLoader]>
*/
val DalvikDexClassLoader get() = classOf<DexClassLoader>()
/**
* 获得 [PathClassLoader] 类型
* @return [Class]<[PathClassLoader]>
*/
val DalvikPathClassLoader get() = classOf<PathClassLoader>()
/**
* 获得 [InMemoryDexClassLoader] 类型
* @return [Class]<[InMemoryDexClassLoader]>
*/
val DalvikInMemoryDexClassLoader get() = classOf<InMemoryDexClassLoader>()
/**
* 获得 [Method] 类型
* @return [Class]<[Method]>
*/
val JavaMethodClass get() = classOf<Method>()
/**
* 获得 [Field] 类型
* @return [Class]<[Field]>
*/
val JavaFieldClass get() = classOf<Field>()
/**
* 获得 [Constructor] 类型
* @return [Class]<[Constructor]>
*/
val JavaConstructorClass get() = classOf<Constructor<*>>()
/**
* 获得 [Member] 类型
* @return [Class]<[Member]>
*/
val JavaMemberClass get() = classOf<Member>()
/**
* 获得 [Annotation] 类型
* @return [Class]<[Annotation]>
*/
val JavaAnnotationClass get() = classOf<Annotation>()
/**
* 获得 [java.util.function.Function] 类型
* @return [Class]<[JavaFunction]>
*/
val FunctionClass get() = classOf<JavaFunction<*, *>>()
/**
* 获得 [Optional] 类型
* @return [Class]<[Optional]>
*/
val OptionalClass get() = classOf<Optional<*>>()
/**
* 获得 [OptionalInt] 类型
* @return [Class]<[OptionalInt]>
*/
val OptionalIntClass get() = classOf<OptionalInt>()
/**
* 获得 [OptionalLong] 类型
* @return [Class]<[OptionalLong]>
*/
val OptionalLongClass get() = classOf<OptionalLong>()
/**
* 获得 [OptionalDouble] 类型
* @return [Class]<[OptionalDouble]>
*/
val OptionalDoubleClass get() = classOf<OptionalDouble>()
/**
* 获得 [Objects] 类型
* @return [Class]<[Objects]>
*/
val ObjectsClass get() = classOf<Objects>()
/**
* 获得 [Runtime] 类型
* @return [Class]<[Runtime]>
*/
val RuntimeClass get() = classOf<Runtime>()
/**
* 获得 [NullPointerException] 类型
* @return [Class]<[NullPointerException]>
*/
val NullPointerExceptionClass get() = classOf<NullPointerException>()
/**
* 获得 [NumberFormatException] 类型
* @return [Class]<[NumberFormatException]>
*/
val NumberFormatExceptionClass get() = classOf<NumberFormatException>()
/**
* 获得 [IllegalStateException] 类型
* @return [Class]<[IllegalStateException]>
*/
val IllegalStateExceptionClass get() = classOf<IllegalStateException>()
/**
* 获得 [RuntimeException] 类型
* @return [Class]<[RuntimeException]>
*/
val RuntimeExceptionClass get() = classOf<RuntimeException>()
/**
* 获得 [ClassNotFoundException] 类型
* @return [Class]<[ClassNotFoundException]>
*/
val ClassNotFoundExceptionClass get() = classOf<ClassNotFoundException>()
/**
* 获得 [NoClassDefFoundError] 类型
* @return [Class]<[NoClassDefFoundError]>
*/
val NoClassDefFoundErrorClass get() = classOf<NoClassDefFoundError>()
/**
* 获得 [NoSuchMethodError] 类型
* @return [Class]<[NoSuchMethodError]>
*/
val NoSuchMethodErrorClass get() = classOf<NoSuchMethodError>()
/**
* 获得 [NoSuchFieldError] 类型
* @return [Class]<[NoSuchFieldError]>
*/
val NoSuchFieldErrorClass get() = classOf<NoSuchFieldError>()
/**
* 获得 [Error] 类型
* @return [Class]<[Error]>
*/
val ErrorClass get() = classOf<Error>()
/**
* 获得 [Exception] 类型
* @return [Class]<[Exception]>
*/
val ExceptionClass get() = classOf<Exception>()
/**
* 获得 [Throwable] 类型
* @return [Class]<[Throwable]>
*/
val ThrowableClass get() = classOf<Throwable>()

View File

@@ -0,0 +1,253 @@
/*
* YukiReflection - An efficient Reflection API for Java and Android built in Kotlin
* Copyright (C) 2019-2023 HighCapable
* https://github.com/fankes/YukiReflection
*
* 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/2/5.
* This file is Modified by fankes on 2023/1/21.
*/
@file:Suppress("unused")
package com.highcapable.yukireflection.utils
import java.io.ByteArrayOutputStream
import java.io.PrintStream
import java.util.concurrent.ExecutorService
import java.util.concurrent.Executors
/**
* 创建当前线程池服务
* @return [ExecutorService]
*/
private val currentThreadPool get() = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors())
/**
* 对 [T] 返回无返回值的 [Unit]
* @return [Unit]
*/
internal fun <T> T?.unit() = let {}
/**
* 启动 [Thread] 延迟等待 [block] 的结果 [T]
* @param delayMs 延迟毫秒 - 默认 1 ms
* @param block 方法块
* @return [T]
*/
internal inline fun <T> T.await(delayMs: Long = 1, crossinline block: (T) -> Unit): T {
currentThreadPool.apply {
execute {
if (delayMs > 0) Thread.sleep(delayMs)
block(this@await)
shutdown()
}
}
return this
}
/**
* 获取数组内容依次列出的字符串表示
* @return [String]
*/
internal inline fun <reified T> Array<out T>.value() = if (isNotEmpty()) {
var value = ""
forEach { value += it.toString() + ", " }
"[${value.trim().let { it.substring(0, it.lastIndex) }}]"
} else "[]"
/**
* 通过 [conditions] 查找符合条件的最后一个元素的下标
* @return [Int] 没有找到符合条件的下标将返回 -1
*/
internal inline fun <reified T> Sequence<T>.findLastIndex(conditions: (T) -> Boolean) =
withIndex().findLast { conditions(it.value) }?.index ?: -1
/**
* 返回最后一个元素的下标
* @return [Int] 如果 [Sequence] 为空将返回 -1
*/
internal inline fun <reified T> Sequence<T>.lastIndex() = foldIndexed(-1) { index, _, _ -> index }.takeIf { it >= 0 } ?: -1
/**
* 满足条件判断方法体 - 对 [kotlin.takeIf] 进行封装
* @param other 需要满足不为空的对象 - 仅用于判断是否为 null
* @param predicate 原始方法体
* @return [T] or null
*/
internal inline fun <T> T.takeIf(other: Any?, predicate: (T) -> Boolean) = if (other != null) takeIf(predicate) else null
/**
* 满足条件返回值 - 对 [kotlin.let] 进行封装
* @param other 需要满足不为空的对象 - 仅用于判断是否为 null
* @param block 原始方法体
* @return [R] or null
*/
internal inline fun <T, R> T.let(other: Any?, block: (T) -> R) = if (other != null) let(block) else null
/**
* 条件判断方法体捕获异常返回 true
* @param block 原始方法体
* @return [Boolean]
*/
internal inline fun runOrTrue(block: () -> Boolean) = runCatching { block() }.getOrNull() ?: true
/**
* 条件判断方法体捕获异常返回 false
* @param block 原始方法体
* @return [Boolean]
*/
internal inline fun runOrFalse(block: () -> Boolean) = runCatching { block() }.getOrNull() ?: false
/**
* 获取完整的异常堆栈内容
* @return [String]
*/
internal fun Throwable.toStackTrace() = ByteArrayOutputStream().also { printStackTrace(PrintStream(it)) }.toString()
/**
* 计算方法执行耗时
* @param block 方法块
* @return [RunBlockResult]
*/
internal inline fun <R> runBlocking(block: () -> R): RunBlockResult {
val start = System.currentTimeMillis()
block()
return RunBlockResult(afterMs = System.currentTimeMillis() - start)
}
/**
* 构造耗时计算结果类
* @param afterMs 耗时
*/
internal class RunBlockResult(internal val afterMs: Long) {
/**
* 获取耗时计算结果
* @param result 回调结果 - ([Long] 耗时)
*/
internal inline fun result(result: (Long) -> Unit) = result(afterMs)
}
/**
* 创建多项条件判断 - 条件对象 [T]
* @param initiate 方法体
* @return [Conditions.Result]
*/
internal inline fun <T> T.conditions(initiate: Conditions<T>.() -> Unit) = Conditions(value = this).apply(initiate).build()
/**
* 构造条件判断类
* @param value 当前条件对象
*/
internal class Conditions<T>(internal var value: T) {
/** 全部判断条件数组 (与) */
private val andConditions = ArrayList<Boolean>()
/** 全部判断条件数组 (或) */
private val optConditions = ArrayList<Boolean>()
/**
* 添加与 (and) 条件
* @param value 条件值
*/
internal fun and(value: Boolean) {
andConditions.add(value)
}
/**
* 添加或 (or) 条件
* @param value 条件值
*/
internal fun opt(value: Boolean) {
optConditions.add(value)
}
/**
* 结束方法体
* @return [Result]
*/
internal fun build() = Result()
/**
* 构造条件判断结果类
*/
inner class Result internal constructor() {
/**
* 获取条件判断结果
* @return [Boolean]
*/
private val result by lazy {
optConditions.takeIf { it.isNotEmpty() }?.any { it } == true ||
andConditions.takeIf { it.isNotEmpty() }?.any { it.not() }?.not() == true
}
/**
* 当条件成立
* @param callback 回调
*/
internal inline fun finally(callback: () -> Unit): Result {
if (result) callback()
return this
}
/**
* 当条件不成立
* @param callback 回调
*/
internal inline fun without(callback: () -> Unit): Result {
if (result.not()) callback()
return this
}
}
}
/**
* 获取 [ModifyValue] 对象
* @return [ModifyValue]
*/
internal fun <T> T.value() = ModifyValue(value = this)
/**
* 可修改变量实现类
* @param value 变量自身实例
*/
internal data class ModifyValue<T>(var value: T)
/**
* 随机种子工具类
*/
internal object RandomSeed {
/** 随机字母和数字定义 */
private const val RANDOM_LETTERS_NUMBERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
/**
* 生成随机字符串
* @param length 生成长度 - 默认 15
* @return [String]
*/
internal fun createString(length: Int = 15) = StringBuilder().apply {
for (i in 1..length) append(RANDOM_LETTERS_NUMBERS[(0..RANDOM_LETTERS_NUMBERS.lastIndex).random()])
}.toString()
}