From c4a396392589ece45407bd2fa1dce347ae9f9cd9 Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Thu, 17 Jan 2013 22:06:11 +0400 Subject: [PATCH] Fix nested classes codegen bug When constructing a closure, codegen in some cases incorrectly determined if it needed to store a reference from a nested class to the outer --- .../jet/codegen/context/CodegenContext.java | 15 +++++++-------- .../innerNested/createdNestedInOuterMember.kt | 14 ++++++++++++++ .../generated/InnerNestedGenTestGenerated.java | 5 +++++ 3 files changed, 26 insertions(+), 8 deletions(-) create mode 100644 compiler/testData/codegen/innerNested/createdNestedInOuterMember.kt diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/context/CodegenContext.java b/compiler/backend/src/org/jetbrains/jet/codegen/context/CodegenContext.java index e26542628ca..06494001cc4 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/context/CodegenContext.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/context/CodegenContext.java @@ -32,8 +32,7 @@ import java.util.HashMap; import java.util.Map; import static org.jetbrains.jet.codegen.AsmUtil.CAPTURED_THIS_FIELD; -import static org.jetbrains.jet.codegen.binding.CodegenBinding.CLASS_FOR_FUNCTION; -import static org.jetbrains.jet.codegen.binding.CodegenBinding.FQN; +import static org.jetbrains.jet.codegen.binding.CodegenBinding.*; import static org.jetbrains.jet.lang.resolve.java.AsmTypeConstants.OBJECT_TYPE; public abstract class CodegenContext { @@ -265,12 +264,12 @@ public abstract class CodegenContext { } protected void initOuterExpression(JetTypeMapper typeMapper, ClassDescriptor classDescriptor) { - final ClassDescriptor enclosingClass = getEnclosingClass(); - outerExpression = enclosingClass != null - ? StackValue - .field(typeMapper.mapType(enclosingClass), CodegenBinding.getJvmInternalName(typeMapper.getBindingTrace(), classDescriptor), - CAPTURED_THIS_FIELD, - false) + ClassDescriptor enclosingClass = getEnclosingClass(); + outerExpression = enclosingClass != null && canHaveOuter(typeMapper.getBindingContext(), classDescriptor) + ? StackValue.field(typeMapper.mapType(enclosingClass), + CodegenBinding.getJvmInternalName(typeMapper.getBindingTrace(), classDescriptor), + CAPTURED_THIS_FIELD, + false) : null; } diff --git a/compiler/testData/codegen/innerNested/createdNestedInOuterMember.kt b/compiler/testData/codegen/innerNested/createdNestedInOuterMember.kt new file mode 100644 index 00000000000..f4c0640c7ab --- /dev/null +++ b/compiler/testData/codegen/innerNested/createdNestedInOuterMember.kt @@ -0,0 +1,14 @@ +fun foo(f: (Int) -> Int) = f(0) + +class Outer { + class Nested { + val y = foo { a -> a } + } + + fun bar(): String { + val a = Nested() + return "OK" + } +} + +fun box() = Outer().bar() diff --git a/compiler/tests/org/jetbrains/jet/codegen/generated/InnerNestedGenTestGenerated.java b/compiler/tests/org/jetbrains/jet/codegen/generated/InnerNestedGenTestGenerated.java index adf62589bed..0bc745f7d2b 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/generated/InnerNestedGenTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/codegen/generated/InnerNestedGenTestGenerated.java @@ -38,6 +38,11 @@ public class InnerNestedGenTestGenerated extends AbstractCodegenTest { doTest("compiler/testData/codegen/innerNested/createNestedClass.kt"); } + @TestMetadata("createdNestedInOuterMember.kt") + public void testCreatedNestedInOuterMember() throws Exception { + doTest("compiler/testData/codegen/innerNested/createdNestedInOuterMember.kt"); + } + @TestMetadata("dataLocalVariable.kt") public void testDataLocalVariable() throws Exception { doTest("compiler/testData/codegen/innerNested/dataLocalVariable.kt");