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

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

package name.remal

import org.objectweb.asm.Opcodes.ACONST_NULL
import org.objectweb.asm.Opcodes.DCONST_0
import org.objectweb.asm.Opcodes.DCONST_1
import org.objectweb.asm.Opcodes.FCONST_0
import org.objectweb.asm.Opcodes.FCONST_1
import org.objectweb.asm.Opcodes.FCONST_2
import org.objectweb.asm.Opcodes.ICONST_0
import org.objectweb.asm.Opcodes.ICONST_1
import org.objectweb.asm.Opcodes.LCONST_0
import org.objectweb.asm.Type
import org.objectweb.asm.Type.getType
import org.objectweb.asm.tree.AbstractInsnNode
import org.objectweb.asm.tree.InsnNode
import org.objectweb.asm.tree.LdcInsnNode
import org.objectweb.asm.tree.TypeAnnotationNode

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


fun AbstractInsnNode.getPrevious(predicate: (node: AbstractInsnNode) -> Boolean): AbstractInsnNode? {
    var node = previous
    while (node != null) {
        if (predicate(node)) return node
        node = node.previous
    }
    return null
}

fun AbstractInsnNode.getNext(predicate: (node: AbstractInsnNode) -> Boolean): AbstractInsnNode? {
    var node = next
    while (node != null) {
        if (predicate(node)) return node
        node = node.next
    }
    return null
}

fun Any?.toInsnNode() = when (this) {
    null -> InsnNode(ACONST_NULL)
    is Boolean -> if (this) InsnNode(ICONST_1) else InsnNode(ICONST_0)
    is Char -> this.toInt().let {
        if (0 <= it && it <= 5) {
            InsnNode(ICONST_0 + it)
        } else {
            LdcInsnNode(it)
        }
    }
    is Byte -> this.toInt().let {
        if (-1 <= it && it <= 5) {
            InsnNode(ICONST_0 + it)
        } else {
            LdcInsnNode(it)
        }
    }
    is Short -> this.toInt().let {
        if (-1 <= it && it <= 5) {
            InsnNode(ICONST_0 + it)
        } else {
            LdcInsnNode(it)
        }
    }
    is Int -> this.let {
        if (-1 <= it && it <= 5) {
            InsnNode(ICONST_0 + it)
        } else {
            LdcInsnNode(it)
        }
    }
    is Float -> this.let {
        if (0.0f == it) {
            InsnNode(FCONST_0)
        } else if (1.0f == it) {
            InsnNode(FCONST_1)
        } else if (2.0f == it) {
            InsnNode(FCONST_2)
        } else {
            LdcInsnNode(it)
        }
    }
    is Long -> this.let {
        if (0L <= it && it <= 1L) {
            InsnNode(LCONST_0 + it.toInt())
        } else {
            LdcInsnNode(it)
        }
    }
    is Double -> this.let {
        if (0.0 == it) {
            InsnNode(DCONST_0)
        } else if (1.0 == it) {
            InsnNode(DCONST_1)
        } else {
            LdcInsnNode(it)
        }
    }
    is String -> LdcInsnNode(this)
    is Type -> LdcInsnNode(this)
    is Class<*> -> LdcInsnNode(getType(this))
    else -> throw IllegalArgumentException("$this is not a constant")
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy