com.flyjingfish.android_aop_plugin.scanner_visitor.MethodParamNamesScanner.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of android-aop-plugin Show documentation
Show all versions of android-aop-plugin Show documentation
Lightweight Aop for Android platform, you deserve it, action is worse than your heartbeat
package com.flyjingfish.android_aop_plugin.scanner_visitor
import org.objectweb.asm.ClassReader
import org.objectweb.asm.tree.ClassNode
import org.objectweb.asm.tree.LocalVariableNode
import org.objectweb.asm.tree.MethodNode
import kotlin.math.min
class MethodParamNamesScanner(inputStreamBytes: ByteArray) {
private val methods: List
init {
val cr = ClassReader(inputStreamBytes)
val cn = ClassNode()
cr.accept(cn, ClassReader.EXPAND_FRAMES)
val methods = cn.methods
this.methods = methods
}
/**
* 获取参数名列表辅助方法
*
* @param name
* @param desc
* @param size
* @return
*/
fun getParamNames(
name: String,
desc: String,
size: Int
): List {
val list: MutableList = ArrayList()
for (i in methods.indices) {
val varNames = mutableMapOf()
val method = methods[i]
if (method.desc == desc && method.name == name) {
val localVariables = method.localVariables ?: continue
for (l in localVariables.indices) {
val varName = localVariables[l].name
// index-记录了正确的方法本地变量索引。(方法本地变量顺序可能会被打乱。而index记录了原始的顺序)
val index = localVariables[l].index
if ("this" != varName)
varNames[index] = (LocalVariable(index, varName))
}
val sortedMap = varNames.entries.sortedBy { it.key }.associate { it.toPair() }
val tmpArr = mutableListOf()
for (entry in sortedMap.entries) {
tmpArr.add(entry.value)
}
val len = min(tmpArr.size , size)
for (j in 0 until len) {
list.add(tmpArr[j].name)
}
break
}
}
if (size > 0 && list.isEmpty()) {
for (i in 0 until size) {
list.add("var$i")
}
}
return list
}
fun getParamInfo(
name: String,
desc: String,
size: Int
): List {
val list: MutableList = ArrayList()
for (i in methods.indices) {
val varNames = mutableMapOf()
val method = methods[i]
if (method.desc == desc && method.name == name) {
val localVariables = method.localVariables ?: continue
for (l in localVariables.indices) {
val varName = localVariables[l].name
// index-记录了正确的方法本地变量索引。(方法本地变量顺序可能会被打乱。而index记录了原始的顺序)
val index = localVariables[l].index
if ("this" != varName)
varNames[index] = (LocalNode(index, localVariables[l]))
}
val sortedMap = varNames.entries.sortedBy { it.key }.associate { it.toPair() }
val tmpArr = mutableListOf()
for (entry in sortedMap.entries) {
tmpArr.add(entry.value)
}
val len = min(tmpArr.size , size)
for (j in 0 until len) {
list.add(tmpArr[j].variableNode)
}
break
}
}
return list
}
fun getMethodNode(
name: String,
desc: String
): MethodNode?{
for (i in methods.indices) {
val method = methods[i]
if (method.desc == desc && method.name == name) {
return method
}
}
return null
}
/**
* 方法本地变量索引和参数名封装
* @author xby Administrator
*/
private class LocalVariable(var index: Int, var name: String) :
Comparable {
override fun compareTo(other: LocalVariable): Int {
return index - other.index
}
}
private class LocalNode(var index: Int, var variableNode: LocalVariableNode) :
Comparable {
override fun compareTo(other: LocalVariable): Int {
return index - other.index
}
}
}