[K/JS] Fix private constructor delegating inside single class with ES6 mode ^KT-59335 Fixed

This commit is contained in:
Artem Kobzar
2023-06-20 11:07:08 +00:00
committed by Space Team
parent 79dbacb621
commit 66bdb9ce79
11 changed files with 51 additions and 8 deletions
@@ -189,12 +189,13 @@ object JsIrBuilder {
isVar: Boolean = false, isVar: Boolean = false,
isConst: Boolean = false, isConst: Boolean = false,
isLateinit: Boolean = false, isLateinit: Boolean = false,
initializer: IrExpression? = null initializer: IrExpression? = null,
origin: IrDeclarationOrigin = SYNTHESIZED_DECLARATION
): IrVariable = buildVariable( ): IrVariable = buildVariable(
parent, parent,
UNDEFINED_OFFSET, UNDEFINED_OFFSET,
UNDEFINED_OFFSET, UNDEFINED_OFFSET,
SYNTHESIZED_DECLARATION, origin,
Name.identifier(name), Name.identifier(name),
type, type,
isVar, isVar,
@@ -44,12 +44,10 @@ class ES6ConstructorCallLowering(val context: JsIrBackendContext) : BodyLowering
} }
} }
val isDelegatingCall = val isDelegatingCall = expression.isSyntheticDelegatingReplacement && currentFunction != null
expression.isSyntheticDelegatingReplacement && currentFunction != null && currentFunction.parentAsClass != irClass
val factoryFunctionCall = JsIrBuilder.buildCall( val factoryFunctionCall = JsIrBuilder.buildCall(
factoryFunction.symbol, factoryFunction.symbol,
superQualifierSymbol = irClass.symbol.takeIf { isDelegatingCall },
origin = if (isDelegatingCall) ES6_DELEGATING_CONSTRUCTOR_REPLACEMENT else JsStatementOrigins.SYNTHESIZED_STATEMENT origin = if (isDelegatingCall) ES6_DELEGATING_CONSTRUCTOR_REPLACEMENT else JsStatementOrigins.SYNTHESIZED_STATEMENT
).apply { ).apply {
copyValueArgumentsFrom(expression, factoryFunction) copyValueArgumentsFrom(expression, factoryFunction)
@@ -155,7 +155,8 @@ class ES6ConstructorLowering(val context: JsIrBackendContext) : DeclarationTrans
type = irClass.defaultType, type = irClass.defaultType,
parent = this, parent = this,
name = Namer.SYNTHETIC_RECEIVER_NAME, name = Namer.SYNTHETIC_RECEIVER_NAME,
initializer = initializer initializer = initializer,
origin = IrDeclarationOrigin.IR_TEMPORARY_VARIABLE
) )
} }
@@ -226,7 +226,9 @@ class ES6CollectPrimaryConstructorsWhichCouldBeOptimizedLowering(private val con
} }
private fun IrClass.canBeOptimized(): Boolean { private fun IrClass.canBeOptimized(): Boolean {
return superClass?.symbol != context.throwableClass && !isSubclassOfExternalClassWithRequiredBoxParameter() && !hasPrimaryDelegatedToSecondaryOrSecondaryToPrimary() return superClass?.symbol != context.throwableClass &&
!isSubclassOfExternalClassWithRequiredBoxParameter() &&
!hasPrimaryDelegatedToSecondaryOrSecondaryToPrimary()
} }
private fun IrClass.hasPrimaryDelegatedToSecondaryOrSecondaryToPrimary(): Boolean { private fun IrClass.hasPrimaryDelegatedToSecondaryOrSecondaryToPrimary(): Boolean {
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.ir.backend.js.transformers.irToJs
import org.jetbrains.kotlin.backend.common.ir.inlineFunction import org.jetbrains.kotlin.backend.common.ir.inlineFunction
import org.jetbrains.kotlin.backend.common.ir.innerInlinedBlockOrThis import org.jetbrains.kotlin.backend.common.ir.innerInlinedBlockOrThis
import org.jetbrains.kotlin.ir.backend.js.ir.JsIrBuilder
import org.jetbrains.kotlin.ir.backend.js.utils.JsGenerationContext import org.jetbrains.kotlin.ir.backend.js.utils.JsGenerationContext
import org.jetbrains.kotlin.ir.backend.js.utils.emptyScope import org.jetbrains.kotlin.ir.backend.js.utils.emptyScope
import org.jetbrains.kotlin.ir.backend.js.utils.isTheLastReturnStatementIn import org.jetbrains.kotlin.ir.backend.js.utils.isTheLastReturnStatementIn
@@ -205,7 +205,7 @@ fun translateCall(
Pair(function, superQualifier.owner) Pair(function, superQualifier.owner)
} }
if (expression.isSyntheticDelegatingReplacement || currentDispatchReceiver.canUseSuperRef(context, klass)) { if (currentDispatchReceiver.canUseSuperRef(context, klass)) {
return JsInvocation(JsNameRef(context.getNameForMemberFunction(target), JsSuperRef()), arguments) return JsInvocation(JsNameRef(context.getNameForMemberFunction(target), JsSuperRef()), arguments)
} }
@@ -4478,6 +4478,12 @@ public class BoxJsTestGenerated extends AbstractBoxJsTest {
runTest("js/js.translator/testData/box/inheritance/definitionOrder.kt"); runTest("js/js.translator/testData/box/inheritance/definitionOrder.kt");
} }
@Test
@TestMetadata("delegatingToSecondaryCtor.kt")
public void testDelegatingToSecondaryCtor() throws Exception {
runTest("js/js.translator/testData/box/inheritance/delegatingToSecondaryCtor.kt");
}
@Test @Test
@TestMetadata("fromFakeClasses.kt") @TestMetadata("fromFakeClasses.kt")
public void testFromFakeClasses() throws Exception { public void testFromFakeClasses() throws Exception {
@@ -5106,6 +5106,12 @@ public class FirJsBoxTestGenerated extends AbstractFirJsBoxTest {
runTest("js/js.translator/testData/box/inheritance/definitionOrder.kt"); runTest("js/js.translator/testData/box/inheritance/definitionOrder.kt");
} }
@Test
@TestMetadata("delegatingToSecondaryCtor.kt")
public void testDelegatingToSecondaryCtor() throws Exception {
runTest("js/js.translator/testData/box/inheritance/delegatingToSecondaryCtor.kt");
}
@Test @Test
@TestMetadata("fromFakeClasses.kt") @TestMetadata("fromFakeClasses.kt")
public void testFromFakeClasses() throws Exception { public void testFromFakeClasses() throws Exception {
@@ -5212,6 +5212,12 @@ public class IrBoxJsES6TestGenerated extends AbstractIrBoxJsES6Test {
runTest("js/js.translator/testData/box/inheritance/definitionOrder.kt"); runTest("js/js.translator/testData/box/inheritance/definitionOrder.kt");
} }
@Test
@TestMetadata("delegatingToSecondaryCtor.kt")
public void testDelegatingToSecondaryCtor() throws Exception {
runTest("js/js.translator/testData/box/inheritance/delegatingToSecondaryCtor.kt");
}
@Test @Test
@TestMetadata("fromFakeClasses.kt") @TestMetadata("fromFakeClasses.kt")
public void testFromFakeClasses() throws Exception { public void testFromFakeClasses() throws Exception {
@@ -5106,6 +5106,12 @@ public class IrBoxJsTestGenerated extends AbstractIrBoxJsTest {
runTest("js/js.translator/testData/box/inheritance/definitionOrder.kt"); runTest("js/js.translator/testData/box/inheritance/definitionOrder.kt");
} }
@Test
@TestMetadata("delegatingToSecondaryCtor.kt")
public void testDelegatingToSecondaryCtor() throws Exception {
runTest("js/js.translator/testData/box/inheritance/delegatingToSecondaryCtor.kt");
}
@Test @Test
@TestMetadata("fromFakeClasses.kt") @TestMetadata("fromFakeClasses.kt")
public void testFromFakeClasses() throws Exception { public void testFromFakeClasses() throws Exception {
@@ -0,0 +1,16 @@
// EXPECTED_REACHABLE_NODES: 1344
open class MyClass1 private constructor(val value: String) {
constructor(i: Int): this(i.toString())
}
class MyClass2 : MyClass1 {
constructor(i: Int): super(i)
}
fun test(x: Any) = x is MyClass2
fun box(): String {
val b = test(MyClass2(0))
return if (b) "OK" else "NOT OK"
}