All Downloads are FREE. Search and download functionalities are using the official Maven repository.

name.remal.org.objectweb.asm.tree.MethodNode.kt Maven / Gradle / Ivy

package name.remal

import org.objectweb.asm.Type
import org.objectweb.asm.tree.AbstractInsnNode
import org.objectweb.asm.tree.AnnotationNode
import org.objectweb.asm.tree.JumpInsnNode
import org.objectweb.asm.tree.LabelNode
import org.objectweb.asm.tree.LineNumberNode
import org.objectweb.asm.tree.LookupSwitchInsnNode
import org.objectweb.asm.tree.MethodNode
import org.objectweb.asm.tree.TableSwitchInsnNode
import org.objectweb.asm.tree.TypeAnnotationNode

val MethodNode.hasParameters: Boolean get() = Type.getArgumentTypes(desc).isNotEmpty()

val MethodNode.allAnnotations: List
    get() = sequenceOf(visibleAnnotations, invisibleAnnotations)
        .filterNotNull()
        .flatten()
        .toList()

val MethodNode.allTypeAnnotations: List
    get() = sequenceOf(visibleTypeAnnotations, invisibleTypeAnnotations)
        .filterNotNull()
        .flatten()
        .toList()

val MethodNode.unusedLabelNodes: Set
    get() {
        val instructions = this.instructions ?: return emptySet()
        return buildSet {
            instructions.forEach { if (it is LabelNode) add(it) }

            run {
                var index = -1
                while ((++index) < instructions.size()) {
                    val insn = instructions[index]
                    if (insn is LabelNode) {
                        remove(insn)
                        break
                    } else if (insn is LineNumberNode) {
                        continue
                    } else {
                        break
                    }
                }
            }

            if (isNotEmpty()) {
                tryCatchBlocks?.forEach { remove(it.start); remove(it.end); remove(it.handler) }
                localVariables?.forEach { remove(it.start); remove(it.end) }
                visibleLocalVariableAnnotations?.forEach { it.start?.let(this::removeAll); it.end?.let(this::removeAll) }
                invisibleLocalVariableAnnotations?.forEach { it.start?.let(this::removeAll); it.end?.let(this::removeAll) }
                instructions.forEach {
                    if (it is JumpInsnNode) remove(it.label)
                    if (it is LookupSwitchInsnNode) {
                        remove(it.dflt)
                        it.labels?.let(this::removeAll)
                    }
                    if (it is TableSwitchInsnNode) {
                        remove(it.dflt)
                        it.labels?.let(this::removeAll)
                    }
                }
            }
        }
    }


fun MethodNode.getAllParameterAnnotations(paramIndex: Int): List {
    return sequenceOf(visibleParameterAnnotations, invisibleParameterAnnotations)
        .flatMap { it?.getOrNull(paramIndex)?.asSequence() ?: emptySequence() }
        .filterNotNull()
        .toList()
}


data class InstructionNodeContext(
    val node: T,
    val previousNode: AbstractInsnNode?,
    val nextNode: AbstractInsnNode?
)

data class InstructionNodeFilter(
    val nodeType: Class,
    val predicate: ((context: InstructionNodeContext) -> Boolean)? = null
)

fun  Class.toInstructionNodeFilter() = InstructionNodeFilter(this)




© 2015 - 2025 Weber Informatics LLC | Privacy Policy