diff --git a/compiler/tests-common/org/jetbrains/kotlin/codegen/InlineTestUtil.kt b/compiler/tests-common/org/jetbrains/kotlin/codegen/InlineTestUtil.kt index 127cdc4a50b..efe64cd1abc 100644 --- a/compiler/tests-common/org/jetbrains/kotlin/codegen/InlineTestUtil.kt +++ b/compiler/tests-common/org/jetbrains/kotlin/codegen/InlineTestUtil.kt @@ -30,20 +30,20 @@ import org.jetbrains.org.objectweb.asm.tree.MethodNode import java.util.* object InlineTestUtil { - fun checkNoCallsToInline(files: Iterable, sourceFiles: List) { - val inlineInfo = obtainInlineInfo(files) + fun checkNoCallsToInline(outputFiles: Iterable, sourceFiles: List) { + val inlineInfo = obtainInlineInfo(outputFiles) val inlineMethods = inlineInfo.inlineMethods assert(!inlineMethods.isEmpty()) { "There are no inline methods" } - val notInlinedCalls = checkInlineMethodNotInvoked(files, inlineMethods) + val notInlinedCalls = checkInlineMethodNotInvoked(outputFiles, inlineMethods) assert(notInlinedCalls.isEmpty()) { "All inline methods should be inlined but:\n" + notInlinedCalls.joinToString("\n") } val skipParameterChecking = sourceFiles.any { InTextDirectivesUtils.isDirectiveDefined(it.text, "NO_CHECK_LAMBDA_INLINING") - } || !doLambdaInliningCheck(files, inlineInfo) + } || !doLambdaInliningCheck(outputFiles, inlineInfo) if (!skipParameterChecking) { - val notInlinedParameters = checkParametersInlined(files, inlineInfo) + val notInlinedParameters = checkParametersInlined(outputFiles, inlineInfo, sourceFiles) 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" @@ -80,6 +80,7 @@ object InlineTestUtil { val binaryClass = loadBinaryClass(file) val inlineFunctions = inlineFunctionsJvmNames(binaryClass.classHeader) + //if inline function creates anonymous object then do not try to check that all lambdas are inlined val classVisitor = object : ClassVisitorWithName() { override fun visitMethod(access: Int, name: String, desc: String, signature: String?, exceptions: Array?): MethodVisitor? { if (name + desc in inlineFunctions) { @@ -149,20 +150,30 @@ object InlineTestUtil { return notInlined } - private fun checkParametersInlined(files: Iterable, inlineInfo: InlineInfo): ArrayList { + private fun checkParametersInlined(outputFiles: Iterable, inlineInfo: InlineInfo, sourceFiles: List): ArrayList { + val skipMethods = + sourceFiles.flatMap { + InTextDirectivesUtils.findLinesWithPrefixesRemoved(it.text, "// SKIP_INLINE_CHECK_IN: ") + }.toSet() + val inlinedMethods = inlineInfo.inlineMethods val notInlinedParameters = ArrayList() - for (file in files) { + for (file in outputFiles) { if (!isClassOrPackagePartKind(loadBinaryClass(file))) continue 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 } + if (skipMethods.contains(name)) { + return null + } + return object: MethodNodeWithAnonymousObjectCheck(inlineInfo, access, name, desc, signature, exceptions) { override fun onAnonymousConstructorCallOrSingletonAccess(owner: String) { val fromCall = MethodInfo(className, this.name, this.desc)