Read new Metadata annotation in check-library-abi-version.kts

This commit is contained in:
Alexander Udalov
2016-01-11 17:28:17 +03:00
parent a4daa08e5c
commit 86bbc9f15b
@@ -26,35 +26,47 @@ import org.jetbrains.org.objectweb.asm.*
* Some additional information is printed to stderr * Some additional information is printed to stderr
*/ */
fun loadAbiVersionOfClass(bytes: ByteArray): IntArray? { fun loadClassVersions(bytes: ByteArray): Pair<List<Int>, List<Int>>? {
var result: IntArray? = null var metadata: IntArray? = null
var bytecode: IntArray? = null
ClassReader(bytes).accept(object : ClassVisitor(Opcodes.ASM5) { ClassReader(bytes).accept(object : ClassVisitor(Opcodes.ASM5) {
override fun visitAnnotation(desc: String, visible: Boolean): AnnotationVisitor? { override fun visitAnnotation(desc: String, visible: Boolean): AnnotationVisitor? {
if (desc == "Lkotlin/jvm/internal/KotlinClass;") { return when (desc) {
return object : AnnotationVisitor(Opcodes.ASM5) { "Lkotlin/Metadata;" ->
override fun visit(name: String, value: Any) { object : AnnotationVisitor(Opcodes.ASM5) {
if (name == "version") { override fun visit(name: String, value: Any) {
result = value as IntArray when (name) {
} "mv" -> metadata = value as IntArray
else if (name == "abiVersion") { "bv" -> bytecode = value as IntArray
result = intArrayOf(0, value as Int, 0) }
} }
} }
} "Lkotlin/jvm/internal/KotlinClass;" ->
object : AnnotationVisitor(Opcodes.ASM5) {
override fun visit(name: String, value: Any) {
if (name == "version") {
metadata = value as IntArray
bytecode = metadata
}
}
}
else -> null
} }
return null
} }
}, 0) }, 0)
return result return if (metadata != null && bytecode != null) Pair(metadata!!.toList(), bytecode!!.toList()) else null
} }
fun loadVersion(library: File): IntArray { fun loadVersions(library: File): String {
val jarFile = JarFile(library) val jarFile = JarFile(library)
try { try {
for (entry in jarFile.entries()) { for (entry in jarFile.entries()) {
if (entry.getName().endsWith(".class")) { if (entry.getName().endsWith(".class")) {
val classBytes = jarFile.getInputStream(entry).readBytes() val classBytes = jarFile.getInputStream(entry).readBytes()
loadAbiVersionOfClass(classBytes)?.let { return it } loadClassVersions(classBytes)?.let {
val (metadata, bytecode) = it
return "metadata = ${metadata.joinToString(".")}, bytecode = ${bytecode.joinToString(".")}"
}
} }
} }
} }
@@ -74,13 +86,13 @@ fun main(args: Array<String>) {
val library1 = File(args[0]) val library1 = File(args[0])
val library2 = File(args[1]) val library2 = File(args[1])
val v1 = loadVersion(library1).joinToString(".") val v1 = loadVersions(library1)
val v2 = loadVersion(library2).joinToString(".") val v2 = loadVersions(library2)
if (v1 != v2) { if (v1 != v2) {
System.err.println("ABI versions differ:") System.err.println("ABI versions differ:")
System.err.println(" $library1 has version $v1") System.err.println(" $library1: $v1")
System.err.println(" $library2 has version $v2") System.err.println(" $library2: $v2")
System.exit(3) System.exit(3)
} }
} }