Move strip-kotlin-annotations script to buildSrc

... and invoke it directly in kotlin-reflect's build file, instead of
running another instance of compiler to evaluate a script. Also only
strip kotlin.Metadata, since it's the only annotation with heavy
metadata on Kotlin-generated class files
This commit is contained in:
Alexander Udalov
2017-11-07 17:27:54 +01:00
parent 38bee07fd0
commit 208e68a968
7 changed files with 24 additions and 73 deletions
+1
View File
@@ -45,6 +45,7 @@ dependencies {
// TODO: adding the dep to the plugin breaks the build unexpectedly, resolve and uncomment
// compile("org.jetbrains.kotlin:kotlin-gradle-plugin:${rootProject.extra["bootstrap_kotlin_version"]}")
compile("com.github.jengelman.gradle.plugins:shadow:${property("versions.shadow")}")
compile("org.ow2.asm:asm-all:6.0_BETA")
}
samWithReceiver {
+63
View File
@@ -0,0 +1,63 @@
@file:Suppress("unused") // usages in build scripts are not tracked properly
import org.gradle.api.logging.Logger
import org.objectweb.asm.*
import java.io.BufferedOutputStream
import java.io.File
import java.io.FileOutputStream
import java.util.jar.JarFile
import java.util.zip.ZipOutputStream
/**
* Removes @kotlin.Metadata annotations from compiled Kotlin classes
*/
fun stripMetadata(logger: Logger, classNamePattern: String, inFile: File, outFile: File) {
val classRegex = classNamePattern.toRegex()
assert(inFile.exists()) { "Input file not found at $inFile" }
fun transform(entryName: String, bytes: ByteArray): ByteArray {
if (!entryName.endsWith(".class")) return bytes
if (!classRegex.matches(entryName.removeSuffix(".class"))) return bytes
var changed = false
val classWriter = ClassWriter(0)
val classVisitor = object : ClassVisitor(Opcodes.ASM5, classWriter) {
override fun visitAnnotation(desc: String, visible: Boolean): AnnotationVisitor? {
if (Type.getType(desc).internalName == "kotlin/Metadata") {
changed = true
return null
}
return super.visitAnnotation(desc, visible)
}
}
ClassReader(bytes).accept(classVisitor, 0)
if (!changed) return bytes
return classWriter.toByteArray()
}
ZipOutputStream(BufferedOutputStream(FileOutputStream(outFile))).use { outJar ->
JarFile(inFile).use { inJar ->
for (entry in inJar.entries()) {
val inBytes = inJar.getInputStream(entry).readBytes()
val outBytes = transform(entry.name, inBytes)
if (inBytes.size < outBytes.size) {
error("Size increased for ${entry.name}: was ${inBytes.size} bytes, became ${outBytes.size} bytes")
}
entry.compressedSize = -1L
outJar.putNextEntry(entry)
outJar.write(outBytes)
outJar.closeEntry()
}
}
}
logger.info("Stripping @kotlin.Metadata annotations from all classes in $inFile")
logger.info("Class name pattern: $classNamePattern")
logger.info("Input file size: ${inFile.length()} bytes")
logger.info("Output written to $outFile")
logger.info("Output file size: ${outFile.length()} bytes")
}