From 766857881a02da0380c307c77e2fcf37ecd62913 Mon Sep 17 00:00:00 2001 From: Ilya Goncharov Date: Mon, 9 Aug 2021 12:49:06 +0300 Subject: [PATCH] [JS IR] Review remarks - Use intrinsic on this - Enqueue invoke for DCE - Change transform - Ignore instead of target backend ^KT-46204 fixed --- .../FirBlackBoxCodegenTestGenerated.java | 6 +++ .../org/jetbrains/kotlin/ir/backend/js/Dce.kt | 8 +++- .../transformers/irToJs/JsClassGenerator.kt | 21 ++++++---- .../irToJs/JsIntrinsicTransformers.kt | 41 ++----------------- .../kotlin/ir/backend/js/utils/misc.kt | 13 ++++-- ...pendFunctionAsSupertypeIsCheckWithArity.kt | 4 +- .../codegen/BlackBoxCodegenTestGenerated.java | 6 +++ .../IrBlackBoxCodegenTestGenerated.java | 6 +++ .../LightAnalysisModeTestGenerated.java | 5 +++ .../src/kotlin/coroutines_13/IntrinsicsJs.kt | 10 ++--- 10 files changed, 63 insertions(+), 57 deletions(-) diff --git a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java index be40041fe58..0badfa1988a 100644 --- a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java +++ b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java @@ -10205,6 +10205,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT runTest("compiler/testData/codegen/box/coroutines/featureIntersection/suspendFunctionAsSupertypeIsCheck.kt"); } + @Test + @TestMetadata("suspendFunctionAsSupertypeIsCheckWithArity.kt") + public void testSuspendFunctionAsSupertypeIsCheckWithArity() throws Exception { + runTest("compiler/testData/codegen/box/coroutines/featureIntersection/suspendFunctionAsSupertypeIsCheckWithArity.kt"); + } + @Test @TestMetadata("suspendFunctionIsAs.kt") public void testSuspendFunctionIsAs() throws Exception { diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/Dce.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/Dce.kt index a59021a966e..8aa8ba912ec 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/Dce.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/Dce.kt @@ -22,8 +22,8 @@ import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid import org.jetbrains.kotlin.ir.visitors.acceptVoid -import org.jetbrains.kotlin.js.config.RuntimeDiagnostic import org.jetbrains.kotlin.js.config.JSConfigurationKeys +import org.jetbrains.kotlin.js.config.RuntimeDiagnostic import org.jetbrains.kotlin.utils.addIfNotNull import java.util.* @@ -458,6 +458,12 @@ fun usefulDeclarations( val klass = arg.getClass() constructedClasses.addIfNotNull(klass) } + context.intrinsics.jsInvokeSuspendSuperType, + context.intrinsics.jsInvokeSuspendSuperTypeWithReceiver, + context.intrinsics.jsInvokeSuspendSuperTypeWithReceiverAndParam -> { + invokeFunForLambda(expression) + .enqueue("intrinsic: suspendSuperType") + } } } diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/JsClassGenerator.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/JsClassGenerator.kt index f750ef956bb..5ce9fa2c1c0 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/JsClassGenerator.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/JsClassGenerator.kt @@ -6,6 +6,7 @@ package org.jetbrains.kotlin.ir.backend.js.transformers.irToJs import org.jetbrains.kotlin.descriptors.DescriptorVisibilities +import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.ir.backend.js.export.isExported import org.jetbrains.kotlin.ir.backend.js.utils.* import org.jetbrains.kotlin.ir.declarations.* @@ -162,19 +163,21 @@ class JsClassGenerator(private val irClass: IrClass, val context: JsGenerationCo // interface II : I // II.prototype.foo = I.prototype.foo if (!irClass.isInterface) { - declaration.realOverrideTarget.let { - val implClassDeclaration = it.parent as IrClass + declaration.collectRealOverrides() + .find { it.modality != Modality.ABSTRACT } + ?.let { + val implClassDeclaration = it.parent as IrClass - if (implClassDeclaration.shouldCopyFrom() && !implClassDeclaration.defaultType.isFunctionType()) { - val implMethodName = context.getNameForMemberFunction(it) - val implClassName = context.getNameForClass(implClassDeclaration) + if (implClassDeclaration.shouldCopyFrom()) { + val implMethodName = context.getNameForMemberFunction(it) + val implClassName = context.getNameForClass(implClassDeclaration) - val implClassPrototype = prototypeOf(implClassName.makeRef()) - val implMemberRef = JsNameRef(implMethodName, implClassPrototype) + val implClassPrototype = prototypeOf(implClassName.makeRef()) + val implMemberRef = JsNameRef(implMethodName, implClassPrototype) - classModel.postDeclarationBlock.statements += jsAssignment(memberRef, implMemberRef).makeStmt() + classModel.postDeclarationBlock.statements += jsAssignment(memberRef, implMemberRef).makeStmt() + } } - } } return Pair(memberRef, null) diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/JsIntrinsicTransformers.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/JsIntrinsicTransformers.kt index c0d43a72d80..cd25b8e2367 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/JsIntrinsicTransformers.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/JsIntrinsicTransformers.kt @@ -6,9 +6,7 @@ package org.jetbrains.kotlin.ir.backend.js.transformers.irToJs import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext -import org.jetbrains.kotlin.ir.backend.js.utils.JsGenerationContext -import org.jetbrains.kotlin.ir.backend.js.utils.Namer -import org.jetbrains.kotlin.ir.backend.js.utils.emptyScope +import org.jetbrains.kotlin.ir.backend.js.utils.* import org.jetbrains.kotlin.ir.backend.js.utils.getClassRef import org.jetbrains.kotlin.ir.declarations.IrClass import org.jetbrains.kotlin.ir.declarations.IrConstructor @@ -232,45 +230,14 @@ class JsIntrinsicTransformers(backendContext: JsIrBackendContext) { val suspendInvokeTransform: (IrCall, JsGenerationContext) -> JsExpression = { call, context: JsGenerationContext -> // Because it is intrinsic, we know everything about this function // There is callable reference as extension receiver - val invokeFun = (call.extensionReceiver as IrCall) - .getValueArgument(0)!! - .type - .getClass()!! - .declarations - .filterIsInstance() - .single { it.name.asString() == "invoke" } + val invokeFun = invokeFunForLambda(call) val jsInvokeFunName = context.getNameForMemberFunction(invokeFun) - val jsExtensionReceiver = call.extensionReceiver?.accept(IrElementToJsExpressionTransformer(), context)!! as JsInvocation + val jsExtensionReceiver = call.extensionReceiver?.accept(IrElementToJsExpressionTransformer(), context)!! val args = translateCallArguments(call, context) - val jsArgsForClosureFun = args.mapIndexed { index, _ -> JsName("${"$"}p$index") } - // Function to make closure for invoke to avoid losing this - jsExtensionReceiver.arguments[0] = JsInvocation( - JsNameRef( - Namer.BIND_FUNCTION, - JsFunction( - emptyScope, - JsBlock( - JsReturn( - JsInvocation( - JsNameRef( - jsInvokeFunName, - jsExtensionReceiver.arguments[0] - ), - jsArgsForClosureFun.map { it.makeRef() } - ) - ) - ), - "Function to make closure for invoke to avoid losing this" - ).also { func -> - func.parameters.addAll(jsArgsForClosureFun.map { JsParameter(it) }) - } - ), JsThisRef() - ) - - JsInvocation(jsExtensionReceiver, args) + JsInvocation(JsNameRef(jsInvokeFunName, jsExtensionReceiver), args) } add(intrinsics.jsInvokeSuspendSuperType, suspendInvokeTransform) diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/utils/misc.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/utils/misc.kt index 85cdf894e5d..56562b20c26 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/utils/misc.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/utils/misc.kt @@ -18,9 +18,8 @@ import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl import org.jetbrains.kotlin.ir.expressions.impl.IrVarargImpl import org.jetbrains.kotlin.ir.types.IrType +import org.jetbrains.kotlin.ir.types.getClass import org.jetbrains.kotlin.ir.types.isNullableAny -import org.jetbrains.kotlin.ir.types.isUnit -import org.jetbrains.kotlin.ir.util.isEffectivelyExternal import org.jetbrains.kotlin.ir.util.isEffectivelyExternal import org.jetbrains.kotlin.ir.util.isTopLevelDeclaration import org.jetbrains.kotlin.name.Name @@ -118,4 +117,12 @@ fun IrBody.prependFunctionCall( fun IrDeclaration.isImportedFromModuleOnly(): Boolean { return isTopLevel && isEffectivelyExternal() && (getJsModule() != null && !isJsNonModule() || (parent as? IrAnnotationContainer)?.getJsModule() != null) -} \ No newline at end of file +} + +fun invokeFunForLambda(call: IrCall) = + call.extensionReceiver!! + .type + .getClass()!! + .declarations + .filterIsInstance() + .single { it.name.asString() == "invoke" } \ No newline at end of file diff --git a/compiler/testData/codegen/box/coroutines/featureIntersection/suspendFunctionAsSupertypeIsCheckWithArity.kt b/compiler/testData/codegen/box/coroutines/featureIntersection/suspendFunctionAsSupertypeIsCheckWithArity.kt index d6ff9d58ff4..26496916827 100644 --- a/compiler/testData/codegen/box/coroutines/featureIntersection/suspendFunctionAsSupertypeIsCheckWithArity.kt +++ b/compiler/testData/codegen/box/coroutines/featureIntersection/suspendFunctionAsSupertypeIsCheckWithArity.kt @@ -1,6 +1,6 @@ // KJS_WITH_FULL_RUNTIME -// TARGET_BACKEND: JS -// IGNORE_BACKEND: JS +// IGNORE_BACKEND: JS, JVM, JVM_IR +// IGNORE_BACKEND_FIR: JVM_IR // !LANGUAGE: +SuspendFunctionAsSupertype import kotlin.coroutines.* diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java index 26569c7d5b1..65e51517466 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java @@ -10109,6 +10109,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { runTest("compiler/testData/codegen/box/coroutines/featureIntersection/suspendFunctionAsSupertypeIsCheck.kt"); } + @Test + @TestMetadata("suspendFunctionAsSupertypeIsCheckWithArity.kt") + public void testSuspendFunctionAsSupertypeIsCheckWithArity() throws Exception { + runTest("compiler/testData/codegen/box/coroutines/featureIntersection/suspendFunctionAsSupertypeIsCheckWithArity.kt"); + } + @Test @TestMetadata("suspendFunctionIsAs.kt") public void testSuspendFunctionIsAs() throws Exception { diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java index ef67ae22a7e..60b547f5070 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java @@ -10205,6 +10205,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes runTest("compiler/testData/codegen/box/coroutines/featureIntersection/suspendFunctionAsSupertypeIsCheck.kt"); } + @Test + @TestMetadata("suspendFunctionAsSupertypeIsCheckWithArity.kt") + public void testSuspendFunctionAsSupertypeIsCheckWithArity() throws Exception { + runTest("compiler/testData/codegen/box/coroutines/featureIntersection/suspendFunctionAsSupertypeIsCheckWithArity.kt"); + } + @Test @TestMetadata("suspendFunctionIsAs.kt") public void testSuspendFunctionIsAs() throws Exception { diff --git a/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index 69369b6a579..0abb71943c3 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -7883,6 +7883,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes runTest("compiler/testData/codegen/box/coroutines/featureIntersection/suspendFunctionAsSupertypeIsCheck.kt"); } + @TestMetadata("suspendFunctionAsSupertypeIsCheckWithArity.kt") + public void ignoreSuspendFunctionAsSupertypeIsCheckWithArity() throws Exception { + runTest("compiler/testData/codegen/box/coroutines/featureIntersection/suspendFunctionAsSupertypeIsCheckWithArity.kt"); + } + private void runTest(String testDataFilePath) throws Exception { KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM, testDataFilePath); } diff --git a/libraries/stdlib/js-ir/src/kotlin/coroutines_13/IntrinsicsJs.kt b/libraries/stdlib/js-ir/src/kotlin/coroutines_13/IntrinsicsJs.kt index 453f862d3b5..893e2b8e1a3 100644 --- a/libraries/stdlib/js-ir/src/kotlin/coroutines_13/IntrinsicsJs.kt +++ b/libraries/stdlib/js-ir/src/kotlin/coroutines_13/IntrinsicsJs.kt @@ -74,7 +74,7 @@ public actual inline fun (suspend () -> T).startCoroutineUninterceptedOrRetu ): Any? { val a = this.asDynamic() return if (jsTypeOf(a) == "function") a(completion) - else ::invoke.invokeSuspendSuperType(completion) + else this.invokeSuspendSuperType(completion) } /** @@ -97,7 +97,7 @@ public actual inline fun (suspend R.() -> T).startCoroutineUninterceptedO ): Any? { val a = this.asDynamic() return if (jsTypeOf(a) == "function") a(receiver, completion) - else ::invoke.invokeSuspendSuperTypeWithReceiver(receiver, completion) + else this.invokeSuspendSuperTypeWithReceiver(receiver, completion) } @InlineOnly @@ -108,7 +108,7 @@ internal actual inline fun (suspend R.(P) -> T).startCoroutineUninterc ): Any? { val a = this.asDynamic() return if (jsTypeOf(a) == "function") a(receiver, param, completion) - else ::invoke.invokeSuspendSuperTypeWithReceiverAndParam(receiver, param, completion) + else this.invokeSuspendSuperTypeWithReceiverAndParam(receiver, param, completion) } /** @@ -134,7 +134,7 @@ public actual fun (suspend () -> T).createCoroutineUnintercepted( createCoroutineFromSuspendFunction(completion) { val a = this.asDynamic() if (jsTypeOf(a) == "function") a(completion) - else ::invoke.invokeSuspendSuperType(completion) + else this.invokeSuspendSuperType(completion) } /** @@ -161,7 +161,7 @@ public actual fun (suspend R.() -> T).createCoroutineUnintercepted( createCoroutineFromSuspendFunction(completion) { val a = this.asDynamic() if (jsTypeOf(a) == "function") a(receiver, completion) - else ::invoke.invokeSuspendSuperTypeWithReceiver(receiver, completion) + else this.invokeSuspendSuperTypeWithReceiver(receiver, completion) } /**