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 {
|
||||
var state = 0
|
||||
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 {
|
||||
return t::toString
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
//WITH_RUNTIME
|
||||
// IGNORE_BACKEND: JS
|
||||
fun box(): String {
|
||||
val a = intArrayOf(1, 2)
|
||||
val b = arrayOf("OK")
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
// Enable when callable references to builtin members is supported
|
||||
// IGNORE_BACKEND: JS
|
||||
fun box(): String {
|
||||
val f = "KOTLIN"::get
|
||||
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 {
|
||||
if ((Boolean::not)(true) != false) return "Fail 1"
|
||||
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 {
|
||||
ENTRY
|
||||
}
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
// TODO: muted automatically, investigate should it be ran for JS or not
|
||||
// IGNORE_BACKEND: JS
|
||||
|
||||
class A
|
||||
|
||||
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 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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
fun box(): String =
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
// TODO: muted automatically, investigate should it be ran for JS or not
|
||||
// IGNORE_BACKEND: JS
|
||||
|
||||
// WITH_RUNTIME
|
||||
|
||||
fun box(): String =
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
// Enable when callable references to builtin members is supported
|
||||
// IGNORE_BACKEND: JS
|
||||
// FILE: 1.kt
|
||||
|
||||
package test
|
||||
|
||||
@@ -14,43 +14,9 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
// TODO Store callable references for members in class
|
||||
Kotlin.getCallableRefForMemberFunction = function (memberName) {
|
||||
return function () {
|
||||
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.getCallableRef = function(name, f) {
|
||||
f.callableName = name;
|
||||
return f;
|
||||
};
|
||||
|
||||
Kotlin.getCallableRefZeroArg = function(name, getter, setter) {
|
||||
|
||||
+1
-7
@@ -143,13 +143,7 @@ public class CallableReferenceInlineTestsGenerated extends AbstractCallableRefer
|
||||
@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.");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("map.kt")
|
||||
|
||||
+11
-77
@@ -1865,37 +1865,19 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
||||
@TestMetadata("kCallableNameIntrinsic.kt")
|
||||
public void testKCallableNameIntrinsic() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/callableReference/bound/kCallableNameIntrinsic.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("kt12738.kt")
|
||||
public void testKt12738() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/callableReference/bound/kt12738.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("kt15446.kt")
|
||||
public void testKt15446() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/callableReference/bound/kt15446.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("multiCase.kt")
|
||||
@@ -1925,13 +1907,7 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
||||
@TestMetadata("simpleFunction.kt")
|
||||
public void testSimpleFunction() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/callableReference/bound/simpleFunction.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("simpleProperty.kt")
|
||||
@@ -2036,13 +2012,7 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
||||
@TestMetadata("booleanNotIntrinsic.kt")
|
||||
public void testBooleanNotIntrinsic() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/callableReference/function/booleanNotIntrinsic.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("classMemberFromClass.kt")
|
||||
@@ -2096,25 +2066,13 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
||||
@TestMetadata("enumValueOfMethod.kt")
|
||||
public void testEnumValueOfMethod() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/callableReference/function/enumValueOfMethod.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("equalsIntrinsic.kt")
|
||||
public void testEqualsIntrinsic() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/callableReference/function/equalsIntrinsic.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("extensionFromClass.kt")
|
||||
@@ -2270,13 +2228,7 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
||||
@TestMetadata("newArray.kt")
|
||||
public void testNewArray() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/callableReference/function/newArray.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("overloadedFun.kt")
|
||||
@@ -2446,13 +2398,7 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
||||
@TestMetadata("localFunctionName.kt")
|
||||
public void testLocalFunctionName() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/callableReference/function/local/localFunctionName.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("localLocal.kt")
|
||||
@@ -9975,25 +9921,13 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
||||
@TestMetadata("kt10131.kt")
|
||||
public void testKt10131() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/intrinsics/kt10131.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("kt10131a.kt")
|
||||
public void testKt10131a() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/intrinsics/kt10131a.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("kt12125.kt")
|
||||
|
||||
@@ -75,14 +75,6 @@ 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 DELEGATE = "$delegate";
|
||||
|
||||
private static final String ROOT_PACKAGE = "_";
|
||||
@@ -198,15 +190,7 @@ public final class Namer {
|
||||
@NotNull
|
||||
private final JsObjectScope kotlinScope;
|
||||
@NotNull
|
||||
private final JsName callableRefForMemberFunctionName;
|
||||
@NotNull
|
||||
private final JsName boundCallableRefForMemberFunctionName;
|
||||
@NotNull
|
||||
private final JsName callableRefForExtensionFunctionName;
|
||||
@NotNull
|
||||
private final JsName boundCallableRefForExtensionFunctionName;
|
||||
@NotNull
|
||||
private final JsName callableRefForConstructorName;
|
||||
public static final String FUNCTION_CALLABLE_REF = "getCallableRef";
|
||||
@NotNull
|
||||
public static final String PROPERTY_CALLABLE_REF_ZERO_ARG = "getCallableRefZeroArg";
|
||||
@NotNull
|
||||
@@ -225,12 +209,6 @@ public final class Namer {
|
||||
callGetProperty = kotlin("callGetter");
|
||||
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");
|
||||
}
|
||||
|
||||
@@ -245,31 +223,6 @@ public final class Namer {
|
||||
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
|
||||
public static JsExpression throwNPEFunctionRef() {
|
||||
return new JsNameRef(THROW_NPE_FUN_NAME, kotlinObject());
|
||||
|
||||
+71
-66
@@ -16,23 +16,30 @@
|
||||
|
||||
package org.jetbrains.kotlin.js.translate.reference
|
||||
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import com.intellij.openapi.project.Project
|
||||
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.resolve.diagnostics.ErrorsJs
|
||||
import org.jetbrains.kotlin.js.translate.callTranslator.CallTranslator
|
||||
import org.jetbrains.kotlin.js.translate.context.Namer
|
||||
import org.jetbrains.kotlin.js.translate.context.TranslationContext
|
||||
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.JsDescriptorUtils
|
||||
import org.jetbrains.kotlin.psi.KtCallExpression
|
||||
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.DescriptorUtils
|
||||
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.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.ResolvedValueArgument
|
||||
import org.jetbrains.kotlin.resolve.calls.util.CallMaker
|
||||
import org.jetbrains.kotlin.types.expressions.DoubleColonLHS
|
||||
|
||||
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(
|
||||
descriptor: FunctionDescriptor,
|
||||
context: TranslationContext,
|
||||
expression: KtCallableReferenceExpression,
|
||||
receiver: JsExpression?
|
||||
): JsExpression {
|
||||
return when {
|
||||
// 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, receiver)
|
||||
isMember(descriptor) ->
|
||||
translateForMemberFunction(descriptor, context, receiver)
|
||||
else ->
|
||||
ReferenceTranslator.translateAsValueReference(descriptor, context)
|
||||
val realResolvedCall = expression.callableReference.getFunctionResolvedCallWithAssert(context.bindingContext())
|
||||
val fakeExpression = constructFakeFunctionCall(expression.project, descriptor)
|
||||
|
||||
val fakeCall = CallMaker.makeCall(fakeExpression, null, null, fakeExpression, fakeExpression.valueArguments)
|
||||
val fakeResolvedCall = object : DelegatingResolvedCall<FunctionDescriptor>(realResolvedCall) {
|
||||
val valueArgumentList = fakeCall.valueArguments.map(::ExpressionValueArgument)
|
||||
val valueArgumentMap = valueArgumentList.withIndex().associate { (index, arg) -> descriptor.valueParameters[index] to arg }
|
||||
|
||||
override fun getCall() = fakeCall
|
||||
|
||||
override fun getValueArgumentsByIndex(): List<ResolvedValueArgument> = valueArgumentList
|
||||
|
||||
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(
|
||||
@@ -111,7 +144,7 @@ object CallableReferenceTranslator {
|
||||
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 {
|
||||
@@ -151,11 +184,15 @@ object CallableReferenceTranslator {
|
||||
|
||||
val accessorResult = translator(accessorContext, call, valueParam, receiverParam)
|
||||
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) {
|
||||
JsInvocation(JsNameRef("bind", accessorFunction), JsLiteral.NULL, receiver)
|
||||
JsInvocation(JsNameRef("bind", function), JsLiteral.NULL, receiver)
|
||||
}
|
||||
else {
|
||||
accessorFunction
|
||||
function
|
||||
}
|
||||
}
|
||||
|
||||
@@ -181,47 +218,15 @@ object CallableReferenceTranslator {
|
||||
return invocation
|
||||
}
|
||||
|
||||
private fun isConstructor(descriptor: CallableDescriptor) = descriptor is ConstructorDescriptor
|
||||
|
||||
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,
|
||||
private fun wrapFunctionCallableRef(
|
||||
context: TranslationContext,
|
||||
receiver: JsExpression?
|
||||
name: String,
|
||||
function: JsExpression
|
||||
): JsExpression {
|
||||
val funName = context.getNameForDescriptor(descriptor)
|
||||
val funNameAsString = context.program().getStringLiteral(funName.toString())
|
||||
if (receiver == null) {
|
||||
return JsInvocation(context.namer().callableRefForMemberFunctionReference(), funNameAsString)
|
||||
}
|
||||
else {
|
||||
return JsInvocation(context.namer().boundCallableRefForMemberFunctionReference(), receiver, funNameAsString)
|
||||
}
|
||||
val nameLiteral = context.program().getStringLiteral(name)
|
||||
val invokeName = Namer.FUNCTION_CALLABLE_REF
|
||||
val invokeFun = JsNameRef(invokeName, Namer.kotlinObject())
|
||||
val invocation = JsInvocation(invokeFun, nameLiteral, function)
|
||||
return invocation
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user