Skip to content

Commit

Permalink
fix(core.transform-kit): 检查缺少方法时先看旧类是否有实现
Browse files Browse the repository at this point in the history
典型的场景应该是androidx等库对新版本Android SDK新增API的依赖非常及时,
但这些依赖并不总是有用。在低版本Android SDK上编译时,新增API不存在对
这些库实际上没有影响。

我们检查替换类名时也应该先看看原先依赖的方法是否能找到。如果本来就找不到,
那我们的新类也没必要一定实现缺失的方法。

#1251
  • Loading branch information
shifujun committed Dec 12, 2023
1 parent 8bac299 commit d9deb2f
Showing 1 changed file with 19 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import javassist.expr.ExprEditor
import javassist.expr.MethodCall

object ReplaceClassName {
private val mNewNames = mutableSetOf<String>()
private val oldToNewRenameMap = mutableMapOf<String, String>()

/**
* MutableMap<defClass, MutableMap<method, MutableSet<useClass>>>
Expand All @@ -34,13 +34,13 @@ object ReplaceClassName {
mutableMapOf()

fun resetErrorCount() {
mNewNames.clear()
oldToNewRenameMap.clear()
errorResult.clear()
}

fun replaceClassName(ctClass: CtClass, oldName: String, newName: String) {
ctClass.replaceClassName(oldName, newName)
mNewNames.add(newName)
oldToNewRenameMap[oldName] = newName
}

fun checkAll(
Expand All @@ -49,9 +49,12 @@ object ReplaceClassName {
): Map<String, Map<String, Set<String>>> {
inputClassNames.forEach { inputClassName ->
val inputClass = classPool[inputClassName]
if (inputClass.refClasses.any { mNewNames.contains(it) }) {
mNewNames.forEach { newName ->
inputClass.checkMethodExist(classPool[newName])
val oldNames = oldToNewRenameMap.keys
val newNames = oldToNewRenameMap.values
if (inputClass.refClasses.any { newNames.contains(it) }) {
oldNames.forEach { oldName ->
val newName = oldToNewRenameMap[oldName]
inputClass.checkMethodExist(classPool[oldName], classPool[newName])
}
}
}
Expand All @@ -61,14 +64,21 @@ object ReplaceClassName {
/**
* 检查ctClass对refClassName引用的方法确实都存在
*/
private fun CtClass.checkMethodExist(refClass: CtClass) {
private fun CtClass.checkMethodExist(oldClass: CtClass, newClass: CtClass) {
val invokeClass = name
val refClassName = refClass.name
val refClassName = newClass.name
instrument(object : ExprEditor() {
override fun edit(m: MethodCall) {
if (m.className == refClassName) {
try {
refClass.getMethod(m.methodName, m.signature)
oldClass.getMethod(m.methodName, m.signature)
} catch (ignored: NotFoundException) {
//替换前旧的类就没有这个方法,就不用管替换后的类是否实现了。
return
}

try {
newClass.getMethod(m.methodName, m.signature)
} catch (ignored: NotFoundException) {
val methodString = "${m.methodName}:${m.signature}"
var methodMap = errorResult[refClassName]
Expand Down

0 comments on commit d9deb2f

Please sign in to comment.