Fix closure's reference to outer closure

#KT-3276 Fixed
This commit is contained in:
Alexander Udalov
2013-01-29 22:15:45 +04:00
parent be349f6229
commit 9007a6214a
7 changed files with 116 additions and 2 deletions
@@ -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
@@ -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"
}
@@ -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"
}
@@ -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"
}
@@ -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")
}
@@ -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"
}
@@ -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);