diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/InlineTestUtil.kt b/compiler/tests/org/jetbrains/kotlin/codegen/InlineTestUtil.kt index 96954517752..4f281a4a8bd 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/InlineTestUtil.kt +++ b/compiler/tests/org/jetbrains/kotlin/codegen/InlineTestUtil.kt @@ -23,16 +23,14 @@ import org.jetbrains.kotlin.load.java.JvmAnnotationNames import org.jetbrains.kotlin.load.kotlin.FileBasedKotlinClass import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader import org.jetbrains.kotlin.psi.KtFile -import org.jetbrains.kotlin.resolve.jvm.JvmClassName import org.jetbrains.kotlin.test.InTextDirectivesUtils import org.jetbrains.org.objectweb.asm.* import org.jetbrains.org.objectweb.asm.tree.MethodNode import java.util.* -import kotlin.properties.Delegates object InlineTestUtil { private val KOTLIN_MULTIFILE_CLASS_DESC = - "L" + AsmUtil.internalNameByFqNameWithoutInnerClasses(JvmAnnotationNames.KOTLIN_MULTIFILE_CLASS) + ";" + AsmUtil.asmDescByFqNameWithoutInnerClasses(JvmAnnotationNames.KOTLIN_MULTIFILE_CLASS) fun checkNoCallsToInline(files: Iterable, sourceFiles: List) { val inlineInfo = obtainInlineInfo(files) @@ -42,16 +40,16 @@ object InlineTestUtil { val notInlinedCalls = checkInlineMethodNotInvoked(files, inlineMethods) assert(notInlinedCalls.isEmpty()) { "All inline methods should be inlined but:\n" + notInlinedCalls.joinToString("\n") } - - val skipParameterChecking = - sourceFiles.asSequence().filter { - InTextDirectivesUtils.isDirectiveDefined(it.text, "NO_CHECK_LAMBDA_INLINING") - }.any() + val skipParameterChecking = sourceFiles.any { + InTextDirectivesUtils.isDirectiveDefined(it.text, "NO_CHECK_LAMBDA_INLINING") + } if (!skipParameterChecking) { val notInlinedParameters = checkParametersInlined(files, inlineInfo) - assert(notInlinedParameters.isEmpty()) { "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" } + assert(notInlinedParameters.isEmpty()) { + "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)) { 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) { return } @@ -129,42 +127,37 @@ object InlineTestUtil { val inlinedMethods = inlineInfo.inlineMethods val notInlinedParameters = ArrayList() for (file in files) { - val kotlinClassHeader = getClassHeader(file) - if (isClassOrPackagePartKind(kotlinClassHeader)) { - val cr = ClassReader(file.asByteArray()) + if (!isClassOrPackagePartKind(getClassHeader(file))) continue - cr.accept(object : ClassVisitorWithName() { + ClassReader(file.asByteArray()).accept(object : ClassVisitorWithName() { + override fun visitMethod(access: Int, name: String, desc: String, signature: String?, exceptions: Array?): MethodVisitor? { + val declaration = MethodInfo(className, name, desc) + //do not check anonymous object creation in inline functions and in package facades + if (declaration in inlinedMethods) { + return null + } - override fun visitMethod(access: Int, name: String, desc: String, signature: String?, exceptions: Array?): MethodVisitor? { - JvmClassName.byInternalName(className).fqNameForClassNameWithoutDollars - val declaration = MethodInfo(className, name, desc) - //do not check anonymous object creation in inline functions and in package facades - if (declaration in inlinedMethods) { - return null + return object : MethodNode(Opcodes.ASM5, access, name, desc, signature, exceptions) { + private fun isInlineParameterLikeOwner(owner: String) = + "$" in owner && !isTopLevelOrInnerOrPackageClass(owner, inlineInfo) + + override fun visitMethodInsn(opcode: Int, owner: String, name: String, desc: String, itf: Boolean) { + if ("".equals(name) && isInlineParameterLikeOwner(owner)) { + val fromCall = MethodInfo(className, this.name, this.desc) + notInlinedParameters.add(NotInlinedParameter(owner, fromCall)) + } } - return object : MethodNode(Opcodes.ASM5, access, name, desc, signature, exceptions) { - private fun isInlineParameterLikeOwner(owner: String) = owner.contains("$") && !isTopLevelOrInnerOrPackageClass(owner, inlineInfo) - - override fun visitMethodInsn(opcode: Int, owner: String, name: String, desc: String, itf: Boolean) { - if ("".equals(name) && isInlineParameterLikeOwner(owner)) { - /*constuctor creation*/ - val fromCall = MethodInfo(className, this.name, this.desc) - notInlinedParameters.add(NotInlinedParameter(owner, fromCall)) - } - } - - override fun visitFieldInsn(opcode: Int, owner: String, name: String, desc: String) { - if (opcode == Opcodes.GETSTATIC && isInlineParameterLikeOwner(owner)) { - val fromCall = MethodInfo(className, this.name, this.desc) - notInlinedParameters.add(NotInlinedParameter(owner, fromCall)) - } - super.visitFieldInsn(opcode, owner, name, desc) + override fun visitFieldInsn(opcode: Int, owner: String, name: String, desc: String) { + if (opcode == Opcodes.GETSTATIC && isInlineParameterLikeOwner(owner)) { + val fromCall = MethodInfo(className, this.name, this.desc) + notInlinedParameters.add(NotInlinedParameter(owner, fromCall)) } + super.visitFieldInsn(opcode, owner, name, desc) } } - }, 0) - } + } + }, 0) } return notInlinedParameters @@ -202,9 +195,8 @@ object InlineTestUtil { private data class MethodInfo(val owner: String, val name: String, val desc: String) - open private class ClassVisitorWithName() : ClassVisitor(Opcodes.ASM5) { - - var className: String by Delegates.notNull() + private open class ClassVisitorWithName : ClassVisitor(Opcodes.ASM5) { + lateinit var className: String override fun visit(version: Int, access: Int, name: String, signature: String?, superName: String?, interfaces: Array?) { className = name