From da7ff5b868e3fed2447aae0f372967b099dd45d8 Mon Sep 17 00:00:00 2001 From: Sergej Jaskiewicz Date: Mon, 30 May 2022 18:55:06 +0300 Subject: [PATCH] [JS IR] Fix replacing super.toString() call with a runtime function call #KT-52553 Fixed --- .../js/lower/calls/MethodsOfAnyCallsTransformer.kt | 14 +++++++++++--- js/js.translator/testData/box/builtins/toString.kt | 14 +++++++++++++- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/calls/MethodsOfAnyCallsTransformer.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/calls/MethodsOfAnyCallsTransformer.kt index f3247f96e33..636a41e82a6 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/calls/MethodsOfAnyCallsTransformer.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/calls/MethodsOfAnyCallsTransformer.kt @@ -6,7 +6,6 @@ package org.jetbrains.kotlin.ir.backend.js.lower.calls import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext -import org.jetbrains.kotlin.ir.util.irCall import org.jetbrains.kotlin.ir.expressions.IrCall import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.expressions.IrFunctionAccessExpression @@ -14,8 +13,8 @@ import org.jetbrains.kotlin.ir.types.IrDynamicType import org.jetbrains.kotlin.ir.types.isAny import org.jetbrains.kotlin.ir.types.isArray import org.jetbrains.kotlin.ir.types.isString +import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.ir.util.isFakeOverriddenFromAny -import org.jetbrains.kotlin.ir.util.isSuperToAny import org.jetbrains.kotlin.name.Name @@ -64,12 +63,21 @@ class MethodsOfAnyCallsTransformer(context: JsIrBackendContext) : CallsTransform private fun shouldReplaceToStringWithRuntimeCall(call: IrFunctionAccessExpression): Boolean { val function = call.symbol.owner - if (function.valueParameters.size != 0 && function.name.asString() != "toString" ) + if (function.valueParameters.isNotEmpty() && function.name.asString() != "toString" ) return false if (function.extensionReceiverParameter != null) return false + if (call is IrCall) { + val superQualifierSymbol = call.superQualifierSymbol + if (superQualifierSymbol != null && + !superQualifierSymbol.owner.isInterface && + superQualifierSymbol != intrinsics.anyClassSymbol) { + return false + } + } + val receiverParameterType = function.dispatchReceiverParameter?.type ?: return false return receiverParameterType.run { diff --git a/js/js.translator/testData/box/builtins/toString.kt b/js/js.translator/testData/box/builtins/toString.kt index fb467fcc8d2..14d29bf64e9 100644 --- a/js/js.translator/testData/box/builtins/toString.kt +++ b/js/js.translator/testData/box/builtins/toString.kt @@ -7,6 +7,17 @@ class A { class B +// KT-52553 +interface Parser +abstract class AbstractNamedParser(val name: String): Parser { + override fun toString(): String = "$name ${super.toString()}" +} +abstract class PredicateTokenParser(name: String): Parser, AbstractNamedParser(name) { +} +data class TokenEqualityParser(val expected: Int): PredicateTokenParser("$expected") { + override fun toString(): String = super.toString() +} + fun box(): String { assertEquals(A().toString(), "42") assertEquals(B().toString(), "[object Object]") @@ -16,5 +27,6 @@ fun box(): String { assertEquals("123".toString(), "123") assertEquals((123 as Any).toString(), "123") assertEquals(null.toString(), "null") + assertEquals(TokenEqualityParser(2).toString(), "2 [object Object]") return "OK" -} \ No newline at end of file +}