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

name.remal.building.gradle_plugins.utils.asmUtils.kt Maven / Gradle / Ivy

There is a newer version: 1.9.2
Show newest version
package name.remal.building.gradle_plugins.utils

import com.google.common.collect.ImmutableListMultimap
import com.google.common.collect.MultimapBuilder
import org.objectweb.asm.*
import org.objectweb.asm.tree.AnnotationNode
import org.objectweb.asm.tree.ClassNode

internal val ASM_API = run {
    val field = ClassVisitor::class.java.getDeclaredField("api").apply { isAccessible = true }
    return@run field.getInt(ClassWriter(0))
}


internal val ClassNode.annotations: List
    get() {
        val annotations: MutableList = mutableListOf()
        this.visibleAnnotations?.let { annotations += it }
        this.invisibleAnnotations?.let { annotations += it }
        return annotations
    }


internal val AnnotationNode.valuesMultimap: ImmutableListMultimap
    get() {
        values.let { values ->
            if (null == values || values.isEmpty()) return ImmutableListMultimap.of()
            val valuesMultimap = MultimapBuilder.hashKeys().arrayListValues().build()
            (0..values.size - 1 step 2).forEach { index ->
                val field = values[index] as String
                val value = values[index + 1]
                if (value is List<*>) {
                    value.forEach { valuesMultimap.put(field, it) }
                } else {
                    valuesMultimap.put(field, value)
                }
            }
            return ImmutableListMultimap.copyOf(valuesMultimap)
        }
    }

private val stringsArrayClass = arrayOf().javaClass
@Suppress("UNCHECKED_CAST")
internal val AnnotationNode.stringValuesMultimap: ImmutableListMultimap
    get() {
        val valuesMultimap = this.valuesMultimap
        if (valuesMultimap.isEmpty) return ImmutableListMultimap.of()
        val stringValuesMultimap = MultimapBuilder.hashKeys().arrayListValues().build()
        valuesMultimap.keySet().forEach forEachKey@ { key ->
            valuesMultimap[key].forEach { value ->
                if (value is AnnotationNode) {
                    // do nothing
                } else if (value is Type) {
                    stringValuesMultimap.put(key, value.className)
                } else if (stringsArrayClass.isAssignableFrom(value.javaClass)) {
                    value as Array
                    val desc = value[0]
                    stringValuesMultimap.put(key, desc.substring(1, desc.length - 2) + '.' + value[1])
                } else {
                    stringValuesMultimap.put(key, value.toString())
                }
            }
        }
        return ImmutableListMultimap.copyOf(stringValuesMultimap)
    }


internal class OnlyClassInfoVisitor(cv: ClassVisitor?) : ClassVisitor(ASM_API, cv) {

    override fun visitField(access: Int, name: String?, fieldDesc: String?, signature: String?, value: Any?): FieldVisitor? {
        return null
    }

    override fun visitMethod(access: Int, name: String?, methodDesc: String?, signature: String?, exceptions: Array?): MethodVisitor? {
        return null
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy