From 159df7964a6430f357e55d86f78ba4d982d00ca8 Mon Sep 17 00:00:00 2001 From: Anton Bannykh Date: Tue, 22 Nov 2016 16:44:10 +0300 Subject: [PATCH] JS: bound callable references (KT-13573). --- .../bound/companionObjectReceiver.kt | 3 - .../bound/enumEntryMember.kt | 2 - .../callableReference/bound/inline/simple.kt | 3 - .../bound/inline/simpleVal.kt | 3 - .../bound/kCallableNameIntrinsic.kt | 5 +- .../box/callableReference/bound/kt12738.kt | 3 +- .../box/callableReference/bound/multiCase.kt | 51 +++++ .../callableReference/bound/nullReceiver.kt | 5 - .../callableReference/bound/objectReceiver.kt | 3 - .../callableReference/bound/simpleFunction.kt | 3 +- .../callableReference/bound/simpleProperty.kt | 2 +- .../bound/syntheticExtensionOnLHS.kt | 4 +- .../callableReference/bound/intrinsic.kt | 2 + .../boxInline/callableReference/classLevel.kt | 2 + .../callableReference/classLevel2.kt | 2 + .../boxInline/callableReference/intrinsic.kt | 2 + .../callableReference/propertyIntrinsic.kt | 2 + .../callableReference/topLevelExtension.kt | 2 + .../ir/IrBlackBoxCodegenTestGenerated.java | 6 + .../codegen/BlackBoxCodegenTestGenerated.java | 6 + .../kotlin/generators/tests/GenerateTests.kt | 8 +- ...CallableReferenceInlineTestsGenerated.java | 197 ++++++++++++++++++ .../semantics/JsCodegenBoxTestGenerated.java | 58 +----- .../abstractClassesForGeneratedTests.kt | 2 + .../kotlin/js/translate/context/Namer.java | 45 ++++ .../reference/CallableReferenceTranslator.kt | 134 ++++++++---- js/js.translator/testData/kotlin_lib_ecma5.js | 36 +++- js/js.translator/testData/test.html | 4 +- 28 files changed, 474 insertions(+), 121 deletions(-) create mode 100644 compiler/testData/codegen/box/callableReference/bound/multiCase.kt create mode 100644 js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/CallableReferenceInlineTestsGenerated.java diff --git a/compiler/testData/codegen/box/callableReference/bound/companionObjectReceiver.kt b/compiler/testData/codegen/box/callableReference/bound/companionObjectReceiver.kt index 61cdc700fcf..ddf856c54da 100644 --- a/compiler/testData/codegen/box/callableReference/bound/companionObjectReceiver.kt +++ b/compiler/testData/codegen/box/callableReference/bound/companionObjectReceiver.kt @@ -1,6 +1,3 @@ -// TODO investigate should it be ran for JS or not -// IGNORE_BACKEND: JS - class A { companion object { fun ok() = "OK" diff --git a/compiler/testData/codegen/box/callableReference/bound/enumEntryMember.kt b/compiler/testData/codegen/box/callableReference/bound/enumEntryMember.kt index c4848e9ed44..ce40fb403cf 100644 --- a/compiler/testData/codegen/box/callableReference/bound/enumEntryMember.kt +++ b/compiler/testData/codegen/box/callableReference/bound/enumEntryMember.kt @@ -1,6 +1,4 @@ -// TODO: muted automatically, investigate should it be ran for JS or not // IGNORE_BACKEND: JS - enum class E { A, B; diff --git a/compiler/testData/codegen/box/callableReference/bound/inline/simple.kt b/compiler/testData/codegen/box/callableReference/bound/inline/simple.kt index fa072a29a94..ab672b23ac4 100644 --- a/compiler/testData/codegen/box/callableReference/bound/inline/simple.kt +++ b/compiler/testData/codegen/box/callableReference/bound/inline/simple.kt @@ -1,6 +1,3 @@ -// TODO: muted automatically, investigate should it be ran for JS or not -// IGNORE_BACKEND: JS - inline fun foo(x: () -> String) = x() fun String.id() = this diff --git a/compiler/testData/codegen/box/callableReference/bound/inline/simpleVal.kt b/compiler/testData/codegen/box/callableReference/bound/inline/simpleVal.kt index b94704195e4..fea3e21c688 100644 --- a/compiler/testData/codegen/box/callableReference/bound/inline/simpleVal.kt +++ b/compiler/testData/codegen/box/callableReference/bound/inline/simpleVal.kt @@ -1,6 +1,3 @@ -// TODO: muted automatically, investigate should it be ran for JS or not -// IGNORE_BACKEND: JS - inline fun go(f: () -> String) = f() fun String.id(): String = this diff --git a/compiler/testData/codegen/box/callableReference/bound/kCallableNameIntrinsic.kt b/compiler/testData/codegen/box/callableReference/bound/kCallableNameIntrinsic.kt index 5e80d95a730..3dcd0359a85 100644 --- a/compiler/testData/codegen/box/callableReference/bound/kCallableNameIntrinsic.kt +++ b/compiler/testData/codegen/box/callableReference/bound/kCallableNameIntrinsic.kt @@ -1,8 +1,5 @@ -// TODO: muted automatically, investigate should it be ran for JS or not +// Enable when callable references to builtin members is supported // IGNORE_BACKEND: JS - -// See KT-12995 - fun box(): String { var state = 0 val name = (state++)::toString.name diff --git a/compiler/testData/codegen/box/callableReference/bound/kt12738.kt b/compiler/testData/codegen/box/callableReference/bound/kt12738.kt index 9b2f2e641d1..668798431de 100644 --- a/compiler/testData/codegen/box/callableReference/bound/kt12738.kt +++ b/compiler/testData/codegen/box/callableReference/bound/kt12738.kt @@ -1,6 +1,5 @@ -// TODO: muted automatically, investigate should it be ran for JS or not +// Enable when callable references to builtin members is supported // IGNORE_BACKEND: JS - fun get(t: T): () -> String { return t::toString } diff --git a/compiler/testData/codegen/box/callableReference/bound/multiCase.kt b/compiler/testData/codegen/box/callableReference/bound/multiCase.kt new file mode 100644 index 00000000000..1ffad7fac0e --- /dev/null +++ b/compiler/testData/codegen/box/callableReference/bound/multiCase.kt @@ -0,0 +1,51 @@ +class A(var v: Int) { + fun f(x: Int) = x * v +} + +fun A.g(x: Int) = x * f(x); + +var A.w: Int + get() = 1000 * v + set(c: Int) { + v = c + 10 + } + +object F { + var u = 0 +} + +fun box(): String { + val a = A(5) + + val av = a::v + if (av() != 5) return "fail1: ${av()}" + if (av.get() != 5) return "fail2: ${av.get()}" + av.set(7) + if (a.v != 7) return "fail3: ${a.v}" + + val af = a::f + if (af(10) != 70) return "fail4: ${af(10)}" + + val ag = a::g + if (ag(10) != 700) return "fail5: ${ag(10)}" + + val aw = a::w + if (aw() != 7000) return "fail6: ${aw()}" + if (aw.get() != 7000) return "fail7: ${aw.get()}" + aw.set(5) + if (a.v != 15) return "fail8: ${a.v}" + + val fu = F::u + if (fu() != 0) return "fail9: ${fu()}" + if (fu.get() != 0) return "fail10: ${fu.get()}" + fu.set(8) + if (F.u != 8) return "fail11: ${F.u}" + + val x = 100 + + fun A.lf() = v * x; + val alf = a::lf + if (alf() != 1500) return "fail9: ${alf()}" + + return "OK" +} diff --git a/compiler/testData/codegen/box/callableReference/bound/nullReceiver.kt b/compiler/testData/codegen/box/callableReference/bound/nullReceiver.kt index cd2bee58f02..0111a54d58b 100644 --- a/compiler/testData/codegen/box/callableReference/bound/nullReceiver.kt +++ b/compiler/testData/codegen/box/callableReference/bound/nullReceiver.kt @@ -1,8 +1,3 @@ -// TODO: investigate should it be ran for JS or not -// IGNORE_BACKEND: JS - -// See https://youtrack.jetbrains.com/issue/KT-14939 - val String?.ok: String get() = "OK" diff --git a/compiler/testData/codegen/box/callableReference/bound/objectReceiver.kt b/compiler/testData/codegen/box/callableReference/bound/objectReceiver.kt index 417ca7ad143..a03203792d5 100644 --- a/compiler/testData/codegen/box/callableReference/bound/objectReceiver.kt +++ b/compiler/testData/codegen/box/callableReference/bound/objectReceiver.kt @@ -1,6 +1,3 @@ -// TODO investigate should it be ran for JS or not -// IGNORE_BACKEND: JS - object Singleton { fun ok() = "OK" } diff --git a/compiler/testData/codegen/box/callableReference/bound/simpleFunction.kt b/compiler/testData/codegen/box/callableReference/bound/simpleFunction.kt index b135dc477f0..327c73d5914 100644 --- a/compiler/testData/codegen/box/callableReference/bound/simpleFunction.kt +++ b/compiler/testData/codegen/box/callableReference/bound/simpleFunction.kt @@ -1,6 +1,5 @@ -// TODO: muted automatically, investigate should it be ran for JS or not +// Enable when callable references to builtin members is supported // IGNORE_BACKEND: JS - fun box(): String { val f = "KOTLIN"::get return "${f(1)}${f(0)}" diff --git a/compiler/testData/codegen/box/callableReference/bound/simpleProperty.kt b/compiler/testData/codegen/box/callableReference/bound/simpleProperty.kt index 6faaba09a5c..533c75f6bf7 100644 --- a/compiler/testData/codegen/box/callableReference/bound/simpleProperty.kt +++ b/compiler/testData/codegen/box/callableReference/bound/simpleProperty.kt @@ -1,4 +1,4 @@ -// TODO: muted automatically, investigate should it be ran for JS or not +// Enable when callable references to builtin members are supported. // IGNORE_BACKEND: JS fun box(): String { diff --git a/compiler/testData/codegen/box/callableReference/bound/syntheticExtensionOnLHS.kt b/compiler/testData/codegen/box/callableReference/bound/syntheticExtensionOnLHS.kt index 67a5f20aed6..b8be5402715 100644 --- a/compiler/testData/codegen/box/callableReference/bound/syntheticExtensionOnLHS.kt +++ b/compiler/testData/codegen/box/callableReference/bound/syntheticExtensionOnLHS.kt @@ -1,6 +1,4 @@ -// TODO: muted automatically, investigate should it be ran for JS or not -// IGNORE_BACKEND: JS - +// TARGET_BACKEND: JVM // WITH_RUNTIME // FILE: A.java diff --git a/compiler/testData/codegen/boxInline/callableReference/bound/intrinsic.kt b/compiler/testData/codegen/boxInline/callableReference/bound/intrinsic.kt index ab6fb03092d..4ef94a1c8a3 100644 --- a/compiler/testData/codegen/boxInline/callableReference/bound/intrinsic.kt +++ b/compiler/testData/codegen/boxInline/callableReference/bound/intrinsic.kt @@ -1,3 +1,5 @@ +// Enable when callable references to builtin members is supported +// IGNORE_BACKEND: JS // FILE: 1.kt package test diff --git a/compiler/testData/codegen/boxInline/callableReference/classLevel.kt b/compiler/testData/codegen/boxInline/callableReference/classLevel.kt index 384931b1398..9444000c34c 100644 --- a/compiler/testData/codegen/boxInline/callableReference/classLevel.kt +++ b/compiler/testData/codegen/boxInline/callableReference/classLevel.kt @@ -1,3 +1,5 @@ +// Enable when using lambdas as extension lambdas is supported (KT-13312) +// IGNORE_BACKEND: JS // FILE: 1.kt package test diff --git a/compiler/testData/codegen/boxInline/callableReference/classLevel2.kt b/compiler/testData/codegen/boxInline/callableReference/classLevel2.kt index 893b834aed8..5f90d337c73 100644 --- a/compiler/testData/codegen/boxInline/callableReference/classLevel2.kt +++ b/compiler/testData/codegen/boxInline/callableReference/classLevel2.kt @@ -1,3 +1,5 @@ +// Enable when using lambdas as extension lambdas is supported (KT-13312) +// IGNORE_BACKEND: JS // FILE: 1.kt package test diff --git a/compiler/testData/codegen/boxInline/callableReference/intrinsic.kt b/compiler/testData/codegen/boxInline/callableReference/intrinsic.kt index f6c3817e65a..97d006f4ae8 100644 --- a/compiler/testData/codegen/boxInline/callableReference/intrinsic.kt +++ b/compiler/testData/codegen/boxInline/callableReference/intrinsic.kt @@ -1,3 +1,5 @@ +// Enable when callable references to builtin members and using lambdas as extension lambdas (KT-13312) is supported +// IGNORE_BACKEND: JS // FILE: 1.kt package test diff --git a/compiler/testData/codegen/boxInline/callableReference/propertyIntrinsic.kt b/compiler/testData/codegen/boxInline/callableReference/propertyIntrinsic.kt index 2be864d9bb9..47e150ff126 100644 --- a/compiler/testData/codegen/boxInline/callableReference/propertyIntrinsic.kt +++ b/compiler/testData/codegen/boxInline/callableReference/propertyIntrinsic.kt @@ -1,3 +1,5 @@ +// Enable when callable references to builtin members and using lambdas as extension lambdas (KT-13312) is supported +// IGNORE_BACKEND: JS // FILE: 1.kt package test diff --git a/compiler/testData/codegen/boxInline/callableReference/topLevelExtension.kt b/compiler/testData/codegen/boxInline/callableReference/topLevelExtension.kt index eaabbf11261..f3fe5e147ca 100644 --- a/compiler/testData/codegen/boxInline/callableReference/topLevelExtension.kt +++ b/compiler/testData/codegen/boxInline/callableReference/topLevelExtension.kt @@ -1,3 +1,5 @@ +// Enable when using lambdas as extension lambdas is supported (KT-13312) +// IGNORE_BACKEND: JS // FILE: 1.kt package test diff --git a/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java b/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java index dab0804b81e..bb3a54eb83c 100644 --- a/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java @@ -1525,6 +1525,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes doTest(fileName); } + @TestMetadata("multiCase.kt") + public void testMultiCase() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/callableReference/bound/multiCase.kt"); + doTest(fileName); + } + @TestMetadata("nullReceiver.kt") public void testNullReceiver() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/callableReference/bound/nullReceiver.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java index 3d6a1cb21e9..697c797c140 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java @@ -1525,6 +1525,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { doTest(fileName); } + @TestMetadata("multiCase.kt") + public void testMultiCase() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/callableReference/bound/multiCase.kt"); + doTest(fileName); + } + @TestMetadata("nullReceiver.kt") public void testNullReceiver() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/callableReference/bound/nullReceiver.kt"); diff --git a/generators/src/org/jetbrains/kotlin/generators/tests/GenerateTests.kt b/generators/src/org/jetbrains/kotlin/generators/tests/GenerateTests.kt index 244e5bf038c..3a75c70d6b5 100755 --- a/generators/src/org/jetbrains/kotlin/generators/tests/GenerateTests.kt +++ b/generators/src/org/jetbrains/kotlin/generators/tests/GenerateTests.kt @@ -1200,13 +1200,17 @@ fun main(args: Array) { model("codegen/boxInline/nonLocalReturns/", targetBackend = TargetBackend.JS) } - testClass() { + testClass { model("codegen/boxInline/property/", targetBackend = TargetBackend.JS) } - testClass() { + testClass { model("codegen/boxInline/noInline/", targetBackend = TargetBackend.JS) } + + testClass { + model("codegen/boxInline/callableReference/", targetBackend = TargetBackend.JS) + } } } diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/CallableReferenceInlineTestsGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/CallableReferenceInlineTestsGenerated.java new file mode 100644 index 00000000000..fc625687238 --- /dev/null +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/CallableReferenceInlineTestsGenerated.java @@ -0,0 +1,197 @@ +/* + * Copyright 2010-2016 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.kotlin.js.test.semantics; + +import com.intellij.testFramework.TestDataPath; +import org.jetbrains.kotlin.test.JUnit3RunnerWithInners; +import org.jetbrains.kotlin.test.KotlinTestUtils; +import org.jetbrains.kotlin.test.TargetBackend; +import org.jetbrains.kotlin.test.TestMetadata; +import org.junit.runner.RunWith; + +import java.io.File; +import java.util.regex.Pattern; + +/** This class is generated by {@link org.jetbrains.kotlin.generators.tests.TestsPackage}. DO NOT MODIFY MANUALLY */ +@SuppressWarnings("all") +@TestMetadata("compiler/testData/codegen/boxInline/callableReference") +@TestDataPath("$PROJECT_ROOT") +@RunWith(JUnit3RunnerWithInners.class) +public class CallableReferenceInlineTestsGenerated extends AbstractCallableReferenceInlineTests { + public void testAllFilesPresentInCallableReference() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/boxInline/callableReference"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JS, true); + } + + @TestMetadata("classLevel.kt") + public void testClassLevel() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/callableReference/classLevel.kt"); + try { + doTest(fileName); + } + catch (Throwable ignore) { + return; + } + throw new AssertionError("Looks like this test can be unmuted. Remove IGNORE_BACKEND directive for that."); + } + + @TestMetadata("classLevel2.kt") + public void testClassLevel2() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/callableReference/classLevel2.kt"); + try { + doTest(fileName); + } + catch (Throwable ignore) { + return; + } + throw new AssertionError("Looks like this test can be unmuted. Remove IGNORE_BACKEND directive for that."); + } + + @TestMetadata("constructor.kt") + public void testConstructor() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/callableReference/constructor.kt"); + doTest(fileName); + } + + @TestMetadata("intrinsic.kt") + public void testIntrinsic() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/callableReference/intrinsic.kt"); + try { + doTest(fileName); + } + catch (Throwable ignore) { + return; + } + throw new AssertionError("Looks like this test can be unmuted. Remove IGNORE_BACKEND directive for that."); + } + + @TestMetadata("propertyIntrinsic.kt") + public void testPropertyIntrinsic() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/callableReference/propertyIntrinsic.kt"); + try { + doTest(fileName); + } + catch (Throwable ignore) { + return; + } + throw new AssertionError("Looks like this test can be unmuted. Remove IGNORE_BACKEND directive for that."); + } + + @TestMetadata("propertyReference.kt") + public void testPropertyReference() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/callableReference/propertyReference.kt"); + doTest(fileName); + } + + @TestMetadata("topLevel.kt") + public void testTopLevel() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/callableReference/topLevel.kt"); + doTest(fileName); + } + + @TestMetadata("topLevelExtension.kt") + public void testTopLevelExtension() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/callableReference/topLevelExtension.kt"); + try { + doTest(fileName); + } + catch (Throwable ignore) { + return; + } + throw new AssertionError("Looks like this test can be unmuted. Remove IGNORE_BACKEND directive for that."); + } + + @TestMetadata("topLevelProperty.kt") + public void testTopLevelProperty() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/callableReference/topLevelProperty.kt"); + doTest(fileName); + } + + @TestMetadata("compiler/testData/codegen/boxInline/callableReference/bound") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class Bound extends AbstractCallableReferenceInlineTests { + public void testAllFilesPresentInBound() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/boxInline/callableReference/bound"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JS, true); + } + + @TestMetadata("classProperty.kt") + public void testClassProperty() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/callableReference/bound/classProperty.kt"); + doTest(fileName); + } + + @TestMetadata("expression.kt") + public void testExpression() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/callableReference/bound/expression.kt"); + doTest(fileName); + } + + @TestMetadata("extensionReceiver.kt") + public void testExtensionReceiver() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/callableReference/bound/extensionReceiver.kt"); + doTest(fileName); + } + + @TestMetadata("filter.kt") + public void testFilter() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/callableReference/bound/filter.kt"); + doTest(fileName); + } + + @TestMetadata("intrinsic.kt") + public void testIntrinsic() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/callableReference/bound/intrinsic.kt"); + try { + doTest(fileName); + } + catch (Throwable ignore) { + return; + } + throw new AssertionError("Looks like this test can be unmuted. Remove IGNORE_BACKEND directive for that."); + } + + @TestMetadata("map.kt") + public void testMap() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/callableReference/bound/map.kt"); + doTest(fileName); + } + + @TestMetadata("objectProperty.kt") + public void testObjectProperty() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/callableReference/bound/objectProperty.kt"); + doTest(fileName); + } + + @TestMetadata("propertyImportedFromObject.kt") + public void testPropertyImportedFromObject() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/callableReference/bound/propertyImportedFromObject.kt"); + doTest(fileName); + } + + @TestMetadata("simple.kt") + public void testSimple() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/callableReference/bound/simple.kt"); + doTest(fileName); + } + + @TestMetadata("topLevelExtensionProperty.kt") + public void testTopLevelExtensionProperty() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/callableReference/bound/topLevelExtensionProperty.kt"); + doTest(fileName); + } + } +} diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java index bc42c0ef6dd..b5092a72baa 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java @@ -1877,13 +1877,7 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { @TestMetadata("companionObjectReceiver.kt") public void testCompanionObjectReceiver() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/callableReference/bound/companionObjectReceiver.kt"); - try { - doTest(fileName); - } - catch (Throwable ignore) { - return; - } - throw new AssertionError("Looks like this test can be unmuted. Remove IGNORE_BACKEND directive for that."); + doTest(fileName); } @TestMetadata("enumEntryMember.kt") @@ -1922,28 +1916,22 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { throw new AssertionError("Looks like this test can be unmuted. Remove IGNORE_BACKEND directive for that."); } + @TestMetadata("multiCase.kt") + public void testMultiCase() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/callableReference/bound/multiCase.kt"); + doTest(fileName); + } + @TestMetadata("nullReceiver.kt") public void testNullReceiver() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/callableReference/bound/nullReceiver.kt"); - try { - doTest(fileName); - } - catch (Throwable ignore) { - return; - } - throw new AssertionError("Looks like this test can be unmuted. Remove IGNORE_BACKEND directive for that."); + doTest(fileName); } @TestMetadata("objectReceiver.kt") public void testObjectReceiver() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/callableReference/bound/objectReceiver.kt"); - try { - doTest(fileName); - } - catch (Throwable ignore) { - return; - } - throw new AssertionError("Looks like this test can be unmuted. Remove IGNORE_BACKEND directive for that."); + doTest(fileName); } @TestMetadata("primitiveReceiver.kt") @@ -1976,18 +1964,6 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { throw new AssertionError("Looks like this test can be unmuted. Remove IGNORE_BACKEND directive for that."); } - @TestMetadata("syntheticExtensionOnLHS.kt") - public void testSyntheticExtensionOnLHS() throws Exception { - String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/callableReference/bound/syntheticExtensionOnLHS.kt"); - try { - doTest(fileName); - } - catch (Throwable ignore) { - return; - } - throw new AssertionError("Looks like this test can be unmuted. Remove IGNORE_BACKEND directive for that."); - } - @TestMetadata("compiler/testData/codegen/box/callableReference/bound/equals") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) @@ -2056,25 +2032,13 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { @TestMetadata("simple.kt") public void testSimple() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/callableReference/bound/inline/simple.kt"); - try { - doTest(fileName); - } - catch (Throwable ignore) { - return; - } - throw new AssertionError("Looks like this test can be unmuted. Remove IGNORE_BACKEND directive for that."); + doTest(fileName); } @TestMetadata("simpleVal.kt") public void testSimpleVal() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/callableReference/bound/inline/simpleVal.kt"); - try { - doTest(fileName); - } - catch (Throwable ignore) { - return; - } - throw new AssertionError("Looks like this test can be unmuted. Remove IGNORE_BACKEND directive for that."); + doTest(fileName); } } } diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/abstractClassesForGeneratedTests.kt b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/abstractClassesForGeneratedTests.kt index 7507305974b..6a6c387797b 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/abstractClassesForGeneratedTests.kt +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/abstractClassesForGeneratedTests.kt @@ -33,6 +33,8 @@ abstract class AbstractPropertyAccessorsInlineTests : BorrowedInlineTest("proper abstract class AbstractNoInlineTests : BorrowedInlineTest("noInline/") +abstract class AbstractCallableReferenceInlineTests : BorrowedInlineTest("callableReference/") + abstract class AbstractBoxJsTest() : BasicBoxTest( BasicBoxTest.TEST_DATA_DIR_PATH + "box/", BasicBoxTest.TEST_DATA_DIR_PATH + "out/box/" diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/context/Namer.java b/js/js.translator/src/org/jetbrains/kotlin/js/translate/context/Namer.java index 5eb5c854398..d9b84e1c829 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/context/Namer.java +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/context/Namer.java @@ -77,12 +77,17 @@ public final class Namer { public static final String OUTER_FIELD_NAME = "$outer"; private static final String CALLABLE_REF_FOR_MEMBER_FUNCTION_NAME = "getCallableRefForMemberFunction"; + private static final String BOUND_CALLABLE_REF_FOR_MEMBER_FUNCTION_NAME = "getBoundCallableRefForMemberFunction"; private static final String CALLABLE_REF_FOR_EXTENSION_FUNCTION_NAME = "getCallableRefForExtensionFunction"; + private static final String BOUND_CALLABLE_REF_FOR_EXTENSION_FUNCTION_NAME = "getBoundCallableRefForExtensionFunction"; private static final String CALLABLE_REF_FOR_LOCAL_EXTENSION_FUNCTION_NAME = "getCallableRefForLocalExtensionFunction"; + private static final String BOUND_CALLABLE_REF_FOR_LOCAL_EXTENSION_FUNCTION_NAME = "getBoundCallableRefForLocalExtensionFunction"; private static final String CALLABLE_REF_FOR_CONSTRUCTOR_NAME = "getCallableRefForConstructor"; private static final String CALLABLE_REF_FOR_TOP_LEVEL_PROPERTY = "getCallableRefForTopLevelProperty"; private static final String CALLABLE_REF_FOR_MEMBER_PROPERTY = "getCallableRefForMemberProperty"; + private static final String BOUND_CALLABLE_REF_FOR_MEMBER_PROPERTY = "getBoundCallableRefForMemberProperty"; private static final String CALLABLE_REF_FOR_EXTENSION_PROPERTY = "getCallableRefForExtensionProperty"; + private static final String BOUND_CALLABLE_REF_FOR_EXTENSION_PROPERTY = "getBoundCallableRefForExtensionProperty"; private static final String DELEGATE = "$delegate"; @@ -191,18 +196,28 @@ public final class Namer { @NotNull private final JsName callableRefForMemberFunctionName; @NotNull + private final JsName boundCallableRefForMemberFunctionName; + @NotNull private final JsName callableRefForExtensionFunctionName; @NotNull + private final JsName boundCallableRefForExtensionFunctionName; + @NotNull private final JsName callableRefForLocalExtensionFunctionName; @NotNull + private final JsName boundCallableRefForLocalExtensionFunctionName; + @NotNull private final JsName callableRefForConstructorName; @NotNull private final JsName callableRefForTopLevelProperty; @NotNull private final JsName callableRefForMemberProperty; @NotNull + private final JsName boundCallableRefForMemberProperty; + @NotNull private final JsName callableRefForExtensionProperty; @NotNull + private final JsName boundCallableRefForExtensionProperty; + @NotNull private final JsExpression callGetProperty; @NotNull private final JsExpression callSetProperty; @@ -217,12 +232,17 @@ public final class Namer { callSetProperty = kotlin("callSetter"); callableRefForMemberFunctionName = kotlinScope.declareName(CALLABLE_REF_FOR_MEMBER_FUNCTION_NAME); + boundCallableRefForMemberFunctionName = kotlinScope.declareName(BOUND_CALLABLE_REF_FOR_MEMBER_FUNCTION_NAME); callableRefForExtensionFunctionName = kotlinScope.declareName(CALLABLE_REF_FOR_EXTENSION_FUNCTION_NAME); + boundCallableRefForExtensionFunctionName = kotlinScope.declareName(BOUND_CALLABLE_REF_FOR_EXTENSION_FUNCTION_NAME); callableRefForLocalExtensionFunctionName = kotlinScope.declareName(CALLABLE_REF_FOR_LOCAL_EXTENSION_FUNCTION_NAME); + boundCallableRefForLocalExtensionFunctionName = kotlinScope.declareName(BOUND_CALLABLE_REF_FOR_LOCAL_EXTENSION_FUNCTION_NAME); callableRefForConstructorName = kotlinScope.declareName(CALLABLE_REF_FOR_CONSTRUCTOR_NAME); callableRefForTopLevelProperty = kotlinScope.declareName(CALLABLE_REF_FOR_TOP_LEVEL_PROPERTY); callableRefForMemberProperty = kotlinScope.declareName(CALLABLE_REF_FOR_MEMBER_PROPERTY); + boundCallableRefForMemberProperty = kotlinScope.declareName(BOUND_CALLABLE_REF_FOR_MEMBER_PROPERTY); callableRefForExtensionProperty = kotlinScope.declareName(CALLABLE_REF_FOR_EXTENSION_PROPERTY); + boundCallableRefForExtensionProperty = kotlinScope.declareName(BOUND_CALLABLE_REF_FOR_EXTENSION_PROPERTY); isTypeName = kotlinScope.declareName("isType"); } @@ -243,16 +263,31 @@ public final class Namer { return kotlin(callableRefForMemberFunctionName); } + @NotNull + public JsExpression boundCallableRefForMemberFunctionReference() { + return kotlin(boundCallableRefForMemberFunctionName); + } + @NotNull public JsExpression callableRefForExtensionFunctionReference() { return kotlin(callableRefForExtensionFunctionName); } + @NotNull + public JsExpression boundCallableRefForExtensionFunctionReference() { + return kotlin(boundCallableRefForExtensionFunctionName); + } + @NotNull public JsExpression callableRefForLocalExtensionFunctionReference() { return kotlin(callableRefForLocalExtensionFunctionName); } + @NotNull + public JsExpression boundCallableRefForLocalExtensionFunctionReference() { + return kotlin(boundCallableRefForLocalExtensionFunctionName); + } + @NotNull public JsExpression callableRefForConstructorReference() { return kotlin(callableRefForConstructorName); @@ -268,11 +303,21 @@ public final class Namer { return kotlin(callableRefForMemberProperty); } + @NotNull + public JsExpression boundCallableRefForMemberPropertyReference() { + return kotlin(boundCallableRefForMemberProperty); + } + @NotNull public JsExpression callableRefForExtensionPropertyReference() { return kotlin(callableRefForExtensionProperty); } + @NotNull + public JsExpression boundCallableRefForExtensionPropertyReference() { + return kotlin(boundCallableRefForExtensionProperty); + } + @NotNull public static JsExpression throwNPEFunctionRef() { return new JsNameRef(THROW_NPE_FUN_NAME, kotlinObject()); diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/reference/CallableReferenceTranslator.kt b/js/js.translator/src/org/jetbrains/kotlin/js/translate/reference/CallableReferenceTranslator.kt index f821be970f6..a1dde7568a4 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/reference/CallableReferenceTranslator.kt +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/reference/CallableReferenceTranslator.kt @@ -21,20 +21,41 @@ import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.js.resolve.diagnostics.ErrorsJs import org.jetbrains.kotlin.js.translate.context.TranslationContext +import org.jetbrains.kotlin.js.translate.general.Translation import org.jetbrains.kotlin.js.translate.utils.* import org.jetbrains.kotlin.psi.KtCallableReferenceExpression +import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.DescriptorUtils +import org.jetbrains.kotlin.resolve.PropertyImportedFromObject +import org.jetbrains.kotlin.types.expressions.DoubleColonLHS import java.util.* object CallableReferenceTranslator { fun translate(expression: KtCallableReferenceExpression, context: TranslationContext): JsExpression { val descriptor = BindingUtils.getDescriptorForReferenceExpression(context.bindingContext(), expression.callableReference) + + val receiver = expression.receiverExpression?.let { r -> + if (context.bindingContext().get(BindingContext.DOUBLE_COLON_LHS, r) is DoubleColonLHS.Expression) { + val block = JsBlock() + val e = Translation.translateAsExpression(r, context, block) + if (!block.isEmpty) { + context.addStatementsToCurrentBlockFrom(block) + } + e + } + else { + null + } + } ?: (descriptor as? PropertyImportedFromObject)?.let { + ReferenceTranslator.translateAsValueReference(it.containingObject, context) + } + return when (descriptor) { is PropertyDescriptor -> - translateForProperty(descriptor, context, expression) + translateForProperty(descriptor, context, expression, receiver) is FunctionDescriptor -> - translateForFunction(descriptor, context, expression) + translateForFunction(descriptor, context, expression, receiver) else -> throw IllegalArgumentException("Expected property or function: $descriptor, expression=${expression.text}") } @@ -45,31 +66,41 @@ object CallableReferenceTranslator { return JsLiteral.NULL } - private fun translateForFunction(descriptor: FunctionDescriptor, context: TranslationContext, expression: KtCallableReferenceExpression): JsExpression { + private fun translateForFunction( + descriptor: FunctionDescriptor, + context: TranslationContext, + expression: KtCallableReferenceExpression, + receiver: JsExpression? + ): JsExpression { return when { - // TODO Support for callable reference to builtin functions and members + // TODO Support for callable reference to builtin functions and members KotlinBuiltIns.isBuiltIn(descriptor) -> reportNotSupported(context, expression) isConstructor(descriptor) -> translateForConstructor(descriptor, context) isExtension(descriptor) -> - translateForExtensionFunction(descriptor, context) + translateForExtensionFunction(descriptor, context, receiver) isMember(descriptor) -> - translateForMemberFunction(descriptor, context) + translateForMemberFunction(descriptor, context, receiver) else -> ReferenceTranslator.translateAsValueReference(descriptor, context) } } - private fun translateForProperty(descriptor: PropertyDescriptor, context: TranslationContext, expression: KtCallableReferenceExpression): JsExpression { + private fun translateForProperty( + descriptor: PropertyDescriptor, + context: TranslationContext, + expression: KtCallableReferenceExpression, + receiver: JsExpression? + ): JsExpression { return when { - // TODO Support for callable reference to builtin properties + // TODO Support for callable reference to builtin properties KotlinBuiltIns.isBuiltIn(descriptor) -> reportNotSupported(context, expression) isExtension(descriptor) -> - translateForExtensionProperty(descriptor, context) + translateForExtensionProperty(descriptor, context, receiver) isMember(descriptor) -> - translateForMemberProperty(descriptor, context) + translateForMemberProperty(descriptor, context, receiver) else -> translateForTopLevelProperty(descriptor, context) } @@ -137,27 +168,49 @@ object CallableReferenceTranslator { return function } - private fun translateForMemberProperty(descriptor: PropertyDescriptor, context: TranslationContext): JsExpression { + private fun translateForMemberProperty( + descriptor: PropertyDescriptor, + context: TranslationContext, + receiver: JsExpression? + ): JsExpression { val jsPropertyName = context.getNameForDescriptor(descriptor) val jsPropertyNameAsString = context.program().getStringLiteral(jsPropertyName.toString()) - return JsInvocation(context.namer().callableRefForMemberPropertyReference(), jsPropertyNameAsString, isVar(descriptor)) + if (receiver == null) { + return JsInvocation(context.namer().callableRefForMemberPropertyReference(), jsPropertyNameAsString, isVar(descriptor)) + } + else { + return JsInvocation(context.namer().boundCallableRefForMemberPropertyReference(), receiver, jsPropertyNameAsString, + isVar(descriptor)) + } } - private fun translateForExtensionProperty(descriptor: PropertyDescriptor, context: TranslationContext): JsExpression { + private fun translateForExtensionProperty( + descriptor: PropertyDescriptor, + context: TranslationContext, + receiver: JsExpression? + ): JsExpression { val jsGetterNameRef = ReferenceTranslator.translateAsValueReference(descriptor.getter!!, context) val propertyName = descriptor.name val jsPropertyNameAsString = context.program().getStringLiteral(propertyName.asString()) - val argumentList = ArrayList(3) + val argumentList = ArrayList(4) + if (receiver != null) { + argumentList.add(receiver) + } argumentList.add(jsPropertyNameAsString) argumentList.add(jsGetterNameRef) if (descriptor.isVar) { val jsSetterNameRef = ReferenceTranslator.translateAsValueReference(descriptor.setter!!, context) argumentList.add(jsSetterNameRef) } - return if (AnnotationsUtils.isNativeObject(descriptor)) - translateForMemberProperty(descriptor, context) - else + return if (AnnotationsUtils.isNativeObject(descriptor)) { + translateForMemberProperty(descriptor, context, receiver) + } + else if (receiver == null) { JsInvocation(context.namer().callableRefForExtensionPropertyReference(), argumentList) + } + else { + JsInvocation(context.namer().boundCallableRefForExtensionPropertyReference(), argumentList) + } } private fun translateForConstructor(descriptor: FunctionDescriptor, context: TranslationContext): JsExpression { @@ -165,39 +218,44 @@ object CallableReferenceTranslator { return JsInvocation(context.namer().callableRefForConstructorReference(), jsFunctionRef) } - private fun translateForExtensionFunction(descriptor: FunctionDescriptor, context: TranslationContext): JsExpression { - val receiverParameterDescriptor = descriptor.extensionReceiverParameter ?: - error("receiverParameter for extension should not be null") - + private fun translateForExtensionFunction(descriptor: FunctionDescriptor, + context: TranslationContext, + receiver: JsExpression? + ): JsExpression { val jsFunctionRef = ReferenceTranslator.translateAsValueReference(descriptor, context) if (descriptor.visibility == Visibilities.LOCAL) { - return JsInvocation(context.namer().callableRefForLocalExtensionFunctionReference(), jsFunctionRef) + if (receiver == null) { + return JsInvocation(context.namer().callableRefForLocalExtensionFunctionReference(), jsFunctionRef) + } + else { + return JsInvocation(context.namer().boundCallableRefForLocalExtensionFunctionReference(), receiver, jsFunctionRef) + } } - else if (AnnotationsUtils.isNativeObject(descriptor)) { - val jetType = receiverParameterDescriptor.type - val receiverClassDescriptor = DescriptorUtils.getClassDescriptorForType(jetType) - return translateAsMemberFunctionReference(descriptor, receiverClassDescriptor, context) + return translateForMemberFunction(descriptor, context, receiver) } else { - return JsInvocation(context.namer().callableRefForExtensionFunctionReference(), jsFunctionRef) + if (receiver == null) { + return JsInvocation(context.namer().callableRefForExtensionFunctionReference(), jsFunctionRef) + } + else { + return JsInvocation(context.namer().boundCallableRefForExtensionFunctionReference(), receiver, jsFunctionRef) + } } } - private fun translateForMemberFunction(descriptor: FunctionDescriptor, context: TranslationContext): JsExpression { - val classDescriptor = JsDescriptorUtils.getContainingDeclaration(descriptor) as? ClassDescriptor ?: - throw IllegalArgumentException("Expected ClassDescriptor: $descriptor") - return translateAsMemberFunctionReference(descriptor, classDescriptor, context) - } - - private fun translateAsMemberFunctionReference( + private fun translateForMemberFunction( descriptor: CallableDescriptor, - classDescriptor: ClassDescriptor, - context: TranslationContext + context: TranslationContext, + receiver: JsExpression? ): JsExpression { - val jsClassNameRef = ReferenceTranslator.translateAsTypeReference(classDescriptor, context) val funName = context.getNameForDescriptor(descriptor) val funNameAsString = context.program().getStringLiteral(funName.toString()) - return JsInvocation(context.namer().callableRefForMemberFunctionReference(), jsClassNameRef, funNameAsString) + if (receiver == null) { + return JsInvocation(context.namer().callableRefForMemberFunctionReference(), funNameAsString) + } + else { + return JsInvocation(context.namer().boundCallableRefForMemberFunctionReference(), receiver, funNameAsString) + } } } diff --git a/js/js.translator/testData/kotlin_lib_ecma5.js b/js/js.translator/testData/kotlin_lib_ecma5.js index 88da990f5b2..25f229e278f 100644 --- a/js/js.translator/testData/kotlin_lib_ecma5.js +++ b/js/js.translator/testData/kotlin_lib_ecma5.js @@ -142,7 +142,7 @@ } // TODO Store callable references for members in class - Kotlin.getCallableRefForMemberFunction = function (klass, memberName) { + Kotlin.getCallableRefForMemberFunction = function (memberName) { return function () { var args = [].slice.call(arguments); var instance = args.shift(); @@ -150,6 +150,12 @@ }; }; + Kotlin.getBoundCallableRefForMemberFunction = function (receiver, memberName) { + return function () { + return receiver[memberName].apply(receiver, arguments); + }; + }; + // TODO Store callable references for extension functions in class // extFun expected receiver as the first argument Kotlin.getCallableRefForExtensionFunction = function (extFun) { @@ -158,6 +164,14 @@ }; }; + Kotlin.getBoundCallableRefForExtensionFunction = function (receiver, extFun) { + return function () { + var args = [].slice.call(arguments); + args.unshift(receiver); + return extFun.apply(null, args); + }; + }; + Kotlin.getCallableRefForLocalExtensionFunction = function (extFun) { return function () { var args = [].slice.call(arguments); @@ -166,6 +180,12 @@ }; }; + Kotlin.getBoundCallableRefForLocalExtensionFunction = function (receiver, extFun) { + return function () { + return extFun.apply(receiver, arguments); + }; + }; + Kotlin.getCallableRefForConstructor = function (klass) { return function () { var obj = Object.create(klass.prototype); @@ -185,11 +205,25 @@ return getPropertyRefClass(getFun, "get_za3rmp$", setFun, "set_wn2jw4$", propertyRefClassMetadataCache.oneArg); }; + Kotlin.getBoundCallableRefForMemberProperty = function(receiver, name, isVar) { + var getFun = Function("receiver", "return function " + name + "() { return receiver['" + name + "']; }")(receiver); + var setFun = isVar ? function(value) { receiver[name] = value; } : null; + return getPropertyRefClass(getFun, "get", setFun, "set_za3rmp$", propertyRefClassMetadataCache.oneArg); + }; + Kotlin.getCallableRefForExtensionProperty = function(name, getFun, setFun) { var getFunWrapper = Function("getFun", "return function " + name + "(receiver, extensionReceiver) { return getFun(receiver, extensionReceiver) }")(getFun); return getPropertyRefClass(getFunWrapper, "get_za3rmp$", setFun, "set_wn2jw4$", propertyRefClassMetadataCache.oneArg); }; + Kotlin.getBoundCallableRefForExtensionProperty = function(receiver, name, getFun, setFun) { + var getFunWrapper = Function("receiver", "getFun", "return function " + name + "(extensionReceiver) { return getFun(receiver, extensionReceiver) }")(receiver, getFun); + if (setFun) { + setFun = setFun.bind(null, receiver); + } + return getPropertyRefClass(getFunWrapper, "get", setFun, "set_za3rmp$", propertyRefClassMetadataCache.oneArg); + }; + function getPropertyRefClass(getFun, getName, setFun, setName, cache) { var obj = getFun; var isMutable = typeof setFun === "function"; diff --git a/js/js.translator/testData/test.html b/js/js.translator/testData/test.html index 40260d86a8e..9a859040b56 100644 --- a/js/js.translator/testData/test.html +++ b/js/js.translator/testData/test.html @@ -2,10 +2,10 @@ - +