JS: bound callable references (KT-13573).
This commit is contained in:
-3
@@ -1,6 +1,3 @@
|
|||||||
// TODO investigate should it be ran for JS or not
|
|
||||||
// IGNORE_BACKEND: JS
|
|
||||||
|
|
||||||
class A {
|
class A {
|
||||||
companion object {
|
companion object {
|
||||||
fun ok() = "OK"
|
fun ok() = "OK"
|
||||||
|
|||||||
@@ -1,6 +1,4 @@
|
|||||||
// TODO: muted automatically, investigate should it be ran for JS or not
|
|
||||||
// IGNORE_BACKEND: JS
|
// IGNORE_BACKEND: JS
|
||||||
|
|
||||||
enum class E {
|
enum class E {
|
||||||
A, B;
|
A, B;
|
||||||
|
|
||||||
|
|||||||
@@ -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()
|
inline fun foo(x: () -> String) = x()
|
||||||
|
|
||||||
fun String.id() = this
|
fun String.id() = this
|
||||||
|
|||||||
@@ -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()
|
inline fun go(f: () -> String) = f()
|
||||||
|
|
||||||
fun String.id(): String = this
|
fun String.id(): String = this
|
||||||
|
|||||||
+1
-4
@@ -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
|
// IGNORE_BACKEND: JS
|
||||||
|
|
||||||
// See KT-12995
|
|
||||||
|
|
||||||
fun box(): String {
|
fun box(): String {
|
||||||
var state = 0
|
var state = 0
|
||||||
val name = (state++)::toString.name
|
val name = (state++)::toString.name
|
||||||
|
|||||||
@@ -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
|
// IGNORE_BACKEND: JS
|
||||||
|
|
||||||
fun <T> get(t: T): () -> String {
|
fun <T> get(t: T): () -> String {
|
||||||
return t::toString
|
return t::toString
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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"
|
||||||
|
}
|
||||||
@@ -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
|
val String?.ok: String
|
||||||
get() = "OK"
|
get() = "OK"
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,3 @@
|
|||||||
// TODO investigate should it be ran for JS or not
|
|
||||||
// IGNORE_BACKEND: JS
|
|
||||||
|
|
||||||
object Singleton {
|
object Singleton {
|
||||||
fun ok() = "OK"
|
fun ok() = "OK"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
// IGNORE_BACKEND: JS
|
||||||
|
|
||||||
fun box(): String {
|
fun box(): String {
|
||||||
val f = "KOTLIN"::get
|
val f = "KOTLIN"::get
|
||||||
return "${f(1)}${f(0)}"
|
return "${f(1)}${f(0)}"
|
||||||
|
|||||||
@@ -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
|
// IGNORE_BACKEND: JS
|
||||||
|
|
||||||
fun box(): String {
|
fun box(): String {
|
||||||
|
|||||||
+1
-3
@@ -1,6 +1,4 @@
|
|||||||
// TODO: muted automatically, investigate should it be ran for JS or not
|
// TARGET_BACKEND: JVM
|
||||||
// IGNORE_BACKEND: JS
|
|
||||||
|
|
||||||
// WITH_RUNTIME
|
// WITH_RUNTIME
|
||||||
// FILE: A.java
|
// FILE: A.java
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
// Enable when callable references to builtin members is supported
|
||||||
|
// IGNORE_BACKEND: JS
|
||||||
// FILE: 1.kt
|
// FILE: 1.kt
|
||||||
|
|
||||||
package test
|
package test
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
// Enable when using lambdas as extension lambdas is supported (KT-13312)
|
||||||
|
// IGNORE_BACKEND: JS
|
||||||
// FILE: 1.kt
|
// FILE: 1.kt
|
||||||
|
|
||||||
package test
|
package test
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
// Enable when using lambdas as extension lambdas is supported (KT-13312)
|
||||||
|
// IGNORE_BACKEND: JS
|
||||||
// FILE: 1.kt
|
// FILE: 1.kt
|
||||||
|
|
||||||
package test
|
package test
|
||||||
|
|||||||
@@ -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
|
// FILE: 1.kt
|
||||||
|
|
||||||
package test
|
package test
|
||||||
|
|||||||
@@ -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
|
// FILE: 1.kt
|
||||||
|
|
||||||
package test
|
package test
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
// Enable when using lambdas as extension lambdas is supported (KT-13312)
|
||||||
|
// IGNORE_BACKEND: JS
|
||||||
// FILE: 1.kt
|
// FILE: 1.kt
|
||||||
|
|
||||||
package test
|
package test
|
||||||
|
|||||||
+6
@@ -1525,6 +1525,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
|||||||
doTest(fileName);
|
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")
|
@TestMetadata("nullReceiver.kt")
|
||||||
public void testNullReceiver() throws Exception {
|
public void testNullReceiver() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/callableReference/bound/nullReceiver.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/callableReference/bound/nullReceiver.kt");
|
||||||
|
|||||||
@@ -1525,6 +1525,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
|||||||
doTest(fileName);
|
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")
|
@TestMetadata("nullReceiver.kt")
|
||||||
public void testNullReceiver() throws Exception {
|
public void testNullReceiver() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/callableReference/bound/nullReceiver.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/callableReference/bound/nullReceiver.kt");
|
||||||
|
|||||||
@@ -1200,13 +1200,17 @@ fun main(args: Array<String>) {
|
|||||||
model("codegen/boxInline/nonLocalReturns/", targetBackend = TargetBackend.JS)
|
model("codegen/boxInline/nonLocalReturns/", targetBackend = TargetBackend.JS)
|
||||||
}
|
}
|
||||||
|
|
||||||
testClass<AbstractPropertyAccessorsInlineTests>() {
|
testClass<AbstractPropertyAccessorsInlineTests> {
|
||||||
model("codegen/boxInline/property/", targetBackend = TargetBackend.JS)
|
model("codegen/boxInline/property/", targetBackend = TargetBackend.JS)
|
||||||
}
|
}
|
||||||
|
|
||||||
testClass<AbstractNoInlineTests>() {
|
testClass<AbstractNoInlineTests> {
|
||||||
model("codegen/boxInline/noInline/", targetBackend = TargetBackend.JS)
|
model("codegen/boxInline/noInline/", targetBackend = TargetBackend.JS)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
testClass<AbstractCallableReferenceInlineTests> {
|
||||||
|
model("codegen/boxInline/callableReference/", targetBackend = TargetBackend.JS)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+197
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+11
-47
@@ -1877,13 +1877,7 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
|||||||
@TestMetadata("companionObjectReceiver.kt")
|
@TestMetadata("companionObjectReceiver.kt")
|
||||||
public void testCompanionObjectReceiver() throws Exception {
|
public void testCompanionObjectReceiver() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/callableReference/bound/companionObjectReceiver.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/callableReference/bound/companionObjectReceiver.kt");
|
||||||
try {
|
doTest(fileName);
|
||||||
doTest(fileName);
|
|
||||||
}
|
|
||||||
catch (Throwable ignore) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
throw new AssertionError("Looks like this test can be unmuted. Remove IGNORE_BACKEND directive for that.");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("enumEntryMember.kt")
|
@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.");
|
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")
|
@TestMetadata("nullReceiver.kt")
|
||||||
public void testNullReceiver() throws Exception {
|
public void testNullReceiver() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/callableReference/bound/nullReceiver.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/callableReference/bound/nullReceiver.kt");
|
||||||
try {
|
doTest(fileName);
|
||||||
doTest(fileName);
|
|
||||||
}
|
|
||||||
catch (Throwable ignore) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
throw new AssertionError("Looks like this test can be unmuted. Remove IGNORE_BACKEND directive for that.");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("objectReceiver.kt")
|
@TestMetadata("objectReceiver.kt")
|
||||||
public void testObjectReceiver() throws Exception {
|
public void testObjectReceiver() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/callableReference/bound/objectReceiver.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/callableReference/bound/objectReceiver.kt");
|
||||||
try {
|
doTest(fileName);
|
||||||
doTest(fileName);
|
|
||||||
}
|
|
||||||
catch (Throwable ignore) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
throw new AssertionError("Looks like this test can be unmuted. Remove IGNORE_BACKEND directive for that.");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("primitiveReceiver.kt")
|
@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.");
|
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")
|
@TestMetadata("compiler/testData/codegen/box/callableReference/bound/equals")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
@RunWith(JUnit3RunnerWithInners.class)
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
@@ -2056,25 +2032,13 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
|||||||
@TestMetadata("simple.kt")
|
@TestMetadata("simple.kt")
|
||||||
public void testSimple() throws Exception {
|
public void testSimple() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/callableReference/bound/inline/simple.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/callableReference/bound/inline/simple.kt");
|
||||||
try {
|
doTest(fileName);
|
||||||
doTest(fileName);
|
|
||||||
}
|
|
||||||
catch (Throwable ignore) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
throw new AssertionError("Looks like this test can be unmuted. Remove IGNORE_BACKEND directive for that.");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("simpleVal.kt")
|
@TestMetadata("simpleVal.kt")
|
||||||
public void testSimpleVal() throws Exception {
|
public void testSimpleVal() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/callableReference/bound/inline/simpleVal.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/callableReference/bound/inline/simpleVal.kt");
|
||||||
try {
|
doTest(fileName);
|
||||||
doTest(fileName);
|
|
||||||
}
|
|
||||||
catch (Throwable ignore) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
throw new AssertionError("Looks like this test can be unmuted. Remove IGNORE_BACKEND directive for that.");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
@@ -33,6 +33,8 @@ abstract class AbstractPropertyAccessorsInlineTests : BorrowedInlineTest("proper
|
|||||||
|
|
||||||
abstract class AbstractNoInlineTests : BorrowedInlineTest("noInline/")
|
abstract class AbstractNoInlineTests : BorrowedInlineTest("noInline/")
|
||||||
|
|
||||||
|
abstract class AbstractCallableReferenceInlineTests : BorrowedInlineTest("callableReference/")
|
||||||
|
|
||||||
abstract class AbstractBoxJsTest() : BasicBoxTest(
|
abstract class AbstractBoxJsTest() : BasicBoxTest(
|
||||||
BasicBoxTest.TEST_DATA_DIR_PATH + "box/",
|
BasicBoxTest.TEST_DATA_DIR_PATH + "box/",
|
||||||
BasicBoxTest.TEST_DATA_DIR_PATH + "out/box/"
|
BasicBoxTest.TEST_DATA_DIR_PATH + "out/box/"
|
||||||
|
|||||||
@@ -77,12 +77,17 @@ public final class Namer {
|
|||||||
public static final String OUTER_FIELD_NAME = "$outer";
|
public static final String OUTER_FIELD_NAME = "$outer";
|
||||||
|
|
||||||
private static final String CALLABLE_REF_FOR_MEMBER_FUNCTION_NAME = "getCallableRefForMemberFunction";
|
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 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 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_CONSTRUCTOR_NAME = "getCallableRefForConstructor";
|
||||||
private static final String CALLABLE_REF_FOR_TOP_LEVEL_PROPERTY = "getCallableRefForTopLevelProperty";
|
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 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 CALLABLE_REF_FOR_EXTENSION_PROPERTY = "getCallableRefForExtensionProperty";
|
||||||
|
private static final String BOUND_CALLABLE_REF_FOR_EXTENSION_PROPERTY = "getBoundCallableRefForExtensionProperty";
|
||||||
|
|
||||||
private static final String DELEGATE = "$delegate";
|
private static final String DELEGATE = "$delegate";
|
||||||
|
|
||||||
@@ -191,18 +196,28 @@ public final class Namer {
|
|||||||
@NotNull
|
@NotNull
|
||||||
private final JsName callableRefForMemberFunctionName;
|
private final JsName callableRefForMemberFunctionName;
|
||||||
@NotNull
|
@NotNull
|
||||||
|
private final JsName boundCallableRefForMemberFunctionName;
|
||||||
|
@NotNull
|
||||||
private final JsName callableRefForExtensionFunctionName;
|
private final JsName callableRefForExtensionFunctionName;
|
||||||
@NotNull
|
@NotNull
|
||||||
|
private final JsName boundCallableRefForExtensionFunctionName;
|
||||||
|
@NotNull
|
||||||
private final JsName callableRefForLocalExtensionFunctionName;
|
private final JsName callableRefForLocalExtensionFunctionName;
|
||||||
@NotNull
|
@NotNull
|
||||||
|
private final JsName boundCallableRefForLocalExtensionFunctionName;
|
||||||
|
@NotNull
|
||||||
private final JsName callableRefForConstructorName;
|
private final JsName callableRefForConstructorName;
|
||||||
@NotNull
|
@NotNull
|
||||||
private final JsName callableRefForTopLevelProperty;
|
private final JsName callableRefForTopLevelProperty;
|
||||||
@NotNull
|
@NotNull
|
||||||
private final JsName callableRefForMemberProperty;
|
private final JsName callableRefForMemberProperty;
|
||||||
@NotNull
|
@NotNull
|
||||||
|
private final JsName boundCallableRefForMemberProperty;
|
||||||
|
@NotNull
|
||||||
private final JsName callableRefForExtensionProperty;
|
private final JsName callableRefForExtensionProperty;
|
||||||
@NotNull
|
@NotNull
|
||||||
|
private final JsName boundCallableRefForExtensionProperty;
|
||||||
|
@NotNull
|
||||||
private final JsExpression callGetProperty;
|
private final JsExpression callGetProperty;
|
||||||
@NotNull
|
@NotNull
|
||||||
private final JsExpression callSetProperty;
|
private final JsExpression callSetProperty;
|
||||||
@@ -217,12 +232,17 @@ public final class Namer {
|
|||||||
callSetProperty = kotlin("callSetter");
|
callSetProperty = kotlin("callSetter");
|
||||||
|
|
||||||
callableRefForMemberFunctionName = kotlinScope.declareName(CALLABLE_REF_FOR_MEMBER_FUNCTION_NAME);
|
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);
|
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);
|
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);
|
callableRefForConstructorName = kotlinScope.declareName(CALLABLE_REF_FOR_CONSTRUCTOR_NAME);
|
||||||
callableRefForTopLevelProperty = kotlinScope.declareName(CALLABLE_REF_FOR_TOP_LEVEL_PROPERTY);
|
callableRefForTopLevelProperty = kotlinScope.declareName(CALLABLE_REF_FOR_TOP_LEVEL_PROPERTY);
|
||||||
callableRefForMemberProperty = kotlinScope.declareName(CALLABLE_REF_FOR_MEMBER_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);
|
callableRefForExtensionProperty = kotlinScope.declareName(CALLABLE_REF_FOR_EXTENSION_PROPERTY);
|
||||||
|
boundCallableRefForExtensionProperty = kotlinScope.declareName(BOUND_CALLABLE_REF_FOR_EXTENSION_PROPERTY);
|
||||||
|
|
||||||
isTypeName = kotlinScope.declareName("isType");
|
isTypeName = kotlinScope.declareName("isType");
|
||||||
}
|
}
|
||||||
@@ -243,16 +263,31 @@ public final class Namer {
|
|||||||
return kotlin(callableRefForMemberFunctionName);
|
return kotlin(callableRefForMemberFunctionName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public JsExpression boundCallableRefForMemberFunctionReference() {
|
||||||
|
return kotlin(boundCallableRefForMemberFunctionName);
|
||||||
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public JsExpression callableRefForExtensionFunctionReference() {
|
public JsExpression callableRefForExtensionFunctionReference() {
|
||||||
return kotlin(callableRefForExtensionFunctionName);
|
return kotlin(callableRefForExtensionFunctionName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public JsExpression boundCallableRefForExtensionFunctionReference() {
|
||||||
|
return kotlin(boundCallableRefForExtensionFunctionName);
|
||||||
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public JsExpression callableRefForLocalExtensionFunctionReference() {
|
public JsExpression callableRefForLocalExtensionFunctionReference() {
|
||||||
return kotlin(callableRefForLocalExtensionFunctionName);
|
return kotlin(callableRefForLocalExtensionFunctionName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public JsExpression boundCallableRefForLocalExtensionFunctionReference() {
|
||||||
|
return kotlin(boundCallableRefForLocalExtensionFunctionName);
|
||||||
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public JsExpression callableRefForConstructorReference() {
|
public JsExpression callableRefForConstructorReference() {
|
||||||
return kotlin(callableRefForConstructorName);
|
return kotlin(callableRefForConstructorName);
|
||||||
@@ -268,11 +303,21 @@ public final class Namer {
|
|||||||
return kotlin(callableRefForMemberProperty);
|
return kotlin(callableRefForMemberProperty);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public JsExpression boundCallableRefForMemberPropertyReference() {
|
||||||
|
return kotlin(boundCallableRefForMemberProperty);
|
||||||
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public JsExpression callableRefForExtensionPropertyReference() {
|
public JsExpression callableRefForExtensionPropertyReference() {
|
||||||
return kotlin(callableRefForExtensionProperty);
|
return kotlin(callableRefForExtensionProperty);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public JsExpression boundCallableRefForExtensionPropertyReference() {
|
||||||
|
return kotlin(boundCallableRefForExtensionProperty);
|
||||||
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public static JsExpression throwNPEFunctionRef() {
|
public static JsExpression throwNPEFunctionRef() {
|
||||||
return new JsNameRef(THROW_NPE_FUN_NAME, kotlinObject());
|
return new JsNameRef(THROW_NPE_FUN_NAME, kotlinObject());
|
||||||
|
|||||||
+96
-38
@@ -21,20 +21,41 @@ import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
|||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.js.resolve.diagnostics.ErrorsJs
|
import org.jetbrains.kotlin.js.resolve.diagnostics.ErrorsJs
|
||||||
import org.jetbrains.kotlin.js.translate.context.TranslationContext
|
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.js.translate.utils.*
|
||||||
import org.jetbrains.kotlin.psi.KtCallableReferenceExpression
|
import org.jetbrains.kotlin.psi.KtCallableReferenceExpression
|
||||||
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||||
|
import org.jetbrains.kotlin.resolve.PropertyImportedFromObject
|
||||||
|
import org.jetbrains.kotlin.types.expressions.DoubleColonLHS
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
object CallableReferenceTranslator {
|
object CallableReferenceTranslator {
|
||||||
|
|
||||||
fun translate(expression: KtCallableReferenceExpression, context: TranslationContext): JsExpression {
|
fun translate(expression: KtCallableReferenceExpression, context: TranslationContext): JsExpression {
|
||||||
val descriptor = BindingUtils.getDescriptorForReferenceExpression(context.bindingContext(), expression.callableReference)
|
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) {
|
return when (descriptor) {
|
||||||
is PropertyDescriptor ->
|
is PropertyDescriptor ->
|
||||||
translateForProperty(descriptor, context, expression)
|
translateForProperty(descriptor, context, expression, receiver)
|
||||||
is FunctionDescriptor ->
|
is FunctionDescriptor ->
|
||||||
translateForFunction(descriptor, context, expression)
|
translateForFunction(descriptor, context, expression, receiver)
|
||||||
else ->
|
else ->
|
||||||
throw IllegalArgumentException("Expected property or function: $descriptor, expression=${expression.text}")
|
throw IllegalArgumentException("Expected property or function: $descriptor, expression=${expression.text}")
|
||||||
}
|
}
|
||||||
@@ -45,31 +66,41 @@ object CallableReferenceTranslator {
|
|||||||
return JsLiteral.NULL
|
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 {
|
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) ->
|
KotlinBuiltIns.isBuiltIn(descriptor) ->
|
||||||
reportNotSupported(context, expression)
|
reportNotSupported(context, expression)
|
||||||
isConstructor(descriptor) ->
|
isConstructor(descriptor) ->
|
||||||
translateForConstructor(descriptor, context)
|
translateForConstructor(descriptor, context)
|
||||||
isExtension(descriptor) ->
|
isExtension(descriptor) ->
|
||||||
translateForExtensionFunction(descriptor, context)
|
translateForExtensionFunction(descriptor, context, receiver)
|
||||||
isMember(descriptor) ->
|
isMember(descriptor) ->
|
||||||
translateForMemberFunction(descriptor, context)
|
translateForMemberFunction(descriptor, context, receiver)
|
||||||
else ->
|
else ->
|
||||||
ReferenceTranslator.translateAsValueReference(descriptor, context)
|
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 {
|
return when {
|
||||||
// TODO Support for callable reference to builtin properties
|
// TODO Support for callable reference to builtin properties
|
||||||
KotlinBuiltIns.isBuiltIn(descriptor) ->
|
KotlinBuiltIns.isBuiltIn(descriptor) ->
|
||||||
reportNotSupported(context, expression)
|
reportNotSupported(context, expression)
|
||||||
isExtension(descriptor) ->
|
isExtension(descriptor) ->
|
||||||
translateForExtensionProperty(descriptor, context)
|
translateForExtensionProperty(descriptor, context, receiver)
|
||||||
isMember(descriptor) ->
|
isMember(descriptor) ->
|
||||||
translateForMemberProperty(descriptor, context)
|
translateForMemberProperty(descriptor, context, receiver)
|
||||||
else ->
|
else ->
|
||||||
translateForTopLevelProperty(descriptor, context)
|
translateForTopLevelProperty(descriptor, context)
|
||||||
}
|
}
|
||||||
@@ -137,27 +168,49 @@ object CallableReferenceTranslator {
|
|||||||
return function
|
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 jsPropertyName = context.getNameForDescriptor(descriptor)
|
||||||
val jsPropertyNameAsString = context.program().getStringLiteral(jsPropertyName.toString())
|
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 jsGetterNameRef = ReferenceTranslator.translateAsValueReference(descriptor.getter!!, context)
|
||||||
val propertyName = descriptor.name
|
val propertyName = descriptor.name
|
||||||
val jsPropertyNameAsString = context.program().getStringLiteral(propertyName.asString())
|
val jsPropertyNameAsString = context.program().getStringLiteral(propertyName.asString())
|
||||||
val argumentList = ArrayList<JsExpression>(3)
|
val argumentList = ArrayList<JsExpression>(4)
|
||||||
|
if (receiver != null) {
|
||||||
|
argumentList.add(receiver)
|
||||||
|
}
|
||||||
argumentList.add(jsPropertyNameAsString)
|
argumentList.add(jsPropertyNameAsString)
|
||||||
argumentList.add(jsGetterNameRef)
|
argumentList.add(jsGetterNameRef)
|
||||||
if (descriptor.isVar) {
|
if (descriptor.isVar) {
|
||||||
val jsSetterNameRef = ReferenceTranslator.translateAsValueReference(descriptor.setter!!, context)
|
val jsSetterNameRef = ReferenceTranslator.translateAsValueReference(descriptor.setter!!, context)
|
||||||
argumentList.add(jsSetterNameRef)
|
argumentList.add(jsSetterNameRef)
|
||||||
}
|
}
|
||||||
return if (AnnotationsUtils.isNativeObject(descriptor))
|
return if (AnnotationsUtils.isNativeObject(descriptor)) {
|
||||||
translateForMemberProperty(descriptor, context)
|
translateForMemberProperty(descriptor, context, receiver)
|
||||||
else
|
}
|
||||||
|
else if (receiver == null) {
|
||||||
JsInvocation(context.namer().callableRefForExtensionPropertyReference(), argumentList)
|
JsInvocation(context.namer().callableRefForExtensionPropertyReference(), argumentList)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
JsInvocation(context.namer().boundCallableRefForExtensionPropertyReference(), argumentList)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun translateForConstructor(descriptor: FunctionDescriptor, context: TranslationContext): JsExpression {
|
private fun translateForConstructor(descriptor: FunctionDescriptor, context: TranslationContext): JsExpression {
|
||||||
@@ -165,39 +218,44 @@ object CallableReferenceTranslator {
|
|||||||
return JsInvocation(context.namer().callableRefForConstructorReference(), jsFunctionRef)
|
return JsInvocation(context.namer().callableRefForConstructorReference(), jsFunctionRef)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun translateForExtensionFunction(descriptor: FunctionDescriptor, context: TranslationContext): JsExpression {
|
private fun translateForExtensionFunction(descriptor: FunctionDescriptor,
|
||||||
val receiverParameterDescriptor = descriptor.extensionReceiverParameter ?:
|
context: TranslationContext,
|
||||||
error("receiverParameter for extension should not be null")
|
receiver: JsExpression?
|
||||||
|
): JsExpression {
|
||||||
val jsFunctionRef = ReferenceTranslator.translateAsValueReference(descriptor, context)
|
val jsFunctionRef = ReferenceTranslator.translateAsValueReference(descriptor, context)
|
||||||
if (descriptor.visibility == Visibilities.LOCAL) {
|
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)) {
|
else if (AnnotationsUtils.isNativeObject(descriptor)) {
|
||||||
val jetType = receiverParameterDescriptor.type
|
return translateForMemberFunction(descriptor, context, receiver)
|
||||||
val receiverClassDescriptor = DescriptorUtils.getClassDescriptorForType(jetType)
|
|
||||||
return translateAsMemberFunctionReference(descriptor, receiverClassDescriptor, context)
|
|
||||||
}
|
}
|
||||||
else {
|
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 {
|
private fun translateForMemberFunction(
|
||||||
val classDescriptor = JsDescriptorUtils.getContainingDeclaration(descriptor) as? ClassDescriptor ?:
|
|
||||||
throw IllegalArgumentException("Expected ClassDescriptor: $descriptor")
|
|
||||||
return translateAsMemberFunctionReference(descriptor, classDescriptor, context)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun translateAsMemberFunctionReference(
|
|
||||||
descriptor: CallableDescriptor,
|
descriptor: CallableDescriptor,
|
||||||
classDescriptor: ClassDescriptor,
|
context: TranslationContext,
|
||||||
context: TranslationContext
|
receiver: JsExpression?
|
||||||
): JsExpression {
|
): JsExpression {
|
||||||
val jsClassNameRef = ReferenceTranslator.translateAsTypeReference(classDescriptor, context)
|
|
||||||
val funName = context.getNameForDescriptor(descriptor)
|
val funName = context.getNameForDescriptor(descriptor)
|
||||||
val funNameAsString = context.program().getStringLiteral(funName.toString())
|
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)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+35
-1
@@ -142,7 +142,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO Store callable references for members in class
|
// TODO Store callable references for members in class
|
||||||
Kotlin.getCallableRefForMemberFunction = function (klass, memberName) {
|
Kotlin.getCallableRefForMemberFunction = function (memberName) {
|
||||||
return function () {
|
return function () {
|
||||||
var args = [].slice.call(arguments);
|
var args = [].slice.call(arguments);
|
||||||
var instance = args.shift();
|
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
|
// TODO Store callable references for extension functions in class
|
||||||
// extFun expected receiver as the first argument
|
// extFun expected receiver as the first argument
|
||||||
Kotlin.getCallableRefForExtensionFunction = function (extFun) {
|
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) {
|
Kotlin.getCallableRefForLocalExtensionFunction = function (extFun) {
|
||||||
return function () {
|
return function () {
|
||||||
var args = [].slice.call(arguments);
|
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) {
|
Kotlin.getCallableRefForConstructor = function (klass) {
|
||||||
return function () {
|
return function () {
|
||||||
var obj = Object.create(klass.prototype);
|
var obj = Object.create(klass.prototype);
|
||||||
@@ -185,11 +205,25 @@
|
|||||||
return getPropertyRefClass(getFun, "get_za3rmp$", setFun, "set_wn2jw4$", propertyRefClassMetadataCache.oneArg);
|
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) {
|
Kotlin.getCallableRefForExtensionProperty = function(name, getFun, setFun) {
|
||||||
var getFunWrapper = Function("getFun", "return function " + name + "(receiver, extensionReceiver) { return getFun(receiver, extensionReceiver) }")(getFun);
|
var getFunWrapper = Function("getFun", "return function " + name + "(receiver, extensionReceiver) { return getFun(receiver, extensionReceiver) }")(getFun);
|
||||||
return getPropertyRefClass(getFunWrapper, "get_za3rmp$", setFun, "set_wn2jw4$", propertyRefClassMetadataCache.oneArg);
|
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) {
|
function getPropertyRefClass(getFun, getName, setFun, setName, cache) {
|
||||||
var obj = getFun;
|
var obj = getFun;
|
||||||
var isMutable = typeof setFun === "function";
|
var isMutable = typeof setFun === "function";
|
||||||
|
|||||||
Vendored
+2
-2
@@ -2,10 +2,10 @@
|
|||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<script type="application/javascript" src="../../../dist/js/kotlin.js"></script>
|
<script type="application/javascript" src="../../../dist/js/kotlin.js"></script>
|
||||||
<script type="application/javascript" src="out/box/native/eval_v5.js"></script>
|
<script type="application/javascript" src="out/codegen/boxInline/callableReference/bound/topLevelExtensionProperty_v5.js"></script>
|
||||||
|
|
||||||
<script type="application/javascript">
|
<script type="application/javascript">
|
||||||
console.log(JS_TESTS.foo.box());
|
console.log(JS_TESTS.box());
|
||||||
</script>
|
</script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|||||||
Reference in New Issue
Block a user