diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/AnonymousObjectTransformer.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/AnonymousObjectTransformer.java index 211b2bdd82a..f459c4b3930 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/AnonymousObjectTransformer.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/AnonymousObjectTransformer.java @@ -81,6 +81,7 @@ public class AnonymousObjectTransformer { @NotNull public InlineResult doTransform(@NotNull AnonymousObjectGeneration anonymousObjectGen, @NotNull FieldRemapper parentRemapper) { + final List innerClassNodes = new ArrayList(); ClassBuilder classBuilder = createClassBuilder(); final List methodsToTransform = new ArrayList(); @@ -95,6 +96,11 @@ public class AnonymousObjectTransformer { super.visit(version, access, name, signature, superName, interfaces); } + @Override + public void visitInnerClass(String name, String outerName, String innerName, int access) { + innerClassNodes.add(new InnerClassNode(name, outerName, innerName, access)); + } + @Override public void visitOuterClass(@NotNull String owner, String name, String desc) { InliningContext parent = inliningContext.getParent(); @@ -200,6 +206,10 @@ public class AnonymousObjectTransformer { SourceMapper.Companion.flushToClassBuilder(sourceMapper, classBuilder); + for (InnerClassNode node : innerClassNodes) { + classBuilder.getVisitor().visitInnerClass(node.name, node.outerName, node.innerName, node.access); + } + classBuilder.done(); anonymousObjectGen.setNewLambdaType(newLambdaType); diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/MethodInliner.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/MethodInliner.java index 1b573fdfc2e..8606a0cffea 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/MethodInliner.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/MethodInliner.java @@ -262,7 +262,14 @@ public class MethodInliner { visitFieldInsn(Opcodes.GETSTATIC, capturedParamDesc.getContainingLambdaName(), "$$$" + capturedParamDesc.getFieldName(), capturedParamDesc.getType().getDescriptor()); } - super.visitMethodInsn(opcode, anonymousObjectGen.getNewLambdaType().getInternalName(), name, anonymousObjectGen.getNewConstructorDescriptor(), itf); + String newInternalName = anonymousObjectGen.getNewLambdaType().getInternalName(); + super.visitMethodInsn(opcode, newInternalName, name, anonymousObjectGen.getNewConstructorDescriptor(), itf); + + //TODO: add new inner class also for other contexts + if (inliningContext.getParent() instanceof RegeneratedClassContext) { + inliningContext.getParent().typeRemapper.addAdditionalMappings(anonymousObjectGen.getOwnerInternalName(), newInternalName); + } + anonymousObjectGen = null; } else { super.visitMethodInsn(opcode, changeOwnerForExternalPackage(owner, opcode), name, desc, itf); diff --git a/compiler/testData/codegen/boxInline/innerClasses/kt10259.1.kt b/compiler/testData/codegen/boxInline/innerClasses/kt10259.1.kt new file mode 100644 index 00000000000..c1c7854b88d --- /dev/null +++ b/compiler/testData/codegen/boxInline/innerClasses/kt10259.1.kt @@ -0,0 +1,22 @@ +import test.* + +fun box(): String { + var encl1 = "fail"; + var encl2 = "fail"; + test { + { + val p = object {} + encl1 = p.javaClass.enclosingMethod.declaringClass.name + { + + val p = object {} + encl2 = p.javaClass.enclosingMethod.declaringClass.name + }() + }() + } + + if (encl1 != "Kt10259_1Kt\$box\$\$inlined\$test\$lambda$1") return "fail 1: $encl1" + if (encl2 != "Kt10259_1Kt\$box\$\$inlined\$test\$lambda\$lambda$2") return "fail 2: $encl2" + + return "OK" +} diff --git a/compiler/testData/codegen/boxInline/innerClasses/kt10259.2.kt b/compiler/testData/codegen/boxInline/innerClasses/kt10259.2.kt new file mode 100644 index 00000000000..e82c338479c --- /dev/null +++ b/compiler/testData/codegen/boxInline/innerClasses/kt10259.2.kt @@ -0,0 +1,5 @@ +package test + +inline fun test(s: () -> Unit) { + s() +} \ No newline at end of file diff --git a/compiler/testData/codegen/bytecodeText/kt10259.kt b/compiler/testData/codegen/bytecodeText/kt10259.kt new file mode 100644 index 00000000000..bf6b46da44e --- /dev/null +++ b/compiler/testData/codegen/bytecodeText/kt10259.kt @@ -0,0 +1,22 @@ +fun box(): String { + var encl1 = "fail"; + var encl2 = "fail"; + test { + { + encl1 = "OK" + { + encl2 = "OK" + }() + }() + } + + return "OK" +} + +inline fun test(s: () -> Unit) { + s() +} + +// 2 INNERCLASS Kt10259Kt\$box\$\$inlined\$test\$lambda\$1 +// 2 INNERCLASS Kt10259Kt\$box\$\$inlined\$test\$lambda\$lambda\$1 +// 4 INNERCLASS \ No newline at end of file diff --git a/compiler/testData/codegen/bytecodeText/kt10259_2.kt b/compiler/testData/codegen/bytecodeText/kt10259_2.kt new file mode 100644 index 00000000000..c0fe532acaf --- /dev/null +++ b/compiler/testData/codegen/bytecodeText/kt10259_2.kt @@ -0,0 +1,22 @@ +fun box(): String { + var encl1 = "fail"; + test { + encl1 = "OK" + } + + return encl1 +} + +inline fun test(crossinline s: () -> Unit) { + { + { + s() + }() + }() +} + +// 3 INNERCLASS Kt10259_2Kt\$test\$1 null +// 2 INNERCLASS Kt10259_2Kt\$test\$1\$1 +// 2 INNERCLASS Kt10259_2Kt\$box\$\$inlined\$test\$1 +// 2 INNERCLASS Kt10259_2Kt\$box\$\$inlined\$test\$lambda\$1 +// 9 INNERCLASS \ No newline at end of file diff --git a/compiler/testData/codegen/bytecodeText/kt10259_3.kt b/compiler/testData/codegen/bytecodeText/kt10259_3.kt new file mode 100644 index 00000000000..95410821b76 --- /dev/null +++ b/compiler/testData/codegen/bytecodeText/kt10259_3.kt @@ -0,0 +1,29 @@ +fun box(): String { + var encl1 = "fail"; + test { + { + { + encl1 = "OK" + }() + }() + } + + return encl1 +} + +inline fun test(crossinline s: () -> Unit) { + { + { + s() + }() + }() +} + +// 3 INNERCLASS Kt10259_3Kt\$test\$1 null +// 2 INNERCLASS Kt10259_3Kt\$test\$1\$1 +// 2 INNERCLASS Kt10259_3Kt\$box\$\$inlined\$test\$1 +// 2 INNERCLASS Kt10259_3Kt\$box\$\$inlined\$test\$lambda\$1 +// inlined: +// 2 INNERCLASS Kt10259_3Kt\$box\$\$inlined\$test\$lambda\$lambda\$lambda\$1 +// 2 INNERCLASS Kt10259_3Kt\$box\$\$inlined\$test\$lambda\$lambda\$lambda\$lambda\$1 +// 13 INNERCLASS \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java index 28200d65c9c..d056261655b 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java @@ -167,6 +167,24 @@ public class BytecodeTextTestGenerated extends AbstractBytecodeTextTest { doTest(fileName); } + @TestMetadata("kt10259.kt") + public void testKt10259() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeText/kt10259.kt"); + doTest(fileName); + } + + @TestMetadata("kt10259_2.kt") + public void testKt10259_2() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeText/kt10259_2.kt"); + doTest(fileName); + } + + @TestMetadata("kt10259_3.kt") + public void testKt10259_3() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeText/kt10259_3.kt"); + doTest(fileName); + } + @TestMetadata("kt2202.kt") public void testKt2202() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeText/kt2202.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/generated/BlackBoxInlineCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/generated/BlackBoxInlineCodegenTestGenerated.java index 671ed23ae58..4f122688194 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/generated/BlackBoxInlineCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/generated/BlackBoxInlineCodegenTestGenerated.java @@ -602,6 +602,21 @@ public class BlackBoxInlineCodegenTestGenerated extends AbstractBlackBoxInlineCo } } + @TestMetadata("compiler/testData/codegen/boxInline/innerClasses") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class InnerClasses extends AbstractBlackBoxInlineCodegenTest { + public void testAllFilesPresentInInnerClasses() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/boxInline/innerClasses"), Pattern.compile("^(.+)\\.1.kt$"), true); + } + + @TestMetadata("kt10259.1.kt") + public void testKt10259() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/innerClasses/kt10259.1.kt"); + doTestMultiFileWithInlineCheck(fileName); + } + } + @TestMetadata("compiler/testData/codegen/boxInline/lambdaClassClash") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) diff --git a/compiler/tests/org/jetbrains/kotlin/jvm/compiler/CompileKotlinAgainstInlineKotlinTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/jvm/compiler/CompileKotlinAgainstInlineKotlinTestGenerated.java index 02899f3bc9b..13a11639910 100644 --- a/compiler/tests/org/jetbrains/kotlin/jvm/compiler/CompileKotlinAgainstInlineKotlinTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/jvm/compiler/CompileKotlinAgainstInlineKotlinTestGenerated.java @@ -602,6 +602,21 @@ public class CompileKotlinAgainstInlineKotlinTestGenerated extends AbstractCompi } } + @TestMetadata("compiler/testData/codegen/boxInline/innerClasses") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class InnerClasses extends AbstractCompileKotlinAgainstInlineKotlinTest { + public void testAllFilesPresentInInnerClasses() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/boxInline/innerClasses"), Pattern.compile("^(.+)\\.1.kt$"), true); + } + + @TestMetadata("kt10259.1.kt") + public void testKt10259() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/innerClasses/kt10259.1.kt"); + doBoxTestWithInlineCheck(fileName); + } + } + @TestMetadata("compiler/testData/codegen/boxInline/lambdaClassClash") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class)