diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/context/MethodContext.java b/compiler/backend/src/org/jetbrains/jet/codegen/context/MethodContext.java index 458097bc1df..1f867415ea0 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/context/MethodContext.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/context/MethodContext.java @@ -41,7 +41,7 @@ public class MethodContext extends CodegenContext { @Override public StackValue lookupInContext(DeclarationDescriptor d, @Nullable StackValue result, GenerationState state, boolean ignoreNoOuter) { if (getContextDescriptor() == d) { - return StackValue.local(0, AsmTypeConstants.OBJECT_TYPE); + return result != null ? result : StackValue.local(0, AsmTypeConstants.OBJECT_TYPE); } //noinspection ConstantConditions diff --git a/compiler/testData/codegen/box/closures/closureInsideClosure/localFunInsideLocalFun.kt b/compiler/testData/codegen/box/closures/closureInsideClosure/localFunInsideLocalFun.kt new file mode 100644 index 00000000000..106b0a763b3 --- /dev/null +++ b/compiler/testData/codegen/box/closures/closureInsideClosure/localFunInsideLocalFun.kt @@ -0,0 +1,13 @@ +fun box(): String { + fun rec(n : Int) { + fun x(m : Int) { + if (n > 0) rec(n - 1) + } + + x(0) + } + + rec(5) + + return "OK" +} diff --git a/compiler/testData/codegen/box/closures/closureInsideClosure/localFunInsideLocalFunDifferentSignatures.kt b/compiler/testData/codegen/box/closures/closureInsideClosure/localFunInsideLocalFunDifferentSignatures.kt new file mode 100644 index 00000000000..38c08c8a19d --- /dev/null +++ b/compiler/testData/codegen/box/closures/closureInsideClosure/localFunInsideLocalFunDifferentSignatures.kt @@ -0,0 +1,13 @@ +fun box(): String { + fun rec(n : Int) { + fun x(m : Int, k : Int) { + if (n > 0) rec(n - 1 + k) + } + + x(0, 0) + } + + rec(5) + + return "OK" +} diff --git a/compiler/testData/codegen/box/closures/closureInsideClosure/threeLevels.kt b/compiler/testData/codegen/box/closures/closureInsideClosure/threeLevels.kt new file mode 100644 index 00000000000..e0fc6457f26 --- /dev/null +++ b/compiler/testData/codegen/box/closures/closureInsideClosure/threeLevels.kt @@ -0,0 +1,17 @@ +fun box(): String { + fun foo(x: Int) { + fun bar(y: Int) { + fun baz(z: Int) { + foo(x - 1) + } + + baz(y) + } + + if (x > 0) bar(x) + } + + foo(1) + + return "OK" +} diff --git a/compiler/testData/codegen/box/closures/closureInsideClosure/threeLevelsDifferentSignatures.kt b/compiler/testData/codegen/box/closures/closureInsideClosure/threeLevelsDifferentSignatures.kt new file mode 100644 index 00000000000..a5fadc55936 --- /dev/null +++ b/compiler/testData/codegen/box/closures/closureInsideClosure/threeLevelsDifferentSignatures.kt @@ -0,0 +1,16 @@ +fun box(): String { + fun foo(x: Int, s: String): String { + fun bar(y: Int) { + fun baz(z: Int, k: Int) { + foo(x - 1 + k, "Fail") + } + + baz(y, 0) + } + + if (x > 0) bar(x) + return s + } + + return foo(1, "OK") +} diff --git a/compiler/testData/codegen/box/closures/closureInsideClosure/varAsFunInsideLocalFun.kt b/compiler/testData/codegen/box/closures/closureInsideClosure/varAsFunInsideLocalFun.kt new file mode 100644 index 00000000000..e0fb5427100 --- /dev/null +++ b/compiler/testData/codegen/box/closures/closureInsideClosure/varAsFunInsideLocalFun.kt @@ -0,0 +1,15 @@ +//KT-3276 + +fun box(): String { + fun rec(n : Int) { + val x = { (m : Int) -> + if (n > 0) rec(n - 1) + } + + x(0) + } + + rec(5) + + return "OK" +} diff --git a/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxCodegenTestGenerated.java index 6424a4c71f0..23cadb3a71b 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxCodegenTestGenerated.java @@ -888,6 +888,7 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { } @TestMetadata("compiler/testData/codegen/box/closures") + @InnerTestClasses({Closures.ClosureInsideClosure.class}) public static class Closures extends AbstractBlackBoxCodegenTest { public void testAllFilesPresentInClosures() throws Exception { JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/codegen/box/closures"), "kt", true); @@ -943,6 +944,45 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { blackBoxFileByFullPath("compiler/testData/codegen/box/closures/simplestClosureAndBoxing.kt"); } + @TestMetadata("compiler/testData/codegen/box/closures/closureInsideClosure") + public static class ClosureInsideClosure extends AbstractBlackBoxCodegenTest { + public void testAllFilesPresentInClosureInsideClosure() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/codegen/box/closures/closureInsideClosure"), "kt", true); + } + + @TestMetadata("localFunInsideLocalFun.kt") + public void testLocalFunInsideLocalFun() throws Exception { + blackBoxFileByFullPath("compiler/testData/codegen/box/closures/closureInsideClosure/localFunInsideLocalFun.kt"); + } + + @TestMetadata("localFunInsideLocalFunDifferentSignatures.kt") + public void testLocalFunInsideLocalFunDifferentSignatures() throws Exception { + blackBoxFileByFullPath("compiler/testData/codegen/box/closures/closureInsideClosure/localFunInsideLocalFunDifferentSignatures.kt"); + } + + @TestMetadata("threeLevels.kt") + public void testThreeLevels() throws Exception { + blackBoxFileByFullPath("compiler/testData/codegen/box/closures/closureInsideClosure/threeLevels.kt"); + } + + @TestMetadata("threeLevelsDifferentSignatures.kt") + public void testThreeLevelsDifferentSignatures() throws Exception { + blackBoxFileByFullPath("compiler/testData/codegen/box/closures/closureInsideClosure/threeLevelsDifferentSignatures.kt"); + } + + @TestMetadata("varAsFunInsideLocalFun.kt") + public void testVarAsFunInsideLocalFun() throws Exception { + blackBoxFileByFullPath("compiler/testData/codegen/box/closures/closureInsideClosure/varAsFunInsideLocalFun.kt"); + } + + } + + public static Test innerSuite() { + TestSuite suite = new TestSuite("Closures"); + suite.addTestSuite(Closures.class); + suite.addTestSuite(ClosureInsideClosure.class); + return suite; + } } @TestMetadata("compiler/testData/codegen/box/controlStructures") @@ -3306,7 +3346,7 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { suite.addTestSuite(Bridges.class); suite.addTestSuite(Casts.class); suite.addTestSuite(Classes.class); - suite.addTestSuite(Closures.class); + suite.addTest(Closures.innerSuite()); suite.addTestSuite(ControlStructures.class); suite.addTest(DefaultArguments.innerSuite()); suite.addTestSuite(Enum.class);