[JS_IR] Enum constructor copy parameters with mapping by index

Previously mapping was by name, and there was clash in case of user
parameters named 'name' or 'ordinal'

^KT-39186 fixed
This commit is contained in:
Ilya Goncharov
2020-10-22 14:45:45 +03:00
parent 2790bc1105
commit 4479bf0933
9 changed files with 67 additions and 7 deletions
@@ -11095,6 +11095,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
runTest("compiler/testData/codegen/box/enum/enumCompanionInit.kt"); runTest("compiler/testData/codegen/box/enum/enumCompanionInit.kt");
} }
@TestMetadata("enumConstructorParameterClashWithDefaults.kt")
public void testEnumConstructorParameterClashWithDefaults() throws Exception {
runTest("compiler/testData/codegen/box/enum/enumConstructorParameterClashWithDefaults.kt");
}
@TestMetadata("enumEntryMembers.kt") @TestMetadata("enumEntryMembers.kt")
public void testEnumEntryMembers() throws Exception { public void testEnumEntryMembers() throws Exception {
runTest("compiler/testData/codegen/box/enum/enumEntryMembers.kt"); runTest("compiler/testData/codegen/box/enum/enumEntryMembers.kt");
@@ -95,6 +95,11 @@ class EnumClassConstructorLowering(val context: JsCommonBackendContext) : Declar
private var IrClass.correspondingEntry by context.mapping.enumClassToCorrespondingEnumEntry private var IrClass.correspondingEntry by context.mapping.enumClassToCorrespondingEnumEntry
private var IrValueDeclaration.valueParameter by context.mapping.enumConstructorOldToNewValueParameters private var IrValueDeclaration.valueParameter by context.mapping.enumConstructorOldToNewValueParameters
private val additionalParameters = listOf(
"name" to context.irBuiltIns.stringType,
"ordinal" to context.irBuiltIns.intType
)
override fun transformFlat(declaration: IrDeclaration): List<IrDeclaration>? { override fun transformFlat(declaration: IrDeclaration): List<IrDeclaration>? {
(declaration.parent as? IrClass)?.let { irClass -> (declaration.parent as? IrClass)?.let { irClass ->
if (!irClass.isEnumClass || irClass.isExpect || irClass.isEffectivelyExternal()) return null if (!irClass.isEnumClass || irClass.isExpect || irClass.isEffectivelyExternal()) return null
@@ -120,8 +125,9 @@ class EnumClassConstructorLowering(val context: JsCommonBackendContext) : Declar
returnType = enumConstructor.returnType returnType = enumConstructor.returnType
}.apply { }.apply {
parent = enumClass parent = enumClass
valueParameters += JsIrBuilder.buildValueParameter(this, "name", 0, context.irBuiltIns.stringType) additionalParameters.forEachIndexed { index, (name, type) ->
valueParameters += JsIrBuilder.buildValueParameter(this, "ordinal", 1, context.irBuiltIns.intType) valueParameters += JsIrBuilder.buildValueParameter(this, name, index, type)
}
copyParameterDeclarationsFrom(enumConstructor) copyParameterDeclarationsFrom(enumConstructor)
val newConstructor = this val newConstructor = this
@@ -143,8 +149,7 @@ class EnumClassConstructorLowering(val context: JsCommonBackendContext) : Declar
val oldParameters = enumConstructor.valueParameters val oldParameters = enumConstructor.valueParameters
val newParameters = valueParameters val newParameters = valueParameters
oldParameters.forEach { old -> oldParameters.forEach { old ->
// TODO Match by index? val new = newParameters.single { it.index == old.index + additionalParameters.size }
val new = newParameters.single { it.name == old.name }
old.valueParameter = new old.valueParameter = new
old.defaultValue?.let { default -> old.defaultValue?.let { default ->
@@ -235,7 +240,7 @@ class EnumClassConstructorBodyTransformer(val context: JsCommonBackendContext) :
} }
override fun visitDelegatingConstructorCall(expression: IrDelegatingConstructorCall): IrExpression { override fun visitDelegatingConstructorCall(expression: IrDelegatingConstructorCall): IrExpression {
val delegatingConstructor = expression.symbol.owner. let { it.newConstructor ?: it } val delegatingConstructor = expression.symbol.owner.let { it.newConstructor ?: it }
return builder.irDelegatingConstructorCall(delegatingConstructor).apply { return builder.irDelegatingConstructorCall(delegatingConstructor).apply {
var valueArgIdx = 0 var valueArgIdx = 0
@@ -426,7 +431,7 @@ class EnumClassCreateInitializerLowering(val context: JsIrBackendContext) : Decl
} }
} }
class EnumEntryCreateGetInstancesFunsLowering(val context: JsIrBackendContext): DeclarationTransformer { class EnumEntryCreateGetInstancesFunsLowering(val context: JsIrBackendContext) : DeclarationTransformer {
private var IrEnumEntry.correspondingField by context.mapping.enumEntryToCorrespondingField private var IrEnumEntry.correspondingField by context.mapping.enumEntryToCorrespondingField
private var IrClass.initEntryInstancesFun: IrSimpleFunction? by context.mapping.enumClassToInitEntryInstancesFun private var IrClass.initEntryInstancesFun: IrSimpleFunction? by context.mapping.enumClassToInitEntryInstancesFun
@@ -472,7 +477,7 @@ class EnumEntryCreateGetInstancesFunsLowering(val context: JsIrBackendContext):
} }
} }
class EnumSyntheticFunctionsLowering(val context: JsIrBackendContext): DeclarationTransformer { class EnumSyntheticFunctionsLowering(val context: JsIrBackendContext) : DeclarationTransformer {
private var IrEnumEntry.getInstanceFun by context.mapping.enumEntryToGetInstanceFun private var IrEnumEntry.getInstanceFun by context.mapping.enumEntryToGetInstanceFun
@@ -0,0 +1,20 @@
enum class A(
name: String,
ordinal: Int
) {
FOO("foo", 4),
BAR("bar", 5);
val testName = name
val testOrdinal = ordinal
}
fun box(): String {
val fooName = A.FOO.testName == "foo"
val fooOrdinal = A.FOO.testOrdinal == 4
val barName = A.BAR.testName == "bar"
val barOrdinal = A.BAR.testOrdinal == 5
return if (fooName && fooOrdinal && barName && barOrdinal) "OK" else "fail"
}
@@ -12495,6 +12495,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
runTest("compiler/testData/codegen/box/enum/enumCompanionInit.kt"); runTest("compiler/testData/codegen/box/enum/enumCompanionInit.kt");
} }
@TestMetadata("enumConstructorParameterClashWithDefaults.kt")
public void testEnumConstructorParameterClashWithDefaults() throws Exception {
runTest("compiler/testData/codegen/box/enum/enumConstructorParameterClashWithDefaults.kt");
}
@TestMetadata("enumEntryMembers.kt") @TestMetadata("enumEntryMembers.kt")
public void testEnumEntryMembers() throws Exception { public void testEnumEntryMembers() throws Exception {
runTest("compiler/testData/codegen/box/enum/enumEntryMembers.kt"); runTest("compiler/testData/codegen/box/enum/enumEntryMembers.kt");
@@ -12495,6 +12495,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
runTest("compiler/testData/codegen/box/enum/enumCompanionInit.kt"); runTest("compiler/testData/codegen/box/enum/enumCompanionInit.kt");
} }
@TestMetadata("enumConstructorParameterClashWithDefaults.kt")
public void testEnumConstructorParameterClashWithDefaults() throws Exception {
runTest("compiler/testData/codegen/box/enum/enumConstructorParameterClashWithDefaults.kt");
}
@TestMetadata("enumEntryMembers.kt") @TestMetadata("enumEntryMembers.kt")
public void testEnumEntryMembers() throws Exception { public void testEnumEntryMembers() throws Exception {
runTest("compiler/testData/codegen/box/enum/enumEntryMembers.kt"); runTest("compiler/testData/codegen/box/enum/enumEntryMembers.kt");
@@ -11095,6 +11095,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
runTest("compiler/testData/codegen/box/enum/enumCompanionInit.kt"); runTest("compiler/testData/codegen/box/enum/enumCompanionInit.kt");
} }
@TestMetadata("enumConstructorParameterClashWithDefaults.kt")
public void testEnumConstructorParameterClashWithDefaults() throws Exception {
runTest("compiler/testData/codegen/box/enum/enumConstructorParameterClashWithDefaults.kt");
}
@TestMetadata("enumEntryMembers.kt") @TestMetadata("enumEntryMembers.kt")
public void testEnumEntryMembers() throws Exception { public void testEnumEntryMembers() throws Exception {
runTest("compiler/testData/codegen/box/enum/enumEntryMembers.kt"); runTest("compiler/testData/codegen/box/enum/enumEntryMembers.kt");
@@ -9510,6 +9510,11 @@ public class IrJsCodegenBoxES6TestGenerated extends AbstractIrJsCodegenBoxES6Tes
runTest("compiler/testData/codegen/box/enum/enumCompanionInit.kt"); runTest("compiler/testData/codegen/box/enum/enumCompanionInit.kt");
} }
@TestMetadata("enumConstructorParameterClashWithDefaults.kt")
public void testEnumConstructorParameterClashWithDefaults() throws Exception {
runTest("compiler/testData/codegen/box/enum/enumConstructorParameterClashWithDefaults.kt");
}
@TestMetadata("enumEntryMembers.kt") @TestMetadata("enumEntryMembers.kt")
public void testEnumEntryMembers() throws Exception { public void testEnumEntryMembers() throws Exception {
runTest("compiler/testData/codegen/box/enum/enumEntryMembers.kt"); runTest("compiler/testData/codegen/box/enum/enumEntryMembers.kt");
@@ -9510,6 +9510,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
runTest("compiler/testData/codegen/box/enum/enumCompanionInit.kt"); runTest("compiler/testData/codegen/box/enum/enumCompanionInit.kt");
} }
@TestMetadata("enumConstructorParameterClashWithDefaults.kt")
public void testEnumConstructorParameterClashWithDefaults() throws Exception {
runTest("compiler/testData/codegen/box/enum/enumConstructorParameterClashWithDefaults.kt");
}
@TestMetadata("enumEntryMembers.kt") @TestMetadata("enumEntryMembers.kt")
public void testEnumEntryMembers() throws Exception { public void testEnumEntryMembers() throws Exception {
runTest("compiler/testData/codegen/box/enum/enumEntryMembers.kt"); runTest("compiler/testData/codegen/box/enum/enumEntryMembers.kt");
@@ -9510,6 +9510,11 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
runTest("compiler/testData/codegen/box/enum/enumCompanionInit.kt"); runTest("compiler/testData/codegen/box/enum/enumCompanionInit.kt");
} }
@TestMetadata("enumConstructorParameterClashWithDefaults.kt")
public void testEnumConstructorParameterClashWithDefaults() throws Exception {
runTest("compiler/testData/codegen/box/enum/enumConstructorParameterClashWithDefaults.kt");
}
@TestMetadata("enumEntryMembers.kt") @TestMetadata("enumEntryMembers.kt")
public void testEnumEntryMembers() throws Exception { public void testEnumEntryMembers() throws Exception {
runTest("compiler/testData/codegen/box/enum/enumEntryMembers.kt"); runTest("compiler/testData/codegen/box/enum/enumEntryMembers.kt");