mirror of
https://github.com/tursom/TursomServer.git
synced 2025-02-08 02:30:36 +08:00
add reflect utils
This commit is contained in:
parent
1cbc2a0c12
commit
7f462da93e
@ -0,0 +1,96 @@
|
||||
@file:Suppress("unused")
|
||||
|
||||
package cn.tursom.core.reflect
|
||||
|
||||
import cn.tursom.core.uncheckedCast
|
||||
import java.lang.reflect.Method
|
||||
|
||||
inline fun <R> Class<*>.getStaticDeclaredMethod(
|
||||
returnType: Class<*>,
|
||||
getMethod: Class<*>.() -> Method?,
|
||||
staticReturn: (method: Method) -> R,
|
||||
): R? {
|
||||
val method = getStaticDeclaredMethod(returnType, false, getMethod)
|
||||
if (method != null) return staticReturn(method)
|
||||
return null
|
||||
}
|
||||
|
||||
inline fun <reified R : Any> Any.getMethod(
|
||||
name: String,
|
||||
clazz: Class<*> = javaClass,
|
||||
returnType: Class<R> = R::class.java,
|
||||
getMethod: Class<*>.() -> Method? = { getMethodFully(name) },
|
||||
): (() -> R)? = clazz.getStaticDeclaredMethod(returnType, getMethod) { method ->
|
||||
{ method(this).uncheckedCast() }
|
||||
} ?: clazz.getStaticDeclaredMethod(name, returnType, getMethod)
|
||||
|
||||
inline fun <reified R : Any, reified T1> Any.getMethod1(
|
||||
name: String,
|
||||
returnType: Class<R> = R::class.java,
|
||||
arg1Type: Class<T1> = T1::class.java,
|
||||
clazz: Class<*> = javaClass,
|
||||
getMethod: Class<*>.() -> Method? = {
|
||||
getMethodFully(name, arg1Type)
|
||||
},
|
||||
): ((T1) -> R)? = clazz.getStaticDeclaredMethod(returnType, getMethod) { method ->
|
||||
{ method(this, it).uncheckedCast() }
|
||||
} ?: clazz.getStaticDeclaredMethod1(name, returnType, arg1Type, getMethod)
|
||||
|
||||
inline fun <reified R : Any, reified T1, reified T2> Any.getMethod2(
|
||||
name: String,
|
||||
returnType: Class<R> = R::class.java,
|
||||
arg1Type: Class<T1> = T1::class.java,
|
||||
arg2Type: Class<T2> = T2::class.java,
|
||||
clazz: Class<*> = javaClass,
|
||||
getMethod: Class<*>.() -> Method? = {
|
||||
getMethodFully(name, arg1Type, arg2Type)
|
||||
},
|
||||
): ((T1, T2) -> R)? = clazz.getStaticDeclaredMethod(returnType, getMethod) { method ->
|
||||
{ v1, v2 -> method(this, v1, v2).uncheckedCast() }
|
||||
} ?: clazz.getStaticDeclaredMethod2(name, returnType, arg1Type, arg2Type, getMethod)
|
||||
|
||||
inline fun <reified R : Any, reified T1, reified T2, reified T3> Any.getMethod3(
|
||||
name: String,
|
||||
returnType: Class<R> = R::class.java,
|
||||
arg1Type: Class<T1> = T1::class.java,
|
||||
arg2Type: Class<T2> = T2::class.java,
|
||||
arg3Type: Class<T3> = T3::class.java,
|
||||
clazz: Class<*> = javaClass,
|
||||
getMethod: Class<*>.() -> Method? = {
|
||||
getMethodFully(name, arg1Type, arg2Type, arg3Type)
|
||||
},
|
||||
): ((T1, T2, T3) -> R)? = clazz.getStaticDeclaredMethod(returnType, getMethod) { method ->
|
||||
{ v1, v2, v3 -> method(this, v1, v2, v3).uncheckedCast() }
|
||||
} ?: clazz.getStaticDeclaredMethod3(name, returnType, arg1Type, arg2Type, arg3Type, getMethod)
|
||||
|
||||
inline fun <reified R : Any, reified T1, reified T2, reified T3, reified T4> Any.getMethod4(
|
||||
name: String,
|
||||
returnType: Class<R> = R::class.java,
|
||||
arg1Type: Class<T1> = T1::class.java,
|
||||
arg2Type: Class<T2> = T2::class.java,
|
||||
arg3Type: Class<T3> = T3::class.java,
|
||||
arg4Type: Class<T4> = T4::class.java,
|
||||
clazz: Class<*> = javaClass,
|
||||
getMethod: Class<*>.() -> Method? = {
|
||||
getMethodFully(name, arg1Type, arg2Type, arg3Type, arg4Type)
|
||||
},
|
||||
): ((T1, T2, T3, T4) -> R)? = clazz.getStaticDeclaredMethod(returnType, getMethod) { method ->
|
||||
{ v1, v2, v3, v4 -> method(this, v1, v2, v3, v4).uncheckedCast() }
|
||||
} ?: clazz.getStaticDeclaredMethod4(name, returnType, arg1Type, arg2Type, arg3Type, arg4Type, getMethod)
|
||||
|
||||
inline fun <reified R, reified T1, reified T2, reified T3, reified T4, reified T5> Any.getMethod5(
|
||||
name: String,
|
||||
returnType: Class<R> = R::class.java,
|
||||
arg1Type: Class<T1> = T1::class.java,
|
||||
arg2Type: Class<T2> = T2::class.java,
|
||||
arg3Type: Class<T3> = T3::class.java,
|
||||
arg4Type: Class<T4> = T4::class.java,
|
||||
arg5Type: Class<T5> = T5::class.java,
|
||||
clazz: Class<*> = javaClass,
|
||||
getMethod: Class<*>.() -> Method? = {
|
||||
getMethodFully(name, arg1Type, arg2Type, arg3Type, arg4Type, arg5Type)
|
||||
},
|
||||
): ((T1, T2, T3, T4, T5) -> R)? = clazz.getStaticDeclaredMethod(returnType, getMethod) { method ->
|
||||
{ v1, v2, v3, v4, v5 -> method(this, v1, v2, v3, v4, v5).uncheckedCast() }
|
||||
} ?: clazz.getStaticDeclaredMethod5(name, returnType, arg1Type, arg2Type, arg3Type, arg4Type, arg5Type, getMethod)
|
||||
|
@ -0,0 +1,76 @@
|
||||
@file:Suppress("unused")
|
||||
|
||||
package cn.tursom.core.reflect
|
||||
|
||||
import cn.tursom.core.uncheckedCast
|
||||
import java.lang.reflect.Method
|
||||
|
||||
inline fun <This, reified R> Class<*>.getMethod(
|
||||
name: String,
|
||||
returnType: Class<out R> = R::class.java,
|
||||
getMethod: Class<*>.() -> Method? = { getMethodFully(name) },
|
||||
): (This.() -> R)? = getStaticDeclaredMethod(returnType, getMethod) { method ->
|
||||
{ method(this).uncheckedCast() }
|
||||
}
|
||||
|
||||
inline fun <This, reified R, reified T1> Class<*>.getMethod1(
|
||||
name: String,
|
||||
returnType: Class<out R> = R::class.java,
|
||||
arg1Type: Class<in T1> = T1::class.java,
|
||||
getMethod: Class<*>.() -> Method? = { getMethodFully(name, arg1Type) },
|
||||
): (This.(T1) -> R)? = getStaticDeclaredMethod(returnType, getMethod) { method ->
|
||||
{ method(this, it).uncheckedCast() }
|
||||
}
|
||||
|
||||
inline fun <This, reified R, reified T1, reified T2> Class<*>.getMethod2(
|
||||
name: String,
|
||||
returnType: Class<out R> = R::class.java,
|
||||
arg1Type: Class<in T1> = T1::class.java,
|
||||
arg2Type: Class<in T2> = T2::class.java,
|
||||
getMethod: Class<*>.() -> Method? = { getMethodFully(name, arg1Type, arg2Type) },
|
||||
): (This.(T1, T2) -> R)? = getStaticDeclaredMethod(returnType, getMethod) { method ->
|
||||
{ v1, v2 -> method(this, v1, v2).uncheckedCast() }
|
||||
}
|
||||
|
||||
inline fun <This, reified R, reified T1, reified T2, reified T3> Class<*>.getMethod3(
|
||||
name: String,
|
||||
returnType: Class<out R> = R::class.java,
|
||||
arg1Type: Class<in T1> = T1::class.java,
|
||||
arg2Type: Class<in T2> = T2::class.java,
|
||||
arg3Type: Class<in T3> = T3::class.java,
|
||||
getMethod: Class<*>.() -> Method? = {
|
||||
getMethodFully(name, arg1Type, arg2Type, arg3Type)
|
||||
},
|
||||
): (This.(T1, T2, T3) -> R)? = getStaticDeclaredMethod(returnType, getMethod) { method ->
|
||||
{ v1, v2, v3 -> method(this, v1, v2, v3).uncheckedCast() }
|
||||
}
|
||||
|
||||
inline fun <This, reified R, reified T1, reified T2, reified T3, reified T4> Class<*>.getMethod4(
|
||||
name: String,
|
||||
returnType: Class<out R> = R::class.java,
|
||||
arg1Type: Class<in T1> = T1::class.java,
|
||||
arg2Type: Class<in T2> = T2::class.java,
|
||||
arg3Type: Class<in T3> = T3::class.java,
|
||||
arg4Type: Class<in T4> = T4::class.java,
|
||||
getMethod: Class<*>.() -> Method? = {
|
||||
getMethodFully(name, arg1Type, arg2Type, arg3Type, arg4Type)
|
||||
},
|
||||
): (This.(T1, T2, T3, T4) -> R)? = getStaticDeclaredMethod(returnType, getMethod) { method ->
|
||||
{ v1, v2, v3, v4 -> method(this, v1, v2, v3, v4).uncheckedCast() }
|
||||
}
|
||||
|
||||
inline fun <This, reified R, reified T1, reified T2, reified T3, reified T4, reified T5> Class<*>.getMethod5(
|
||||
name: String,
|
||||
returnType: Class<out R> = R::class.java,
|
||||
arg1Type: Class<in T1> = T1::class.java,
|
||||
arg2Type: Class<in T2> = T2::class.java,
|
||||
arg3Type: Class<in T3> = T3::class.java,
|
||||
arg4Type: Class<in T4> = T4::class.java,
|
||||
arg5Type: Class<in T5> = T5::class.java,
|
||||
getMethod: Class<*>.() -> Method? = {
|
||||
getMethodFully(name, arg1Type, arg2Type, arg3Type, arg4Type)
|
||||
},
|
||||
): (This.(T1, T2, T3, T4, T5) -> R)? = getStaticDeclaredMethod(returnType, getMethod) { method ->
|
||||
{ v1, v2, v3, v4, v5 -> method(this, v1, v2, v3, v4, v5).uncheckedCast() }
|
||||
}
|
||||
|
@ -0,0 +1,215 @@
|
||||
@file:Suppress("unused")
|
||||
|
||||
package cn.tursom.core.reflect
|
||||
|
||||
import cn.tursom.core.allMethodsSequence
|
||||
import cn.tursom.core.companionObjectInstanceOrNull
|
||||
import cn.tursom.core.uncheckedCast
|
||||
import com.ddbes.kotlin.isStatic
|
||||
import java.lang.reflect.Method
|
||||
|
||||
private var lastGetMethodThreadLocal = ThreadLocal<Method?>()
|
||||
private val lastGetMethod get() = lastGetMethodThreadLocal.get()
|
||||
|
||||
inline fun <reified T> getType() = T::class.java
|
||||
|
||||
infix fun Class<*>.canCast(target: Class<*>): Boolean {
|
||||
if (target == Any::class.java || this == target) return true
|
||||
|
||||
if ((this == Void.TYPE || this == Void::class.java) &&
|
||||
(target == Unit::class.java || target == Void.TYPE || target == Void::class.java)
|
||||
) return true
|
||||
|
||||
if ((this == Byte::class.java || this == getType<Byte>()) &&
|
||||
(target == Byte::class.java || target == Byte::class.java)
|
||||
) return true
|
||||
if ((this == Short::class.java || this == getType<Short>()) &&
|
||||
(target == Short::class.java || target == Short::class.java)
|
||||
) return true
|
||||
if ((this == Int::class.java || this == getType<Int>()) &&
|
||||
(target == Int::class.java || target == getType<Int>())
|
||||
) return true
|
||||
if ((this == Long::class.java || this == getType<Long>()) &&
|
||||
(target == Long::class.java || target == getType<Long>())
|
||||
) return true
|
||||
|
||||
if ((this == Float::class.java || this == getType<Float>()) &&
|
||||
(target == Float::class.java || target == getType<Float>())
|
||||
) return true
|
||||
if ((this == Double::class.java || this == getType<Double>()) &&
|
||||
(target == Double::class.java || target == getType<Double>())
|
||||
) return true
|
||||
|
||||
if ((this == Boolean::class.java || this == getType<Boolean>()) &&
|
||||
(target == Boolean::class.java || target == getType<Boolean>())
|
||||
) return true
|
||||
|
||||
if ((this == Char::class.java || this == getType<Char>()) &&
|
||||
(target == Char::class.java || target == getType<Char>())
|
||||
) return true
|
||||
|
||||
return target.isAssignableFrom(this)
|
||||
}
|
||||
|
||||
private fun Method.match(name: String, vararg type: Class<*>): Boolean {
|
||||
if (this.name != name) return false
|
||||
if (this.parameterTypes.size != type.size) return false
|
||||
this.parameterTypes.forEachIndexed { index, clazz ->
|
||||
if (!(type[index] canCast clazz)) return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
fun Class<*>.getFirstMatchMethod(
|
||||
name: String,
|
||||
vararg type: Class<*>,
|
||||
): Method? {
|
||||
lastGetMethodThreadLocal.remove()
|
||||
allMethodsSequence.forEach { method ->
|
||||
if (method.match(name, *type)) {
|
||||
lastGetMethodThreadLocal.set(method)
|
||||
return method
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
fun Class<*>.getMethodFully(
|
||||
name: String,
|
||||
vararg type: Class<*>,
|
||||
): Method? {
|
||||
lastGetMethodThreadLocal.remove()
|
||||
val scanMethod = scanMethod(name, *type)
|
||||
return (scanMethod.firstOrNull { method ->
|
||||
method.parameterTypes.forEachIndexed { index, clazz ->
|
||||
if (type[index] != clazz) return@firstOrNull false
|
||||
}
|
||||
true
|
||||
} ?: scanMethod.firstOrNull()).also {
|
||||
lastGetMethodThreadLocal.set(it)
|
||||
}
|
||||
}
|
||||
|
||||
fun Class<*>.scanMethod(
|
||||
name: String,
|
||||
vararg type: Class<*>,
|
||||
): List<Method> {
|
||||
@OptIn(ExperimentalStdlibApi::class)
|
||||
return buildList {
|
||||
allMethodsSequence.forEach { method ->
|
||||
if (method.match(name, *type)) add(method)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline fun Class<*>.getStaticDeclaredMethod(
|
||||
returnType: Class<*>,
|
||||
isStatic: Boolean = true,
|
||||
getMethod: Class<*>.() -> Method?,
|
||||
) = try {
|
||||
val method = getMethod()
|
||||
method?.isAccessible = true
|
||||
if (method != null && method.isStatic() == isStatic && method.returnType canCast returnType) method
|
||||
else null
|
||||
} catch (e: Exception) {
|
||||
null
|
||||
}
|
||||
|
||||
inline fun <R> Class<*>.getStaticDeclaredMethod(
|
||||
returnType: Class<*>,
|
||||
getMethod: Class<*>.() -> Method?,
|
||||
staticReturn: (method: Method, companionObjectInstance: Any?) -> R,
|
||||
): R? {
|
||||
val method = getStaticDeclaredMethod(returnType, true, getMethod)
|
||||
if (method != null) return staticReturn(method, null)
|
||||
|
||||
val companionObjectInstance = kotlin.companionObjectInstanceOrNull ?: return null
|
||||
val companionObjectClazz = companionObjectInstance.javaClass
|
||||
val companionMethod = companionObjectClazz.getStaticDeclaredMethod(returnType, false, getMethod)
|
||||
if (companionMethod != null) return staticReturn(companionMethod, companionObjectInstance)
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
inline fun <reified R : Any> Class<*>.getStaticDeclaredMethod(
|
||||
name: String,
|
||||
returnType: Class<R> = R::class.java,
|
||||
getMethod: Class<*>.() -> Method? = {
|
||||
getMethodFully(name)
|
||||
},
|
||||
): (() -> R)? = getStaticDeclaredMethod(
|
||||
returnType, getMethod,
|
||||
{ method, companion -> { method(companion).uncheckedCast() } }
|
||||
)
|
||||
|
||||
inline fun <reified R, reified T1> Class<*>.getStaticDeclaredMethod1(
|
||||
name: String,
|
||||
returnType: Class<R> = R::class.java,
|
||||
arg1Type: Class<T1> = T1::class.java,
|
||||
getMethod: Class<*>.() -> Method? = {
|
||||
getMethodFully(name, arg1Type)
|
||||
},
|
||||
): ((T1) -> R)? = getStaticDeclaredMethod(
|
||||
returnType, getMethod,
|
||||
{ method, companion -> { v1 -> method(companion, v1).uncheckedCast() } }
|
||||
)
|
||||
|
||||
inline fun <reified R, reified T1, reified T2> Class<*>.getStaticDeclaredMethod2(
|
||||
name: String,
|
||||
returnType: Class<R> = R::class.java,
|
||||
arg1Type: Class<T1> = T1::class.java,
|
||||
arg2Type: Class<T2> = T2::class.java,
|
||||
getMethod: Class<*>.() -> Method? = {
|
||||
getMethodFully(name, arg1Type, arg2Type)
|
||||
},
|
||||
): ((T1, T2) -> R)? = getStaticDeclaredMethod(
|
||||
returnType, getMethod,
|
||||
{ method, companion -> { v1, v2 -> method(companion, v1, v2).uncheckedCast() } }
|
||||
)
|
||||
|
||||
inline fun <reified R, reified T1, reified T2, reified T3> Class<*>.getStaticDeclaredMethod3(
|
||||
name: String,
|
||||
returnType: Class<R> = R::class.java,
|
||||
arg1Type: Class<T1> = T1::class.java,
|
||||
arg2Type: Class<T2> = T2::class.java,
|
||||
arg3Type: Class<T3> = T3::class.java,
|
||||
getMethod: Class<*>.() -> Method? = {
|
||||
getMethodFully(name, arg1Type, arg2Type, arg3Type)
|
||||
},
|
||||
): ((T1, T2, T3) -> R)? = getStaticDeclaredMethod(
|
||||
returnType, getMethod,
|
||||
{ method, companion -> { v1, v2, v3 -> method(companion, v1, v2, v3).uncheckedCast() } }
|
||||
)
|
||||
|
||||
inline fun <reified R, reified T1, reified T2, reified T3, reified T4> Class<*>.getStaticDeclaredMethod4(
|
||||
name: String,
|
||||
returnType: Class<R> = R::class.java,
|
||||
arg1Type: Class<T1> = T1::class.java,
|
||||
arg2Type: Class<T2> = T2::class.java,
|
||||
arg3Type: Class<T3> = T3::class.java,
|
||||
arg4Type: Class<T4> = T4::class.java,
|
||||
getMethod: Class<*>.() -> Method? = {
|
||||
getMethodFully(name, arg1Type, arg2Type, arg3Type, arg4Type)
|
||||
},
|
||||
): ((T1, T2, T3, T4) -> R)? = getStaticDeclaredMethod(
|
||||
returnType, getMethod,
|
||||
{ method, companion -> { v1, v2, v3, v4 -> method(companion, v1, v2, v3, v4).uncheckedCast() } }
|
||||
)
|
||||
|
||||
inline fun <reified R, reified T1, reified T2, reified T3, reified T4, reified T5> Class<*>.getStaticDeclaredMethod5(
|
||||
name: String,
|
||||
returnType: Class<R> = R::class.java,
|
||||
arg1Type: Class<T1> = T1::class.java,
|
||||
arg2Type: Class<T2> = T2::class.java,
|
||||
arg3Type: Class<T3> = T3::class.java,
|
||||
arg4Type: Class<T4> = T4::class.java,
|
||||
arg5Type: Class<T5> = T5::class.java,
|
||||
getMethod: Class<*>.() -> Method? = {
|
||||
getMethodFully(name, arg1Type, arg2Type, arg3Type, arg4Type, arg5Type)
|
||||
},
|
||||
): ((T1, T2, T3, T4, T5) -> R)? = getStaticDeclaredMethod(
|
||||
returnType, getMethod,
|
||||
{ method, companion -> { v1, v2, v3, v4, v5 -> method(companion, v1, v2, v3, v4, v5).uncheckedCast() } }
|
||||
)
|
||||
|
||||
|
@ -1,5 +1,7 @@
|
||||
package cn.tursom.core
|
||||
package cn.tursom.core.reflect
|
||||
|
||||
import cn.tursom.core.Unsafe
|
||||
import cn.tursom.core.uncheckedCast
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
import kotlin.reflect.KClass
|
||||
|
272
ts-core/src/main/kotlin/cn/tursom/core/reflect/Members.kt
Normal file
272
ts-core/src/main/kotlin/cn/tursom/core/reflect/Members.kt
Normal file
@ -0,0 +1,272 @@
|
||||
@file:Suppress("unused")
|
||||
|
||||
package com.ddbes.kotlin
|
||||
|
||||
import java.lang.reflect.Field
|
||||
import java.lang.reflect.Member
|
||||
import java.lang.reflect.Modifier
|
||||
|
||||
|
||||
private val fieldModifiersField: Field? = try {
|
||||
Field::class.java.getDeclaredField("modifiers").apply {
|
||||
isAccessible = true
|
||||
}
|
||||
} catch (e: Throwable) {
|
||||
null
|
||||
}
|
||||
|
||||
var fieldModifiers: (Field, Int) -> Unit = { field, modifer ->
|
||||
fieldModifiersField!!.set(field, modifer)
|
||||
}
|
||||
|
||||
var Field.public: Boolean
|
||||
get() = Modifier.isPublic(this.modifiers)
|
||||
set(value) {
|
||||
val modifier = Modifier.PUBLIC
|
||||
fieldModifiers(
|
||||
this,
|
||||
if (value) {
|
||||
modifiers or modifier
|
||||
} else {
|
||||
modifiers and modifier.inv()
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
var Field.private: Boolean
|
||||
get() = Modifier.isPrivate(this.modifiers)
|
||||
set(value) {
|
||||
val modifier = Modifier.PRIVATE
|
||||
fieldModifiers(
|
||||
this,
|
||||
if (value) {
|
||||
modifiers or modifier
|
||||
} else {
|
||||
modifiers and modifier.inv()
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
var Field.protected: Boolean
|
||||
get() = Modifier.isProtected(this.modifiers)
|
||||
set(value) {
|
||||
val modifier = Modifier.PROTECTED
|
||||
fieldModifiers(
|
||||
this,
|
||||
if (value) {
|
||||
modifiers or modifier
|
||||
} else {
|
||||
modifiers and modifier.inv()
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
var Field.static: Boolean
|
||||
get() = Modifier.isStatic(this.modifiers)
|
||||
set(value) {
|
||||
val modifier = Modifier.STATIC
|
||||
fieldModifiers(
|
||||
this,
|
||||
if (value) {
|
||||
modifiers or modifier
|
||||
} else {
|
||||
modifiers and modifier.inv()
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
var Field.final: Boolean
|
||||
get() = Modifier.isFinal(this.modifiers)
|
||||
set(value) {
|
||||
val modifier = Modifier.FINAL
|
||||
fieldModifiers(
|
||||
this,
|
||||
if (value) {
|
||||
modifiers or modifier
|
||||
} else {
|
||||
modifiers and modifier.inv()
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
var Field.synchronized: Boolean
|
||||
get() = Modifier.isSynchronized(this.modifiers)
|
||||
set(value) {
|
||||
val modifier = Modifier.SYNCHRONIZED
|
||||
fieldModifiers(
|
||||
this,
|
||||
if (value) {
|
||||
modifiers or modifier
|
||||
} else {
|
||||
modifiers and modifier.inv()
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
var Field.volatile: Boolean
|
||||
get() = Modifier.isVolatile(this.modifiers)
|
||||
set(value) {
|
||||
val modifier = Modifier.VOLATILE
|
||||
fieldModifiers(
|
||||
this,
|
||||
if (value) {
|
||||
modifiers or modifier
|
||||
} else {
|
||||
modifiers and modifier.inv()
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
var Field.transient: Boolean
|
||||
get() = Modifier.isTransient(this.modifiers)
|
||||
set(value) {
|
||||
val modifier = Modifier.TRANSIENT
|
||||
fieldModifiers(
|
||||
this,
|
||||
if (value) {
|
||||
modifiers or modifier
|
||||
} else {
|
||||
modifiers and modifier.inv()
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
var Field.native: Boolean
|
||||
get() = Modifier.isNative(this.modifiers)
|
||||
set(value) {
|
||||
val modifier = Modifier.NATIVE
|
||||
fieldModifiers(
|
||||
this,
|
||||
if (value) {
|
||||
modifiers or modifier
|
||||
} else {
|
||||
modifiers and modifier.inv()
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
var Field.`interface`: Boolean
|
||||
get() = Modifier.isInterface(this.modifiers)
|
||||
set(value) {
|
||||
val modifier = Modifier.INTERFACE
|
||||
fieldModifiers(
|
||||
this,
|
||||
if (value) {
|
||||
modifiers or modifier
|
||||
} else {
|
||||
modifiers and modifier.inv()
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
var Field.abstract: Boolean
|
||||
get() = Modifier.isAbstract(this.modifiers)
|
||||
set(value) {
|
||||
val modifier = Modifier.ABSTRACT
|
||||
fieldModifiers(
|
||||
this,
|
||||
if (value) {
|
||||
modifiers or modifier
|
||||
} else {
|
||||
modifiers and modifier.inv()
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
var Field.strict: Boolean
|
||||
get() = Modifier.isStrict(this.modifiers)
|
||||
set(value) {
|
||||
val modifier = Modifier.STRICT
|
||||
fieldModifiers(
|
||||
this,
|
||||
if (value) {
|
||||
modifiers or modifier
|
||||
} else {
|
||||
modifiers and modifier.inv()
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
fun Member.isPublic(): Boolean {
|
||||
return Modifier.isPublic(this.modifiers)
|
||||
}
|
||||
|
||||
fun Member.isPrivate(): Boolean {
|
||||
return Modifier.isPrivate(this.modifiers)
|
||||
}
|
||||
|
||||
fun Member.isProtected(): Boolean {
|
||||
return Modifier.isProtected(this.modifiers)
|
||||
}
|
||||
|
||||
fun Member.isStatic(): Boolean {
|
||||
return Modifier.isStatic(this.modifiers)
|
||||
}
|
||||
|
||||
fun Member.isFinal(): Boolean {
|
||||
return Modifier.isFinal(this.modifiers)
|
||||
}
|
||||
|
||||
fun Member.isSynchronized(): Boolean {
|
||||
return Modifier.isSynchronized(this.modifiers)
|
||||
}
|
||||
|
||||
fun Member.isVolatile(): Boolean {
|
||||
return Modifier.isVolatile(this.modifiers)
|
||||
}
|
||||
|
||||
fun Member.isTransient(): Boolean {
|
||||
return Modifier.isTransient(this.modifiers)
|
||||
}
|
||||
|
||||
fun Member.isNative(): Boolean {
|
||||
return Modifier.isNative(this.modifiers)
|
||||
}
|
||||
|
||||
fun Member.isInterface(): Boolean {
|
||||
return Modifier.isInterface(this.modifiers)
|
||||
}
|
||||
|
||||
fun Member.isAbstract(): Boolean {
|
||||
return Modifier.isAbstract(this.modifiers)
|
||||
}
|
||||
|
||||
fun Member.isStrict(): Boolean {
|
||||
return Modifier.isStrict(this.modifiers)
|
||||
}
|
||||
|
||||
val Class<*>.isPublic: Boolean
|
||||
get() = Modifier.isPublic(this.modifiers)
|
||||
|
||||
val Class<*>.isPrivate: Boolean
|
||||
get() = Modifier.isPrivate(this.modifiers)
|
||||
|
||||
val Class<*>.isProtected: Boolean
|
||||
get() = Modifier.isProtected(this.modifiers)
|
||||
|
||||
val Class<*>.isStatic: Boolean
|
||||
get() = Modifier.isStatic(this.modifiers)
|
||||
|
||||
val Class<*>.isFinal: Boolean
|
||||
get() = Modifier.isFinal(this.modifiers)
|
||||
|
||||
val Class<*>.isSynchronized: Boolean
|
||||
get() = Modifier.isSynchronized(this.modifiers)
|
||||
|
||||
val Class<*>.isVolatile: Boolean
|
||||
get() = Modifier.isVolatile(this.modifiers)
|
||||
|
||||
val Class<*>.isTransient: Boolean
|
||||
get() = Modifier.isTransient(this.modifiers)
|
||||
|
||||
val Class<*>.isNative: Boolean
|
||||
get() = Modifier.isNative(this.modifiers)
|
||||
|
||||
//val Class<*>.isInterface: Boolean
|
||||
// get() = Modifier.isInterface(this.modifiers)
|
||||
|
||||
val Class<*>.isAbstract
|
||||
get() = Modifier.isAbstract(this.modifiers)
|
||||
|
||||
val Class<*>.isStrict
|
||||
get() = Modifier.isStrict(this.modifiers)
|
@ -0,0 +1,36 @@
|
||||
package cn.tursom.core.reflect
|
||||
|
||||
import java.lang.reflect.Method
|
||||
|
||||
interface MethodFilter {
|
||||
fun filterMethod(clazz: Class<*>): Sequence<Method>
|
||||
|
||||
companion object
|
||||
}
|
||||
|
||||
|
||||
class Arg1MethodFilter<R>(
|
||||
val prevFilter: ReturnTypeMethodFilter<R>
|
||||
) : MethodFilter {
|
||||
override fun filterMethod(clazz: Class<*>): Sequence<Method> {
|
||||
return prevFilter.filterMethod(clazz).filter { method ->
|
||||
method.parameterCount == 1
|
||||
}
|
||||
}
|
||||
|
||||
fun <T> filter(clazz: Class<T>): Sequence<T.() -> R> {
|
||||
return filterMethod(clazz).map {
|
||||
{
|
||||
it.invoke(this) as R
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun filter(obj: Any): Sequence<() -> R> {
|
||||
return filterMethod(obj.javaClass).map {
|
||||
{
|
||||
it.invoke(obj) as R
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,458 @@
|
||||
package cn.tursom.core.reflect
|
||||
|
||||
import cn.tursom.core.UncheckedCast
|
||||
import cn.tursom.core.cast
|
||||
import cn.tursom.core.forAllMethods
|
||||
import org.slf4j.LoggerFactory
|
||||
import java.lang.reflect.Method
|
||||
import java.lang.reflect.ParameterizedType
|
||||
import kotlin.coroutines.Continuation
|
||||
import kotlin.reflect.jvm.javaType
|
||||
import kotlin.reflect.jvm.kotlinFunction
|
||||
|
||||
@Suppress("unused", "MemberVisibilityCanBePrivate")
|
||||
object MethodInspector {
|
||||
private val logger = LoggerFactory.getLogger(MethodInspector::class.java)
|
||||
|
||||
fun <R> forEachMethod(
|
||||
clazz: Class<*>,
|
||||
returnType: Class<out R>,
|
||||
argumentType: Array<Class<*>>,
|
||||
self: Any? = null,
|
||||
handler: (Method, (Array<Any?>) -> R) -> Unit
|
||||
) {
|
||||
clazz.forAllMethods { method ->
|
||||
val parameterTypes = method.parameterTypes
|
||||
val methodReturnType = if (
|
||||
method.returnType == Void.TYPE ||
|
||||
method.returnType == Void::class.java
|
||||
) Unit::class.java else method.returnType
|
||||
|
||||
val argumentTypeIterator = argumentType.iterator()
|
||||
if (parameterTypes.size == argumentType.size &&
|
||||
parameterTypes.all {
|
||||
argumentTypeIterator.next().isAssignableFrom(it)
|
||||
} &&
|
||||
returnType.isAssignableFrom(methodReturnType)
|
||||
) {
|
||||
method.isAccessible = true
|
||||
@OptIn(UncheckedCast::class)
|
||||
handler(method) { method.invoke(self, *it).cast() }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun <R> forEachSuspendMethod(
|
||||
clazz: Class<*>,
|
||||
returnType: Class<out R>,
|
||||
argumentType: Array<Class<*>>,
|
||||
self: Any? = null,
|
||||
handler: (Method, suspend (Array<Any?>) -> R) -> Unit
|
||||
) {
|
||||
clazz.forAllMethods { method ->
|
||||
val parameterTypes = method.parameterTypes
|
||||
val kotlinFunction = method.kotlinFunction ?: return@forAllMethods
|
||||
var methodReturnType = kotlinFunction.returnType.javaType
|
||||
while (methodReturnType is ParameterizedType) {
|
||||
methodReturnType = methodReturnType.rawType
|
||||
}
|
||||
|
||||
if (methodReturnType !is Class<*>) {
|
||||
logger.warn("method return type {}({}) is not Class", methodReturnType, methodReturnType.javaClass)
|
||||
return@forAllMethods
|
||||
}
|
||||
|
||||
val argumentTypeIterator = argumentType.iterator()
|
||||
if (parameterTypes.size - 1 == argumentType.size &&
|
||||
parameterTypes.dropLast(1).all {
|
||||
argumentTypeIterator.next().isAssignableFrom(it)
|
||||
} &&
|
||||
Continuation::class.java.isAssignableFrom(parameterTypes.last()) &&
|
||||
returnType.isAssignableFrom(methodReturnType)
|
||||
) {
|
||||
method.isAccessible = true
|
||||
@OptIn(UncheckedCast::class)
|
||||
handler(method, { it: Array<Any?>, cont: Continuation<*> -> method.invoke(self, *it, cont) }.cast())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun forEachMethod(clazz: Class<*>, self: Any? = null, handler: (Method, () -> Unit) -> Unit) {
|
||||
forEachMethod(clazz, Unit::class.java, self, handler)
|
||||
}
|
||||
|
||||
fun <R> forEachMethod(
|
||||
clazz: Class<*>,
|
||||
returnType: Class<out R>,
|
||||
self: Any? = null,
|
||||
handler: (Method, () -> R) -> Unit
|
||||
) {
|
||||
clazz.javaClass.forAllMethods { method ->
|
||||
val parameterTypes = method.parameterTypes
|
||||
val methodReturnType = if (
|
||||
method.returnType == Void.TYPE ||
|
||||
method.returnType == Void::class.java
|
||||
) Unit::class.java else method.returnType
|
||||
if (parameterTypes.isEmpty() && returnType.isAssignableFrom(methodReturnType)) {
|
||||
method.isAccessible = true
|
||||
@OptIn(UncheckedCast::class)
|
||||
handler(method) { method.invoke(self).cast() }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun <T, R> forEachMethod(
|
||||
clazz: Class<*>,
|
||||
returnType: Class<out R>,
|
||||
argumentType: Class<T>,
|
||||
self: Any? = null,
|
||||
handler: (Method, (T) -> R) -> Unit
|
||||
) {
|
||||
forEachMethod(clazz, returnType, arrayOf(argumentType), self) { method: Method, m: (Array<Any?>) -> R ->
|
||||
handler(method) {
|
||||
m(arrayOf(it))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun <T1, T2, R> forEachMethod(
|
||||
clazz: Class<*>,
|
||||
returnType: Class<out R>,
|
||||
argumentType1: Class<T1>,
|
||||
argumentType2: Class<T2>,
|
||||
self: Any? = null,
|
||||
handler: (Method, (T1, T2) -> R) -> Unit
|
||||
) {
|
||||
forEachMethod(
|
||||
clazz,
|
||||
returnType,
|
||||
arrayOf(argumentType1, argumentType2),
|
||||
self
|
||||
) { method: Method, m: (Array<Any?>) -> R ->
|
||||
handler(method) { t1, t2 ->
|
||||
m(arrayOf(t1, t2))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun <T1, T2, T3, R> forEachMethod(
|
||||
clazz: Class<*>,
|
||||
returnType: Class<out R>,
|
||||
argumentType1: Class<T1>,
|
||||
argumentType2: Class<T2>,
|
||||
argumentType3: Class<T3>,
|
||||
self: Any? = null,
|
||||
handler: (Method, (T1, T2, T3) -> R) -> Unit
|
||||
) {
|
||||
forEachMethod(
|
||||
clazz,
|
||||
returnType,
|
||||
arrayOf(argumentType1, argumentType2, argumentType3),
|
||||
self
|
||||
) { method: Method, m: (Array<Any?>) -> R ->
|
||||
handler(method) { t1, t2, t3 ->
|
||||
m(arrayOf(t1, t2, t3))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun <T1, T2, T3, T4, R> forEachMethod(
|
||||
clazz: Class<*>,
|
||||
returnType: Class<out R>,
|
||||
argumentType1: Class<T1>,
|
||||
argumentType2: Class<T2>,
|
||||
argumentType3: Class<T3>,
|
||||
argumentType4: Class<T4>,
|
||||
self: Any? = null,
|
||||
handler: (Method, (T1, T2, T3, T4) -> R) -> Unit
|
||||
) {
|
||||
forEachMethod(
|
||||
clazz,
|
||||
returnType,
|
||||
arrayOf(argumentType1, argumentType2, argumentType3, argumentType4),
|
||||
self
|
||||
) { method: Method, m: (Array<Any?>) -> R ->
|
||||
handler(method) { t1, t2, t3, t4 ->
|
||||
m(arrayOf(t1, t2, t3, t4))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun forEachSuspendMethod(clazz: Class<*>, self: Any? = null, handler: (Method, suspend () -> Unit) -> Unit) {
|
||||
forEachSuspendMethod(clazz, Unit::class.java, self, handler)
|
||||
}
|
||||
|
||||
fun <R> forEachSuspendMethod(
|
||||
clazz: Class<*>,
|
||||
returnType: Class<out R>,
|
||||
self: Any? = null,
|
||||
handler: (Method, suspend () -> R) -> Unit
|
||||
) {
|
||||
forEachSuspendMethod(clazz, returnType, arrayOf(), self) { method: Method, m: suspend (Array<Any?>) -> R ->
|
||||
handler(method) {
|
||||
m(arrayOf())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun <T, R> forEachSuspendMethod(
|
||||
clazz: Class<*>,
|
||||
returnType: Class<out R>,
|
||||
argumentType: Class<T>,
|
||||
self: Any? = null,
|
||||
handler: (Method, suspend (T) -> R) -> Unit
|
||||
) {
|
||||
forEachSuspendMethod(
|
||||
clazz,
|
||||
returnType,
|
||||
arrayOf(argumentType),
|
||||
self
|
||||
) { method: Method, m: suspend (Array<Any?>) -> R ->
|
||||
handler(method) {
|
||||
m(arrayOf(it))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun <T1, T2, R> forEachSuspendMethod(
|
||||
clazz: Class<*>,
|
||||
returnType: Class<out R>,
|
||||
argumentType1: Class<T1>,
|
||||
argumentType2: Class<T2>,
|
||||
self: Any? = null,
|
||||
handler: (Method, suspend (T1, T2) -> R) -> Unit
|
||||
) {
|
||||
forEachSuspendMethod(
|
||||
clazz,
|
||||
returnType,
|
||||
arrayOf(argumentType1, argumentType2),
|
||||
self
|
||||
) { method: Method, m: suspend (Array<Any?>) -> R ->
|
||||
handler(method) { t1, t2 ->
|
||||
m(arrayOf(t1, t2))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun <T1, T2, T3, R> forEachSuspendMethod(
|
||||
clazz: Class<*>,
|
||||
returnType: Class<out R>,
|
||||
argumentType1: Class<T1>,
|
||||
argumentType2: Class<T2>,
|
||||
argumentType3: Class<T3>,
|
||||
self: Any? = null,
|
||||
handler: (Method, suspend (T1, T2, T3) -> R) -> Unit
|
||||
) {
|
||||
forEachSuspendMethod(
|
||||
clazz,
|
||||
returnType,
|
||||
arrayOf(argumentType1, argumentType2, argumentType3),
|
||||
self
|
||||
) { method: Method, m: suspend (Array<Any?>) -> R ->
|
||||
handler(method) { t1, t2, t3 ->
|
||||
m(arrayOf(t1, t2, t3))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun <T1, T2, T3, T4, R> forEachSuspendMethod(
|
||||
clazz: Class<*>,
|
||||
returnType: Class<out R>,
|
||||
argumentType1: Class<T1>,
|
||||
argumentType2: Class<T2>,
|
||||
argumentType3: Class<T3>,
|
||||
argumentType4: Class<T4>,
|
||||
self: Any? = null,
|
||||
handler: (Method, suspend (T1, T2, T3, T4) -> R) -> Unit
|
||||
) {
|
||||
forEachSuspendMethod(
|
||||
clazz,
|
||||
returnType,
|
||||
arrayOf(argumentType1, argumentType2, argumentType3, argumentType4),
|
||||
self
|
||||
) { method: Method, m: suspend (Array<Any?>) -> R ->
|
||||
handler(method) { t1, t2, t3, t4 ->
|
||||
m(arrayOf(t1, t2, t3, t4))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fun <R> forEachMethod(
|
||||
self: Any,
|
||||
returnType: Class<out R>,
|
||||
argumentType: Array<Class<*>>,
|
||||
handler: (Method, (Array<Any?>) -> R) -> Unit
|
||||
) {
|
||||
forEachMethod(self.javaClass, returnType, argumentType, self, handler)
|
||||
}
|
||||
|
||||
fun <R> forEachSuspendMethod(
|
||||
self: Any,
|
||||
returnType: Class<out R>,
|
||||
argumentType: Array<Class<*>>,
|
||||
handler: (Method, suspend (Array<Any?>) -> R) -> Unit
|
||||
) {
|
||||
forEachSuspendMethod(self.javaClass, returnType, argumentType, self, handler)
|
||||
}
|
||||
|
||||
fun forEachMethod(self: Any, handler: (Method, () -> Unit) -> Unit) {
|
||||
forEachMethod(self, Unit::class.java, handler)
|
||||
}
|
||||
|
||||
fun <R> forEachMethod(self: Any, returnType: Class<out R>, handler: (Method, () -> R) -> Unit) {
|
||||
forEachMethod(self.javaClass, returnType, self, handler)
|
||||
}
|
||||
|
||||
fun <T, R> forEachMethod(
|
||||
self: Any,
|
||||
returnType: Class<out R>,
|
||||
argumentType: Class<T>,
|
||||
handler: (Method, (T) -> R) -> Unit
|
||||
) {
|
||||
forEachMethod(self, returnType, arrayOf(argumentType)) { method: Method, m: (Array<Any?>) -> R ->
|
||||
handler(method) {
|
||||
m(arrayOf(it))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun <T1, T2, R> forEachMethod(
|
||||
self: Any,
|
||||
returnType: Class<out R>,
|
||||
argumentType1: Class<T1>,
|
||||
argumentType2: Class<T2>,
|
||||
handler: (Method, (T1, T2) -> R) -> Unit
|
||||
) {
|
||||
forEachMethod(
|
||||
self,
|
||||
returnType,
|
||||
arrayOf(argumentType1, argumentType2)
|
||||
) { method: Method, m: (Array<Any?>) -> R ->
|
||||
handler(method) { t1, t2 ->
|
||||
m(arrayOf(t1, t2))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun <T1, T2, T3, R> forEachMethod(
|
||||
self: Any,
|
||||
returnType: Class<out R>,
|
||||
argumentType1: Class<T1>,
|
||||
argumentType2: Class<T2>,
|
||||
argumentType3: Class<T3>,
|
||||
handler: (Method, (T1, T2, T3) -> R) -> Unit
|
||||
) {
|
||||
forEachMethod(
|
||||
self,
|
||||
returnType,
|
||||
arrayOf(argumentType1, argumentType2, argumentType3)
|
||||
) { method: Method, m: (Array<Any?>) -> R ->
|
||||
handler(method) { t1, t2, t3 ->
|
||||
m(arrayOf(t1, t2, t3))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun <T1, T2, T3, T4, R> forEachMethod(
|
||||
self: Any,
|
||||
returnType: Class<out R>,
|
||||
argumentType1: Class<T1>,
|
||||
argumentType2: Class<T2>,
|
||||
argumentType3: Class<T3>,
|
||||
argumentType4: Class<T4>,
|
||||
handler: (Method, (T1, T2, T3, T4) -> R) -> Unit
|
||||
) {
|
||||
forEachMethod(
|
||||
self,
|
||||
returnType,
|
||||
arrayOf(argumentType1, argumentType2, argumentType3, argumentType4)
|
||||
) { method: Method, m: (Array<Any?>) -> R ->
|
||||
handler(method) { t1, t2, t3, t4 ->
|
||||
m(arrayOf(t1, t2, t3, t4))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun forEachSuspendMethod(self: Any, handler: (Method, suspend () -> Unit) -> Unit) {
|
||||
forEachSuspendMethod(self, Unit::class.java, handler)
|
||||
}
|
||||
|
||||
fun <R> forEachSuspendMethod(self: Any, returnType: Class<out R>, handler: (Method, suspend () -> R) -> Unit) {
|
||||
forEachSuspendMethod(self, returnType, arrayOf()) { method: Method, m: suspend (Array<Any?>) -> R ->
|
||||
handler(method) {
|
||||
m(arrayOf())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun <T, R> forEachSuspendMethod(
|
||||
self: Any,
|
||||
returnType: Class<out R>,
|
||||
argumentType: Class<T>,
|
||||
handler: (Method, suspend (T) -> R) -> Unit
|
||||
) {
|
||||
forEachSuspendMethod(self, returnType, arrayOf(argumentType)) { method: Method, m: suspend (Array<Any?>) -> R ->
|
||||
handler(method) {
|
||||
m(arrayOf(it))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun <T1, T2, R> forEachSuspendMethod(
|
||||
self: Any,
|
||||
returnType: Class<out R>,
|
||||
argumentType1: Class<T1>,
|
||||
argumentType2: Class<T2>,
|
||||
handler: (Method, suspend (T1, T2) -> R) -> Unit
|
||||
) {
|
||||
forEachSuspendMethod(
|
||||
self,
|
||||
returnType,
|
||||
arrayOf(argumentType1, argumentType2)
|
||||
) { method: Method, m: suspend (Array<Any?>) -> R ->
|
||||
handler(method) { t1, t2 ->
|
||||
m(arrayOf(t1, t2))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun <T1, T2, T3, R> forEachSuspendMethod(
|
||||
self: Any,
|
||||
returnType: Class<out R>,
|
||||
argumentType1: Class<T1>,
|
||||
argumentType2: Class<T2>,
|
||||
argumentType3: Class<T3>,
|
||||
handler: (Method, suspend (T1, T2, T3) -> R) -> Unit
|
||||
) {
|
||||
forEachSuspendMethod(
|
||||
self,
|
||||
returnType,
|
||||
arrayOf(argumentType1, argumentType2, argumentType3)
|
||||
) { method: Method, m: suspend (Array<Any?>) -> R ->
|
||||
handler(method) { t1, t2, t3 ->
|
||||
m(arrayOf(t1, t2, t3))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun <T1, T2, T3, T4, R> forEachSuspendMethod(
|
||||
self: Any,
|
||||
returnType: Class<out R>,
|
||||
argumentType1: Class<T1>,
|
||||
argumentType2: Class<T2>,
|
||||
argumentType3: Class<T3>,
|
||||
argumentType4: Class<T4>,
|
||||
handler: (Method, suspend (T1, T2, T3, T4) -> R) -> Unit
|
||||
) {
|
||||
forEachSuspendMethod(
|
||||
self,
|
||||
returnType,
|
||||
arrayOf(argumentType1, argumentType2, argumentType3, argumentType4)
|
||||
) { method: Method, m: suspend (Array<Any?>) -> R ->
|
||||
handler(method) { t1, t2, t3, t4 ->
|
||||
m(arrayOf(t1, t2, t3, t4))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,12 +1,19 @@
|
||||
package cn.tursom.core
|
||||
package cn.tursom.core.reflect
|
||||
|
||||
import cn.tursom.core.ThreadLocalSimpleDateFormat
|
||||
import cn.tursom.core.Unsafe.unsafe
|
||||
import cn.tursom.core.cast
|
||||
import cn.tursom.core.getClazz
|
||||
import cn.tursom.core.isInheritanceFrom
|
||||
import java.lang.reflect.Array
|
||||
import java.lang.reflect.Field
|
||||
import java.lang.reflect.Modifier
|
||||
import java.lang.reflect.ParameterizedType
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.*
|
||||
import kotlin.collections.component1
|
||||
import kotlin.collections.component2
|
||||
import kotlin.collections.set
|
||||
|
||||
object Parser {
|
||||
private val dateFormat = ThreadLocalSimpleDateFormat()
|
@ -0,0 +1,22 @@
|
||||
package cn.tursom.core.reflect
|
||||
|
||||
import cn.tursom.core.allMethodsSequence
|
||||
import java.lang.reflect.Method
|
||||
|
||||
class ReturnTypeMethodFilter<R>(
|
||||
val returnType: Class<R>
|
||||
) : MethodFilter {
|
||||
override fun filterMethod(clazz: Class<*>): Sequence<Method> {
|
||||
return clazz.allMethodsSequence.filter { method ->
|
||||
val methodReturnType = if (
|
||||
method.returnType == Void.TYPE ||
|
||||
method.returnType == Void::class.java
|
||||
) Unit::class.java else method.returnType
|
||||
returnType.isAssignableFrom(methodReturnType)
|
||||
}
|
||||
}
|
||||
|
||||
companion object
|
||||
}
|
||||
|
||||
inline fun <reified R> MethodFilter.Companion.returnType() = ReturnTypeMethodFilter(R::class.java)
|
48
ts-core/src/main/kotlin/cn/tursom/core/reflect/utils.kt
Normal file
48
ts-core/src/main/kotlin/cn/tursom/core/reflect/utils.kt
Normal file
@ -0,0 +1,48 @@
|
||||
package cn.tursom.core.reflect
|
||||
|
||||
import cn.tursom.core.Unsafe.get
|
||||
import cn.tursom.core.companionObjectInstanceOrNull
|
||||
import cn.tursom.core.isStatic
|
||||
import cn.tursom.core.uncheckedCast
|
||||
import java.lang.reflect.Field
|
||||
import java.lang.reflect.Method
|
||||
|
||||
inline fun <reified T : Annotation> Class<*>.getAnnotation(): T? = getAnnotation(T::class.java)
|
||||
inline fun <reified T : Annotation> Field.getAnnotation(): T? = getAnnotation(T::class.java)
|
||||
inline fun <reified T : Annotation> Method.getAnnotation(): T? = getAnnotation(T::class.java)
|
||||
|
||||
operator fun Class<*>.contains(obj: Any): Boolean = isInstance(obj)
|
||||
|
||||
fun <T> Class<*>.getStaticField(name: String): T? {
|
||||
val staticField = getDeclaredField(name)
|
||||
if (staticField.isStatic()) {
|
||||
staticField.isAccessible = true
|
||||
return staticField.get(null).uncheckedCast()
|
||||
}
|
||||
|
||||
val companionObjectInstance = kotlin.companionObjectInstanceOrNull
|
||||
if (companionObjectInstance != null) {
|
||||
return companionObjectInstance[name]?.uncheckedCast()
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
inline fun <reified C : Any, T> getStaticField(name: String): T? {
|
||||
return C::class.java.getStaticField(name)
|
||||
}
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
fun <T : Enum<out T>> Class<out T>.valueOf(value: String): T? {
|
||||
var valueOf: Method? = null
|
||||
return try {
|
||||
valueOf = getDeclaredMethod("valueOf", String::class.java)
|
||||
valueOf.invoke(null, value) as T
|
||||
} catch (e: Exception) {
|
||||
try {
|
||||
valueOf?.invoke(null, value.toUpperCase()) as? T?
|
||||
} catch (e: Exception) {
|
||||
null
|
||||
}
|
||||
}
|
||||
}
|
@ -2,6 +2,7 @@ package cn.tursom.core.clone
|
||||
|
||||
import cn.tursom.core.*
|
||||
import cn.tursom.core.datastruct.ArrayMap
|
||||
import cn.tursom.core.reflect.InstantAllocator
|
||||
import cn.tursom.log.impl.Slf4jImpl
|
||||
import kotlin.reflect.KClass
|
||||
import kotlin.reflect.KProperty1
|
||||
|
@ -1,8 +1,12 @@
|
||||
package cn.tursom.core.clone
|
||||
|
||||
import cn.tursom.core.*
|
||||
import cn.tursom.core.Unsafe
|
||||
import cn.tursom.core.allMemberProperties
|
||||
import cn.tursom.core.datastruct.KPropertyValueMap
|
||||
import cn.tursom.core.datastruct.SoftArrayMap
|
||||
import cn.tursom.core.reflect.InstantAllocator
|
||||
import cn.tursom.core.unaryPlus
|
||||
import cn.tursom.core.uncheckedCast
|
||||
import cn.tursom.log.impl.Slf4jImpl
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
import kotlin.collections.component1
|
||||
|
@ -1,7 +1,7 @@
|
||||
package cn.tursom.yaml
|
||||
|
||||
import cn.tursom.core.Parser
|
||||
import cn.tursom.core.ThreadLocalSimpleDateFormat
|
||||
import cn.tursom.core.reflect.Parser
|
||||
import org.yaml.snakeyaml.Yaml
|
||||
import java.lang.reflect.Modifier
|
||||
import java.util.*
|
||||
|
@ -1,7 +1,7 @@
|
||||
package cn.tursom.database
|
||||
|
||||
import cn.tursom.core.InstantAllocator
|
||||
import cn.tursom.core.getClassByPackage
|
||||
import cn.tursom.core.reflect.InstantAllocator
|
||||
import cn.tursom.core.uncheckedCast
|
||||
import org.ktorm.schema.BaseTable
|
||||
import org.ktorm.schema.Column
|
||||
|
@ -1,6 +1,6 @@
|
||||
package cn.tursom.database.mongodb
|
||||
|
||||
import cn.tursom.core.Parser
|
||||
import cn.tursom.core.reflect.Parser
|
||||
import org.bson.Document
|
||||
|
||||
interface BsonFactory<T> {
|
||||
|
@ -1,6 +1,6 @@
|
||||
package cn.tursom.database.mongodb.spring
|
||||
|
||||
import cn.tursom.core.Parser
|
||||
import cn.tursom.core.reflect.Parser
|
||||
import org.bson.Document
|
||||
|
||||
interface BsonFactory<T> {
|
||||
|
Loading…
Reference in New Issue
Block a user