[JS IR] Review remarks
- Use intrinsic on this - Enqueue invoke for DCE - Change transform - Ignore instead of target backend ^KT-46204 fixed
This commit is contained in:
+6
@@ -10205,6 +10205,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
|||||||
runTest("compiler/testData/codegen/box/coroutines/featureIntersection/suspendFunctionAsSupertypeIsCheck.kt");
|
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
|
@Test
|
||||||
@TestMetadata("suspendFunctionIsAs.kt")
|
@TestMetadata("suspendFunctionIsAs.kt")
|
||||||
public void testSuspendFunctionIsAs() throws Exception {
|
public void testSuspendFunctionIsAs() throws Exception {
|
||||||
|
|||||||
@@ -22,8 +22,8 @@ import org.jetbrains.kotlin.ir.util.*
|
|||||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
||||||
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
|
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
|
||||||
import org.jetbrains.kotlin.ir.visitors.acceptVoid
|
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.JSConfigurationKeys
|
||||||
|
import org.jetbrains.kotlin.js.config.RuntimeDiagnostic
|
||||||
import org.jetbrains.kotlin.utils.addIfNotNull
|
import org.jetbrains.kotlin.utils.addIfNotNull
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
@@ -458,6 +458,12 @@ fun usefulDeclarations(
|
|||||||
val klass = arg.getClass()
|
val klass = arg.getClass()
|
||||||
constructedClasses.addIfNotNull(klass)
|
constructedClasses.addIfNotNull(klass)
|
||||||
}
|
}
|
||||||
|
context.intrinsics.jsInvokeSuspendSuperType,
|
||||||
|
context.intrinsics.jsInvokeSuspendSuperTypeWithReceiver,
|
||||||
|
context.intrinsics.jsInvokeSuspendSuperTypeWithReceiverAndParam -> {
|
||||||
|
invokeFunForLambda(expression)
|
||||||
|
.enqueue("intrinsic: suspendSuperType")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+12
-9
@@ -6,6 +6,7 @@
|
|||||||
package org.jetbrains.kotlin.ir.backend.js.transformers.irToJs
|
package org.jetbrains.kotlin.ir.backend.js.transformers.irToJs
|
||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
|
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.export.isExported
|
||||||
import org.jetbrains.kotlin.ir.backend.js.utils.*
|
import org.jetbrains.kotlin.ir.backend.js.utils.*
|
||||||
import org.jetbrains.kotlin.ir.declarations.*
|
import org.jetbrains.kotlin.ir.declarations.*
|
||||||
@@ -162,19 +163,21 @@ class JsClassGenerator(private val irClass: IrClass, val context: JsGenerationCo
|
|||||||
// interface II : I
|
// interface II : I
|
||||||
// II.prototype.foo = I.prototype.foo
|
// II.prototype.foo = I.prototype.foo
|
||||||
if (!irClass.isInterface) {
|
if (!irClass.isInterface) {
|
||||||
declaration.realOverrideTarget.let {
|
declaration.collectRealOverrides()
|
||||||
val implClassDeclaration = it.parent as IrClass
|
.find { it.modality != Modality.ABSTRACT }
|
||||||
|
?.let {
|
||||||
|
val implClassDeclaration = it.parent as IrClass
|
||||||
|
|
||||||
if (implClassDeclaration.shouldCopyFrom() && !implClassDeclaration.defaultType.isFunctionType()) {
|
if (implClassDeclaration.shouldCopyFrom()) {
|
||||||
val implMethodName = context.getNameForMemberFunction(it)
|
val implMethodName = context.getNameForMemberFunction(it)
|
||||||
val implClassName = context.getNameForClass(implClassDeclaration)
|
val implClassName = context.getNameForClass(implClassDeclaration)
|
||||||
|
|
||||||
val implClassPrototype = prototypeOf(implClassName.makeRef())
|
val implClassPrototype = prototypeOf(implClassName.makeRef())
|
||||||
val implMemberRef = JsNameRef(implMethodName, implClassPrototype)
|
val implMemberRef = JsNameRef(implMethodName, implClassPrototype)
|
||||||
|
|
||||||
classModel.postDeclarationBlock.statements += jsAssignment(memberRef, implMemberRef).makeStmt()
|
classModel.postDeclarationBlock.statements += jsAssignment(memberRef, implMemberRef).makeStmt()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return Pair(memberRef, null)
|
return Pair(memberRef, null)
|
||||||
|
|||||||
+4
-37
@@ -6,9 +6,7 @@
|
|||||||
package org.jetbrains.kotlin.ir.backend.js.transformers.irToJs
|
package org.jetbrains.kotlin.ir.backend.js.transformers.irToJs
|
||||||
|
|
||||||
import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext
|
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.*
|
||||||
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.getClassRef
|
import org.jetbrains.kotlin.ir.backend.js.utils.getClassRef
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrConstructor
|
import org.jetbrains.kotlin.ir.declarations.IrConstructor
|
||||||
@@ -232,45 +230,14 @@ class JsIntrinsicTransformers(backendContext: JsIrBackendContext) {
|
|||||||
val suspendInvokeTransform: (IrCall, JsGenerationContext) -> JsExpression = { call, context: JsGenerationContext ->
|
val suspendInvokeTransform: (IrCall, JsGenerationContext) -> JsExpression = { call, context: JsGenerationContext ->
|
||||||
// Because it is intrinsic, we know everything about this function
|
// Because it is intrinsic, we know everything about this function
|
||||||
// There is callable reference as extension receiver
|
// There is callable reference as extension receiver
|
||||||
val invokeFun = (call.extensionReceiver as IrCall)
|
val invokeFun = invokeFunForLambda(call)
|
||||||
.getValueArgument(0)!!
|
|
||||||
.type
|
|
||||||
.getClass()!!
|
|
||||||
.declarations
|
|
||||||
.filterIsInstance<IrSimpleFunction>()
|
|
||||||
.single { it.name.asString() == "invoke" }
|
|
||||||
|
|
||||||
val jsInvokeFunName = context.getNameForMemberFunction(invokeFun)
|
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 args = translateCallArguments(call, context)
|
||||||
val jsArgsForClosureFun = args.mapIndexed { index, _ -> JsName("${"$"}p$index") }
|
|
||||||
|
|
||||||
// Function to make closure for invoke to avoid losing this
|
JsInvocation(JsNameRef(jsInvokeFunName, jsExtensionReceiver), args)
|
||||||
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)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
add(intrinsics.jsInvokeSuspendSuperType, suspendInvokeTransform)
|
add(intrinsics.jsInvokeSuspendSuperType, suspendInvokeTransform)
|
||||||
|
|||||||
@@ -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.IrCallImpl
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrVarargImpl
|
import org.jetbrains.kotlin.ir.expressions.impl.IrVarargImpl
|
||||||
import org.jetbrains.kotlin.ir.types.IrType
|
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.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.isEffectivelyExternal
|
||||||
import org.jetbrains.kotlin.ir.util.isTopLevelDeclaration
|
import org.jetbrains.kotlin.ir.util.isTopLevelDeclaration
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
@@ -119,3 +118,11 @@ fun IrBody.prependFunctionCall(
|
|||||||
fun IrDeclaration.isImportedFromModuleOnly(): Boolean {
|
fun IrDeclaration.isImportedFromModuleOnly(): Boolean {
|
||||||
return isTopLevel && isEffectivelyExternal() && (getJsModule() != null && !isJsNonModule() || (parent as? IrAnnotationContainer)?.getJsModule() != null)
|
return isTopLevel && isEffectivelyExternal() && (getJsModule() != null && !isJsNonModule() || (parent as? IrAnnotationContainer)?.getJsModule() != null)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun invokeFunForLambda(call: IrCall) =
|
||||||
|
call.extensionReceiver!!
|
||||||
|
.type
|
||||||
|
.getClass()!!
|
||||||
|
.declarations
|
||||||
|
.filterIsInstance<IrSimpleFunction>()
|
||||||
|
.single { it.name.asString() == "invoke" }
|
||||||
+2
-2
@@ -1,6 +1,6 @@
|
|||||||
// KJS_WITH_FULL_RUNTIME
|
// KJS_WITH_FULL_RUNTIME
|
||||||
// TARGET_BACKEND: JS
|
// IGNORE_BACKEND: JS, JVM, JVM_IR
|
||||||
// IGNORE_BACKEND: JS
|
// IGNORE_BACKEND_FIR: JVM_IR
|
||||||
// !LANGUAGE: +SuspendFunctionAsSupertype
|
// !LANGUAGE: +SuspendFunctionAsSupertype
|
||||||
|
|
||||||
import kotlin.coroutines.*
|
import kotlin.coroutines.*
|
||||||
|
|||||||
+6
@@ -10109,6 +10109,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
|||||||
runTest("compiler/testData/codegen/box/coroutines/featureIntersection/suspendFunctionAsSupertypeIsCheck.kt");
|
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
|
@Test
|
||||||
@TestMetadata("suspendFunctionIsAs.kt")
|
@TestMetadata("suspendFunctionIsAs.kt")
|
||||||
public void testSuspendFunctionIsAs() throws Exception {
|
public void testSuspendFunctionIsAs() throws Exception {
|
||||||
|
|||||||
+6
@@ -10205,6 +10205,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
|||||||
runTest("compiler/testData/codegen/box/coroutines/featureIntersection/suspendFunctionAsSupertypeIsCheck.kt");
|
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
|
@Test
|
||||||
@TestMetadata("suspendFunctionIsAs.kt")
|
@TestMetadata("suspendFunctionIsAs.kt")
|
||||||
public void testSuspendFunctionIsAs() throws Exception {
|
public void testSuspendFunctionIsAs() throws Exception {
|
||||||
|
|||||||
+5
@@ -7883,6 +7883,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
|||||||
runTest("compiler/testData/codegen/box/coroutines/featureIntersection/suspendFunctionAsSupertypeIsCheck.kt");
|
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 {
|
private void runTest(String testDataFilePath) throws Exception {
|
||||||
KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM, testDataFilePath);
|
KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM, testDataFilePath);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ public actual inline fun <T> (suspend () -> T).startCoroutineUninterceptedOrRetu
|
|||||||
): Any? {
|
): Any? {
|
||||||
val a = this.asDynamic()
|
val a = this.asDynamic()
|
||||||
return if (jsTypeOf(a) == "function") a(completion)
|
return if (jsTypeOf(a) == "function") a(completion)
|
||||||
else ::invoke.invokeSuspendSuperType(completion)
|
else this.invokeSuspendSuperType(completion)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -97,7 +97,7 @@ public actual inline fun <R, T> (suspend R.() -> T).startCoroutineUninterceptedO
|
|||||||
): Any? {
|
): Any? {
|
||||||
val a = this.asDynamic()
|
val a = this.asDynamic()
|
||||||
return if (jsTypeOf(a) == "function") a(receiver, completion)
|
return if (jsTypeOf(a) == "function") a(receiver, completion)
|
||||||
else ::invoke.invokeSuspendSuperTypeWithReceiver(receiver, completion)
|
else this.invokeSuspendSuperTypeWithReceiver(receiver, completion)
|
||||||
}
|
}
|
||||||
|
|
||||||
@InlineOnly
|
@InlineOnly
|
||||||
@@ -108,7 +108,7 @@ internal actual inline fun <R, P, T> (suspend R.(P) -> T).startCoroutineUninterc
|
|||||||
): Any? {
|
): Any? {
|
||||||
val a = this.asDynamic()
|
val a = this.asDynamic()
|
||||||
return if (jsTypeOf(a) == "function") a(receiver, param, completion)
|
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 <T> (suspend () -> T).createCoroutineUnintercepted(
|
|||||||
createCoroutineFromSuspendFunction(completion) {
|
createCoroutineFromSuspendFunction(completion) {
|
||||||
val a = this.asDynamic()
|
val a = this.asDynamic()
|
||||||
if (jsTypeOf(a) == "function") a(completion)
|
if (jsTypeOf(a) == "function") a(completion)
|
||||||
else ::invoke.invokeSuspendSuperType(completion)
|
else this.invokeSuspendSuperType(completion)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -161,7 +161,7 @@ public actual fun <R, T> (suspend R.() -> T).createCoroutineUnintercepted(
|
|||||||
createCoroutineFromSuspendFunction(completion) {
|
createCoroutineFromSuspendFunction(completion) {
|
||||||
val a = this.asDynamic()
|
val a = this.asDynamic()
|
||||||
if (jsTypeOf(a) == "function") a(receiver, completion)
|
if (jsTypeOf(a) == "function") a(receiver, completion)
|
||||||
else ::invoke.invokeSuspendSuperTypeWithReceiver(receiver, completion)
|
else this.invokeSuspendSuperTypeWithReceiver(receiver, completion)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user