From 1310a65f0cc6e39d32bb52fe9e636c8ae42bfa63 Mon Sep 17 00:00:00 2001 From: pyos Date: Wed, 3 Feb 2021 14:52:14 +0100 Subject: [PATCH] JVM: rename this$0 when regenerating nested objects too In the old backend, this was unnecessary because nested objects would reference their lambdas' captures through the original this$0. On JVM_IR, using loose capture fields means a name/descriptor clash can occur on any level of nesting, not just the top. --- .../inline/AnonymousObjectTransformer.kt | 94 ++++++++----------- ...FirBlackBoxInlineCodegenTestGenerated.java | 12 +++ .../twoCapturedReceivers/kt8668_nested.kt | 14 +++ .../twoCapturedReceivers/kt8668_nested_2.kt | 14 +++ .../BlackBoxInlineCodegenTestGenerated.java | 12 +++ ...otlinAgainstInlineKotlinTestGenerated.java | 12 +++ .../IrBlackBoxInlineCodegenTestGenerated.java | 12 +++ ...otlinAgainstInlineKotlinTestGenerated.java | 12 +++ ...JvmIrAgainstOldBoxInlineTestGenerated.java | 12 +++ ...JvmOldAgainstIrBoxInlineTestGenerated.java | 12 +++ .../IrJsCodegenInlineES6TestGenerated.java | 10 ++ .../IrJsCodegenInlineTestGenerated.java | 10 ++ .../JsCodegenInlineTestGenerated.java | 10 ++ 13 files changed, 180 insertions(+), 56 deletions(-) create mode 100644 compiler/testData/codegen/boxInline/anonymousObject/twoCapturedReceivers/kt8668_nested.kt create mode 100644 compiler/testData/codegen/boxInline/anonymousObject/twoCapturedReceivers/kt8668_nested_2.kt diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/AnonymousObjectTransformer.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/AnonymousObjectTransformer.kt index c4a846e2db7..e1f3d2d917d 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/AnonymousObjectTransformer.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/AnonymousObjectTransformer.kt @@ -462,6 +462,29 @@ class AnonymousObjectTransformer( val indexToFunctionalArgument = transformationInfo.functionalArguments val capturedParams = HashSet() + // Possible cases where we need to add each lambda's captures separately: + // + // 1. Top-level object in an inline lambda that is *not* being inlined into another object. In this case, we + // have no choice but to add a separate field for each captured variable. `capturedLambdas` is either empty + // (already have the fields) or contains the parent lambda object (captures used to be read from it, but + // the object will be removed and its contents inlined). + // + // 2. Top-level object in a named inline function. Again, there's no option but to add separate fields. + // `capturedLambdas` contains all lambdas used by this object and nested objects. + // + // 3. Nested object, either in an inline lambda or an inline function. This case has two subcases: + // * The object's captures are passed as separate arguments (e.g. KT-28064 style object that used to be in a lambda); + // we *could* group them into `this$0` now, but choose not to. Lambdas are replaced by their captures to match. + // * The object's captures are already grouped into `this$0`; this includes captured lambda parameters (for objects in + // inline functions) and a reference to the outer object or lambda (for objects in lambdas), so `capturedLambdas` is + // empty anyway. + // + // The only remaining case is a top-level object inside a (crossinline) lambda that is inlined into another object. + // Then, the reference to the soon-to-be-removed lambda class containing the captures (and it exists, or else the object + // would not have needed regeneration in the first place) is simply replaced with a reference to the outer object, and + // that object will contain loose fields for everything we need to capture. + val topLevelInCrossinlineLambda = parentFieldRemapper is InlinedLambdaRemapper && !parentFieldRemapper.parent!!.isRoot + //load captured parameters and patch instruction list // NB: there is also could be object fields val toDelete = arrayListOf() @@ -470,10 +493,12 @@ class AnonymousObjectTransformer( val parameterAload = fieldNode.previous as VarInsnNode val varIndex = parameterAload.`var` val functionalArgument = indexToFunctionalArgument[varIndex] - val newFieldName = if (isThis0(fieldName) && shouldRenameThis0(parentFieldRemapper, indexToFunctionalArgument.values)) - getNewFieldName(fieldName, true) - else - fieldName + // If an outer `this` is already captured by this object, rename it if any inline lambda will capture + // one of the same type, causing the code below to create a clash. Note that the values can be different. + // TODO: this is only really necessary if there will be a name *and* type clash. + val shouldRename = !topLevelInCrossinlineLambda && isThis0(fieldName) && + indexToFunctionalArgument.values.any { it is LambdaInfo && it.capturedVars.any { it.fieldName == fieldName } } + val newFieldName = if (shouldRename) addUniqueField(fieldName + INLINE_FUN_THIS_0_SUFFIX) else fieldName val info = capturedParamBuilder.addCapturedParam( Type.getObjectType(transformationInfo.oldClassName), fieldName, newFieldName, Type.getType(fieldNode.desc), functionalArgument is LambdaInfo, null @@ -508,35 +533,17 @@ class AnonymousObjectTransformer( //For all inlined lambdas add their captured parameters //TODO: some of such parameters could be skipped - we should perform additional analysis val allRecapturedParameters = ArrayList() - if (parentFieldRemapper !is InlinedLambdaRemapper || parentFieldRemapper.parent!!.isRoot) { - // Possible cases: - // - // 1. Top-level object in an inline lambda that is *not* being inlined into another object. In this case, we - // have no choice but to add a separate field for each captured variable. `capturedLambdas` is either empty - // (already have the fields) or contains the parent lambda object (captures used to be read from it, but - // the object will be removed and its contents inlined). - // - // 2. Top-level object in a named inline function. Again, there's no option but to add separate fields. - // `capturedLambdas` contains all lambdas used by this object and nested objects. - // - // 3. Nested object, either in an inline lambda or an inline function. This case has two subcases: - // * The object's captures are passed as separate arguments (e.g. KT-28064 style object that used to be in a lambda); - // we could group them into `this$0` now, but choose not to. Lambdas are replaced by their captures. - // * The object's captures are already grouped into `this$0`; this includes captured lambda parameters (for objects in - // inline functions) and a reference to the outer object or lambda (for objects in lambdas), so `capturedLambdas` is - // empty and the choice doesn't matter. - // - val alreadyAdded = HashMap() + if (!topLevelInCrossinlineLambda) { + val capturedOuterThisTypes = mutableSetOf() for (info in capturedLambdas) { for (desc in info.capturedVars) { - val key = desc.fieldName + "$$$" + desc.type.className - val alreadyAddedParam = alreadyAdded[key] - - val recapturedParamInfo = capturedParamBuilder.addCapturedParam( - desc, - alreadyAddedParam?.newFieldName ?: getNewFieldName(desc.fieldName, false), - alreadyAddedParam != null - ) + // Merge all outer `this` of the same type captured by inlined lambdas, since they have to be the same + // object. Outer `this` captured by the original object itself should have been renamed above, + // and can have a different value even if the same type is captured by a lambda. + val recapturedParamInfo = if (isThis0(desc.fieldName)) + capturedParamBuilder.addCapturedParam(desc, desc.fieldName, !capturedOuterThisTypes.add(desc.type.className)) + else + capturedParamBuilder.addCapturedParam(desc, addUniqueField(desc.fieldName + INLINE_TRANSFORMATION_SUFFIX), false) if (info is ExpressionLambda && info.isCapturedSuspend(desc)) { recapturedParamInfo.functionalArgument = NonInlineableArgumentForInlineableParameterCalledInSuspend } @@ -551,10 +558,6 @@ class AnonymousObjectTransformer( allRecapturedParameters.add(desc) constructorParamBuilder.addCapturedParam(recapturedParamInfo, recapturedParamInfo.newFieldName).remapValue = composed - - if (isThis0(desc.fieldName)) { - alreadyAdded.put(key, recapturedParamInfo) - } } } } else if (capturedLambdas.isNotEmpty()) { @@ -579,24 +582,6 @@ class AnonymousObjectTransformer( return constructorAdditionalFakeParams } - private fun shouldRenameThis0(parentFieldRemapper: FieldRemapper, values: Collection): Boolean { - return if (isFirstDeclSiteLambdaFieldRemapper(parentFieldRemapper)) { - values.any { it is LambdaInfo && it.capturedVars.any { isThis0(it.fieldName) } } - } else false - } - - private fun getNewFieldName(oldName: String, originalField: Boolean): String { - if (AsmUtil.CAPTURED_THIS_FIELD == oldName) { - return if (!originalField) { - oldName - } else { - //rename original 'this$0' in declaration site lambda (inside inline function) to use this$0 only for outer lambda/object access on call site - addUniqueField(oldName + INLINE_FUN_THIS_0_SUFFIX) - } - } - return addUniqueField(oldName + INLINE_TRANSFORMATION_SUFFIX) - } - private fun addUniqueField(name: String): String { val existNames = fieldNames.getOrPut(name) { LinkedList() } val suffix = if (existNames.isEmpty()) "" else "$" + existNames.size @@ -604,7 +589,4 @@ class AnonymousObjectTransformer( existNames.add(newName) return newName } - - private fun isFirstDeclSiteLambdaFieldRemapper(parentRemapper: FieldRemapper): Boolean = - parentRemapper !is RegeneratedLambdaFieldRemapper && parentRemapper !is InlinedLambdaRemapper } diff --git a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxInlineCodegenTestGenerated.java b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxInlineCodegenTestGenerated.java index 64e8d4ad4a3..3e8f3abdd24 100644 --- a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxInlineCodegenTestGenerated.java +++ b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxInlineCodegenTestGenerated.java @@ -647,6 +647,18 @@ public class FirBlackBoxInlineCodegenTestGenerated extends AbstractFirBlackBoxIn runTest("compiler/testData/codegen/boxInline/anonymousObject/twoCapturedReceivers/kt8668_3.kt"); } + @Test + @TestMetadata("kt8668_nested.kt") + public void testKt8668_nested() throws Exception { + runTest("compiler/testData/codegen/boxInline/anonymousObject/twoCapturedReceivers/kt8668_nested.kt"); + } + + @Test + @TestMetadata("kt8668_nested_2.kt") + public void testKt8668_nested_2() throws Exception { + runTest("compiler/testData/codegen/boxInline/anonymousObject/twoCapturedReceivers/kt8668_nested_2.kt"); + } + @Test @TestMetadata("twoDifferentDispatchReceivers.kt") public void testTwoDifferentDispatchReceivers() throws Exception { diff --git a/compiler/testData/codegen/boxInline/anonymousObject/twoCapturedReceivers/kt8668_nested.kt b/compiler/testData/codegen/boxInline/anonymousObject/twoCapturedReceivers/kt8668_nested.kt new file mode 100644 index 00000000000..7c6b9c68918 --- /dev/null +++ b/compiler/testData/codegen/boxInline/anonymousObject/twoCapturedReceivers/kt8668_nested.kt @@ -0,0 +1,14 @@ +// FILE: 1.kt +package test + +class C(val x: String) { + fun f(y: String) = C(y).g { x } + + inline fun g(crossinline h: () -> String) = + { { h() + x }() }() +} + +// FILE: 2.kt +import test.* + +fun box() = C("O").f("K") diff --git a/compiler/testData/codegen/boxInline/anonymousObject/twoCapturedReceivers/kt8668_nested_2.kt b/compiler/testData/codegen/boxInline/anonymousObject/twoCapturedReceivers/kt8668_nested_2.kt new file mode 100644 index 00000000000..2cf776c3eed --- /dev/null +++ b/compiler/testData/codegen/boxInline/anonymousObject/twoCapturedReceivers/kt8668_nested_2.kt @@ -0,0 +1,14 @@ +// FILE: 1.kt +package test + +class C(val x: String) { + inline fun f(crossinline h: () -> String) = C("").g { x + h() } + + inline fun g(crossinline h: () -> String) = + { { h() + x }() }() +} + +// FILE: 2.kt +import test.* + +fun box() = C("O").f { "K" } diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxInlineCodegenTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxInlineCodegenTestGenerated.java index c5518687452..4bbf6aaa6cf 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxInlineCodegenTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxInlineCodegenTestGenerated.java @@ -647,6 +647,18 @@ public class BlackBoxInlineCodegenTestGenerated extends AbstractBlackBoxInlineCo runTest("compiler/testData/codegen/boxInline/anonymousObject/twoCapturedReceivers/kt8668_3.kt"); } + @Test + @TestMetadata("kt8668_nested.kt") + public void testKt8668_nested() throws Exception { + runTest("compiler/testData/codegen/boxInline/anonymousObject/twoCapturedReceivers/kt8668_nested.kt"); + } + + @Test + @TestMetadata("kt8668_nested_2.kt") + public void testKt8668_nested_2() throws Exception { + runTest("compiler/testData/codegen/boxInline/anonymousObject/twoCapturedReceivers/kt8668_nested_2.kt"); + } + @Test @TestMetadata("twoDifferentDispatchReceivers.kt") public void testTwoDifferentDispatchReceivers() throws Exception { diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/CompileKotlinAgainstInlineKotlinTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/CompileKotlinAgainstInlineKotlinTestGenerated.java index 5e2563c6f44..cd25eee936b 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/CompileKotlinAgainstInlineKotlinTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/CompileKotlinAgainstInlineKotlinTestGenerated.java @@ -647,6 +647,18 @@ public class CompileKotlinAgainstInlineKotlinTestGenerated extends AbstractCompi runTest("compiler/testData/codegen/boxInline/anonymousObject/twoCapturedReceivers/kt8668_3.kt"); } + @Test + @TestMetadata("kt8668_nested.kt") + public void testKt8668_nested() throws Exception { + runTest("compiler/testData/codegen/boxInline/anonymousObject/twoCapturedReceivers/kt8668_nested.kt"); + } + + @Test + @TestMetadata("kt8668_nested_2.kt") + public void testKt8668_nested_2() throws Exception { + runTest("compiler/testData/codegen/boxInline/anonymousObject/twoCapturedReceivers/kt8668_nested_2.kt"); + } + @Test @TestMetadata("twoDifferentDispatchReceivers.kt") public void testTwoDifferentDispatchReceivers() throws Exception { diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxInlineCodegenTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxInlineCodegenTestGenerated.java index 923d5b8216d..8489888393a 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxInlineCodegenTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxInlineCodegenTestGenerated.java @@ -647,6 +647,18 @@ public class IrBlackBoxInlineCodegenTestGenerated extends AbstractIrBlackBoxInli runTest("compiler/testData/codegen/boxInline/anonymousObject/twoCapturedReceivers/kt8668_3.kt"); } + @Test + @TestMetadata("kt8668_nested.kt") + public void testKt8668_nested() throws Exception { + runTest("compiler/testData/codegen/boxInline/anonymousObject/twoCapturedReceivers/kt8668_nested.kt"); + } + + @Test + @TestMetadata("kt8668_nested_2.kt") + public void testKt8668_nested_2() throws Exception { + runTest("compiler/testData/codegen/boxInline/anonymousObject/twoCapturedReceivers/kt8668_nested_2.kt"); + } + @Test @TestMetadata("twoDifferentDispatchReceivers.kt") public void testTwoDifferentDispatchReceivers() throws Exception { diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrCompileKotlinAgainstInlineKotlinTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrCompileKotlinAgainstInlineKotlinTestGenerated.java index 77a112550c6..d1a19baf1e7 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrCompileKotlinAgainstInlineKotlinTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrCompileKotlinAgainstInlineKotlinTestGenerated.java @@ -647,6 +647,18 @@ public class IrCompileKotlinAgainstInlineKotlinTestGenerated extends AbstractIrC runTest("compiler/testData/codegen/boxInline/anonymousObject/twoCapturedReceivers/kt8668_3.kt"); } + @Test + @TestMetadata("kt8668_nested.kt") + public void testKt8668_nested() throws Exception { + runTest("compiler/testData/codegen/boxInline/anonymousObject/twoCapturedReceivers/kt8668_nested.kt"); + } + + @Test + @TestMetadata("kt8668_nested_2.kt") + public void testKt8668_nested_2() throws Exception { + runTest("compiler/testData/codegen/boxInline/anonymousObject/twoCapturedReceivers/kt8668_nested_2.kt"); + } + @Test @TestMetadata("twoDifferentDispatchReceivers.kt") public void testTwoDifferentDispatchReceivers() throws Exception { diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/JvmIrAgainstOldBoxInlineTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/JvmIrAgainstOldBoxInlineTestGenerated.java index fc5e88ed307..ce4ed6b602c 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/JvmIrAgainstOldBoxInlineTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/JvmIrAgainstOldBoxInlineTestGenerated.java @@ -647,6 +647,18 @@ public class JvmIrAgainstOldBoxInlineTestGenerated extends AbstractJvmIrAgainstO runTest("compiler/testData/codegen/boxInline/anonymousObject/twoCapturedReceivers/kt8668_3.kt"); } + @Test + @TestMetadata("kt8668_nested.kt") + public void testKt8668_nested() throws Exception { + runTest("compiler/testData/codegen/boxInline/anonymousObject/twoCapturedReceivers/kt8668_nested.kt"); + } + + @Test + @TestMetadata("kt8668_nested_2.kt") + public void testKt8668_nested_2() throws Exception { + runTest("compiler/testData/codegen/boxInline/anonymousObject/twoCapturedReceivers/kt8668_nested_2.kt"); + } + @Test @TestMetadata("twoDifferentDispatchReceivers.kt") public void testTwoDifferentDispatchReceivers() throws Exception { diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/JvmOldAgainstIrBoxInlineTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/JvmOldAgainstIrBoxInlineTestGenerated.java index 0595eeddb3f..3b646a4262f 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/JvmOldAgainstIrBoxInlineTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/JvmOldAgainstIrBoxInlineTestGenerated.java @@ -647,6 +647,18 @@ public class JvmOldAgainstIrBoxInlineTestGenerated extends AbstractJvmOldAgainst runTest("compiler/testData/codegen/boxInline/anonymousObject/twoCapturedReceivers/kt8668_3.kt"); } + @Test + @TestMetadata("kt8668_nested.kt") + public void testKt8668_nested() throws Exception { + runTest("compiler/testData/codegen/boxInline/anonymousObject/twoCapturedReceivers/kt8668_nested.kt"); + } + + @Test + @TestMetadata("kt8668_nested_2.kt") + public void testKt8668_nested_2() throws Exception { + runTest("compiler/testData/codegen/boxInline/anonymousObject/twoCapturedReceivers/kt8668_nested_2.kt"); + } + @Test @TestMetadata("twoDifferentDispatchReceivers.kt") public void testTwoDifferentDispatchReceivers() throws Exception { diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenInlineES6TestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenInlineES6TestGenerated.java index cfbea859cb2..47fd9bacfb7 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenInlineES6TestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenInlineES6TestGenerated.java @@ -506,6 +506,16 @@ public class IrJsCodegenInlineES6TestGenerated extends AbstractIrJsCodegenInline runTest("compiler/testData/codegen/boxInline/anonymousObject/twoCapturedReceivers/kt8668_3.kt"); } + @TestMetadata("kt8668_nested.kt") + public void testKt8668_nested() throws Exception { + runTest("compiler/testData/codegen/boxInline/anonymousObject/twoCapturedReceivers/kt8668_nested.kt"); + } + + @TestMetadata("kt8668_nested_2.kt") + public void testKt8668_nested_2() throws Exception { + runTest("compiler/testData/codegen/boxInline/anonymousObject/twoCapturedReceivers/kt8668_nested_2.kt"); + } + @TestMetadata("twoDifferentDispatchReceivers.kt") public void testTwoDifferentDispatchReceivers() throws Exception { runTest("compiler/testData/codegen/boxInline/anonymousObject/twoCapturedReceivers/twoDifferentDispatchReceivers.kt"); diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenInlineTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenInlineTestGenerated.java index edacdee1ae3..022c5e3c219 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenInlineTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenInlineTestGenerated.java @@ -506,6 +506,16 @@ public class IrJsCodegenInlineTestGenerated extends AbstractIrJsCodegenInlineTes runTest("compiler/testData/codegen/boxInline/anonymousObject/twoCapturedReceivers/kt8668_3.kt"); } + @TestMetadata("kt8668_nested.kt") + public void testKt8668_nested() throws Exception { + runTest("compiler/testData/codegen/boxInline/anonymousObject/twoCapturedReceivers/kt8668_nested.kt"); + } + + @TestMetadata("kt8668_nested_2.kt") + public void testKt8668_nested_2() throws Exception { + runTest("compiler/testData/codegen/boxInline/anonymousObject/twoCapturedReceivers/kt8668_nested_2.kt"); + } + @TestMetadata("twoDifferentDispatchReceivers.kt") public void testTwoDifferentDispatchReceivers() throws Exception { runTest("compiler/testData/codegen/boxInline/anonymousObject/twoCapturedReceivers/twoDifferentDispatchReceivers.kt"); diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/semantics/JsCodegenInlineTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/semantics/JsCodegenInlineTestGenerated.java index edf8a2f4844..c6ceb1eb10d 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/semantics/JsCodegenInlineTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/semantics/JsCodegenInlineTestGenerated.java @@ -506,6 +506,16 @@ public class JsCodegenInlineTestGenerated extends AbstractJsCodegenInlineTest { runTest("compiler/testData/codegen/boxInline/anonymousObject/twoCapturedReceivers/kt8668_3.kt"); } + @TestMetadata("kt8668_nested.kt") + public void testKt8668_nested() throws Exception { + runTest("compiler/testData/codegen/boxInline/anonymousObject/twoCapturedReceivers/kt8668_nested.kt"); + } + + @TestMetadata("kt8668_nested_2.kt") + public void testKt8668_nested_2() throws Exception { + runTest("compiler/testData/codegen/boxInline/anonymousObject/twoCapturedReceivers/kt8668_nested_2.kt"); + } + @TestMetadata("twoDifferentDispatchReceivers.kt") public void testTwoDifferentDispatchReceivers() throws Exception { runTest("compiler/testData/codegen/boxInline/anonymousObject/twoCapturedReceivers/twoDifferentDispatchReceivers.kt");