Skip to content

Commit

Permalink
1.0.24 允许自选访问模式
Browse files Browse the repository at this point in the history
  • Loading branch information
Bkm016 committed Aug 24, 2024
1 parent eaa6ba8 commit c386f77
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 16 deletions.
28 changes: 28 additions & 0 deletions analyser/src/main/kotlin/org/tabooproject/reflex/AnalyseMode.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package org.tabooproject.reflex

enum class AnalyseMode {

/**
* 反射优先
* 失败会尝试使用 ASM 模式
*/
REFLECTION_FIRST,

/**
* 仅反射
* 失败会抛出异常
*/
REFLECTION_ONLY,

/**
* ASM 优先
* 失败会尝试使用反射模式
*/
ASM_FIRST,

/**
* 仅 ASM
* 失败会抛出异常
*/
ASM_ONLY,
}
38 changes: 31 additions & 7 deletions analyser/src/main/kotlin/org/tabooproject/reflex/ClassAnalyser.kt
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,37 @@ import org.tabooproject.reflex.reflection.InstantClassMethod
object ClassAnalyser {

fun analyse(clazz: Class<*>): ClassStructure {
return try {
analyseByReflection(clazz)
} catch (ex: Throwable) {
when (ex) {
is NoClassDefFoundError, is ArrayStoreException -> analyseByASM(clazz)
else -> throw ex
return analyse(clazz, AnalyseMode.REFLECTION_FIRST)
}

fun analyse(clazz: Class<*>, mode: AnalyseMode): ClassStructure {
return when (mode) {
// 反射优先
AnalyseMode.REFLECTION_FIRST -> {
return try {
analyseByReflection(clazz)
} catch (ex: Throwable) {
when (ex) {
is NoClassDefFoundError, is ArrayStoreException -> analyseByASM(clazz)
else -> throw ex
}
}
}
// 仅反射
AnalyseMode.REFLECTION_ONLY -> analyseByReflection(clazz)
// ASM 优先
AnalyseMode.ASM_FIRST -> {
return try {
analyseByASM(clazz)
} catch (ex: Throwable) {
when (ex) {
is ClassNotFoundException -> analyseByReflection(clazz)
else -> throw ex
}
}
}
// 仅 ASM
AnalyseMode.ASM_ONLY -> analyseByASM(clazz)
}
}

Expand All @@ -37,7 +61,7 @@ object ClassAnalyser {
val resourceAsStream = clazz.getResourceAsStream("/${clazz.name.replace('.', '/')}.class")
if (resourceAsStream == null) {
// 无法从资源文件中找到对应的类文件,可能来自远程加载
throw IllegalStateException("Class ${clazz.name} not found (file not in the jar)")
throw ClassNotFoundException("Class ${clazz.name} not found (file not in the jar)")
}
val classReader = ClassReader(resourceAsStream)
val analyser = AsmClassVisitor(clazz, ClassWriter(ClassWriter.COMPUTE_MAXS))
Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
group=org.tabooproject.reflex
version=1.0.23
version=1.0.24
kotlin.incremental=true
kotlin.incremental.java=true
kotlin.caching.enabled=true
Expand Down
24 changes: 16 additions & 8 deletions reflex/src/main/kotlin/org/tabooproject/reflex/ReflexClass.kt
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,12 @@ class ReflexClass(val structure: ClassStructure) {
}

fun getField(name: String, findToParent: Boolean = true, remap: Boolean = true): ClassField {
var fixname = name
var fixed = name
if (remap) {
Reflex.remapper.forEach { fixname = it.field(structure.name ?: return@forEach, fixname) }
Reflex.remapper.forEach { fixed = it.field(structure.name ?: return@forEach, fixed) }
}
return try {
structure.getField(fixname)
structure.getField(fixed)
} catch (ex: NoSuchFieldException) {
if (findToParent) {
superclass?.getField(name, true, remap) ?: throw ex
Expand All @@ -34,12 +34,12 @@ class ReflexClass(val structure: ClassStructure) {
}

fun getMethod(name: String, findToParent: Boolean = true, remap: Boolean = true, vararg parameter: Any?): ClassMethod {
var fixname = name
var fixed = name
if (remap) {
Reflex.remapper.forEach { fixname = it.method(structure.name ?: return@forEach, fixname, *parameter) }
Reflex.remapper.forEach { fixed = it.method(structure.name ?: return@forEach, fixed, *parameter) }
}
return try {
structure.getMethod(fixname, *parameter)
structure.getMethod(fixed, *parameter)
} catch (ex: NoSuchMethodException) {
if (findToParent) {
try {
Expand All @@ -61,16 +61,24 @@ class ReflexClass(val structure: ClassStructure) {
companion object {

private val analyseMap = ConcurrentHashMap<String, ReflexClass>()

fun of(clazz: Class<*>): ReflexClass {
return of(clazz, true)
}

fun of(clazz: Class<*>, mode: AnalyseMode): ReflexClass {
return of(clazz, mode, true)
}

fun of(clazz: Class<*>, saving: Boolean): ReflexClass {
return of(clazz, AnalyseMode.REFLECTION_FIRST, saving)
}

fun of(clazz: Class<*>, mode: AnalyseMode, saving: Boolean): ReflexClass {
if (saving && analyseMap.containsKey(clazz.name)) {
return analyseMap[clazz.name]!!
}
return ReflexClass(ClassAnalyser.analyse(clazz)).apply {
return ReflexClass(ClassAnalyser.analyse(clazz, mode)).apply {
if (saving) {
analyseMap[clazz.name] = this
}
Expand Down

0 comments on commit c386f77

Please sign in to comment.