kotlinx.atomicfu.transformer.AtomicFUTransformerBase.kt Maven / Gradle / Ivy
/*
* Copyright 2017-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
*/
package kotlinx.atomicfu.transformer
import org.objectweb.asm.tree.AbstractInsnNode
import org.objectweb.asm.tree.InsnList
import java.io.File
import org.slf4j.LoggerFactory
abstract class AtomicFUTransformerBase(
var inputDir: File,
var outputDir: File
) {
protected operator fun File.div(child: String) =
File(this, child)
protected fun File.toOutputFile(): File =
outputDir / relativeTo(inputDir).toString()
private val logger = LoggerFactory.getLogger(this::class.java)
protected fun File.mkdirsAndWrite(outBytes: ByteArray) {
parentFile.mkdirs()
writeBytes(outBytes) // write resulting bytes
}
protected fun File.isClassFile() = toString().endsWith(".class")
var verbose = true
protected var lastError: Throwable? = null
protected var transformed = false
data class SourceInfo(
val method: MethodId,
val source: String?,
val i: AbstractInsnNode? = null,
val insnList: InsnList? = null
) {
override fun toString(): String = buildString {
source?.let { append("$it:") }
i?.line?.let { append("$it:") }
append(" $method")
}
}
private fun format(message: String, sourceInfo: SourceInfo? = null): String {
var loc = if (sourceInfo == null) "" else sourceInfo.toString() + ": "
if (verbose && sourceInfo != null && sourceInfo.i != null)
loc += sourceInfo.i.atIndex(sourceInfo.insnList)
return "$loc$message"
}
protected fun info(message: String, sourceInfo: SourceInfo? = null) {
logger.info(format(message, sourceInfo))
}
protected fun debug(message: String, sourceInfo: SourceInfo? = null) {
logger.debug(format(message, sourceInfo))
}
protected fun error(message: String, sourceInfo: SourceInfo? = null) {
logger.error(format(message, sourceInfo))
if (lastError == null) lastError = TransformerException(message)
}
abstract fun transform()
}
class TransformerException(message: String, cause: Throwable? = null) : Exception(message, cause)