From 85a775375a011145dbd268b41c3bfad81f0f3d97 Mon Sep 17 00:00:00 2001 From: Alexey Andreev Date: Mon, 12 Sep 2016 13:51:00 +0300 Subject: [PATCH] JS: when deciding whether inner class of a local class captures `this`, don't check for subtyping, since frontend generates strict classes in descriptors. Remove fix for #KT-13583, since it's no more needed. Fix #KT-13792 --- .../js/test/semantics/BoxJsTestGenerated.java | 6 +++ .../js/translate/context/UsageTracker.kt | 7 +--- .../enclosingClassFromInnerLocalClass.kt | 37 +++++++++++++++++++ 3 files changed, 44 insertions(+), 6 deletions(-) create mode 100644 js/js.translator/testData/box/closure/enclosingClassFromInnerLocalClass.kt diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/BoxJsTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/BoxJsTestGenerated.java index 4f9d36c76e9..5a017334fc4 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/BoxJsTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/BoxJsTestGenerated.java @@ -704,6 +704,12 @@ public class BoxJsTestGenerated extends AbstractBoxJsTest { doTest(fileName); } + @TestMetadata("enclosingClassFromInnerLocalClass.kt") + public void testEnclosingClassFromInnerLocalClass() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("js/js.translator/testData/box/closure/enclosingClassFromInnerLocalClass.kt"); + doTest(fileName); + } + @TestMetadata("enclosingClassFromLocalClass.kt") public void testEnclosingClassFromLocalClass() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("js/js.translator/testData/box/closure/enclosingClassFromLocalClass.kt"); diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/context/UsageTracker.kt b/js/js.translator/src/org/jetbrains/kotlin/js/translate/context/UsageTracker.kt index 2e1ca7cf769..16e591d1710 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/context/UsageTracker.kt +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/context/UsageTracker.kt @@ -115,13 +115,8 @@ class UsageTracker( // Class which instance we are trying to capture val currentClass = descriptor.containingDeclaration as? ClassDescriptor ?: return false - // We always capture enclosing class if it's not outer (i.e. we are capturing members of enclosing class to a local class) - if (containingClass != currentClass && containingClass.containingDeclaration !is ClassDescriptor) { - return false - } - for (outerDeclaration in generateSequence(containingClass) { it.containingDeclaration as? ClassDescriptor }) { - if (DescriptorUtils.isSubclass(outerDeclaration, currentClass)) return true + if (outerDeclaration == currentClass) return true } return false diff --git a/js/js.translator/testData/box/closure/enclosingClassFromInnerLocalClass.kt b/js/js.translator/testData/box/closure/enclosingClassFromInnerLocalClass.kt new file mode 100644 index 00000000000..c8c69928875 --- /dev/null +++ b/js/js.translator/testData/box/closure/enclosingClassFromInnerLocalClass.kt @@ -0,0 +1,37 @@ +package foo + +open class X(private val x: String) { + fun foo(): String { + class B : X("fail1") { + inner class C { + fun bar() = x + } + + fun baz() = C().bar() + } + return B().baz() + } +} + +open class Y(private val x: String) { + fun foo(): String { + class B { + inner class C : Y("fail2") { + fun bar() = x + } + + fun baz() = C().bar() + } + return B().baz() + } +} + +fun box(): String { + val x = X("OK").foo() + if (x != "OK") return x + + val y = Y("OK").foo() + if (y != "OK") return y + + return "OK" +} \ No newline at end of file