JS: refactor generation of callable references to functions
This commit is contained in:
-2
@@ -1,5 +1,3 @@
|
|||||||
// Enable when callable references to builtin members is supported
|
|
||||||
// IGNORE_BACKEND: JS
|
|
||||||
fun box(): String {
|
fun box(): String {
|
||||||
var state = 0
|
var state = 0
|
||||||
val name = (state++)::toString.name
|
val name = (state++)::toString.name
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
// Enable when callable references to builtin members is supported
|
|
||||||
// IGNORE_BACKEND: JS
|
|
||||||
fun <T> get(t: T): () -> String {
|
fun <T> get(t: T): () -> String {
|
||||||
return t::toString
|
return t::toString
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
//WITH_RUNTIME
|
//WITH_RUNTIME
|
||||||
// IGNORE_BACKEND: JS
|
|
||||||
fun box(): String {
|
fun box(): String {
|
||||||
val a = intArrayOf(1, 2)
|
val a = intArrayOf(1, 2)
|
||||||
val b = arrayOf("OK")
|
val b = arrayOf("OK")
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
// Enable when callable references to builtin members is supported
|
|
||||||
// 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)}"
|
||||||
|
|||||||
-3
@@ -1,6 +1,3 @@
|
|||||||
// TODO: muted automatically, investigate should it be ran for JS or not
|
|
||||||
// IGNORE_BACKEND: JS
|
|
||||||
|
|
||||||
fun box(): String {
|
fun box(): String {
|
||||||
if ((Boolean::not)(true) != false) return "Fail 1"
|
if ((Boolean::not)(true) != false) return "Fail 1"
|
||||||
if ((Boolean::not)(false) != true) return "Fail 2"
|
if ((Boolean::not)(false) != true) return "Fail 2"
|
||||||
|
|||||||
@@ -1,6 +1,3 @@
|
|||||||
// TODO: muted automatically, investigate should it be ran for JS or not
|
|
||||||
// IGNORE_BACKEND: JS
|
|
||||||
|
|
||||||
enum class E {
|
enum class E {
|
||||||
ENTRY
|
ENTRY
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,3 @@
|
|||||||
// TODO: muted automatically, investigate should it be ran for JS or not
|
|
||||||
// IGNORE_BACKEND: JS
|
|
||||||
|
|
||||||
class A
|
class A
|
||||||
|
|
||||||
fun box() = if ((A::equals)(A(), A())) "Fail" else "OK"
|
fun box() = if ((A::equals)(A(), A())) "Fail" else "OK"
|
||||||
|
|||||||
-3
@@ -1,6 +1,3 @@
|
|||||||
// TODO: muted automatically, investigate should it be ran for JS or not
|
|
||||||
// IGNORE_BACKEND: JS
|
|
||||||
|
|
||||||
fun box(): String {
|
fun box(): String {
|
||||||
fun OK() {}
|
fun OK() {}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,3 @@
|
|||||||
// TODO: muted automatically, investigate should it be ran for JS or not
|
|
||||||
// IGNORE_BACKEND: JS
|
|
||||||
|
|
||||||
private fun <T> upcast(value: T): T = value
|
private fun <T> upcast(value: T): T = value
|
||||||
|
|
||||||
fun box(): String {
|
fun box(): String {
|
||||||
|
|||||||
-3
@@ -1,6 +1,3 @@
|
|||||||
// TODO: muted automatically, investigate should it be ran for JS or not
|
|
||||||
// IGNORE_BACKEND: JS
|
|
||||||
|
|
||||||
// See KT-12337 Reference to property with invisible setter should not be a KMutableProperty
|
// See KT-12337 Reference to property with invisible setter should not be a KMutableProperty
|
||||||
|
|
||||||
import kotlin.reflect.KProperty1
|
import kotlin.reflect.KProperty1
|
||||||
|
|||||||
@@ -1,6 +1,3 @@
|
|||||||
// TODO: muted automatically, investigate should it be ran for JS or not
|
|
||||||
// IGNORE_BACKEND: JS
|
|
||||||
|
|
||||||
// WITH_RUNTIME
|
// WITH_RUNTIME
|
||||||
|
|
||||||
fun box(): String =
|
fun box(): String =
|
||||||
|
|||||||
@@ -1,6 +1,3 @@
|
|||||||
// TODO: muted automatically, investigate should it be ran for JS or not
|
|
||||||
// IGNORE_BACKEND: JS
|
|
||||||
|
|
||||||
// WITH_RUNTIME
|
// WITH_RUNTIME
|
||||||
|
|
||||||
fun box(): String =
|
fun box(): String =
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
// Enable when callable references to builtin members is supported
|
|
||||||
// IGNORE_BACKEND: JS
|
|
||||||
// FILE: 1.kt
|
// FILE: 1.kt
|
||||||
|
|
||||||
package test
|
package test
|
||||||
|
|||||||
@@ -14,43 +14,9 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// TODO Store callable references for members in class
|
Kotlin.getCallableRef = function(name, f) {
|
||||||
Kotlin.getCallableRefForMemberFunction = function (memberName) {
|
f.callableName = name;
|
||||||
return function () {
|
return f;
|
||||||
var args = [].slice.call(arguments);
|
|
||||||
var instance = args.shift();
|
|
||||||
return instance[memberName].apply(instance, args);
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
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) {
|
|
||||||
return function () {
|
|
||||||
return extFun.apply(null, arguments);
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
Kotlin.getBoundCallableRefForExtensionFunction = function (receiver, extFun) {
|
|
||||||
return function () {
|
|
||||||
var args = [].slice.call(arguments);
|
|
||||||
args.unshift(receiver);
|
|
||||||
return extFun.apply(null, args);
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
Kotlin.getCallableRefForConstructor = function (klass) {
|
|
||||||
return function () {
|
|
||||||
var obj = Object.create(klass.prototype);
|
|
||||||
klass.apply(obj, arguments);
|
|
||||||
return obj;
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Kotlin.getCallableRefZeroArg = function(name, getter, setter) {
|
Kotlin.getCallableRefZeroArg = function(name, getter, setter) {
|
||||||
|
|||||||
+1
-7
@@ -143,13 +143,7 @@ public class CallableReferenceInlineTestsGenerated extends AbstractCallableRefer
|
|||||||
@TestMetadata("intrinsic.kt")
|
@TestMetadata("intrinsic.kt")
|
||||||
public void testIntrinsic() throws Exception {
|
public void testIntrinsic() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/callableReference/bound/intrinsic.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/callableReference/bound/intrinsic.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("map.kt")
|
@TestMetadata("map.kt")
|
||||||
|
|||||||
+11
-77
@@ -1865,37 +1865,19 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
|||||||
@TestMetadata("kCallableNameIntrinsic.kt")
|
@TestMetadata("kCallableNameIntrinsic.kt")
|
||||||
public void testKCallableNameIntrinsic() throws Exception {
|
public void testKCallableNameIntrinsic() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/callableReference/bound/kCallableNameIntrinsic.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/callableReference/bound/kCallableNameIntrinsic.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("kt12738.kt")
|
@TestMetadata("kt12738.kt")
|
||||||
public void testKt12738() throws Exception {
|
public void testKt12738() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/callableReference/bound/kt12738.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/callableReference/bound/kt12738.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("kt15446.kt")
|
@TestMetadata("kt15446.kt")
|
||||||
public void testKt15446() throws Exception {
|
public void testKt15446() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/callableReference/bound/kt15446.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/callableReference/bound/kt15446.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("multiCase.kt")
|
@TestMetadata("multiCase.kt")
|
||||||
@@ -1925,13 +1907,7 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
|||||||
@TestMetadata("simpleFunction.kt")
|
@TestMetadata("simpleFunction.kt")
|
||||||
public void testSimpleFunction() throws Exception {
|
public void testSimpleFunction() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/callableReference/bound/simpleFunction.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/callableReference/bound/simpleFunction.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("simpleProperty.kt")
|
@TestMetadata("simpleProperty.kt")
|
||||||
@@ -2036,13 +2012,7 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
|||||||
@TestMetadata("booleanNotIntrinsic.kt")
|
@TestMetadata("booleanNotIntrinsic.kt")
|
||||||
public void testBooleanNotIntrinsic() throws Exception {
|
public void testBooleanNotIntrinsic() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/callableReference/function/booleanNotIntrinsic.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/callableReference/function/booleanNotIntrinsic.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("classMemberFromClass.kt")
|
@TestMetadata("classMemberFromClass.kt")
|
||||||
@@ -2096,25 +2066,13 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
|||||||
@TestMetadata("enumValueOfMethod.kt")
|
@TestMetadata("enumValueOfMethod.kt")
|
||||||
public void testEnumValueOfMethod() throws Exception {
|
public void testEnumValueOfMethod() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/callableReference/function/enumValueOfMethod.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/callableReference/function/enumValueOfMethod.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("equalsIntrinsic.kt")
|
@TestMetadata("equalsIntrinsic.kt")
|
||||||
public void testEqualsIntrinsic() throws Exception {
|
public void testEqualsIntrinsic() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/callableReference/function/equalsIntrinsic.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/callableReference/function/equalsIntrinsic.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("extensionFromClass.kt")
|
@TestMetadata("extensionFromClass.kt")
|
||||||
@@ -2270,13 +2228,7 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
|||||||
@TestMetadata("newArray.kt")
|
@TestMetadata("newArray.kt")
|
||||||
public void testNewArray() throws Exception {
|
public void testNewArray() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/callableReference/function/newArray.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/callableReference/function/newArray.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("overloadedFun.kt")
|
@TestMetadata("overloadedFun.kt")
|
||||||
@@ -2446,13 +2398,7 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
|||||||
@TestMetadata("localFunctionName.kt")
|
@TestMetadata("localFunctionName.kt")
|
||||||
public void testLocalFunctionName() throws Exception {
|
public void testLocalFunctionName() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/callableReference/function/local/localFunctionName.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/callableReference/function/local/localFunctionName.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("localLocal.kt")
|
@TestMetadata("localLocal.kt")
|
||||||
@@ -9975,25 +9921,13 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
|||||||
@TestMetadata("kt10131.kt")
|
@TestMetadata("kt10131.kt")
|
||||||
public void testKt10131() throws Exception {
|
public void testKt10131() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/intrinsics/kt10131.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/intrinsics/kt10131.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("kt10131a.kt")
|
@TestMetadata("kt10131a.kt")
|
||||||
public void testKt10131a() throws Exception {
|
public void testKt10131a() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/intrinsics/kt10131a.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/intrinsics/kt10131a.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("kt12125.kt")
|
@TestMetadata("kt12125.kt")
|
||||||
|
|||||||
@@ -75,14 +75,6 @@ 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 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 DELEGATE = "$delegate";
|
private static final String DELEGATE = "$delegate";
|
||||||
|
|
||||||
private static final String ROOT_PACKAGE = "_";
|
private static final String ROOT_PACKAGE = "_";
|
||||||
@@ -198,15 +190,7 @@ public final class Namer {
|
|||||||
@NotNull
|
@NotNull
|
||||||
private final JsObjectScope kotlinScope;
|
private final JsObjectScope kotlinScope;
|
||||||
@NotNull
|
@NotNull
|
||||||
private final JsName callableRefForMemberFunctionName;
|
public static final String FUNCTION_CALLABLE_REF = "getCallableRef";
|
||||||
@NotNull
|
|
||||||
private final JsName boundCallableRefForMemberFunctionName;
|
|
||||||
@NotNull
|
|
||||||
private final JsName callableRefForExtensionFunctionName;
|
|
||||||
@NotNull
|
|
||||||
private final JsName boundCallableRefForExtensionFunctionName;
|
|
||||||
@NotNull
|
|
||||||
private final JsName callableRefForConstructorName;
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public static final String PROPERTY_CALLABLE_REF_ZERO_ARG = "getCallableRefZeroArg";
|
public static final String PROPERTY_CALLABLE_REF_ZERO_ARG = "getCallableRefZeroArg";
|
||||||
@NotNull
|
@NotNull
|
||||||
@@ -225,12 +209,6 @@ public final class Namer {
|
|||||||
callGetProperty = kotlin("callGetter");
|
callGetProperty = kotlin("callGetter");
|
||||||
callSetProperty = kotlin("callSetter");
|
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);
|
|
||||||
callableRefForConstructorName = kotlinScope.declareName(CALLABLE_REF_FOR_CONSTRUCTOR_NAME);
|
|
||||||
|
|
||||||
isTypeName = kotlinScope.declareName("isType");
|
isTypeName = kotlinScope.declareName("isType");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -245,31 +223,6 @@ public final class Namer {
|
|||||||
return suggested.getNames().get(0);
|
return suggested.getNames().get(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
|
||||||
public JsExpression callableRefForMemberFunctionReference() {
|
|
||||||
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 callableRefForConstructorReference() {
|
|
||||||
return kotlin(callableRefForConstructorName);
|
|
||||||
}
|
|
||||||
|
|
||||||
@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());
|
||||||
|
|||||||
+71
-66
@@ -16,23 +16,30 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.js.translate.reference
|
package org.jetbrains.kotlin.js.translate.reference
|
||||||
|
|
||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
import com.intellij.openapi.project.Project
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||||
|
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||||
|
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
|
||||||
|
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||||
import org.jetbrains.kotlin.js.backend.ast.*
|
import org.jetbrains.kotlin.js.backend.ast.*
|
||||||
import org.jetbrains.kotlin.js.resolve.diagnostics.ErrorsJs
|
|
||||||
import org.jetbrains.kotlin.js.translate.callTranslator.CallTranslator
|
import org.jetbrains.kotlin.js.translate.callTranslator.CallTranslator
|
||||||
import org.jetbrains.kotlin.js.translate.context.Namer
|
import org.jetbrains.kotlin.js.translate.context.Namer
|
||||||
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.general.Translation
|
||||||
import org.jetbrains.kotlin.js.translate.utils.AnnotationsUtils
|
|
||||||
import org.jetbrains.kotlin.js.translate.utils.BindingUtils
|
import org.jetbrains.kotlin.js.translate.utils.BindingUtils
|
||||||
import org.jetbrains.kotlin.js.translate.utils.JsDescriptorUtils
|
import org.jetbrains.kotlin.psi.KtCallExpression
|
||||||
import org.jetbrains.kotlin.psi.KtCallableReferenceExpression
|
import org.jetbrains.kotlin.psi.KtCallableReferenceExpression
|
||||||
|
import org.jetbrains.kotlin.psi.KtExpression
|
||||||
|
import org.jetbrains.kotlin.psi.KtPsiFactory
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
|
||||||
import org.jetbrains.kotlin.resolve.PropertyImportedFromObject
|
import org.jetbrains.kotlin.resolve.PropertyImportedFromObject
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.callUtil.getFunctionResolvedCallWithAssert
|
||||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getPropertyResolvedCallWithAssert
|
import org.jetbrains.kotlin.resolve.calls.callUtil.getPropertyResolvedCallWithAssert
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.model.DelegatingResolvedCall
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.model.ExpressionValueArgument
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.model.ResolvedValueArgument
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.util.CallMaker
|
||||||
import org.jetbrains.kotlin.types.expressions.DoubleColonLHS
|
import org.jetbrains.kotlin.types.expressions.DoubleColonLHS
|
||||||
|
|
||||||
object CallableReferenceTranslator {
|
object CallableReferenceTranslator {
|
||||||
@@ -66,30 +73,56 @@ object CallableReferenceTranslator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun reportNotSupported(context: TranslationContext, expression: KtCallableReferenceExpression): JsExpression {
|
|
||||||
context.bindingTrace().report(ErrorsJs.REFERENCE_TO_BUILTIN_MEMBERS_NOT_SUPPORTED.on(expression, expression))
|
|
||||||
return JsLiteral.NULL
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun translateForFunction(
|
private fun translateForFunction(
|
||||||
descriptor: FunctionDescriptor,
|
descriptor: FunctionDescriptor,
|
||||||
context: TranslationContext,
|
context: TranslationContext,
|
||||||
expression: KtCallableReferenceExpression,
|
expression: KtCallableReferenceExpression,
|
||||||
receiver: JsExpression?
|
receiver: JsExpression?
|
||||||
): JsExpression {
|
): JsExpression {
|
||||||
return when {
|
val realResolvedCall = expression.callableReference.getFunctionResolvedCallWithAssert(context.bindingContext())
|
||||||
// TODO Support for callable reference to builtin functions and members
|
val fakeExpression = constructFakeFunctionCall(expression.project, descriptor)
|
||||||
KotlinBuiltIns.isBuiltIn(descriptor) ->
|
|
||||||
reportNotSupported(context, expression)
|
val fakeCall = CallMaker.makeCall(fakeExpression, null, null, fakeExpression, fakeExpression.valueArguments)
|
||||||
isConstructor(descriptor) ->
|
val fakeResolvedCall = object : DelegatingResolvedCall<FunctionDescriptor>(realResolvedCall) {
|
||||||
translateForConstructor(descriptor, context)
|
val valueArgumentList = fakeCall.valueArguments.map(::ExpressionValueArgument)
|
||||||
isExtension(descriptor) ->
|
val valueArgumentMap = valueArgumentList.withIndex().associate { (index, arg) -> descriptor.valueParameters[index] to arg }
|
||||||
translateForExtensionFunction(descriptor, context, receiver)
|
|
||||||
isMember(descriptor) ->
|
override fun getCall() = fakeCall
|
||||||
translateForMemberFunction(descriptor, context, receiver)
|
|
||||||
else ->
|
override fun getValueArgumentsByIndex(): List<ResolvedValueArgument> = valueArgumentList
|
||||||
ReferenceTranslator.translateAsValueReference(descriptor, context)
|
|
||||||
|
override fun getValueArguments(): Map<ValueParameterDescriptor, ResolvedValueArgument> = valueArgumentMap
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val function = JsFunction(context.scope(), JsBlock(), "")
|
||||||
|
val receiverParam = if (descriptor.dispatchReceiverParameter != null || descriptor.extensionReceiverParameter != null) {
|
||||||
|
val paramName = function.scope.declareTemporaryName(Namer.getReceiverParameterName())
|
||||||
|
function.parameters += JsParameter(paramName)
|
||||||
|
paramName.makeRef()
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
|
||||||
|
val aliases = mutableMapOf<KtExpression, JsExpression>()
|
||||||
|
for ((index, valueArg) in fakeCall.valueArguments.withIndex()) {
|
||||||
|
val paramName = function.scope.declareTemporaryName(descriptor.valueParameters[index].name.asString())
|
||||||
|
function.parameters += JsParameter(paramName)
|
||||||
|
aliases[valueArg.getArgumentExpression()!!] = paramName.makeRef()
|
||||||
|
}
|
||||||
|
val functionContext = context.innerBlock(function.body).innerContextWithAliasesForExpressions(aliases)
|
||||||
|
val invocation = CallTranslator.translate(functionContext, fakeResolvedCall, receiverParam)
|
||||||
|
function.body.statements += JsReturn(invocation)
|
||||||
|
|
||||||
|
val rawCallableRef = bindIfNecessary(function, receiver)
|
||||||
|
return wrapFunctionCallableRef(context, expression.callableReference.getReferencedName(), rawCallableRef)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun constructFakeFunctionCall(project: Project, referencedFunction: FunctionDescriptor): KtCallExpression {
|
||||||
|
val fakeFunctionCall = StringBuilder("callableReferenceFakeCall(")
|
||||||
|
fakeFunctionCall.append(referencedFunction.valueParameters.map { "p${it.index}" }.joinToString(", "))
|
||||||
|
fakeFunctionCall.append(")")
|
||||||
|
return KtPsiFactory(project).createExpression(fakeFunctionCall.toString()) as KtCallExpression
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun translateForProperty(
|
private fun translateForProperty(
|
||||||
@@ -111,7 +144,7 @@ object CallableReferenceTranslator {
|
|||||||
null
|
null
|
||||||
}
|
}
|
||||||
|
|
||||||
return wrapPropertyCallableRef(context, receiver, descriptor, descriptor.name.identifier, getter, setter)
|
return wrapPropertyCallableRef(context, receiver, descriptor, expression.callableReference.getReferencedName(), getter, setter)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun isSetterVisible(descriptor: PropertyDescriptor, context: TranslationContext): Boolean {
|
private fun isSetterVisible(descriptor: PropertyDescriptor, context: TranslationContext): Boolean {
|
||||||
@@ -151,11 +184,15 @@ object CallableReferenceTranslator {
|
|||||||
|
|
||||||
val accessorResult = translator(accessorContext, call, valueParam, receiverParam)
|
val accessorResult = translator(accessorContext, call, valueParam, receiverParam)
|
||||||
accessorFunction.body.statements += if (isSetter) accessorResult.makeStmt() else JsReturn(accessorResult)
|
accessorFunction.body.statements += if (isSetter) accessorResult.makeStmt() else JsReturn(accessorResult)
|
||||||
|
return bindIfNecessary(accessorFunction, receiver)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun bindIfNecessary(function: JsFunction, receiver: JsExpression?): JsExpression {
|
||||||
return if (receiver != null) {
|
return if (receiver != null) {
|
||||||
JsInvocation(JsNameRef("bind", accessorFunction), JsLiteral.NULL, receiver)
|
JsInvocation(JsNameRef("bind", function), JsLiteral.NULL, receiver)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
accessorFunction
|
function
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -181,47 +218,15 @@ object CallableReferenceTranslator {
|
|||||||
return invocation
|
return invocation
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun isConstructor(descriptor: CallableDescriptor) = descriptor is ConstructorDescriptor
|
private fun wrapFunctionCallableRef(
|
||||||
|
|
||||||
private fun isExtension(descriptor: CallableDescriptor) = DescriptorUtils.isExtension(descriptor)
|
|
||||||
|
|
||||||
private fun isMember(descriptor: CallableDescriptor) = JsDescriptorUtils.getContainingDeclaration(descriptor) is ClassDescriptor
|
|
||||||
|
|
||||||
private fun translateForConstructor(descriptor: FunctionDescriptor, context: TranslationContext): JsExpression {
|
|
||||||
val jsFunctionRef = ReferenceTranslator.translateAsValueReference(descriptor, context)
|
|
||||||
return JsInvocation(context.namer().callableRefForConstructorReference(), jsFunctionRef)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun translateForExtensionFunction(descriptor: FunctionDescriptor,
|
|
||||||
context: TranslationContext,
|
|
||||||
receiver: JsExpression?
|
|
||||||
): JsExpression {
|
|
||||||
val jsFunctionRef = ReferenceTranslator.translateAsValueReference(descriptor, context)
|
|
||||||
if (AnnotationsUtils.isNativeObject(descriptor)) {
|
|
||||||
return translateForMemberFunction(descriptor, context, receiver)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (receiver == null) {
|
|
||||||
return JsInvocation(context.namer().callableRefForExtensionFunctionReference(), jsFunctionRef)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return JsInvocation(context.namer().boundCallableRefForExtensionFunctionReference(), receiver, jsFunctionRef)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun translateForMemberFunction(
|
|
||||||
descriptor: CallableDescriptor,
|
|
||||||
context: TranslationContext,
|
context: TranslationContext,
|
||||||
receiver: JsExpression?
|
name: String,
|
||||||
|
function: JsExpression
|
||||||
): JsExpression {
|
): JsExpression {
|
||||||
val funName = context.getNameForDescriptor(descriptor)
|
val nameLiteral = context.program().getStringLiteral(name)
|
||||||
val funNameAsString = context.program().getStringLiteral(funName.toString())
|
val invokeName = Namer.FUNCTION_CALLABLE_REF
|
||||||
if (receiver == null) {
|
val invokeFun = JsNameRef(invokeName, Namer.kotlinObject())
|
||||||
return JsInvocation(context.namer().callableRefForMemberFunctionReference(), funNameAsString)
|
val invocation = JsInvocation(invokeFun, nameLiteral, function)
|
||||||
}
|
return invocation
|
||||||
else {
|
|
||||||
return JsInvocation(context.namer().boundCallableRefForMemberFunctionReference(), receiver, funNameAsString)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user