diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsIrBackendContext.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsIrBackendContext.kt index d9a811ecc41..4d65d5db041 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsIrBackendContext.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsIrBackendContext.kt @@ -45,6 +45,8 @@ import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.resolve.scopes.MemberScope import org.jetbrains.kotlin.types.Variance import org.jetbrains.kotlin.types.isNullable +import org.jetbrains.kotlin.util.collectionUtils.filterIsInstanceMapNotNull +import org.jetbrains.kotlin.utils.addToStdlib.cast class JsIrBackendContext( val module: ModuleDescriptor, @@ -161,7 +163,13 @@ class JsIrBackendContext( return numbers + listOf(Name.identifier("String"), Name.identifier("Boolean")) } - fun getOperatorByName(name: Name, type: IrSimpleType) = operatorMap[name]?.get(type.classifier) + fun getOperatorByName(name: Name, lhsType: IrSimpleType, rhsType: IrSimpleType?) = + operatorMap[name]?.get(lhsType.classifier)?.let { candidates -> + if (rhsType == null) + candidates.singleOrNull() + else + candidates.singleOrNull { it.owner.valueParameters[0].type.cast().classifier == rhsType.classifier } + } override val coroutineSymbols = JsCommonCoroutineSymbols(symbolTable, module, this) @@ -311,17 +319,16 @@ class JsIrBackendContext( val klocalDelegateBuilder = getFunctions(FqName("kotlin.js.getLocalDelegateReference")).single().let { symbolTable.referenceSimpleFunction(it) } - private fun referenceOperators(): Map> { + private fun referenceOperators(): Map>> { val primitiveIrSymbols = irBuiltIns.primitiveIrTypes.map { it.classifierOrFail as IrClassSymbol } - - return OperatorNames.ALL.map { name -> - // TODO to replace KotlinType with IrType we need right equals on IrType - name to primitiveIrSymbols.fold(mutableMapOf()) { m, s -> - val function = s.owner.declarations.filterIsInstance().singleOrNull { it.name == name } - function?.let { m.put(s, it.symbol) } - m + return OperatorNames.ALL.associateWith { name -> + primitiveIrSymbols.associateWith { classSymbol -> + classSymbol.owner.declarations + .filterIsInstanceMapNotNull { function -> + function.symbol.takeIf { function.name == name } + } } - }.toMap() + } } private fun findProperty(memberScope: MemberScope, name: Name): List = diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/ir/IrArithBuilder.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/ir/IrArithBuilder.kt index c8cb4a167c2..08f8aaef1f3 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/ir/IrArithBuilder.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/ir/IrArithBuilder.kt @@ -16,7 +16,7 @@ class JsIrArithBuilder(val context: JsIrBackendContext) { val symbols = context.ir.symbols private fun buildBinaryOperator(name: Name, l: IrExpression, r: IrExpression): IrExpression { - val symbol = context.getOperatorByName(name, l.type as IrSimpleType) + val symbol = context.getOperatorByName(name, l.type as IrSimpleType, r.type as IrSimpleType) return JsIrBuilder.buildCall(symbol!!).apply { dispatchReceiver = l putValueArgument(0, r) @@ -24,7 +24,7 @@ class JsIrArithBuilder(val context: JsIrBackendContext) { } private fun buildUnaryOperator(name: Name, v: IrExpression): IrExpression { - val symbol = context.getOperatorByName(name, v.type as IrSimpleType)!! + val symbol = context.getOperatorByName(name, v.type as IrSimpleType, null)!! return JsIrBuilder.buildCall(symbol).apply { dispatchReceiver = v } } @@ -45,4 +45,4 @@ class JsIrArithBuilder(val context: JsIrBackendContext) { JsIrBuilder.buildIfElse(context.irBuiltIns.booleanType, l, r, JsIrBuilder.buildBoolean(context.irBuiltIns.booleanType, false)) fun oror(l: IrExpression, r: IrExpression) = // if (l) true else r JsIrBuilder.buildIfElse(context.irBuiltIns.booleanType, l, JsIrBuilder.buildBoolean(context.irBuiltIns.booleanType, true), r) -} \ No newline at end of file +}