From 0dea6b94c6c621c3bca617c2cd87976684ffa1c0 Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Tue, 1 Sep 2020 21:52:58 +0200 Subject: [PATCH] JVM IR: unmute boxInline tests on enclosing method/class In box tests, only check that Java reflection does not crash on the EnclosingMethod attribute generated in these classes. If it doesn't crash, most likely it returns the value that can be read from the class file by ASM, which is what the newly added bytecode listing tests are checking now. --- .../boxInline/enclosingInfo/inlineChain2.kt | 20 ++--- .../enclosingInfo/transformedConstructor.kt | 31 +++---- .../transformedConstructorWithNestedInline.kt | 35 ++++---- .../codegen/boxInline/innerClasses/kt10259.kt | 18 ++-- .../enclosingInfo/crossinlineLambdaChain.kt | 23 ++++++ .../enclosingInfo/crossinlineLambdaChain.txt | 82 +++++++++++++++++++ .../crossinlineLambdaChain_ir.txt | 82 +++++++++++++++++++ .../inline/enclosingInfo/kt10259.kt | 26 ++++++ .../inline/enclosingInfo/kt10259.txt | 57 +++++++++++++ .../inline/enclosingInfo/kt10259_ir.txt | 58 +++++++++++++ .../enclosingInfo/transformedConstructor.kt | 30 +++++++ .../enclosingInfo/transformedConstructor.txt | 54 ++++++++++++ .../transformedConstructorWithNestedInline.kt | 34 ++++++++ ...transformedConstructorWithNestedInline.txt | 55 +++++++++++++ ...nsformedConstructorWithNestedInline_ir.txt | 56 +++++++++++++ .../transformedConstructor_ir.txt | 55 +++++++++++++ .../codegen/BytecodeListingTestGenerated.java | 33 ++++++++ .../ir/IrBytecodeListingTestGenerated.java | 33 ++++++++ 18 files changed, 719 insertions(+), 63 deletions(-) create mode 100644 compiler/testData/codegen/bytecodeListing/inline/enclosingInfo/crossinlineLambdaChain.kt create mode 100644 compiler/testData/codegen/bytecodeListing/inline/enclosingInfo/crossinlineLambdaChain.txt create mode 100644 compiler/testData/codegen/bytecodeListing/inline/enclosingInfo/crossinlineLambdaChain_ir.txt create mode 100644 compiler/testData/codegen/bytecodeListing/inline/enclosingInfo/kt10259.kt create mode 100644 compiler/testData/codegen/bytecodeListing/inline/enclosingInfo/kt10259.txt create mode 100644 compiler/testData/codegen/bytecodeListing/inline/enclosingInfo/kt10259_ir.txt create mode 100644 compiler/testData/codegen/bytecodeListing/inline/enclosingInfo/transformedConstructor.kt create mode 100644 compiler/testData/codegen/bytecodeListing/inline/enclosingInfo/transformedConstructor.txt create mode 100644 compiler/testData/codegen/bytecodeListing/inline/enclosingInfo/transformedConstructorWithNestedInline.kt create mode 100644 compiler/testData/codegen/bytecodeListing/inline/enclosingInfo/transformedConstructorWithNestedInline.txt create mode 100644 compiler/testData/codegen/bytecodeListing/inline/enclosingInfo/transformedConstructorWithNestedInline_ir.txt create mode 100644 compiler/testData/codegen/bytecodeListing/inline/enclosingInfo/transformedConstructor_ir.txt diff --git a/compiler/testData/codegen/boxInline/enclosingInfo/inlineChain2.kt b/compiler/testData/codegen/boxInline/enclosingInfo/inlineChain2.kt index 64e36c99087..61bea887e11 100644 --- a/compiler/testData/codegen/boxInline/enclosingInfo/inlineChain2.kt +++ b/compiler/testData/codegen/boxInline/enclosingInfo/inlineChain2.kt @@ -1,8 +1,7 @@ // TARGET_BACKEND: JVM -// IGNORE_BACKEND: JVM_IR -// IGNORE_BACKEND_MULTI_MODULE: JVM_IR +// WITH_RUNTIME // FILE: 1.kt -// WITH_REFLECT + package test inline fun call(crossinline s: () -> R) = { s() }() @@ -18,11 +17,9 @@ fun box(): String { test { "OK" } } - var enclosingMethod = res.javaClass.enclosingMethod - if (enclosingMethod?.name != "invoke") return "fail 1: ${enclosingMethod?.name}" - - var enclosingClass = res.javaClass.enclosingClass - if (enclosingClass?.name != "_2Kt\$box$\$inlined\$call$1") return "fail 2: ${enclosingClass?.name}" + // Check that Java reflection doesn't crash. Actual values are tested in bytecodeListing/inline/enclosingInfo/. + res.javaClass.enclosingMethod + res.javaClass.enclosingClass val res2 = call { call { @@ -30,11 +27,8 @@ fun box(): String { } } - enclosingMethod = res2.javaClass.enclosingMethod - if (enclosingMethod?.name != "invoke") return "fail 1: ${enclosingMethod?.name}" - - enclosingClass = res2.javaClass.enclosingClass - if (enclosingClass?.name != "_2Kt\$box$\$inlined\$call$2\$lambda$1") return "fail 2: ${enclosingClass?.name}" + res2.javaClass.enclosingMethod + res2.javaClass.enclosingClass return res2() } diff --git a/compiler/testData/codegen/boxInline/enclosingInfo/transformedConstructor.kt b/compiler/testData/codegen/boxInline/enclosingInfo/transformedConstructor.kt index 3a0f157a36e..d38572bc83f 100644 --- a/compiler/testData/codegen/boxInline/enclosingInfo/transformedConstructor.kt +++ b/compiler/testData/codegen/boxInline/enclosingInfo/transformedConstructor.kt @@ -1,44 +1,39 @@ -// IGNORE_BACKEND: JVM_IR -// IGNORE_BACKEND_MULTI_MODULE: JVM_IR // TARGET_BACKEND: JVM +// WITH_RUNTIME // FILE: 1.kt -// WITH_REFLECT + package test interface Z { - fun a() : String + fun a(): String } inline fun test(crossinline z: () -> String) = - object : Z { + object : Z { + val p = z() - val p = z() - - override fun a() = p - } + override fun a() = p + } // FILE: 2.kt import test.* fun box(): String { - /*This captured parameter would be added to object constructor*/ - val captured = "OK"; + // This captured parameter would be added to object constructor + val captured = "OK" var z: Any = "fail" val res = test { - z = { captured } (z as Function0)() } - - val enclosingConstructor = z.javaClass.enclosingConstructor - if (enclosingConstructor?.name != "_2Kt\$box$\$inlined\$test$1") return "fail 1: ${enclosingConstructor?.name}" - - val enclosingClass = z.javaClass.enclosingClass - if (enclosingClass?.name != "_2Kt\$box$\$inlined\$test$1") return "fail 2: ${enclosingClass?.name}" + // Check that Java reflection doesn't crash. Actual values are tested in bytecodeListing/inline/enclosingInfo/. + z.javaClass.enclosingConstructor + z.javaClass.enclosingMethod + z.javaClass.enclosingClass return res.a() } diff --git a/compiler/testData/codegen/boxInline/enclosingInfo/transformedConstructorWithNestedInline.kt b/compiler/testData/codegen/boxInline/enclosingInfo/transformedConstructorWithNestedInline.kt index 82665d81469..1f27c71804f 100644 --- a/compiler/testData/codegen/boxInline/enclosingInfo/transformedConstructorWithNestedInline.kt +++ b/compiler/testData/codegen/boxInline/enclosingInfo/transformedConstructorWithNestedInline.kt @@ -1,50 +1,43 @@ -// IGNORE_BACKEND: JVM_IR -// IGNORE_BACKEND_MULTI_MODULE: JVM_IR // TARGET_BACKEND: JVM +// WITH_RUNTIME // FILE: 1.kt -// WITH_REFLECT + package test interface Z { - fun a() : String + fun a(): String } inline fun test(crossinline z: () -> String) = - object : Z { + object : Z { + val p = z() - val p = z() + override fun a() = p + } - override fun a() = p - } - - -inline fun call(crossinline z: () -> T) = z() +inline fun call(crossinline z: () -> T) = z() // FILE: 2.kt import test.* fun box(): String { - /*This captured parameter would be added to object constructor*/ - val captured = "OK"; + // This captured parameter would be added to object constructor + val captured = "OK" var z: Any = "fail" val res = test { - call { z = { captured } } - (z as Function0)() } - - val enclosingConstructor = z.javaClass.enclosingConstructor - if (enclosingConstructor?.name != "_2Kt\$box$\$inlined\$test$1") return "fail 1: ${enclosingConstructor?.name}" - - val enclosingClass = z.javaClass.enclosingClass - if (enclosingClass?.name != "_2Kt\$box$\$inlined\$test$1") return "fail 2: ${enclosingClass?.name}" + // Check that Java reflection doesn't crash. Actual values are tested in bytecodeListing/inline/enclosingInfo/. + z.javaClass.enclosingConstructor + z.javaClass.enclosingMethod + z.javaClass.enclosingClass return res.a() } diff --git a/compiler/testData/codegen/boxInline/innerClasses/kt10259.kt b/compiler/testData/codegen/boxInline/innerClasses/kt10259.kt index 64e2fcde473..65988cdd445 100644 --- a/compiler/testData/codegen/boxInline/innerClasses/kt10259.kt +++ b/compiler/testData/codegen/boxInline/innerClasses/kt10259.kt @@ -1,9 +1,8 @@ -// IGNORE_BACKEND: JVM_IR -// IGNORE_BACKEND_MULTI_MODULE: JVM_IR // TARGET_BACKEND: JVM // NO_CHECK_LAMBDA_INLINING // WITH_RUNTIME // FILE: 1.kt + package test inline fun test(s: () -> Unit) { @@ -15,22 +14,19 @@ inline fun test(s: () -> Unit) { import test.* fun box(): String { - var encl1 = "fail"; - var encl2 = "fail"; + var s1 = "" + var s2 = "" test { { val p = object {} - encl1 = p.javaClass.enclosingMethod.declaringClass.name + // Check that Java reflection doesn't crash. Actual values are tested in bytecodeListing/inline/enclosingInfo/. + s1 = p.javaClass.enclosingMethod.declaringClass.toString(); { - - val p = object {} - encl2 = p.javaClass.enclosingMethod.declaringClass.name + val q = object {} + s2 = q.javaClass.enclosingMethod.declaringClass.toString() }() }() } - if (encl1 != "_2Kt\$box\$\$inlined\$test\$lambda$1") return "fail 1: $encl1" - if (encl2 != "_2Kt\$box\$\$inlined\$test\$lambda$1$2") return "fail 2: $encl2" - return "OK" } diff --git a/compiler/testData/codegen/bytecodeListing/inline/enclosingInfo/crossinlineLambdaChain.kt b/compiler/testData/codegen/bytecodeListing/inline/enclosingInfo/crossinlineLambdaChain.kt new file mode 100644 index 00000000000..c3bdc7e74de --- /dev/null +++ b/compiler/testData/codegen/bytecodeListing/inline/enclosingInfo/crossinlineLambdaChain.kt @@ -0,0 +1,23 @@ +// FILE: 1.kt + +package test + +inline fun call(crossinline s: () -> R) = { s() }() + +inline fun test(crossinline z: () -> String) = { z() } + +// FILE: 2.kt + +import test.* + +fun box() { + val res = call { + test { "OK" } + } + + val res2 = call { + call { + test { "OK" } + } + } +} diff --git a/compiler/testData/codegen/bytecodeListing/inline/enclosingInfo/crossinlineLambdaChain.txt b/compiler/testData/codegen/bytecodeListing/inline/enclosingInfo/crossinlineLambdaChain.txt new file mode 100644 index 00000000000..ea7858afcd0 --- /dev/null +++ b/compiler/testData/codegen/bytecodeListing/inline/enclosingInfo/crossinlineLambdaChain.txt @@ -0,0 +1,82 @@ +@kotlin.Metadata +public final class _2Kt$box$$inlined$call$1$lambda$1 { + // source: '1.kt' + enclosing method _2Kt$box$$inlined$call$1.invoke()Ljava/lang/Object; + inner (anonymous) class _2Kt$box$$inlined$call$1$lambda$1 + public method (): void + public synthetic bridge method invoke(): java.lang.Object + public final @org.jetbrains.annotations.NotNull method invoke(): java.lang.String +} + +@kotlin.Metadata +public final class _2Kt$box$$inlined$call$1 { + // source: '1.kt' + enclosing method _2Kt.box()V + inner (anonymous) class _2Kt$box$$inlined$call$1 + public method (): void + public final method invoke(): java.lang.Object +} + +@kotlin.Metadata +public final class _2Kt$box$$inlined$call$2$lambda$1$1 { + // source: '1.kt' + enclosing method _2Kt$box$$inlined$call$2$lambda$1.invoke()Ljava/lang/Object; + inner (anonymous) class _2Kt$box$$inlined$call$2$lambda$1$1 + public method (): void + public synthetic bridge method invoke(): java.lang.Object + public final @org.jetbrains.annotations.NotNull method invoke(): java.lang.String +} + +@kotlin.Metadata +public final class _2Kt$box$$inlined$call$2$lambda$1 { + // source: '1.kt' + enclosing method _2Kt$box$$inlined$call$2.invoke()Ljava/lang/Object; + inner (anonymous) class _2Kt$box$$inlined$call$2$lambda$1 + public method (): void + public final method invoke(): java.lang.Object +} + +@kotlin.Metadata +public final class _2Kt$box$$inlined$call$2 { + // source: '1.kt' + enclosing method _2Kt.box()V + inner (anonymous) class _2Kt$box$$inlined$call$2 + public method (): void + public final method invoke(): java.lang.Object +} + +@kotlin.Metadata +public final class _2Kt { + // source: '2.kt' + public final static method box(): void +} + +@kotlin.Metadata +public final class test/_1Kt$call$1 { + // source: '1.kt' + enclosing method test/_1Kt.call(Lkotlin/jvm/functions/Function0;)Ljava/lang/Object; + synthetic final field $s: kotlin.jvm.functions.Function0 + inner (anonymous) class test/_1Kt$call$1 + public method (p0: kotlin.jvm.functions.Function0): void + public final method invoke(): java.lang.Object +} + +@kotlin.Metadata +public final class test/_1Kt$test$1 { + // source: '1.kt' + enclosing method test/_1Kt.test(Lkotlin/jvm/functions/Function0;)Lkotlin/jvm/functions/Function0; + synthetic final field $z: kotlin.jvm.functions.Function0 + inner (anonymous) class test/_1Kt$test$1 + public method (p0: kotlin.jvm.functions.Function0): void + public synthetic bridge method invoke(): java.lang.Object + public final @org.jetbrains.annotations.NotNull method invoke(): java.lang.String +} + +@kotlin.Metadata +public final class test/_1Kt { + // source: '1.kt' + inner (anonymous) class test/_1Kt$call$1 + inner (anonymous) class test/_1Kt$test$1 + public final static method call(@org.jetbrains.annotations.NotNull p0: kotlin.jvm.functions.Function0): java.lang.Object + public final static @org.jetbrains.annotations.NotNull method test(@org.jetbrains.annotations.NotNull p0: kotlin.jvm.functions.Function0): kotlin.jvm.functions.Function0 +} diff --git a/compiler/testData/codegen/bytecodeListing/inline/enclosingInfo/crossinlineLambdaChain_ir.txt b/compiler/testData/codegen/bytecodeListing/inline/enclosingInfo/crossinlineLambdaChain_ir.txt new file mode 100644 index 00000000000..cc3004e5d3d --- /dev/null +++ b/compiler/testData/codegen/bytecodeListing/inline/enclosingInfo/crossinlineLambdaChain_ir.txt @@ -0,0 +1,82 @@ +@kotlin.Metadata +public final class _2Kt$box$$inlined$call$1 { + // source: '1.kt' + enclosing method _2Kt.box()V + inner (anonymous) class _2Kt$box$$inlined$call$1 + public method (): void + public final method invoke(): java.lang.Object +} + +@kotlin.Metadata +public final class _2Kt$box$$inlined$call$2 { + // source: '1.kt' + enclosing method _2Kt.box()V + inner (anonymous) class _2Kt$box$$inlined$call$2 + public method (): void + public final method invoke(): java.lang.Object +} + +@kotlin.Metadata +public final class _2Kt$box$lambda-1$$inlined$test$1 { + // source: '1.kt' + enclosing method _2Kt.box()V + inner (anonymous) class _2Kt$box$lambda-1$$inlined$test$1 + public method (): void + public synthetic bridge method invoke(): java.lang.Object + public final @org.jetbrains.annotations.NotNull method invoke(): java.lang.String +} + +@kotlin.Metadata +public final class _2Kt$box$lambda-4$$inlined$call$1 { + // source: '1.kt' + enclosing method _2Kt.box()V + inner (anonymous) class _2Kt$box$lambda-4$$inlined$call$1 + public method (): void + public final method invoke(): java.lang.Object +} + +@kotlin.Metadata +public final class _2Kt$box$lambda-4$lambda-3$$inlined$test$1 { + // source: '1.kt' + enclosing method _2Kt.box()V + inner (anonymous) class _2Kt$box$lambda-4$lambda-3$$inlined$test$1 + public method (): void + public synthetic bridge method invoke(): java.lang.Object + public final @org.jetbrains.annotations.NotNull method invoke(): java.lang.String +} + +@kotlin.Metadata +public final class _2Kt { + // source: '2.kt' + public final static method box(): void +} + +@kotlin.Metadata +public final class test/_1Kt$call$1 { + // source: '1.kt' + enclosing method test/_1Kt.call(Lkotlin/jvm/functions/Function0;)Ljava/lang/Object; + synthetic final field $s: kotlin.jvm.functions.Function0 + inner (anonymous) class test/_1Kt$call$1 + public method (p0: kotlin.jvm.functions.Function0): void + public final method invoke(): java.lang.Object +} + +@kotlin.Metadata +public final class test/_1Kt$test$1 { + // source: '1.kt' + enclosing method test/_1Kt.test(Lkotlin/jvm/functions/Function0;)Lkotlin/jvm/functions/Function0; + synthetic final field $z: kotlin.jvm.functions.Function0 + inner (anonymous) class test/_1Kt$test$1 + public method (p0: kotlin.jvm.functions.Function0): void + public synthetic bridge method invoke(): java.lang.Object + public final @org.jetbrains.annotations.NotNull method invoke(): java.lang.String +} + +@kotlin.Metadata +public final class test/_1Kt { + // source: '1.kt' + inner (anonymous) class test/_1Kt$call$1 + inner (anonymous) class test/_1Kt$test$1 + public final static method call(@org.jetbrains.annotations.NotNull p0: kotlin.jvm.functions.Function0): java.lang.Object + public final static @org.jetbrains.annotations.NotNull method test(@org.jetbrains.annotations.NotNull p0: kotlin.jvm.functions.Function0): kotlin.jvm.functions.Function0 +} diff --git a/compiler/testData/codegen/bytecodeListing/inline/enclosingInfo/kt10259.kt b/compiler/testData/codegen/bytecodeListing/inline/enclosingInfo/kt10259.kt new file mode 100644 index 00000000000..656a3d40c7b --- /dev/null +++ b/compiler/testData/codegen/bytecodeListing/inline/enclosingInfo/kt10259.kt @@ -0,0 +1,26 @@ +// FILE: 1.kt + +package test + +inline fun test(s: () -> Unit) { + s() +} + +// FILE: 2.kt + +import test.* + +fun box() { + var s1 = "" + var s2 = "" + test { + { + val p = object {} + s1 = p.toString(); + { + val q = object {} + s2 = q.toString() + }() + }() + } +} diff --git a/compiler/testData/codegen/bytecodeListing/inline/enclosingInfo/kt10259.txt b/compiler/testData/codegen/bytecodeListing/inline/enclosingInfo/kt10259.txt new file mode 100644 index 00000000000..a3c15ddbfcf --- /dev/null +++ b/compiler/testData/codegen/bytecodeListing/inline/enclosingInfo/kt10259.txt @@ -0,0 +1,57 @@ +@kotlin.Metadata +public final class _2Kt$box$$inlined$test$lambda$1$1 { + // source: '2.kt' + enclosing method _2Kt$box$$inlined$test$lambda$1.invoke()V + inner (anonymous) class _2Kt$box$$inlined$test$lambda$1 + inner (anonymous) class _2Kt$box$$inlined$test$lambda$1$1 + method (): void +} + +@kotlin.Metadata +public final class _2Kt$box$$inlined$test$lambda$1$2$1 { + // source: '2.kt' + enclosing method _2Kt$box$$inlined$test$lambda$1$2.invoke()V + inner (anonymous) class _2Kt$box$$inlined$test$lambda$1 + inner (anonymous) class _2Kt$box$$inlined$test$lambda$1$2 + inner (anonymous) class _2Kt$box$$inlined$test$lambda$1$2$1 + method (): void +} + +@kotlin.Metadata +final class _2Kt$box$$inlined$test$lambda$1$2 { + // source: '2.kt' + enclosing method _2Kt$box$$inlined$test$lambda$1.invoke()V + synthetic final field this$0: _2Kt$box$$inlined$test$lambda$1 + inner (anonymous) class _2Kt$box$$inlined$test$lambda$1 + inner (anonymous) class _2Kt$box$$inlined$test$lambda$1$2 + inner (anonymous) class _2Kt$box$$inlined$test$lambda$1$2$1 + method (p0: _2Kt$box$$inlined$test$lambda$1): void + public synthetic bridge method invoke(): java.lang.Object + public final method invoke(): void +} + +@kotlin.Metadata +final class _2Kt$box$$inlined$test$lambda$1 { + // source: '2.kt' + enclosing method _2Kt.box()V + synthetic final field $s1$inlined: kotlin.jvm.internal.Ref$ObjectRef + synthetic final field $s2$inlined: kotlin.jvm.internal.Ref$ObjectRef + inner (anonymous) class _2Kt$box$$inlined$test$lambda$1 + inner (anonymous) class _2Kt$box$$inlined$test$lambda$1$1 + inner (anonymous) class _2Kt$box$$inlined$test$lambda$1$2 + method (p0: kotlin.jvm.internal.Ref$ObjectRef, p1: kotlin.jvm.internal.Ref$ObjectRef): void + public synthetic bridge method invoke(): java.lang.Object + public final method invoke(): void +} + +@kotlin.Metadata +public final class _2Kt { + // source: '2.kt' + public final static method box(): void +} + +@kotlin.Metadata +public final class test/_1Kt { + // source: '1.kt' + public final static method test(@org.jetbrains.annotations.NotNull p0: kotlin.jvm.functions.Function0): void +} diff --git a/compiler/testData/codegen/bytecodeListing/inline/enclosingInfo/kt10259_ir.txt b/compiler/testData/codegen/bytecodeListing/inline/enclosingInfo/kt10259_ir.txt new file mode 100644 index 00000000000..5f093f069c8 --- /dev/null +++ b/compiler/testData/codegen/bytecodeListing/inline/enclosingInfo/kt10259_ir.txt @@ -0,0 +1,58 @@ +@kotlin.Metadata +public final class _2Kt$box$1$1$1$q$1 { + // source: '2.kt' + enclosing method _2Kt$box$1$1$1.invoke()V + inner (anonymous) class _2Kt$box$1$1 + inner (anonymous) class _2Kt$box$1$1$1 + inner (anonymous) class _2Kt$box$1$1$1$q$1 + method (): void +} + +@kotlin.Metadata +final class _2Kt$box$1$1$1 { + // source: '2.kt' + enclosing method _2Kt$box$1$1.invoke()V + synthetic final field $s2: kotlin.jvm.internal.Ref$ObjectRef + inner (anonymous) class _2Kt$box$1$1 + inner (anonymous) class _2Kt$box$1$1$1 + inner (anonymous) class _2Kt$box$1$1$1$q$1 + method (p0: kotlin.jvm.internal.Ref$ObjectRef): void + public synthetic bridge method invoke(): java.lang.Object + public final method invoke(): void +} + +@kotlin.Metadata +public final class _2Kt$box$1$1$p$1 { + // source: '2.kt' + enclosing method _2Kt$box$1$1.invoke()V + inner (anonymous) class _2Kt$box$1$1 + inner (anonymous) class _2Kt$box$1$1$p$1 + method (): void +} + +@kotlin.Metadata +final class _2Kt$box$1$1 { + // source: '2.kt' + enclosing method _2Kt.box()V + synthetic final field $s1: kotlin.jvm.internal.Ref$ObjectRef + synthetic final field $s2: kotlin.jvm.internal.Ref$ObjectRef + inner (anonymous) class _2Kt$box$1$1 + inner (anonymous) class _2Kt$box$1$1$1 + inner (anonymous) class _2Kt$box$1$1$p$1 + method (p0: kotlin.jvm.internal.Ref$ObjectRef, p1: kotlin.jvm.internal.Ref$ObjectRef): void + public synthetic bridge method invoke(): java.lang.Object + public final method invoke(): void +} + +@kotlin.Metadata +public final class _2Kt { + // source: '2.kt' + inner (anonymous) class _2Kt$box$1$1 + public final static method box(): void +} + +@kotlin.Metadata +public final class test/_1Kt { + // source: '1.kt' + public final static method test(@org.jetbrains.annotations.NotNull p0: kotlin.jvm.functions.Function0): void +} diff --git a/compiler/testData/codegen/bytecodeListing/inline/enclosingInfo/transformedConstructor.kt b/compiler/testData/codegen/bytecodeListing/inline/enclosingInfo/transformedConstructor.kt new file mode 100644 index 00000000000..eae23e3b7ca --- /dev/null +++ b/compiler/testData/codegen/bytecodeListing/inline/enclosingInfo/transformedConstructor.kt @@ -0,0 +1,30 @@ +// FILE: 1.kt + +package test + +interface Z { + fun a(): String +} + +inline fun test(crossinline z: () -> String) = + object : Z { + val p = z() + + override fun a() = p + } + +// FILE: 2.kt + +import test.* + +fun box() { + // This captured parameter would be added to object constructor + val captured = "OK" + var z: Any = "fail" + val res = test { + z = { + captured + } + (z as Function0)() + } +} diff --git a/compiler/testData/codegen/bytecodeListing/inline/enclosingInfo/transformedConstructor.txt b/compiler/testData/codegen/bytecodeListing/inline/enclosingInfo/transformedConstructor.txt new file mode 100644 index 00000000000..f8293fe6691 --- /dev/null +++ b/compiler/testData/codegen/bytecodeListing/inline/enclosingInfo/transformedConstructor.txt @@ -0,0 +1,54 @@ +@kotlin.Metadata +final class _2Kt$box$$inlined$test$1$lambda$1 { + // source: '2.kt' + enclosing method _2Kt$box$$inlined$test$1.(Lkotlin/jvm/internal/Ref$ObjectRef;Ljava/lang/String;)V + synthetic final field this$0: _2Kt$box$$inlined$test$1 + inner (anonymous) class _2Kt$box$$inlined$test$1$lambda$1 + method (p0: _2Kt$box$$inlined$test$1): void + public synthetic bridge method invoke(): java.lang.Object + public final @org.jetbrains.annotations.NotNull method invoke(): java.lang.String +} + +@kotlin.Metadata +public final class _2Kt$box$$inlined$test$1 { + // source: '1.kt' + enclosing method _2Kt.box()V + synthetic final field $captured$inlined: java.lang.String + synthetic final field $z$inlined: kotlin.jvm.internal.Ref$ObjectRef + private final @org.jetbrains.annotations.NotNull field p: java.lang.String + inner (anonymous) class _2Kt$box$$inlined$test$1 + public method (p0: kotlin.jvm.internal.Ref$ObjectRef, p1: java.lang.String): void + public @org.jetbrains.annotations.NotNull method a(): java.lang.String + public final @org.jetbrains.annotations.NotNull method getP(): java.lang.String +} + +@kotlin.Metadata +public final class _2Kt { + // source: '2.kt' + public final static method box(): void +} + +@kotlin.Metadata +public interface test/Z { + // source: '1.kt' + public abstract @org.jetbrains.annotations.NotNull method a(): java.lang.String +} + +@kotlin.Metadata +public final class test/_1Kt$test$1 { + // source: '1.kt' + enclosing method test/_1Kt.test(Lkotlin/jvm/functions/Function0;)Ltest/Z; + synthetic final field $z: kotlin.jvm.functions.Function0 + private final @org.jetbrains.annotations.NotNull field p: java.lang.String + inner (anonymous) class test/_1Kt$test$1 + public method (p0: kotlin.jvm.functions.Function0): void + public @org.jetbrains.annotations.NotNull method a(): java.lang.String + public final @org.jetbrains.annotations.NotNull method getP(): java.lang.String +} + +@kotlin.Metadata +public final class test/_1Kt { + // source: '1.kt' + inner (anonymous) class test/_1Kt$test$1 + public final static @org.jetbrains.annotations.NotNull method test(@org.jetbrains.annotations.NotNull p0: kotlin.jvm.functions.Function0): test.Z +} diff --git a/compiler/testData/codegen/bytecodeListing/inline/enclosingInfo/transformedConstructorWithNestedInline.kt b/compiler/testData/codegen/bytecodeListing/inline/enclosingInfo/transformedConstructorWithNestedInline.kt new file mode 100644 index 00000000000..fc896cf1020 --- /dev/null +++ b/compiler/testData/codegen/bytecodeListing/inline/enclosingInfo/transformedConstructorWithNestedInline.kt @@ -0,0 +1,34 @@ +// FILE: 1.kt + +package test + +interface Z { + fun a(): String +} + +inline fun test(crossinline z: () -> String) = + object : Z { + val p = z() + + override fun a() = p + } + +inline fun call(crossinline z: () -> T) = z() + +// FILE: 2.kt + +import test.* + +fun box() { + // This captured parameter would be added to object constructor + val captured = "OK" + var z: Any = "fail" + val res = test { + call { + z = { + captured + } + } + (z as Function0)() + } +} diff --git a/compiler/testData/codegen/bytecodeListing/inline/enclosingInfo/transformedConstructorWithNestedInline.txt b/compiler/testData/codegen/bytecodeListing/inline/enclosingInfo/transformedConstructorWithNestedInline.txt new file mode 100644 index 00000000000..d12e9010e72 --- /dev/null +++ b/compiler/testData/codegen/bytecodeListing/inline/enclosingInfo/transformedConstructorWithNestedInline.txt @@ -0,0 +1,55 @@ +@kotlin.Metadata +final class _2Kt$box$$inlined$test$1$lambda$1 { + // source: '2.kt' + enclosing method _2Kt$box$$inlined$test$1.(Lkotlin/jvm/internal/Ref$ObjectRef;Ljava/lang/String;)V + synthetic final field this$0: _2Kt$box$$inlined$test$1 + inner (anonymous) class _2Kt$box$$inlined$test$1$lambda$1 + method (p0: _2Kt$box$$inlined$test$1): void + public synthetic bridge method invoke(): java.lang.Object + public final @org.jetbrains.annotations.NotNull method invoke(): java.lang.String +} + +@kotlin.Metadata +public final class _2Kt$box$$inlined$test$1 { + // source: '1.kt' + enclosing method _2Kt.box()V + synthetic final field $captured$inlined: java.lang.String + synthetic final field $z$inlined: kotlin.jvm.internal.Ref$ObjectRef + private final @org.jetbrains.annotations.NotNull field p: java.lang.String + inner (anonymous) class _2Kt$box$$inlined$test$1 + public method (p0: kotlin.jvm.internal.Ref$ObjectRef, p1: java.lang.String): void + public @org.jetbrains.annotations.NotNull method a(): java.lang.String + public final @org.jetbrains.annotations.NotNull method getP(): java.lang.String +} + +@kotlin.Metadata +public final class _2Kt { + // source: '2.kt' + public final static method box(): void +} + +@kotlin.Metadata +public interface test/Z { + // source: '1.kt' + public abstract @org.jetbrains.annotations.NotNull method a(): java.lang.String +} + +@kotlin.Metadata +public final class test/_1Kt$test$1 { + // source: '1.kt' + enclosing method test/_1Kt.test(Lkotlin/jvm/functions/Function0;)Ltest/Z; + synthetic final field $z: kotlin.jvm.functions.Function0 + private final @org.jetbrains.annotations.NotNull field p: java.lang.String + inner (anonymous) class test/_1Kt$test$1 + public method (p0: kotlin.jvm.functions.Function0): void + public @org.jetbrains.annotations.NotNull method a(): java.lang.String + public final @org.jetbrains.annotations.NotNull method getP(): java.lang.String +} + +@kotlin.Metadata +public final class test/_1Kt { + // source: '1.kt' + inner (anonymous) class test/_1Kt$test$1 + public final static method call(@org.jetbrains.annotations.NotNull p0: kotlin.jvm.functions.Function0): java.lang.Object + public final static @org.jetbrains.annotations.NotNull method test(@org.jetbrains.annotations.NotNull p0: kotlin.jvm.functions.Function0): test.Z +} diff --git a/compiler/testData/codegen/bytecodeListing/inline/enclosingInfo/transformedConstructorWithNestedInline_ir.txt b/compiler/testData/codegen/bytecodeListing/inline/enclosingInfo/transformedConstructorWithNestedInline_ir.txt new file mode 100644 index 00000000000..670f2afdc88 --- /dev/null +++ b/compiler/testData/codegen/bytecodeListing/inline/enclosingInfo/transformedConstructorWithNestedInline_ir.txt @@ -0,0 +1,56 @@ +@kotlin.Metadata +public final class _2Kt$box$$inlined$test$1 { + // source: '1.kt' + enclosing method _2Kt.box()V + synthetic final field $captured$inlined: java.lang.String + synthetic final field $z$inlined: kotlin.jvm.internal.Ref$ObjectRef + private final @org.jetbrains.annotations.NotNull field p: java.lang.String + inner (anonymous) class _2Kt$box$$inlined$test$1 + public method (p0: kotlin.jvm.internal.Ref$ObjectRef, p1: java.lang.String): void + public @org.jetbrains.annotations.NotNull method a(): java.lang.String + public final @org.jetbrains.annotations.NotNull method getP(): java.lang.String +} + +@kotlin.Metadata +final class _2Kt$box$res$1$1$1 { + // source: '2.kt' + enclosing method _2Kt.box()V + synthetic final field $captured: java.lang.String + inner (anonymous) class _2Kt$box$res$1$1$1 + method (p0: java.lang.String): void + public synthetic bridge method invoke(): java.lang.Object + public final @org.jetbrains.annotations.NotNull method invoke(): java.lang.String +} + +@kotlin.Metadata +public final class _2Kt { + // source: '2.kt' + inner (anonymous) class _2Kt$box$res$1$1$1 + public final static method box(): void +} + +@kotlin.Metadata +public interface test/Z { + // source: '1.kt' + public abstract @org.jetbrains.annotations.NotNull method a(): java.lang.String +} + +@kotlin.Metadata +public final class test/_1Kt$test$1 { + // source: '1.kt' + enclosing method test/_1Kt.test(Lkotlin/jvm/functions/Function0;)Ltest/Z; + synthetic final field $z: kotlin.jvm.functions.Function0 + private final @org.jetbrains.annotations.NotNull field p: java.lang.String + inner (anonymous) class test/_1Kt$test$1 + public method (p0: kotlin.jvm.functions.Function0): void + public @org.jetbrains.annotations.NotNull method a(): java.lang.String + public final @org.jetbrains.annotations.NotNull method getP(): java.lang.String +} + +@kotlin.Metadata +public final class test/_1Kt { + // source: '1.kt' + inner (anonymous) class test/_1Kt$test$1 + public final static method call(@org.jetbrains.annotations.NotNull p0: kotlin.jvm.functions.Function0): java.lang.Object + public final static @org.jetbrains.annotations.NotNull method test(@org.jetbrains.annotations.NotNull p0: kotlin.jvm.functions.Function0): test.Z +} diff --git a/compiler/testData/codegen/bytecodeListing/inline/enclosingInfo/transformedConstructor_ir.txt b/compiler/testData/codegen/bytecodeListing/inline/enclosingInfo/transformedConstructor_ir.txt new file mode 100644 index 00000000000..3f3d889f69e --- /dev/null +++ b/compiler/testData/codegen/bytecodeListing/inline/enclosingInfo/transformedConstructor_ir.txt @@ -0,0 +1,55 @@ +@kotlin.Metadata +public final class _2Kt$box$$inlined$test$1 { + // source: '1.kt' + enclosing method _2Kt.box()V + synthetic final field $captured$inlined: java.lang.String + synthetic final field $z$inlined: kotlin.jvm.internal.Ref$ObjectRef + private final @org.jetbrains.annotations.NotNull field p: java.lang.String + inner (anonymous) class _2Kt$box$$inlined$test$1 + public method (p0: kotlin.jvm.internal.Ref$ObjectRef, p1: java.lang.String): void + public @org.jetbrains.annotations.NotNull method a(): java.lang.String + public final @org.jetbrains.annotations.NotNull method getP(): java.lang.String +} + +@kotlin.Metadata +final class _2Kt$box$res$1$1 { + // source: '2.kt' + enclosing method _2Kt.box()V + synthetic final field $captured: java.lang.String + inner (anonymous) class _2Kt$box$res$1$1 + method (p0: java.lang.String): void + public synthetic bridge method invoke(): java.lang.Object + public final @org.jetbrains.annotations.NotNull method invoke(): java.lang.String +} + +@kotlin.Metadata +public final class _2Kt { + // source: '2.kt' + inner (anonymous) class _2Kt$box$res$1$1 + public final static method box(): void +} + +@kotlin.Metadata +public interface test/Z { + // source: '1.kt' + public abstract @org.jetbrains.annotations.NotNull method a(): java.lang.String +} + +@kotlin.Metadata +public final class test/_1Kt$test$1 { + // source: '1.kt' + enclosing method test/_1Kt.test(Lkotlin/jvm/functions/Function0;)Ltest/Z; + synthetic final field $z: kotlin.jvm.functions.Function0 + private final @org.jetbrains.annotations.NotNull field p: java.lang.String + inner (anonymous) class test/_1Kt$test$1 + public method (p0: kotlin.jvm.functions.Function0): void + public @org.jetbrains.annotations.NotNull method a(): java.lang.String + public final @org.jetbrains.annotations.NotNull method getP(): java.lang.String +} + +@kotlin.Metadata +public final class test/_1Kt { + // source: '1.kt' + inner (anonymous) class test/_1Kt$test$1 + public final static @org.jetbrains.annotations.NotNull method test(@org.jetbrains.annotations.NotNull p0: kotlin.jvm.functions.Function0): test.Z +} diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeListingTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeListingTestGenerated.java index 610b8ddf051..6e1830b912f 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeListingTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeListingTestGenerated.java @@ -446,6 +446,39 @@ public class BytecodeListingTestGenerated extends AbstractBytecodeListingTest { public void testSimpleNamed() throws Exception { runTest("compiler/testData/codegen/bytecodeListing/inline/simpleNamed.kt"); } + + @TestMetadata("compiler/testData/codegen/bytecodeListing/inline/enclosingInfo") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class EnclosingInfo extends AbstractBytecodeListingTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, this, testDataFilePath); + } + + public void testAllFilesPresentInEnclosingInfo() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/bytecodeListing/inline/enclosingInfo"), Pattern.compile("^(.+)\\.kt$"), null, true); + } + + @TestMetadata("crossinlineLambdaChain.kt") + public void testCrossinlineLambdaChain() throws Exception { + runTest("compiler/testData/codegen/bytecodeListing/inline/enclosingInfo/crossinlineLambdaChain.kt"); + } + + @TestMetadata("kt10259.kt") + public void testKt10259() throws Exception { + runTest("compiler/testData/codegen/bytecodeListing/inline/enclosingInfo/kt10259.kt"); + } + + @TestMetadata("transformedConstructor.kt") + public void testTransformedConstructor() throws Exception { + runTest("compiler/testData/codegen/bytecodeListing/inline/enclosingInfo/transformedConstructor.kt"); + } + + @TestMetadata("transformedConstructorWithNestedInline.kt") + public void testTransformedConstructorWithNestedInline() throws Exception { + runTest("compiler/testData/codegen/bytecodeListing/inline/enclosingInfo/transformedConstructorWithNestedInline.kt"); + } + } } @TestMetadata("compiler/testData/codegen/bytecodeListing/inlineClasses") diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBytecodeListingTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBytecodeListingTestGenerated.java index 3798739e1b3..ba578531e6d 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBytecodeListingTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBytecodeListingTestGenerated.java @@ -416,6 +416,39 @@ public class IrBytecodeListingTestGenerated extends AbstractIrBytecodeListingTes public void testSimpleNamed() throws Exception { runTest("compiler/testData/codegen/bytecodeListing/inline/simpleNamed.kt"); } + + @TestMetadata("compiler/testData/codegen/bytecodeListing/inline/enclosingInfo") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class EnclosingInfo extends AbstractIrBytecodeListingTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM_IR, testDataFilePath); + } + + public void testAllFilesPresentInEnclosingInfo() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/bytecodeListing/inline/enclosingInfo"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true); + } + + @TestMetadata("crossinlineLambdaChain.kt") + public void testCrossinlineLambdaChain() throws Exception { + runTest("compiler/testData/codegen/bytecodeListing/inline/enclosingInfo/crossinlineLambdaChain.kt"); + } + + @TestMetadata("kt10259.kt") + public void testKt10259() throws Exception { + runTest("compiler/testData/codegen/bytecodeListing/inline/enclosingInfo/kt10259.kt"); + } + + @TestMetadata("transformedConstructor.kt") + public void testTransformedConstructor() throws Exception { + runTest("compiler/testData/codegen/bytecodeListing/inline/enclosingInfo/transformedConstructor.kt"); + } + + @TestMetadata("transformedConstructorWithNestedInline.kt") + public void testTransformedConstructorWithNestedInline() throws Exception { + runTest("compiler/testData/codegen/bytecodeListing/inline/enclosingInfo/transformedConstructorWithNestedInline.kt"); + } + } } @TestMetadata("compiler/testData/codegen/bytecodeListing/inlineClasses")