[JS IR BE] Support call super with default parameters
This commit is contained in:
@@ -153,6 +153,14 @@ fun IrClass.addSimpleDelegatingConstructor(
|
|||||||
val IrCall.isSuspend get() = (symbol.owner as? IrSimpleFunction)?.isSuspend == true
|
val IrCall.isSuspend get() = (symbol.owner as? IrSimpleFunction)?.isSuspend == true
|
||||||
val IrFunctionReference.isSuspend get() = (symbol.owner as? IrSimpleFunction)?.isSuspend == true
|
val IrFunctionReference.isSuspend get() = (symbol.owner as? IrSimpleFunction)?.isSuspend == true
|
||||||
|
|
||||||
|
val IrSimpleFunction.isOverridable: Boolean
|
||||||
|
get() = visibility != Visibilities.PRIVATE && modality != Modality.FINAL && (parent as? IrClass)?.isFinalClass != true
|
||||||
|
|
||||||
|
val IrSimpleFunction.isOverridableOrOverrides: Boolean get() = isOverridable || overriddenSymbols.isNotEmpty()
|
||||||
|
|
||||||
|
val IrClass.isFinalClass: Boolean
|
||||||
|
get() = modality == Modality.FINAL && kind != ClassKind.ENUM_CLASS
|
||||||
|
|
||||||
fun IrValueParameter.copyTo(
|
fun IrValueParameter.copyTo(
|
||||||
irFunction: IrFunction,
|
irFunction: IrFunction,
|
||||||
origin: IrDeclarationOrigin = this.origin,
|
origin: IrDeclarationOrigin = this.origin,
|
||||||
|
|||||||
+49
-22
@@ -6,10 +6,7 @@
|
|||||||
package org.jetbrains.kotlin.backend.common.lower
|
package org.jetbrains.kotlin.backend.common.lower
|
||||||
|
|
||||||
import org.jetbrains.kotlin.backend.common.*
|
import org.jetbrains.kotlin.backend.common.*
|
||||||
import org.jetbrains.kotlin.backend.common.descriptors.WrappedClassConstructorDescriptor
|
import org.jetbrains.kotlin.backend.common.descriptors.*
|
||||||
import org.jetbrains.kotlin.backend.common.descriptors.WrappedSimpleFunctionDescriptor
|
|
||||||
import org.jetbrains.kotlin.backend.common.descriptors.WrappedValueParameterDescriptor
|
|
||||||
import org.jetbrains.kotlin.backend.common.descriptors.synthesizedName
|
|
||||||
import org.jetbrains.kotlin.backend.common.ir.copyTo
|
import org.jetbrains.kotlin.backend.common.ir.copyTo
|
||||||
import org.jetbrains.kotlin.backend.common.ir.copyTypeParametersFrom
|
import org.jetbrains.kotlin.backend.common.ir.copyTypeParametersFrom
|
||||||
import org.jetbrains.kotlin.backend.common.ir.ir2string
|
import org.jetbrains.kotlin.backend.common.ir.ir2string
|
||||||
@@ -39,7 +36,7 @@ import org.jetbrains.kotlin.name.Name
|
|||||||
|
|
||||||
// TODO: fix expect/actual default parameters
|
// TODO: fix expect/actual default parameters
|
||||||
|
|
||||||
open class DefaultArgumentStubGenerator constructor(val context: CommonBackendContext, private val skipInlineMethods: Boolean = true) :
|
open class DefaultArgumentStubGenerator constructor(open val context: CommonBackendContext, private val skipInlineMethods: Boolean = true) :
|
||||||
DeclarationContainerLoweringPass {
|
DeclarationContainerLoweringPass {
|
||||||
override fun lower(irDeclarationContainer: IrDeclarationContainer) {
|
override fun lower(irDeclarationContainer: IrDeclarationContainer) {
|
||||||
irDeclarationContainer.transformDeclarationsFlat { memberDeclaration ->
|
irDeclarationContainer.transformDeclarationsFlat { memberDeclaration ->
|
||||||
@@ -50,7 +47,7 @@ open class DefaultArgumentStubGenerator constructor(val context: CommonBackendCo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private val symbols = context.ir.symbols
|
private val symbols get() = context.ir.symbols
|
||||||
|
|
||||||
private fun lower(irFunction: IrFunction): List<IrFunction> {
|
private fun lower(irFunction: IrFunction): List<IrFunction> {
|
||||||
if (!irFunction.needsDefaultArgumentsLowering(skipInlineMethods))
|
if (!irFunction.needsDefaultArgumentsLowering(skipInlineMethods))
|
||||||
@@ -124,8 +121,8 @@ open class DefaultArgumentStubGenerator constructor(val context: CommonBackendCo
|
|||||||
variables[valueParameter] = temporaryVariable
|
variables[valueParameter] = temporaryVariable
|
||||||
}
|
}
|
||||||
|
|
||||||
if (irFunction is IrConstructor) {
|
when (irFunction) {
|
||||||
+IrDelegatingConstructorCallImpl(
|
is IrConstructor -> +IrDelegatingConstructorCallImpl(
|
||||||
startOffset = irFunction.startOffset,
|
startOffset = irFunction.startOffset,
|
||||||
endOffset = irFunction.endOffset,
|
endOffset = irFunction.endOffset,
|
||||||
type = context.irBuiltIns.unitType,
|
type = context.irBuiltIns.unitType,
|
||||||
@@ -139,16 +136,8 @@ open class DefaultArgumentStubGenerator constructor(val context: CommonBackendCo
|
|||||||
|
|
||||||
params.forEachIndexed { i, variable -> putValueArgument(i, irGet(variable)) }
|
params.forEachIndexed { i, variable -> putValueArgument(i, irGet(variable)) }
|
||||||
}
|
}
|
||||||
} else {
|
is IrSimpleFunction -> +irReturn(dispatchToImplementation(irFunction, newIrFunction, params))
|
||||||
+irReturn(irCall(irFunction).apply {
|
else -> error("Unknown function declaration")
|
||||||
newIrFunction.typeParameters.forEachIndexed { i, param ->
|
|
||||||
putTypeArgument(i, param.defaultType)
|
|
||||||
}
|
|
||||||
dispatchReceiver = newIrFunction.dispatchReceiverParameter?.let { irGet(it) }
|
|
||||||
extensionReceiver = newIrFunction.extensionReceiverParameter?.let { irGet(it) }
|
|
||||||
|
|
||||||
params.forEachIndexed { i, variable -> putValueArgument(i, irGet(variable)) }
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Remove default argument initializers.
|
// Remove default argument initializers.
|
||||||
@@ -158,6 +147,42 @@ open class DefaultArgumentStubGenerator constructor(val context: CommonBackendCo
|
|||||||
return listOf(irFunction, newIrFunction)
|
return listOf(irFunction, newIrFunction)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun IrBlockBodyBuilder.dispatchToImplementation(
|
||||||
|
irFunction: IrSimpleFunction,
|
||||||
|
newIrFunction: IrFunction,
|
||||||
|
params: MutableList<IrVariable>
|
||||||
|
): IrExpression {
|
||||||
|
val dispatchCall = irCall(irFunction).apply {
|
||||||
|
newIrFunction.typeParameters.forEachIndexed { i, param ->
|
||||||
|
putTypeArgument(i, param.defaultType)
|
||||||
|
}
|
||||||
|
dispatchReceiver = newIrFunction.dispatchReceiverParameter?.let { irGet(it) }
|
||||||
|
extensionReceiver = newIrFunction.extensionReceiverParameter?.let { irGet(it) }
|
||||||
|
|
||||||
|
params.forEachIndexed { i, variable -> putValueArgument(i, irGet(variable)) }
|
||||||
|
}
|
||||||
|
return if (needSpecialDispatch(irFunction)) {
|
||||||
|
val handlerDeclaration = newIrFunction.valueParameters.last()
|
||||||
|
// if $handler != null $handler(a, b, c) else foo(a, b, c)
|
||||||
|
irIfThenElse(
|
||||||
|
irFunction.returnType,
|
||||||
|
irEqualsNull(irGet(handlerDeclaration)),
|
||||||
|
dispatchCall,
|
||||||
|
generateHandleCall(handlerDeclaration, irFunction, newIrFunction, params)
|
||||||
|
)
|
||||||
|
} else dispatchCall
|
||||||
|
}
|
||||||
|
|
||||||
|
protected open fun needSpecialDispatch(irFunction: IrSimpleFunction) = false
|
||||||
|
protected open fun IrBlockBodyBuilder.generateHandleCall(
|
||||||
|
handlerDeclaration: IrValueParameter,
|
||||||
|
oldIrFunction: IrFunction,
|
||||||
|
newIrFunction: IrFunction,
|
||||||
|
params: MutableList<IrVariable>
|
||||||
|
): IrExpression {
|
||||||
|
assert(needSpecialDispatch(oldIrFunction as IrSimpleFunction))
|
||||||
|
error("This method should be overridden")
|
||||||
|
}
|
||||||
|
|
||||||
private fun log(msg: () -> String) = context.log { "DEFAULT-REPLACER: ${msg()}" }
|
private fun log(msg: () -> String) = context.log { "DEFAULT-REPLACER: ${msg()}" }
|
||||||
}
|
}
|
||||||
@@ -171,6 +196,8 @@ private fun maskParameter(function: IrFunction, number: Int) =
|
|||||||
private fun markerParameterDeclaration(function: IrFunction) =
|
private fun markerParameterDeclaration(function: IrFunction) =
|
||||||
function.valueParameters.single { it.name == kConstructorMarkerName }
|
function.valueParameters.single { it.name == kConstructorMarkerName }
|
||||||
|
|
||||||
|
val DEFAULT_DISPATCH_CALL = object : IrStatementOriginImpl("DEFAULT_DISPATCH_CALL") {}
|
||||||
|
|
||||||
open class DefaultParameterInjector constructor(
|
open class DefaultParameterInjector constructor(
|
||||||
val context: CommonBackendContext,
|
val context: CommonBackendContext,
|
||||||
private val skipInline: Boolean = true
|
private val skipInline: Boolean = true
|
||||||
@@ -192,12 +219,11 @@ open class DefaultParameterInjector constructor(
|
|||||||
return expression
|
return expression
|
||||||
|
|
||||||
val (symbolForCall, params) = parametersForCall(expression)
|
val (symbolForCall, params) = parametersForCall(expression)
|
||||||
symbolForCall as IrConstructorSymbol
|
|
||||||
return IrDelegatingConstructorCallImpl(
|
return IrDelegatingConstructorCallImpl(
|
||||||
startOffset = expression.startOffset,
|
startOffset = expression.startOffset,
|
||||||
endOffset = expression.endOffset,
|
endOffset = expression.endOffset,
|
||||||
type = context.irBuiltIns.unitType,
|
type = context.irBuiltIns.unitType,
|
||||||
symbol = symbolForCall,
|
symbol = symbolForCall as IrConstructorSymbol,
|
||||||
descriptor = symbolForCall.descriptor,
|
descriptor = symbolForCall.descriptor,
|
||||||
typeArgumentsCount = symbolForCall.owner.typeParameters.size
|
typeArgumentsCount = symbolForCall.owner.typeParameters.size
|
||||||
)
|
)
|
||||||
@@ -209,7 +235,6 @@ open class DefaultParameterInjector constructor(
|
|||||||
}
|
}
|
||||||
dispatchReceiver = expression.dispatchReceiver
|
dispatchReceiver = expression.dispatchReceiver
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitCall(expression: IrCall): IrExpression {
|
override fun visitCall(expression: IrCall): IrExpression {
|
||||||
@@ -238,7 +263,9 @@ open class DefaultParameterInjector constructor(
|
|||||||
type = symbol.owner.returnType,
|
type = symbol.owner.returnType,
|
||||||
symbol = symbol,
|
symbol = symbol,
|
||||||
descriptor = descriptor,
|
descriptor = descriptor,
|
||||||
typeArgumentsCount = expression.typeArgumentsCount
|
typeArgumentsCount = expression.typeArgumentsCount,
|
||||||
|
origin = DEFAULT_DISPATCH_CALL,
|
||||||
|
superQualifierSymbol = expression.superQualifierSymbol
|
||||||
)
|
)
|
||||||
.apply {
|
.apply {
|
||||||
this.copyTypeArgumentsFrom(expression)
|
this.copyTypeArgumentsFrom(expression)
|
||||||
|
|||||||
@@ -241,6 +241,8 @@ class JsIntrinsics(private val irBuiltIns: IrBuiltIns, val context: JsIrBackendC
|
|||||||
|
|
||||||
val jsArraySlice = unOp("slice")
|
val jsArraySlice = unOp("slice")
|
||||||
|
|
||||||
|
val jsBind = defineJsBindIntrinsic()
|
||||||
|
|
||||||
// TODO move to IntrinsifyCallsLowering
|
// TODO move to IntrinsifyCallsLowering
|
||||||
val doNotIntrinsifyAnnotationSymbol = context.symbolTable.referenceClass(context.getInternalClass("DoNotIntrinsify"))
|
val doNotIntrinsifyAnnotationSymbol = context.symbolTable.referenceClass(context.getInternalClass("DoNotIntrinsify"))
|
||||||
|
|
||||||
@@ -302,6 +304,19 @@ class JsIntrinsics(private val irBuiltIns: IrBuiltIns, val context: JsIrBackendC
|
|||||||
externalPackageFragment.declarations += it
|
externalPackageFragment.declarations += it
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun defineJsBindIntrinsic() =
|
||||||
|
JsIrBuilder.buildFunction(
|
||||||
|
"\$jsBind\$",
|
||||||
|
returnType = irBuiltIns.anyNType,
|
||||||
|
parent = externalPackageFragment,
|
||||||
|
origin = JsLoweredDeclarationOrigin.JS_INTRINSICS_STUB
|
||||||
|
).also {
|
||||||
|
listOf("receiver", "target").mapIndexedTo(it.valueParameters) { i, p ->
|
||||||
|
JsIrBuilder.buildValueParameter(p, i, irBuiltIns.anyType).also { v -> v.parent = it }
|
||||||
|
}
|
||||||
|
externalPackageFragment.declarations += it
|
||||||
|
}
|
||||||
|
|
||||||
private fun defineSetJSPropertyIntrinsic() =
|
private fun defineSetJSPropertyIntrinsic() =
|
||||||
JsIrBuilder.buildFunction(
|
JsIrBuilder.buildFunction(
|
||||||
"\$setJSProperty\$",
|
"\$setJSProperty\$",
|
||||||
|
|||||||
@@ -182,7 +182,7 @@ private val CallableReferenceLoweringPhase = makeJsPhase(
|
|||||||
)
|
)
|
||||||
|
|
||||||
private val DefaultArgumentStubGeneratorPhase = makeJsPhase(
|
private val DefaultArgumentStubGeneratorPhase = makeJsPhase(
|
||||||
{ context, module -> DefaultArgumentStubGenerator(context).lower(module) },
|
{ context, module -> JsDefaultArgumentStubGenerator(context).lower(module) },
|
||||||
name = "DefaultArgumentStubGenerator",
|
name = "DefaultArgumentStubGenerator",
|
||||||
description = "Generate synthetic stubs for functions with default parameter values"
|
description = "Generate synthetic stubs for functions with default parameter values"
|
||||||
)
|
)
|
||||||
@@ -200,6 +200,12 @@ private val DefaultParameterCleanerPhase = makeJsPhase(
|
|||||||
description = "Clean default parameters up"
|
description = "Clean default parameters up"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
private val JsDefaultCallbackGeneratorPhase = makeJsPhase(
|
||||||
|
{ context, module -> JsDefaultCallbackGenerator(context).lower(module) },
|
||||||
|
name = "JsDefaultCallbackGenerator",
|
||||||
|
description = "Build binding for super calls with default parameters"
|
||||||
|
)
|
||||||
|
|
||||||
private val VarargLoweringPhase = makeJsPhase(
|
private val VarargLoweringPhase = makeJsPhase(
|
||||||
{ context, module -> VarargLowering(context).lower(module) },
|
{ context, module -> VarargLowering(context).lower(module) },
|
||||||
name = "VarargLowering",
|
name = "VarargLowering",
|
||||||
@@ -342,6 +348,7 @@ val jsPhases = listOf(
|
|||||||
DefaultArgumentStubGeneratorPhase,
|
DefaultArgumentStubGeneratorPhase,
|
||||||
DefaultParameterInjectorPhase,
|
DefaultParameterInjectorPhase,
|
||||||
DefaultParameterCleanerPhase,
|
DefaultParameterCleanerPhase,
|
||||||
|
JsDefaultCallbackGeneratorPhase,
|
||||||
VarargLoweringPhase,
|
VarargLoweringPhase,
|
||||||
PropertiesLoweringPhase,
|
PropertiesLoweringPhase,
|
||||||
InitializersLoweringPhase,
|
InitializersLoweringPhase,
|
||||||
|
|||||||
+109
@@ -0,0 +1,109 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||||
|
* that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.ir.backend.js.lower
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.backend.common.BodyLoweringPass
|
||||||
|
import org.jetbrains.kotlin.backend.common.ir.isOverridableOrOverrides
|
||||||
|
import org.jetbrains.kotlin.backend.common.lower.DefaultArgumentStubGenerator
|
||||||
|
import org.jetbrains.kotlin.backend.common.lower.DEFAULT_DISPATCH_CALL
|
||||||
|
import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext
|
||||||
|
import org.jetbrains.kotlin.ir.builders.IrBlockBodyBuilder
|
||||||
|
import org.jetbrains.kotlin.ir.builders.irCall
|
||||||
|
import org.jetbrains.kotlin.ir.builders.irGet
|
||||||
|
import org.jetbrains.kotlin.ir.builders.irImplicitCast
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.IrValueParameter
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.IrVariable
|
||||||
|
import org.jetbrains.kotlin.ir.expressions.*
|
||||||
|
import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl
|
||||||
|
import org.jetbrains.kotlin.ir.expressions.impl.IrFunctionReferenceImpl
|
||||||
|
import org.jetbrains.kotlin.ir.util.deepCopyWithSymbols
|
||||||
|
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||||
|
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||||
|
import org.jetbrains.kotlin.name.FqName
|
||||||
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
|
||||||
|
class JsDefaultArgumentStubGenerator(override val context: JsIrBackendContext) : DefaultArgumentStubGenerator(context, true) {
|
||||||
|
|
||||||
|
override fun needSpecialDispatch(irFunction: IrSimpleFunction) = irFunction.isOverridableOrOverrides
|
||||||
|
|
||||||
|
override fun IrBlockBodyBuilder.generateHandleCall(
|
||||||
|
handlerDeclaration: IrValueParameter,
|
||||||
|
oldIrFunction: IrFunction,
|
||||||
|
newIrFunction: IrFunction,
|
||||||
|
params: MutableList<IrVariable>
|
||||||
|
): IrExpression {
|
||||||
|
val paramCount = oldIrFunction.valueParameters.size
|
||||||
|
val invokeFunctionN = resolveInvoke(paramCount)
|
||||||
|
// NOTE: currently we do not have a syntax to perform super extension call
|
||||||
|
// but in case we have such functionality in the future the logic bellow should be fixed
|
||||||
|
return irCall(invokeFunctionN, IrStatementOrigin.INVOKE).apply {
|
||||||
|
dispatchReceiver = irImplicitCast(irGet(handlerDeclaration), invokeFunctionN.dispatchReceiverParameter!!.type)
|
||||||
|
assert(newIrFunction.extensionReceiverParameter == null)
|
||||||
|
params.forEachIndexed { i, variable -> putValueArgument(i, irGet(variable)) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun resolveInvoke(paramCount: Int): IrSimpleFunction {
|
||||||
|
assert(paramCount > 0)
|
||||||
|
val fqn = FqName.fromSegments(listOf("kotlin", "Function$paramCount"))
|
||||||
|
val functionKlass = context.run { symbolTable.referenceClass(getClass(fqn)) }.owner
|
||||||
|
return functionKlass.declarations.filterIsInstance<IrSimpleFunction>().first { it.name == Name.identifier("invoke") }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val BIND_CALL = object : IrStatementOriginImpl("BIND_CALL") {}
|
||||||
|
|
||||||
|
class JsDefaultCallbackGenerator(val context: JsIrBackendContext): BodyLoweringPass {
|
||||||
|
override fun lower(irBody: IrBody) {
|
||||||
|
irBody.transformChildrenVoid(object : IrElementTransformerVoid() {
|
||||||
|
override fun visitCall(expression: IrCall): IrExpression {
|
||||||
|
super.visitCall(expression)
|
||||||
|
if (expression.origin != DEFAULT_DISPATCH_CALL || expression.superQualifierSymbol == null) return expression
|
||||||
|
|
||||||
|
val binding = buildBoundSuperCall(expression)
|
||||||
|
|
||||||
|
expression.putValueArgument(expression.valueArgumentsCount - 1, binding)
|
||||||
|
|
||||||
|
return expression
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun buildBoundSuperCall(irCall: IrCall): IrExpression {
|
||||||
|
|
||||||
|
val originalFunction = context.ir.defaultParameterDeclarationsCache.entries.first { it.value == irCall.symbol.owner }.key
|
||||||
|
|
||||||
|
val reference = irCall.run {
|
||||||
|
IrFunctionReferenceImpl(
|
||||||
|
startOffset,
|
||||||
|
endOffset,
|
||||||
|
context.irBuiltIns.anyType,
|
||||||
|
originalFunction.symbol,
|
||||||
|
originalFunction.descriptor,
|
||||||
|
0,
|
||||||
|
BIND_CALL
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return irCall.run {
|
||||||
|
IrCallImpl(
|
||||||
|
startOffset,
|
||||||
|
endOffset,
|
||||||
|
context.irBuiltIns.anyType,
|
||||||
|
context.intrinsics.jsBind.symbol,
|
||||||
|
context.intrinsics.jsBind.descriptor,
|
||||||
|
BIND_CALL,
|
||||||
|
superQualifierSymbol
|
||||||
|
)
|
||||||
|
}.apply {
|
||||||
|
putValueArgument(0, irCall.dispatchReceiver?.deepCopyWithSymbols())
|
||||||
|
putValueArgument(1, reference)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+15
@@ -11,6 +11,7 @@ import org.jetbrains.kotlin.ir.backend.js.utils.Namer
|
|||||||
import org.jetbrains.kotlin.ir.declarations.IrConstructor
|
import org.jetbrains.kotlin.ir.declarations.IrConstructor
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrCall
|
import org.jetbrains.kotlin.ir.expressions.IrCall
|
||||||
|
import org.jetbrains.kotlin.ir.expressions.IrFunctionReference
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||||
import org.jetbrains.kotlin.ir.types.classifierOrFail
|
import org.jetbrains.kotlin.ir.types.classifierOrFail
|
||||||
import org.jetbrains.kotlin.ir.util.getInlineClassBackingField
|
import org.jetbrains.kotlin.ir.util.getInlineClassBackingField
|
||||||
@@ -201,6 +202,20 @@ class JsIntrinsicTransformers(backendContext: JsIrBackendContext) {
|
|||||||
val fieldName = context.getNameForSymbol(field.symbol)
|
val fieldName = context.getNameForSymbol(field.symbol)
|
||||||
JsNameRef(fieldName, arg)
|
JsNameRef(fieldName, arg)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
add(intrinsics.jsBind) { call: IrCall, context: JsGenerationContext ->
|
||||||
|
val receiver = call.getValueArgument(0)!!
|
||||||
|
val reference = call.getValueArgument(1) as IrFunctionReference
|
||||||
|
val superClass = call.superQualifierSymbol!!
|
||||||
|
|
||||||
|
val jsReceiver = receiver.accept(IrElementToJsExpressionTransformer(), context)
|
||||||
|
val functionName = context.getNameForSymbol(reference.symbol)
|
||||||
|
val superName = context.getNameForSymbol(superClass).makeRef()
|
||||||
|
val qPrototype = JsNameRef(functionName, prototypeOf(superName))
|
||||||
|
val bindRef = JsNameRef(Namer.BIND_FUNCTION, qPrototype)
|
||||||
|
|
||||||
|
JsInvocation(bindRef, jsReceiver)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ object Namer {
|
|||||||
|
|
||||||
val CALL_FUNCTION = "call"
|
val CALL_FUNCTION = "call"
|
||||||
val APPLY_FUNCTION = "apply"
|
val APPLY_FUNCTION = "apply"
|
||||||
|
val BIND_FUNCTION = "bind"
|
||||||
|
|
||||||
val SLICE_FUNCTION = "slice"
|
val SLICE_FUNCTION = "slice"
|
||||||
val CONCAT_FUNCTION = "concat"
|
val CONCAT_FUNCTION = "concat"
|
||||||
|
|||||||
@@ -214,6 +214,9 @@ fun IrBuilderWithScope.irCall(callee: IrFunctionSymbol, descriptor: FunctionDesc
|
|||||||
fun IrBuilderWithScope.irCall(callee: IrFunction): IrCall =
|
fun IrBuilderWithScope.irCall(callee: IrFunction): IrCall =
|
||||||
irCall(callee.symbol, callee.descriptor, callee.returnType)
|
irCall(callee.symbol, callee.descriptor, callee.returnType)
|
||||||
|
|
||||||
|
fun IrBuilderWithScope.irCall(callee: IrFunction, origin: IrStatementOrigin): IrCall =
|
||||||
|
IrCallImpl(startOffset, endOffset, callee.returnType, callee.symbol, callee.descriptor, origin)
|
||||||
|
|
||||||
fun IrBuilderWithScope.irDelegatingConstructorCall(callee: IrConstructor): IrDelegatingConstructorCall =
|
fun IrBuilderWithScope.irDelegatingConstructorCall(callee: IrConstructor): IrDelegatingConstructorCall =
|
||||||
IrDelegatingConstructorCallImpl(startOffset, endOffset, callee.returnType, callee.symbol, callee.descriptor, callee.typeParameters.size)
|
IrDelegatingConstructorCallImpl(startOffset, endOffset, callee.returnType, callee.symbol, callee.descriptor, callee.typeParameters.size)
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
// WITH_RUNTIME
|
// WITH_RUNTIME
|
||||||
// WITH_COROUTINES
|
// WITH_COROUTINES
|
||||||
// COMMON_COROUTINES_TEST
|
// COMMON_COROUTINES_TEST
|
||||||
// DONT_RUN_GENERATED_CODE: JS_IR
|
|
||||||
import helpers.*
|
import helpers.*
|
||||||
import COROUTINES_PACKAGE.*
|
import COROUTINES_PACKAGE.*
|
||||||
import COROUTINES_PACKAGE.intrinsics.*
|
import COROUTINES_PACKAGE.intrinsics.*
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
// !LANGUAGE: +MultiPlatformProjects
|
// !LANGUAGE: +MultiPlatformProjects
|
||||||
// IGNORE_BACKEND: NATIVE
|
// IGNORE_BACKEND: NATIVE
|
||||||
// IGNORE_BACKEND: JVM_IR
|
// IGNORE_BACKEND: JVM_IR
|
||||||
// IGNORE_BACKEND: JS_IR
|
|
||||||
// IGNORE_BACKEND: JVM
|
// IGNORE_BACKEND: JVM
|
||||||
|
|
||||||
// FILE: lib.kt
|
// FILE: lib.kt
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND: JVM_IR
|
|
||||||
// IGNORE_BACKEND: JS_IR
|
// IGNORE_BACKEND: JS_IR
|
||||||
// TODO: muted automatically, investigate should it be ran for JS or not
|
// TODO: muted automatically, investigate should it be ran for JS or not
|
||||||
// IGNORE_BACKEND: JS, NATIVE
|
// IGNORE_BACKEND: JS, NATIVE
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND: JS_IR
|
|
||||||
// EXPECTED_REACHABLE_NODES: 1299
|
// EXPECTED_REACHABLE_NODES: 1299
|
||||||
package foo
|
package foo
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND: JS_IR
|
|
||||||
// EXPECTED_REACHABLE_NODES: 1302
|
// EXPECTED_REACHABLE_NODES: 1302
|
||||||
package foo
|
package foo
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user