[JS IR BE] Fix fake override functions resolve
Use signature of function 'target' (a real function that will be called instad of fake override) to make boxing/unboxing decision for return value and type parameters on call site.
This commit is contained in:
@@ -360,3 +360,5 @@ fun Scope.createTemporaryVariableWithWrappedDescriptor(
|
||||
irExpression, nameHint, isMutable, origin, descriptor
|
||||
).apply { descriptor.bind(this) }
|
||||
}
|
||||
|
||||
val IrFunction.isOverridable: Boolean get() = this is IrSimpleFunction && this.isOverridable
|
||||
|
||||
+35
-6
@@ -7,17 +7,16 @@ package org.jetbrains.kotlin.ir.backend.js.lower
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.FileLoweringPass
|
||||
import org.jetbrains.kotlin.backend.common.lower.AbstractValueUsageTransformer
|
||||
import org.jetbrains.kotlin.backend.common.utils.isPrimitiveArray
|
||||
import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext
|
||||
import org.jetbrains.kotlin.ir.backend.js.ir.JsIrBuilder
|
||||
import org.jetbrains.kotlin.ir.backend.js.utils.realOverrideTarget
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.ir.types.isNothing
|
||||
import org.jetbrains.kotlin.ir.types.makeNotNull
|
||||
import org.jetbrains.kotlin.ir.util.getInlinedClass
|
||||
import org.jetbrains.kotlin.ir.util.isInlined
|
||||
import org.jetbrains.kotlin.ir.util.isNullable
|
||||
import org.jetbrains.kotlin.ir.util.patchDeclarationParents
|
||||
import org.jetbrains.kotlin.ir.util.*
|
||||
|
||||
|
||||
// Copied and adapted from Kotlin/Native
|
||||
@@ -34,10 +33,11 @@ class AutoboxingTransformer(val context: JsIrBackendContext) : AbstractValueUsag
|
||||
|
||||
val actualType = when (this) {
|
||||
is IrCall -> {
|
||||
if (this.symbol.owner.let { it is IrSimpleFunction && it.isSuspend }) {
|
||||
val function = this.symbol.owner
|
||||
if (function.let { it is IrSimpleFunction && it.isSuspend }) {
|
||||
irBuiltIns.anyNType
|
||||
} else {
|
||||
this.symbol.owner.returnType
|
||||
function.realOverrideTarget.returnType
|
||||
}
|
||||
}
|
||||
is IrGetField -> this.symbol.owner.type
|
||||
@@ -121,6 +121,34 @@ class AutoboxingTransformer(val context: JsIrBackendContext) : AbstractValueUsag
|
||||
}
|
||||
}
|
||||
|
||||
private val IrFunctionAccessExpression.target: IrFunction
|
||||
get() = when (this) {
|
||||
is IrCall -> this.callTarget
|
||||
is IrDelegatingConstructorCall -> this.symbol.owner
|
||||
else -> TODO(this.render())
|
||||
}
|
||||
|
||||
private val IrCall.callTarget: IrFunction
|
||||
get() = symbol.owner.realOverrideTarget
|
||||
|
||||
|
||||
override fun IrExpression.useAsDispatchReceiver(expression: IrFunctionAccessExpression): IrExpression {
|
||||
return this.useAsArgument(expression.target.dispatchReceiverParameter!!)
|
||||
}
|
||||
|
||||
override fun IrExpression.useAsExtensionReceiver(expression: IrFunctionAccessExpression): IrExpression {
|
||||
return this.useAsArgument(expression.target.extensionReceiverParameter!!)
|
||||
}
|
||||
|
||||
override fun IrExpression.useAsValueArgument(
|
||||
expression: IrFunctionAccessExpression,
|
||||
parameter: IrValueParameter
|
||||
): IrExpression {
|
||||
|
||||
return this.useAsArgument(expression.target.valueParameters[parameter.index])
|
||||
}
|
||||
|
||||
|
||||
override fun IrExpression.useAsVarargElement(expression: IrVararg): IrExpression {
|
||||
return this.useAs(
|
||||
if (this.type.isInlined())
|
||||
@@ -141,3 +169,4 @@ class AutoboxingTransformer(val context: JsIrBackendContext) : AbstractValueUsag
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
+6
-5
@@ -8,11 +8,11 @@ package org.jetbrains.kotlin.ir.backend.js.transformers.irToJs
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
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.realOverrideTarget
|
||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||
import org.jetbrains.kotlin.ir.declarations.IrConstructor
|
||||
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol
|
||||
import org.jetbrains.kotlin.ir.types.IrDynamicType
|
||||
import org.jetbrains.kotlin.ir.util.isFunctionTypeOrSubtype
|
||||
import org.jetbrains.kotlin.ir.util.parentAsClass
|
||||
@@ -121,7 +121,8 @@ class IrElementToJsExpressionTransformer : BaseIrElementToJsNodeTransformer<JsEx
|
||||
}
|
||||
|
||||
override fun visitCall(expression: IrCall, context: JsGenerationContext): JsExpression {
|
||||
val symbol = expression.symbol
|
||||
val function = expression.symbol.owner.realOverrideTarget
|
||||
val symbol = function.symbol
|
||||
|
||||
context.staticContext.intrinsics[symbol]?.let {
|
||||
return it(expression, context)
|
||||
@@ -143,13 +144,13 @@ class IrElementToJsExpressionTransformer : BaseIrElementToJsNodeTransformer<JsEx
|
||||
return JsInvocation(callRef, jsDispatchReceiver?.let { listOf(it) + arguments } ?: arguments)
|
||||
}
|
||||
|
||||
return if (symbol is IrConstructorSymbol) {
|
||||
return if (function is IrConstructor) {
|
||||
// Inline class primary constructor takes a single value of to
|
||||
// initialize underlying property.
|
||||
// TODO: Support initialization block
|
||||
val klass = symbol.owner.parentAsClass
|
||||
val klass = function.parentAsClass
|
||||
if (klass.isInline) {
|
||||
assert(symbol.owner.isPrimary) {
|
||||
assert(function.isPrimary) {
|
||||
"Inline class secondary constructors must be lowered into static methods"
|
||||
}
|
||||
// Argument value constructs unboxed inline class instance
|
||||
|
||||
+3
-2
@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.backend.common.onlyIf
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
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.realOverrideTarget
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrClassifierSymbol
|
||||
@@ -105,7 +106,7 @@ class JsClassGenerator(private val irClass: IrClass, val context: JsGenerationCo
|
||||
return translatedFunction?.makeStmt()
|
||||
}
|
||||
|
||||
val memberName = context.getNameForSymbol(declaration.symbol)
|
||||
val memberName = context.getNameForSymbol(declaration.realOverrideTarget.symbol)
|
||||
val memberRef = JsNameRef(memberName, classPrototypeRef)
|
||||
|
||||
translatedFunction?.let { return jsAssignment(memberRef, it.apply { name = null }).makeStmt() }
|
||||
@@ -115,7 +116,7 @@ class JsClassGenerator(private val irClass: IrClass, val context: JsGenerationCo
|
||||
// interface II : I
|
||||
// II.prototype.foo = I.prototype.foo
|
||||
if (!irClass.isInterface) {
|
||||
declaration.resolveFakeOverride()?.let {
|
||||
declaration.realOverrideTarget.let { it ->
|
||||
var implClassDeclaration = it.parent as IrClass
|
||||
|
||||
// special case
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright 2010-2019 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.utils
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.ir.declarations.IrConstructor
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
||||
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
|
||||
import org.jetbrains.kotlin.ir.util.collectRealOverrides
|
||||
|
||||
val IrFunction.realOverrideTarget: IrFunction
|
||||
get() = when (this) {
|
||||
is IrSimpleFunction -> this.realOverrideTarget
|
||||
is IrConstructor -> this
|
||||
else -> error(this)
|
||||
}
|
||||
|
||||
val IrSimpleFunction.realOverrideTarget: IrSimpleFunction
|
||||
get(): IrSimpleFunction {
|
||||
val realOverrides = collectRealOverrides()
|
||||
return realOverrides.find { it.modality != Modality.ABSTRACT } ?: realOverrides.first()
|
||||
}
|
||||
@@ -17,11 +17,7 @@ import org.jetbrains.kotlin.ir.declarations.impl.IrValueParameterImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.*
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrTypeParameterSymbolImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrValueParameterSymbolImpl
|
||||
import org.jetbrains.kotlin.ir.types.*
|
||||
import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl
|
||||
import org.jetbrains.kotlin.ir.types.impl.makeTypeProjection
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.psiUtil.endOffset
|
||||
@@ -291,11 +287,8 @@ fun IrClass.isSubclassOf(ancestor: IrClass): Boolean {
|
||||
return this.hasAncestorInSuperTypes()
|
||||
}
|
||||
|
||||
// This implementation is from kotlin-native
|
||||
// TODO: use this implementation instead of any other
|
||||
fun IrSimpleFunction.resolveFakeOverride(): IrSimpleFunction? {
|
||||
|
||||
if (isReal) return this
|
||||
fun IrSimpleFunction.collectRealOverrides(): Set<IrSimpleFunction> {
|
||||
if (isReal) return setOf(this)
|
||||
|
||||
val visited = mutableSetOf<IrSimpleFunction>()
|
||||
val realOverrides = mutableSetOf<IrSimpleFunction>()
|
||||
@@ -324,7 +317,13 @@ fun IrSimpleFunction.resolveFakeOverride(): IrSimpleFunction? {
|
||||
visited.clear()
|
||||
realOverrides.toList().forEach { excludeRepeated(it) }
|
||||
|
||||
return realOverrides.singleOrNull { it.modality != Modality.ABSTRACT }
|
||||
return realOverrides
|
||||
}
|
||||
|
||||
// This implementation is from kotlin-native
|
||||
// TODO: use this implementation instead of any other
|
||||
fun IrSimpleFunction.resolveFakeOverride(): IrSimpleFunction? {
|
||||
return collectRealOverrides().singleOrNull { it.modality != Modality.ABSTRACT }
|
||||
}
|
||||
|
||||
fun IrField.resolveFakeOverride(): IrField? {
|
||||
|
||||
Reference in New Issue
Block a user