JS: extension lambdas translated same as local lambdas (KT-13312 fixed)
This commit is contained in:
@@ -0,0 +1,23 @@
|
||||
fun test1(f: (Int) -> Int) = f(1)
|
||||
|
||||
fun test2(f: Int.() -> Int) = 2.f()
|
||||
|
||||
class A(val foo: Int.() -> Int)
|
||||
|
||||
fun box(): String {
|
||||
val a: (Int) -> Int = { it }
|
||||
val b: Int.() -> Int = { this }
|
||||
|
||||
if (test1(a) != 1) return "fail 1a"
|
||||
if (test1(b) != 1) return "fail 1b"
|
||||
if (test2(a) != 2) return "fail 2a"
|
||||
if (test2(b) != 2) return "fail 2b"
|
||||
|
||||
val x = A({ this })
|
||||
|
||||
if (x.foo(3) != 3) return "fail 3"
|
||||
if (with(x) { foo(4) } != 4) return "fail 4"
|
||||
if (with(x) { 5.foo() } != 5) return "fail 5"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -1,6 +1,3 @@
|
||||
// TODO: muted automatically, investigate should it be ran for JS or not
|
||||
// IGNORE_BACKEND: JS
|
||||
|
||||
fun test(cl: Int.() -> Int):Int = 11.cl()
|
||||
|
||||
class Foo {
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
// TODO: muted automatically, investigate should it be ran for JS or not
|
||||
// IGNORE_BACKEND: JS
|
||||
|
||||
fun box(): String {
|
||||
val f = fun (s: String): String = s
|
||||
val g = f as String.() -> String
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
// TODO: muted automatically, investigate should it be ran for JS or not
|
||||
// IGNORE_BACKEND: JS
|
||||
|
||||
class It(val id: String)
|
||||
|
||||
fun box(): String {
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
// TODO: muted automatically, investigate should it be ran for JS or not
|
||||
// IGNORE_BACKEND: JS
|
||||
|
||||
fun box(): String {
|
||||
operator fun Int?.inc() = (this ?: 0) + 1
|
||||
var counter: Int? = null
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
// TODO: muted automatically, investigate should it be ran for JS or not
|
||||
// IGNORE_BACKEND: JS
|
||||
|
||||
// WITH_REFLECT
|
||||
|
||||
fun doStuff(fn: String.() -> String) = "ok".fn()
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
// Enable when using lambdas as extension lambdas is supported (KT-13312)
|
||||
// IGNORE_BACKEND: JS
|
||||
// FILE: 1.kt
|
||||
|
||||
package test
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
// Enable when using lambdas as extension lambdas is supported (KT-13312)
|
||||
// IGNORE_BACKEND: JS
|
||||
// FILE: 1.kt
|
||||
|
||||
package test
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
// Enable when using lambdas as extension lambdas is supported (KT-13312)
|
||||
// IGNORE_BACKEND: JS
|
||||
// FILE: 1.kt
|
||||
|
||||
package test
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
@kotlin.Metadata
|
||||
public final class A {
|
||||
private final @org.jetbrains.annotations.NotNull field foo: kotlin.jvm.functions.Function1
|
||||
public method <init>(@org.jetbrains.annotations.NotNull p0: kotlin.jvm.functions.Function1): void
|
||||
public final @org.jetbrains.annotations.NotNull method getFoo(): kotlin.jvm.functions.Function1
|
||||
}
|
||||
|
||||
@kotlin.Metadata
|
||||
public final class Kt13312Kt {
|
||||
public final static @org.jetbrains.annotations.NotNull method box(): java.lang.String
|
||||
public final static method test1(@org.jetbrains.annotations.NotNull p0: kotlin.jvm.functions.Function1): int
|
||||
public final static method test2(@org.jetbrains.annotations.NotNull p0: kotlin.jvm.functions.Function1): int
|
||||
}
|
||||
+6
@@ -7142,6 +7142,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("kt13312.kt")
|
||||
public void testKt13312() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/extensionFunctions/kt13312.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("kt1776.kt")
|
||||
public void testKt1776() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/extensionFunctions/kt1776.kt");
|
||||
|
||||
@@ -7142,6 +7142,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("kt13312.kt")
|
||||
public void testKt13312() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/extensionFunctions/kt13312.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("kt1776.kt")
|
||||
public void testKt1776() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/extensionFunctions/kt1776.kt");
|
||||
|
||||
@@ -7142,6 +7142,12 @@ public class LightAnalysisModeCodegenTestGenerated extends AbstractLightAnalysis
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("kt13312.kt")
|
||||
public void testKt13312() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/extensionFunctions/kt13312.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("kt1776.kt")
|
||||
public void testKt1776() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/extensionFunctions/kt1776.kt");
|
||||
|
||||
@@ -23,8 +23,8 @@ import org.jetbrains.kotlin.js.backend.ast.metadata.sideEffects
|
||||
import org.jetbrains.kotlin.js.backend.ast.metadata.staticRef
|
||||
import org.jetbrains.kotlin.js.backend.ast.metadata.synthetic
|
||||
import org.jetbrains.kotlin.js.inline.util.IdentitySet
|
||||
import org.jetbrains.kotlin.js.translate.utils.JsAstUtils
|
||||
import org.jetbrains.kotlin.js.inline.util.rewriters.ContinueReplacingVisitor
|
||||
import org.jetbrains.kotlin.js.translate.context.Namer
|
||||
import org.jetbrains.kotlin.js.translate.utils.JsAstUtils.*
|
||||
import org.jetbrains.kotlin.js.translate.utils.jsAstUtils.*
|
||||
|
||||
@@ -288,8 +288,8 @@ internal class ExpressionDecomposer private constructor(
|
||||
|
||||
private fun Callable.process() {
|
||||
qualifier = accept(qualifier)
|
||||
val matchedIndices = arguments.indicesOfExtractable
|
||||
if (!matchedIndices.hasNext()) return
|
||||
var matchedIndices = arguments.indicesOfExtractable
|
||||
if (matchedIndices.isEmpty()) return
|
||||
|
||||
if (qualifier in containsNodeWithSideEffect) {
|
||||
val callee = qualifier as? JsNameRef
|
||||
@@ -307,20 +307,27 @@ internal class ExpressionDecomposer private constructor(
|
||||
else {
|
||||
if (receiver != null && applyBindIfNecessary) {
|
||||
val receiverTmp = receiver.extractToTemporary()
|
||||
qualifier = JsAstUtils.invokeBind(receiverTmp, pureFqn(callee.ident, receiverTmp))
|
||||
val fqn = JsNameRef(callee.ident, receiverTmp).apply {
|
||||
synthetic = true
|
||||
callee.name?.let { sideEffects = it.sideEffects }
|
||||
}
|
||||
qualifier = fqn.extractToTemporary()
|
||||
qualifier = Namer.getFunctionCallRef(qualifier)
|
||||
arguments.add(0, receiverTmp)
|
||||
matchedIndices = matchedIndices.map { it + 1 }
|
||||
}
|
||||
else {
|
||||
qualifier = qualifier.extractToTemporary()
|
||||
}
|
||||
qualifier = qualifier.extractToTemporary()
|
||||
}
|
||||
}
|
||||
|
||||
processByIndices(arguments, matchedIndices)
|
||||
}
|
||||
|
||||
private fun processByIndices(elements: MutableList<JsExpression>, matchedIndices: Iterator<Int>) {
|
||||
private fun processByIndices(elements: MutableList<JsExpression>, matchedIndices: List<Int>) {
|
||||
var prev = 0
|
||||
while (matchedIndices.hasNext()) {
|
||||
val curr = matchedIndices.next()
|
||||
|
||||
for (curr in matchedIndices) {
|
||||
for (i in prev..curr-1) {
|
||||
val arg = elements[i]
|
||||
if (arg !in containsNodeWithSideEffect) continue
|
||||
@@ -374,8 +381,8 @@ internal class ExpressionDecomposer private constructor(
|
||||
}
|
||||
}
|
||||
|
||||
private val List<JsNode>.indicesOfExtractable: Iterator<Int>
|
||||
get() = indices.filter { get(it) in containsExtractable }.iterator()
|
||||
private val List<JsNode>.indicesOfExtractable: List<Int>
|
||||
get() = indices.filter { get(it) in containsExtractable }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -24,6 +24,7 @@ import org.jetbrains.kotlin.js.inline.clean.removeDefaultInitializers
|
||||
import org.jetbrains.kotlin.js.inline.context.InliningContext
|
||||
import org.jetbrains.kotlin.js.inline.util.*
|
||||
import org.jetbrains.kotlin.js.inline.util.rewriters.ReturnReplacingVisitor
|
||||
import org.jetbrains.kotlin.js.translate.context.Namer
|
||||
|
||||
class FunctionInlineMutator
|
||||
private constructor(
|
||||
@@ -77,7 +78,7 @@ private constructor(
|
||||
return when (qualifier) {
|
||||
is JsInvocation -> qualifier
|
||||
is JsNameRef -> {
|
||||
val callee = if (qualifier.ident == "call") qualifier.qualifier else (qualifier.name?.staticRef as? JsExpression)
|
||||
val callee = if (qualifier.ident == Namer.CALL_FUNCTION) qualifier.qualifier else (qualifier.name?.staticRef as? JsExpression)
|
||||
callee?.let { getInnerCall(it) }
|
||||
}
|
||||
else -> null
|
||||
|
||||
@@ -171,7 +171,6 @@ private fun JsFunction.markInlineArguments(descriptor: CallableDescriptor) {
|
||||
val params = descriptor.valueParameters
|
||||
val paramsJs = parameters
|
||||
val inlineFuns = IdentitySet<JsName>()
|
||||
val inlineExtensionFuns = IdentitySet<JsName>()
|
||||
val offset = if (descriptor.isExtension) 1 else 0
|
||||
|
||||
for ((i, param) in params.withIndex()) {
|
||||
@@ -180,25 +179,21 @@ private fun JsFunction.markInlineArguments(descriptor: CallableDescriptor) {
|
||||
val type = param.type
|
||||
if (!type.isFunctionTypeOrSubtype) continue
|
||||
|
||||
val namesSet = if (type.isExtensionFunctionType) inlineExtensionFuns else inlineFuns
|
||||
namesSet.add(paramsJs[i + offset].name)
|
||||
inlineFuns.add(paramsJs[i + offset].name)
|
||||
}
|
||||
|
||||
val visitor = object: JsVisitorWithContextImpl() {
|
||||
override fun endVisit(x: JsInvocation, ctx: JsContext<*>) {
|
||||
val qualifier: JsExpression?
|
||||
val namesSet: Set<JsName>
|
||||
|
||||
if (isCallInvocation(x)) {
|
||||
qualifier = (x.qualifier as? JsNameRef)?.qualifier
|
||||
namesSet = inlineExtensionFuns
|
||||
} else {
|
||||
qualifier = x.qualifier
|
||||
namesSet = inlineFuns
|
||||
}
|
||||
|
||||
(qualifier as? JsNameRef)?.name?.let { name ->
|
||||
if (name in namesSet) {
|
||||
if (name in inlineFuns) {
|
||||
x.inlineStrategy = InlineStrategy.IN_PLACE
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,14 +18,14 @@ package org.jetbrains.kotlin.js.inline.clean
|
||||
|
||||
import org.jetbrains.kotlin.js.backend.ast.JsFunction
|
||||
|
||||
class FunctionPostProcessor(root: JsFunction) {
|
||||
class FunctionPostProcessor(val root: JsFunction) {
|
||||
val optimizations = listOf(
|
||||
//{ TemporaryAssignmentElimination(root.body).apply() },
|
||||
{ RedundantLabelRemoval(root.body).apply() },
|
||||
{ WhileConditionFolding(root.body).apply() },
|
||||
{ DoWhileGuardElimination(root.body).apply() },
|
||||
{ TemporaryVariableElimination(root).apply() },
|
||||
{ RedundantBindElimination(root.body).apply() },
|
||||
{ RedundantCallElimination(root.body).apply() },
|
||||
{ IfStatementReduction(root.body).apply() },
|
||||
{ DeadCodeElimination(root.body).apply() },
|
||||
{ RedundantVariableDeclarationElimination(root.body).apply() },
|
||||
|
||||
+15
-12
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
* Copyright 2010-2017 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.
|
||||
@@ -20,11 +20,11 @@ import org.jetbrains.kotlin.js.backend.ast.JsBlock
|
||||
import org.jetbrains.kotlin.js.backend.ast.JsInvocation
|
||||
import org.jetbrains.kotlin.js.backend.ast.JsNameRef
|
||||
import org.jetbrains.kotlin.js.backend.ast.RecursiveJsVisitor
|
||||
import org.jetbrains.kotlin.js.inline.util.getCallerQualifier
|
||||
import org.jetbrains.kotlin.js.inline.util.isCallInvocation
|
||||
|
||||
// TODO: this optimization is a little unfair. It tries to recognize pattern like this a.bind(b)(args) and
|
||||
// replace it with b.a(args). However, we can't be completely sure that `a` is a Function.
|
||||
// Using JS-independent AST should solve the issue (as well as many other issues).
|
||||
class RedundantBindElimination(private val root: JsBlock) {
|
||||
// Replaces a.foo.call(a, b) with a.foo(b)
|
||||
class RedundantCallElimination(private val root: JsBlock) {
|
||||
private var changed = false
|
||||
|
||||
fun apply(): Boolean {
|
||||
@@ -35,15 +35,18 @@ class RedundantBindElimination(private val root: JsBlock) {
|
||||
}
|
||||
|
||||
private fun tryEliminate(invocation: JsInvocation) {
|
||||
val qualifier = invocation.qualifier as? JsInvocation ?: return
|
||||
if (!isCallInvocation(invocation)) return
|
||||
|
||||
val outerQualifier = qualifier.qualifier as? JsNameRef ?: return
|
||||
val name = outerQualifier.ident
|
||||
if (name != "bind") return
|
||||
val qualifier = getCallerQualifier(invocation) as? JsNameRef ?: return
|
||||
|
||||
val qualifierReplacement = outerQualifier.qualifier ?: return
|
||||
invocation.qualifier = qualifierReplacement
|
||||
changed = true
|
||||
val receiver = qualifier.qualifier as? JsNameRef ?: return
|
||||
val firstArg = invocation.arguments.firstOrNull() as? JsNameRef ?: return
|
||||
|
||||
if (receiver.qualifier == null && receiver.name != null && firstArg.qualifier == null && receiver.name == firstArg.name) {
|
||||
invocation.arguments.removeAt(0)
|
||||
invocation.qualifier = qualifier
|
||||
changed = true
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
@@ -28,7 +28,7 @@ import kotlin.coroutines.intrinsics.*
|
||||
public fun <R, T> (suspend R.() -> T).createCoroutine(
|
||||
receiver: R,
|
||||
completion: Continuation<T>
|
||||
): Continuation<Unit> = this.asDynamic().call(receiver, completion, true).facade
|
||||
): Continuation<Unit> = this.asDynamic()(receiver, completion, true).facade
|
||||
|
||||
/**
|
||||
* Starts coroutine with receiver type [R] and result type [T].
|
||||
@@ -40,7 +40,7 @@ public fun <R, T> (suspend R.() -> T).startCoroutine(
|
||||
receiver: R,
|
||||
completion: Continuation<T>
|
||||
) {
|
||||
this.asDynamic().call(receiver, completion)
|
||||
this.asDynamic()(receiver, completion)
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -45,20 +45,6 @@ Kotlin.getBoundCallableRefForExtensionFunction = function (receiver, extFun) {
|
||||
};
|
||||
};
|
||||
|
||||
Kotlin.getCallableRefForLocalExtensionFunction = function (extFun) {
|
||||
return function () {
|
||||
var args = [].slice.call(arguments);
|
||||
var instance = args.shift();
|
||||
return extFun.apply(instance, args);
|
||||
};
|
||||
};
|
||||
|
||||
Kotlin.getBoundCallableRefForLocalExtensionFunction = function (receiver, extFun) {
|
||||
return function () {
|
||||
return extFun.apply(receiver, arguments);
|
||||
};
|
||||
};
|
||||
|
||||
Kotlin.getCallableRefForConstructor = function (klass) {
|
||||
return function () {
|
||||
var obj = Object.create(klass.prototype);
|
||||
|
||||
+3
-21
@@ -39,25 +39,13 @@ public class CallableReferenceInlineTestsGenerated extends AbstractCallableRefer
|
||||
@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.");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@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.");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("constructor.kt")
|
||||
@@ -111,13 +99,7 @@ public class CallableReferenceInlineTestsGenerated extends AbstractCallableRefer
|
||||
@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.");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("topLevelProperty.kt")
|
||||
|
||||
+11
-35
@@ -8127,6 +8127,12 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("kt13312.kt")
|
||||
public void testKt13312() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/extensionFunctions/kt13312.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("kt1776.kt")
|
||||
public void testKt1776() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/extensionFunctions/kt1776.kt");
|
||||
@@ -8160,13 +8166,7 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
||||
@TestMetadata("kt3646.kt")
|
||||
public void testKt3646() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/extensionFunctions/kt3646.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("kt3969.kt")
|
||||
@@ -8966,13 +8966,7 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
||||
@TestMetadata("castFunctionToExtension.kt")
|
||||
public void testCastFunctionToExtension() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/functions/invoke/castFunctionToExtension.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("extensionInvokeOnExpr.kt")
|
||||
@@ -9173,13 +9167,7 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
||||
@TestMetadata("kt4989.kt")
|
||||
public void testKt4989() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/functions/localFunctions/kt4989.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("localExtensionOnNullableParameter.kt")
|
||||
@@ -12657,13 +12645,7 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
||||
@TestMetadata("kt4987.kt")
|
||||
public void testKt4987() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/operatorConventions/kt4987.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("nestedMaps.kt")
|
||||
@@ -16607,13 +16589,7 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
||||
@TestMetadata("functionFromStdlib.kt")
|
||||
public void testFunctionFromStdlib() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/reflection/functions/functionFromStdlib.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("functionReferenceErasedToKFunction.kt")
|
||||
|
||||
+4
-20
@@ -17,7 +17,6 @@
|
||||
package org.jetbrains.kotlin.js.translate.callTranslator
|
||||
|
||||
import org.jetbrains.kotlin.builtins.functions.FunctionInvokeDescriptor
|
||||
import org.jetbrains.kotlin.builtins.isExtensionFunctionType
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.js.PredefinedAnnotation
|
||||
import org.jetbrains.kotlin.js.backend.ast.*
|
||||
@@ -101,20 +100,12 @@ object DefaultFunctionCallCase : FunctionCallCase() {
|
||||
|
||||
val functionRef = ReferenceTranslator.translateAsValueReference(callableDescriptor, context)
|
||||
|
||||
val referenceToCall =
|
||||
if (callableDescriptor.visibility == Visibilities.LOCAL) {
|
||||
Namer.getFunctionCallRef(functionRef)
|
||||
}
|
||||
else {
|
||||
functionRef
|
||||
}
|
||||
|
||||
return JsInvocation(referenceToCall, argumentsInfo.argsWithReceiver(extensionReceiver!!))
|
||||
return JsInvocation(functionRef, argumentsInfo.argsWithReceiver(extensionReceiver!!))
|
||||
}
|
||||
|
||||
override fun FunctionCallInfo.bothReceivers(): JsExpression {
|
||||
// TODO: think about crazy case: spreadOperator + native
|
||||
val functionRef = JsNameRef(functionName, dispatchReceiver!!)
|
||||
val functionRef = JsAstUtils.pureFqn(functionName, dispatchReceiver!!)
|
||||
return JsInvocation(functionRef, argumentsInfo.argsWithReceiver(extensionReceiver!!))
|
||||
}
|
||||
}
|
||||
@@ -170,14 +161,7 @@ object InvokeIntrinsic : FunctionCallCase() {
|
||||
}
|
||||
|
||||
override fun FunctionCallInfo.dispatchReceiver(): JsExpression {
|
||||
val receiver = resolvedCall.dispatchReceiver!!
|
||||
val jsReceiver = if (receiver.type.isExtensionFunctionType) {
|
||||
pureFqn(Namer.CALL_FUNCTION, dispatchReceiver)
|
||||
}
|
||||
else {
|
||||
dispatchReceiver!!
|
||||
}
|
||||
return JsInvocation(jsReceiver, argumentsInfo.translateArguments)
|
||||
return JsInvocation(dispatchReceiver!!, argumentsInfo.translateArguments)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -194,7 +178,7 @@ object InvokeIntrinsic : FunctionCallCase() {
|
||||
* extLambda.call(obj, some, args)
|
||||
*/
|
||||
override fun FunctionCallInfo.bothReceivers(): JsExpression {
|
||||
return JsInvocation(Namer.getFunctionCallRef(dispatchReceiver!!), argumentsInfo.argsWithReceiver(extensionReceiver!!))
|
||||
return JsInvocation(dispatchReceiver!!, argumentsInfo.argsWithReceiver(extensionReceiver!!))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -130,7 +130,7 @@ object DefaultVariableAccessCase : VariableAccessCase() {
|
||||
}
|
||||
|
||||
override fun VariableAccessInfo.bothReceivers(): JsExpression {
|
||||
val funRef = JsNameRef(context.getNameForDescriptor(getAccessDescriptorIfNeeded()), dispatchReceiver!!)
|
||||
val funRef = JsAstUtils.pureFqn(context.getNameForDescriptor(getAccessDescriptorIfNeeded()), dispatchReceiver!!)
|
||||
return JsInvocation(funRef, extensionReceiver!!, *additionalArguments.toTypedArray())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -211,10 +211,6 @@ public final class Namer {
|
||||
@NotNull
|
||||
private final JsName boundCallableRefForExtensionFunctionName;
|
||||
@NotNull
|
||||
private final JsName callableRefForLocalExtensionFunctionName;
|
||||
@NotNull
|
||||
private final JsName boundCallableRefForLocalExtensionFunctionName;
|
||||
@NotNull
|
||||
private final JsName callableRefForConstructorName;
|
||||
@NotNull
|
||||
private final JsName callableRefForTopLevelProperty;
|
||||
@@ -244,8 +240,6 @@ public final class Namer {
|
||||
boundCallableRefForMemberFunctionName = kotlinScope.declareName(BOUND_CALLABLE_REF_FOR_MEMBER_FUNCTION_NAME);
|
||||
callableRefForExtensionFunctionName = kotlinScope.declareName(CALLABLE_REF_FOR_EXTENSION_FUNCTION_NAME);
|
||||
boundCallableRefForExtensionFunctionName = kotlinScope.declareName(BOUND_CALLABLE_REF_FOR_EXTENSION_FUNCTION_NAME);
|
||||
callableRefForLocalExtensionFunctionName = kotlinScope.declareName(CALLABLE_REF_FOR_LOCAL_EXTENSION_FUNCTION_NAME);
|
||||
boundCallableRefForLocalExtensionFunctionName = kotlinScope.declareName(BOUND_CALLABLE_REF_FOR_LOCAL_EXTENSION_FUNCTION_NAME);
|
||||
callableRefForConstructorName = kotlinScope.declareName(CALLABLE_REF_FOR_CONSTRUCTOR_NAME);
|
||||
callableRefForTopLevelProperty = kotlinScope.declareName(CALLABLE_REF_FOR_TOP_LEVEL_PROPERTY);
|
||||
callableRefForMemberProperty = kotlinScope.declareName(CALLABLE_REF_FOR_MEMBER_PROPERTY);
|
||||
@@ -287,16 +281,6 @@ public final class Namer {
|
||||
return kotlin(boundCallableRefForExtensionFunctionName);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public JsExpression callableRefForLocalExtensionFunctionReference() {
|
||||
return kotlin(callableRefForLocalExtensionFunctionName);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public JsExpression boundCallableRefForLocalExtensionFunctionReference() {
|
||||
return kotlin(boundCallableRefForLocalExtensionFunctionName);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public JsExpression callableRefForConstructorReference() {
|
||||
return kotlin(callableRefForConstructorName);
|
||||
|
||||
+1
-2
@@ -19,7 +19,6 @@ package org.jetbrains.kotlin.js.translate.expression
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.PropertyAccessorDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||
import org.jetbrains.kotlin.js.backend.ast.JsExpression
|
||||
import org.jetbrains.kotlin.js.backend.ast.JsFunction
|
||||
import org.jetbrains.kotlin.js.backend.ast.JsParameter
|
||||
@@ -77,7 +76,7 @@ private fun FunctionDescriptor.getCorrectTypeParameters() =
|
||||
|
||||
|
||||
private val FunctionDescriptor.requiresExtensionReceiverParameter
|
||||
get() = DescriptorUtils.isExtension(this) && visibility != Visibilities.LOCAL
|
||||
get() = DescriptorUtils.isExtension(this)
|
||||
|
||||
fun TranslationContext.translateFunction(declaration: KtDeclarationWithBody, function: JsFunction) {
|
||||
val descriptor = BindingUtils.getFunctionDescriptor(bindingContext(), declaration)
|
||||
|
||||
+1
-9
@@ -223,15 +223,7 @@ object CallableReferenceTranslator {
|
||||
receiver: JsExpression?
|
||||
): JsExpression {
|
||||
val jsFunctionRef = ReferenceTranslator.translateAsValueReference(descriptor, context)
|
||||
if (descriptor.visibility == Visibilities.LOCAL) {
|
||||
if (receiver == null) {
|
||||
return JsInvocation(context.namer().callableRefForLocalExtensionFunctionReference(), jsFunctionRef)
|
||||
}
|
||||
else {
|
||||
return JsInvocation(context.namer().boundCallableRefForLocalExtensionFunctionReference(), receiver, jsFunctionRef)
|
||||
}
|
||||
}
|
||||
else if (AnnotationsUtils.isNativeObject(descriptor)) {
|
||||
if (AnnotationsUtils.isNativeObject(descriptor)) {
|
||||
return translateForMemberFunction(descriptor, context, receiver)
|
||||
}
|
||||
else {
|
||||
|
||||
+3
-3
@@ -16,12 +16,12 @@
|
||||
|
||||
package org.jetbrains.kotlin.js.translate.reference;
|
||||
|
||||
import org.jetbrains.kotlin.js.backend.ast.JsBinaryOperation;
|
||||
import org.jetbrains.kotlin.js.backend.ast.JsExpression;
|
||||
import org.jetbrains.kotlin.js.backend.ast.JsNameRef;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.descriptors.*;
|
||||
import org.jetbrains.kotlin.js.backend.ast.JsBinaryOperation;
|
||||
import org.jetbrains.kotlin.js.backend.ast.JsExpression;
|
||||
import org.jetbrains.kotlin.js.backend.ast.JsNameRef;
|
||||
import org.jetbrains.kotlin.js.translate.callTranslator.CallTranslator;
|
||||
import org.jetbrains.kotlin.js.translate.context.TranslationContext;
|
||||
import org.jetbrains.kotlin.js.translate.general.AbstractTranslator;
|
||||
|
||||
@@ -18,11 +18,9 @@
|
||||
|
||||
package org.jetbrains.kotlin.js.translate.utils
|
||||
|
||||
import org.jetbrains.kotlin.js.backend.ast.metadata.descriptor
|
||||
import org.jetbrains.kotlin.js.backend.ast.metadata.inlineStrategy
|
||||
import org.jetbrains.kotlin.js.backend.ast.metadata.psiElement
|
||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||
import org.jetbrains.kotlin.js.backend.ast.*
|
||||
import org.jetbrains.kotlin.js.backend.ast.metadata.*
|
||||
import org.jetbrains.kotlin.js.inline.util.isCallInvocation
|
||||
import org.jetbrains.kotlin.js.translate.context.TranslationContext
|
||||
import org.jetbrains.kotlin.js.translate.reference.CallExpressionTranslator
|
||||
|
||||
@@ -3,5 +3,5 @@ function A(v) {
|
||||
}
|
||||
|
||||
function nativeBox(b) {
|
||||
return b.bar_asnz92$(new A("foo"), function(i, s) { return "" + this.v + s + i })
|
||||
return b.bar_asnz92$(new A("foo"), function($reciever, i, s) { return "" + $reciever.v + s + i })
|
||||
}
|
||||
|
||||
@@ -3,5 +3,5 @@ function A(v) {
|
||||
}
|
||||
|
||||
function bar(a, extLambda) {
|
||||
return extLambda.call(a, 4, "boo")
|
||||
return extLambda(a, 4, "boo")
|
||||
}
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
function bar(a, extLambda) {
|
||||
return extLambda.call(a, 4, "boo")
|
||||
return extLambda(a, 4, "boo")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user