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

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

There is a newer version: 1.26.147
Show newest version
package name.remal

import name.remal.asm.AsmUtils.fromJavaToBytecodeAnnotationValue
import org.objectweb.asm.Type
import org.objectweb.asm.Type.getDescriptor
import org.objectweb.asm.tree.AnnotationNode
import kotlin.reflect.KClass
import kotlin.reflect.KProperty1
import kotlin.reflect.jvm.javaMethod

val AnnotationNode.mapValues: Map
    get() = buildMap {
        if (values != null) {
            val iterator = values.iterator()
            while (iterator.hasNext()) {
                val name = iterator.next() as String
                val value = iterator.next()
                put(name, value)
            }
        }
    }


operator fun AnnotationNode.get(fieldName: String): Any? {
    if (values == null) return null
    val iterator = values.iterator()
    while (iterator.hasNext()) {
        val name = iterator.next() as String
        val value = iterator.next()
        if (fieldName == name) {
            return value
        }
    }
    return null
}

private fun AnnotationNode.getImpl(annotationProperty: KProperty1): Any? {
    val method = annotationProperty.getter.javaMethod ?: throw IllegalArgumentException("annotationProperty must be direct annotation method reference")
    if (desc != getDescriptor(method.declaringClass)) throw IllegalArgumentException("$method is not a method of $desc")
    return get(method.name)
}

@JvmName("getByte")
operator fun AnnotationNode.get(annotationProperty: KProperty1): Byte? = getImpl(annotationProperty) as? Byte

@JvmName("getBoolean")
operator fun AnnotationNode.get(annotationProperty: KProperty1): Boolean? = getImpl(annotationProperty) as? Boolean

@JvmName("getChar")
operator fun AnnotationNode.get(annotationProperty: KProperty1): Char? = getImpl(annotationProperty) as? Char

@JvmName("getShort")
operator fun AnnotationNode.get(annotationProperty: KProperty1): Short? = getImpl(annotationProperty) as? Short

@JvmName("getInt")
operator fun AnnotationNode.get(annotationProperty: KProperty1): Int? = getImpl(annotationProperty) as? Int

@JvmName("getLong")
operator fun AnnotationNode.get(annotationProperty: KProperty1): Long? = getImpl(annotationProperty) as? Long

@JvmName("getFloat")
operator fun AnnotationNode.get(annotationProperty: KProperty1): Float? = getImpl(annotationProperty) as? Float

@JvmName("getDouble")
operator fun AnnotationNode.get(annotationProperty: KProperty1): Double? = getImpl(annotationProperty) as? Double

@JvmName("getString")
operator fun AnnotationNode.get(annotationProperty: KProperty1): String? = getImpl(annotationProperty) as? String

@JvmName("getClass")
operator fun AnnotationNode.get(annotationProperty: KProperty1>): Type? = getImpl(annotationProperty) as? Type

@JvmName("getEnum")
operator fun AnnotationNode.get(annotationProperty: KProperty1>): Array? = (getImpl(annotationProperty) as? Array<*>)?.nullIf { isArrayOf() }?.uncheckedCast()

@JvmName("getAnnotation")
operator fun AnnotationNode.get(annotationProperty: KProperty1): AnnotationNode? = getImpl(annotationProperty) as? AnnotationNode

@JvmName("getByteArray")
operator fun AnnotationNode.get(annotationProperty: KProperty1>): MutableList? = (getImpl(annotationProperty) as? MutableList<*>)?.nullIf { any { it !is Byte } }?.uncheckedCast()

@JvmName("getBooleanArray")
operator fun AnnotationNode.get(annotationProperty: KProperty1>): MutableList? = (getImpl(annotationProperty) as? MutableList<*>)?.nullIf { any { it !is Boolean } }?.uncheckedCast()

@JvmName("getCharArray")
operator fun AnnotationNode.get(annotationProperty: KProperty1>): MutableList? = (getImpl(annotationProperty) as? MutableList<*>)?.nullIf { any { it !is Char } }?.uncheckedCast()

@JvmName("getShortArray")
operator fun AnnotationNode.get(annotationProperty: KProperty1>): MutableList? = (getImpl(annotationProperty) as? MutableList<*>)?.nullIf { any { it !is Short } }?.uncheckedCast()

@JvmName("getIntArray")
operator fun AnnotationNode.get(annotationProperty: KProperty1>): MutableList? = (getImpl(annotationProperty) as? MutableList<*>)?.nullIf { any { it !is Int } }?.uncheckedCast()

@JvmName("getLongArray")
operator fun AnnotationNode.get(annotationProperty: KProperty1>): MutableList? = (getImpl(annotationProperty) as? MutableList<*>)?.nullIf { any { it !is Long } }?.uncheckedCast()

@JvmName("getFloatArray")
operator fun AnnotationNode.get(annotationProperty: KProperty1>): MutableList? = (getImpl(annotationProperty) as? MutableList<*>)?.nullIf { any { it !is Float } }?.uncheckedCast()

@JvmName("getDoubleArray")
operator fun AnnotationNode.get(annotationProperty: KProperty1>): MutableList? = (getImpl(annotationProperty) as? MutableList<*>)?.nullIf { any { it !is Double } }?.uncheckedCast()

@JvmName("getStringArray")
operator fun AnnotationNode.get(annotationProperty: KProperty1>): MutableList? = (getImpl(annotationProperty) as? MutableList<*>)?.nullIf { any { it !is String } }?.uncheckedCast()

@JvmName("getClassArray")
operator fun AnnotationNode.get(annotationProperty: KProperty1>>): MutableList? = (getImpl(annotationProperty) as? MutableList<*>)?.nullIf { any { it !is Type } }?.uncheckedCast()

@JvmName("getEnumArray")
operator fun AnnotationNode.get(annotationProperty: KProperty1>>): MutableList>? = (getImpl(annotationProperty) as? MutableList<*>)?.nullIf { any { !(it is Array<*> && it.isArrayOf()) } }?.uncheckedCast()

@JvmName("getAnnotationArray")
operator fun AnnotationNode.get(annotationProperty: KProperty1>): MutableList? = (getImpl(annotationProperty) as? MutableList<*>)?.nullIf { any { it !is AnnotationNode } }?.uncheckedCast()


operator fun AnnotationNode.set(fieldName: String, value: Any?) {
    if (value == null) {
        if (values != null) {
            val iterator = values.iterator()
            while (iterator.hasNext()) {
                val name = iterator.next() as String
                if (fieldName == name) iterator.remove()
                iterator.next()
                if (fieldName == name) iterator.remove()
            }
        }

    } else {
        val transformedValue = fromJavaToBytecodeAnnotationValue(value)
        var replaced = false
        (0 until values.size step 2).forEach { index ->
            val name = values[index] as String
            if (fieldName == name) {
                values[index + 1] = transformedValue
                replaced = true
            }
        }
        if (!replaced) {
            values.add(fieldName)
            values.add(transformedValue)
        }
    }
}

private fun AnnotationNode.setImpl(annotationProperty: KProperty1, value: Any?) {
    val method = annotationProperty.getter.javaMethod ?: throw IllegalArgumentException("annotationProperty must be direct annotation method reference")
    if (desc != getDescriptor(method.declaringClass)) throw IllegalArgumentException("$method is not a method of $desc")
    set(method.name, value)
}

@JvmName("setByte")
operator fun AnnotationNode.set(annotationProperty: KProperty1, value: Byte?) = setImpl(annotationProperty, value)

@JvmName("setBoolean")
operator fun AnnotationNode.set(annotationProperty: KProperty1, value: Boolean?) = setImpl(annotationProperty, value)

@JvmName("setChar")
operator fun AnnotationNode.set(annotationProperty: KProperty1, value: Char?) = setImpl(annotationProperty, value)

@JvmName("setShort")
operator fun AnnotationNode.set(annotationProperty: KProperty1, value: Short?) = setImpl(annotationProperty, value)

@JvmName("setInt")
operator fun AnnotationNode.set(annotationProperty: KProperty1, value: Int?) = setImpl(annotationProperty, value)

@JvmName("setLong")
operator fun AnnotationNode.set(annotationProperty: KProperty1, value: Long?) = setImpl(annotationProperty, value)

@JvmName("setFloat")
operator fun AnnotationNode.set(annotationProperty: KProperty1, value: Float?) = setImpl(annotationProperty, value)

@JvmName("setDouble")
operator fun AnnotationNode.set(annotationProperty: KProperty1, value: Double?) = setImpl(annotationProperty, value)

@JvmName("setString")
operator fun AnnotationNode.set(annotationProperty: KProperty1, value: String?) = setImpl(annotationProperty, value)

@JvmName("setType")
operator fun AnnotationNode.set(annotationProperty: KProperty1>, value: Type?) = setImpl(annotationProperty, value)

@JvmName("setTypeAsClass")
operator fun  AnnotationNode.set(annotationProperty: KProperty1>, value: Class?) = setImpl(annotationProperty, value)

@JvmName("setTypeAsKClass")
operator fun  AnnotationNode.set(annotationProperty: KProperty1>, value: KClass?) = setImpl(annotationProperty, value?.java)

@JvmName("setEnum")
operator fun AnnotationNode.set(annotationProperty: KProperty1>, value: Array?) = setImpl(annotationProperty, value)

@JvmName("setEnumAsEnum")
operator fun > AnnotationNode.set(annotationProperty: KProperty1>, value: Enum?) = setImpl(annotationProperty, value)

@JvmName("setAnnotation")
operator fun AnnotationNode.set(annotationProperty: KProperty1, value: AnnotationNode?) = setImpl(annotationProperty, value)

@JvmName("setAnnotationAsAnnotation")
operator fun  AnnotationNode.set(annotationProperty: KProperty1, value: T?) = setImpl(annotationProperty, value)

@JvmName("setByteArray")
operator fun AnnotationNode.set(annotationProperty: KProperty1>, value: List?) = setImpl(annotationProperty, value)

@JvmName("setBooleanArray")
operator fun AnnotationNode.set(annotationProperty: KProperty1>, value: List?) = setImpl(annotationProperty, value)

@JvmName("setCharArray")
operator fun AnnotationNode.set(annotationProperty: KProperty1>, value: List?) = setImpl(annotationProperty, value)

@JvmName("setShortArray")
operator fun AnnotationNode.set(annotationProperty: KProperty1>, value: List?) = setImpl(annotationProperty, value)

@JvmName("setIntArray")
operator fun AnnotationNode.set(annotationProperty: KProperty1>, value: List?) = setImpl(annotationProperty, value)

@JvmName("setLongArray")
operator fun AnnotationNode.set(annotationProperty: KProperty1>, value: List?) = setImpl(annotationProperty, value)

@JvmName("setFloatArray")
operator fun AnnotationNode.set(annotationProperty: KProperty1>, value: List?) = setImpl(annotationProperty, value)

@JvmName("setDoubleArray")
operator fun AnnotationNode.set(annotationProperty: KProperty1>, value: List?) = setImpl(annotationProperty, value)

@JvmName("setStringArray")
operator fun AnnotationNode.set(annotationProperty: KProperty1>, value: List?) = setImpl(annotationProperty, value)

@JvmName("setTypeArray")
operator fun AnnotationNode.set(annotationProperty: KProperty1>>, value: List?) = setImpl(annotationProperty, value)

@JvmName("setTypeAsClassArray")
operator fun  AnnotationNode.set(annotationProperty: KProperty1>>, value: List>?) = setImpl(annotationProperty, value)

@JvmName("setTypeAsKClassArray")
operator fun  AnnotationNode.set(annotationProperty: KProperty1>>, value: List>?) = setImpl(annotationProperty, value?.map(KClass<*>::java))

@JvmName("setEnumArray")
operator fun AnnotationNode.set(annotationProperty: KProperty1>>, value: List>?) = setImpl(annotationProperty, value)

@JvmName("setEnumAsEnumArray")
operator fun > AnnotationNode.set(annotationProperty: KProperty1>>, value: List>?) = setImpl(annotationProperty, value)

@JvmName("setAnnotationArray")
operator fun AnnotationNode.set(annotationProperty: KProperty1>, value: List?) = setImpl(annotationProperty, value)

@JvmName("setAnnotationAsAnnotationArray")
operator fun  AnnotationNode.set(annotationProperty: KProperty1>, value: List?) = setImpl(annotationProperty, value)




© 2015 - 2024 Weber Informatics LLC | Privacy Policy