Minor, cleanup InlineTestUtil.kt

This commit is contained in:
Alexander Udalov
2016-01-17 19:59:28 +03:00
parent d50a531934
commit f88abc5b1f
@@ -23,16 +23,14 @@ import org.jetbrains.kotlin.load.java.JvmAnnotationNames
import org.jetbrains.kotlin.load.kotlin.FileBasedKotlinClass import org.jetbrains.kotlin.load.kotlin.FileBasedKotlinClass
import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader
import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.resolve.jvm.JvmClassName
import org.jetbrains.kotlin.test.InTextDirectivesUtils import org.jetbrains.kotlin.test.InTextDirectivesUtils
import org.jetbrains.org.objectweb.asm.* import org.jetbrains.org.objectweb.asm.*
import org.jetbrains.org.objectweb.asm.tree.MethodNode import org.jetbrains.org.objectweb.asm.tree.MethodNode
import java.util.* import java.util.*
import kotlin.properties.Delegates
object InlineTestUtil { object InlineTestUtil {
private val KOTLIN_MULTIFILE_CLASS_DESC = private val KOTLIN_MULTIFILE_CLASS_DESC =
"L" + AsmUtil.internalNameByFqNameWithoutInnerClasses(JvmAnnotationNames.KOTLIN_MULTIFILE_CLASS) + ";" AsmUtil.asmDescByFqNameWithoutInnerClasses(JvmAnnotationNames.KOTLIN_MULTIFILE_CLASS)
fun checkNoCallsToInline(files: Iterable<OutputFile>, sourceFiles: List<KtFile>) { fun checkNoCallsToInline(files: Iterable<OutputFile>, sourceFiles: List<KtFile>) {
val inlineInfo = obtainInlineInfo(files) val inlineInfo = obtainInlineInfo(files)
@@ -42,16 +40,16 @@ object InlineTestUtil {
val notInlinedCalls = checkInlineMethodNotInvoked(files, inlineMethods) val notInlinedCalls = checkInlineMethodNotInvoked(files, inlineMethods)
assert(notInlinedCalls.isEmpty()) { "All inline methods should be inlined but:\n" + notInlinedCalls.joinToString("\n") } assert(notInlinedCalls.isEmpty()) { "All inline methods should be inlined but:\n" + notInlinedCalls.joinToString("\n") }
val skipParameterChecking = sourceFiles.any {
val skipParameterChecking =
sourceFiles.asSequence().filter {
InTextDirectivesUtils.isDirectiveDefined(it.text, "NO_CHECK_LAMBDA_INLINING") InTextDirectivesUtils.isDirectiveDefined(it.text, "NO_CHECK_LAMBDA_INLINING")
}.any() }
if (!skipParameterChecking) { if (!skipParameterChecking) {
val notInlinedParameters = checkParametersInlined(files, inlineInfo) val notInlinedParameters = checkParametersInlined(files, inlineInfo)
assert(notInlinedParameters.isEmpty()) { "All inline parameters should be inlined but:\n${notInlinedParameters.joinToString("\n")}\n" + assert(notInlinedParameters.isEmpty()) {
"but if you have not inlined lambdas or anonymous objects enable NO_CHECK_LAMBDA_INLINING directive" } "All inline parameters should be inlined but:\n${notInlinedParameters.joinToString("\n")}\n" +
"but if you have not inlined lambdas or anonymous objects enable NO_CHECK_LAMBDA_INLINING directive"
}
} }
} }
@@ -110,7 +108,7 @@ object InlineTestUtil {
if (inlinedMethods.contains(methodCall)) { if (inlinedMethods.contains(methodCall)) {
val fromCall = MethodInfo(className, this.name, this.desc) val fromCall = MethodInfo(className, this.name, this.desc)
//skip delegation to trait impl from child class //skip delegation to interface DefaultImpls from child class
if (methodCall.owner.endsWith(JvmAbi.DEFAULT_IMPLS_SUFFIX) && fromCall.owner != methodCall.owner) { if (methodCall.owner.endsWith(JvmAbi.DEFAULT_IMPLS_SUFFIX) && fromCall.owner != methodCall.owner) {
return return
} }
@@ -129,14 +127,10 @@ object InlineTestUtil {
val inlinedMethods = inlineInfo.inlineMethods val inlinedMethods = inlineInfo.inlineMethods
val notInlinedParameters = ArrayList<NotInlinedParameter>() val notInlinedParameters = ArrayList<NotInlinedParameter>()
for (file in files) { for (file in files) {
val kotlinClassHeader = getClassHeader(file) if (!isClassOrPackagePartKind(getClassHeader(file))) continue
if (isClassOrPackagePartKind(kotlinClassHeader)) {
val cr = ClassReader(file.asByteArray())
cr.accept(object : ClassVisitorWithName() {
ClassReader(file.asByteArray()).accept(object : ClassVisitorWithName() {
override fun visitMethod(access: Int, name: String, desc: String, signature: String?, exceptions: Array<String>?): MethodVisitor? { override fun visitMethod(access: Int, name: String, desc: String, signature: String?, exceptions: Array<String>?): MethodVisitor? {
JvmClassName.byInternalName(className).fqNameForClassNameWithoutDollars
val declaration = MethodInfo(className, name, desc) val declaration = MethodInfo(className, name, desc)
//do not check anonymous object creation in inline functions and in package facades //do not check anonymous object creation in inline functions and in package facades
if (declaration in inlinedMethods) { if (declaration in inlinedMethods) {
@@ -144,11 +138,11 @@ object InlineTestUtil {
} }
return object : MethodNode(Opcodes.ASM5, access, name, desc, signature, exceptions) { return object : MethodNode(Opcodes.ASM5, access, name, desc, signature, exceptions) {
private fun isInlineParameterLikeOwner(owner: String) = owner.contains("$") && !isTopLevelOrInnerOrPackageClass(owner, inlineInfo) private fun isInlineParameterLikeOwner(owner: String) =
"$" in owner && !isTopLevelOrInnerOrPackageClass(owner, inlineInfo)
override fun visitMethodInsn(opcode: Int, owner: String, name: String, desc: String, itf: Boolean) { override fun visitMethodInsn(opcode: Int, owner: String, name: String, desc: String, itf: Boolean) {
if ("<init>".equals(name) && isInlineParameterLikeOwner(owner)) { if ("<init>".equals(name) && isInlineParameterLikeOwner(owner)) {
/*constuctor creation*/
val fromCall = MethodInfo(className, this.name, this.desc) val fromCall = MethodInfo(className, this.name, this.desc)
notInlinedParameters.add(NotInlinedParameter(owner, fromCall)) notInlinedParameters.add(NotInlinedParameter(owner, fromCall))
} }
@@ -165,7 +159,6 @@ object InlineTestUtil {
} }
}, 0) }, 0)
} }
}
return notInlinedParameters return notInlinedParameters
} }
@@ -202,9 +195,8 @@ object InlineTestUtil {
private data class MethodInfo(val owner: String, val name: String, val desc: String) private data class MethodInfo(val owner: String, val name: String, val desc: String)
open private class ClassVisitorWithName() : ClassVisitor(Opcodes.ASM5) { private open class ClassVisitorWithName : ClassVisitor(Opcodes.ASM5) {
lateinit var className: String
var className: String by Delegates.notNull()
override fun visit(version: Int, access: Int, name: String, signature: String?, superName: String?, interfaces: Array<String>?) { override fun visit(version: Int, access: Int, name: String, signature: String?, superName: String?, interfaces: Array<String>?) {
className = name className = name