1 /* 2 * Copyright 2017-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. 3 */ 4 5 package kotlinx.atomicfu.transformer 6 7 import org.objectweb.asm.tree.AbstractInsnNode 8 import org.objectweb.asm.tree.InsnList 9 import java.io.File 10 import org.slf4j.LoggerFactory 11 12 abstract class AtomicFUTransformerBase( 13 var inputDir: File, 14 var outputDir: File 15 ) { divnull16 protected operator fun File.div(child: String) = 17 File(this, child) 18 19 protected fun File.toOutputFile(): File = 20 outputDir / relativeTo(inputDir).toString() 21 22 private val logger = LoggerFactory.getLogger(this::class.java) 23 24 protected fun File.mkdirsAndWrite(outBytes: ByteArray) { 25 parentFile.mkdirs() 26 writeBytes(outBytes) // write resulting bytes 27 } 28 isClassFilenull29 protected fun File.isClassFile() = toString().endsWith(".class") 30 31 var verbose = true 32 protected var lastError: Throwable? = null 33 protected var transformed = false 34 35 data class SourceInfo( 36 val method: MethodId, 37 val source: String?, 38 val i: AbstractInsnNode? = null, 39 val insnList: InsnList? = null 40 ) { 41 override fun toString(): String = buildString { 42 source?.let { append("$it:") } 43 i?.line?.let { append("$it:") } 44 append(" $method") 45 } 46 } 47 formatnull48 private fun format(message: String, sourceInfo: SourceInfo? = null): String { 49 var loc = if (sourceInfo == null) "" else sourceInfo.toString() + ": " 50 if (verbose && sourceInfo != null && sourceInfo.i != null) 51 loc += sourceInfo.i.atIndex(sourceInfo.insnList) 52 return "$loc$message" 53 } 54 infonull55 protected fun info(message: String, sourceInfo: SourceInfo? = null) { 56 logger.info(format(message, sourceInfo)) 57 } 58 debugnull59 protected fun debug(message: String, sourceInfo: SourceInfo? = null) { 60 logger.debug(format(message, sourceInfo)) 61 } 62 errornull63 protected fun error(message: String, sourceInfo: SourceInfo? = null) { 64 logger.error(format(message, sourceInfo)) 65 if (lastError == null) lastError = TransformerException(message) 66 } 67 transformnull68 abstract fun transform() 69 } 70 71 class TransformerException(message: String, cause: Throwable? = null) : Exception(message, cause)