[FIR2IR] Correctly generate delegating constructor call for secondary constructors in enums

^KT-56927 Fxied
This commit is contained in:
Dmitriy Novozhilov
2023-04-27 12:19:58 +03:00
committed by Space Team
parent a818c543a9
commit 7958a9debd
9 changed files with 20 additions and 17 deletions
@@ -347,7 +347,18 @@ internal class ClassMemberGenerator(
val irConstructorSymbol = declarationStorage.getIrFunctionSymbol(constructorSymbol) as IrConstructorSymbol val irConstructorSymbol = declarationStorage.getIrFunctionSymbol(constructorSymbol) as IrConstructorSymbol
val typeArguments = constructedTypeRef.coneType.fullyExpandedType(session).typeArguments val typeArguments = constructedTypeRef.coneType.fullyExpandedType(session).typeArguments
val constructor = constructorSymbol.fir val constructor = constructorSymbol.fir
if (constructor.isFromEnumClass || constructor.returnTypeRef.isEnum) { /*
* We should generate enum constructor call only if it is used to create new enum entry (so it's super constructor call)
* If it is this constructor call that we are facing secondary constructor of enum, and should generate
* regular delegating constructor call
*
* enum class Some(val x: Int) {
* A(); // <---- super call, IrEnumConstructorCall
*
* constructor() : this(10) // <---- this call, IrDelegatingConstructorCall
* }
*/
if ((constructor.isFromEnumClass || constructor.returnTypeRef.isEnum) && this.isSuper) {
IrEnumConstructorCallImpl( IrEnumConstructorCallImpl(
startOffset, endOffset, startOffset, endOffset,
constructedIrType, constructedIrType,
@@ -1,5 +1,3 @@
// IGNORE_BACKEND_K2: JS_IR, NATIVE
enum class Test { enum class Test {
A(0), A(0),
B; B;
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_K2: JS_IR, NATIVE
enum class Test(val x: Int, val str: String) { enum class Test(val x: Int, val str: String) {
OK; OK;
constructor(x: Int = 0) : this(x, "OK") constructor(x: Int = 0) : this(x, "OK")
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_K2: JS_IR, NATIVE
enum class Test(val x: Int, val str: String) { enum class Test(val x: Int, val str: String) {
OK; OK;
constructor(vararg xs: Int) : this(xs.size + 42, "OK") constructor(vararg xs: Int) : this(xs.size + 42, "OK")
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_K2: JS_IR, NATIVE
package test package test
enum class My(val s: String) { enum class My(val s: String) {
-1
View File
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_K2: JS_IR, NATIVE
// WITH_STDLIB // WITH_STDLIB
import kotlin.test.assertEquals import kotlin.test.assertEquals
@@ -1,5 +1,3 @@
// IGNORE_BACKEND_K2: JS_IR, NATIVE
enum class A1(val prop1: String) { enum class A1(val prop1: String) {
X("asd"), X("asd"),
Y() { Y() {
@@ -160,7 +160,7 @@ FILE fqName:<root> fileName:/enumWithMultipleCtors.kt
CONSTRUCTOR visibility:private <> (x:kotlin.Int) returnType:<root>.A CONSTRUCTOR visibility:private <> (x:kotlin.Int) returnType:<root>.A
VALUE_PARAMETER name:x index:0 type:kotlin.Int VALUE_PARAMETER name:x index:0 type:kotlin.Int
BLOCK_BODY BLOCK_BODY
ENUM_CONSTRUCTOR_CALL 'private constructor <init> (arg: kotlin.String) declared in <root>.A' DELEGATING_CONSTRUCTOR_CALL 'private constructor <init> (arg: kotlin.String) declared in <root>.A'
arg: CALL 'public final fun toString (): kotlin.String declared in kotlin.Int' type=kotlin.String origin=null arg: CALL 'public final fun toString (): kotlin.String declared in kotlin.Int' type=kotlin.String origin=null
$this: GET_VAR 'x: kotlin.Int declared in <root>.A.<init>' type=kotlin.Int origin=null $this: GET_VAR 'x: kotlin.Int declared in <root>.A.<init>' type=kotlin.Int origin=null
CALL 'public final fun <set-prop3> (<set-?>: kotlin.String): kotlin.Unit declared in <root>.A' type=kotlin.Unit origin=EQ CALL 'public final fun <set-prop3> (<set-?>: kotlin.String): kotlin.Unit declared in <root>.A' type=kotlin.Unit origin=EQ
@@ -23,7 +23,7 @@ FILE fqName:<root> fileName:/enumWithSecondaryCtor.kt
ENUM_CONSTRUCTOR_CALL 'private constructor <init> () declared in <root>.Test0' ENUM_CONSTRUCTOR_CALL 'private constructor <init> () declared in <root>.Test0'
CONSTRUCTOR visibility:private <> () returnType:<root>.Test0 CONSTRUCTOR visibility:private <> () returnType:<root>.Test0
BLOCK_BODY BLOCK_BODY
ENUM_CONSTRUCTOR_CALL 'private constructor <init> (x: kotlin.Int) [primary] declared in <root>.Test0' DELEGATING_CONSTRUCTOR_CALL 'private constructor <init> (x: kotlin.Int) [primary] declared in <root>.Test0'
x: CONST Int type=kotlin.Int value=0 x: CONST Int type=kotlin.Int value=0
FUN ENUM_CLASS_SPECIAL_MEMBER name:values visibility:public modality:FINAL <> () returnType:kotlin.Array<<root>.Test0> FUN ENUM_CLASS_SPECIAL_MEMBER name:values visibility:public modality:FINAL <> () returnType:kotlin.Array<<root>.Test0>
SYNTHETIC_BODY kind=ENUM_VALUES SYNTHETIC_BODY kind=ENUM_VALUES
@@ -102,7 +102,7 @@ FILE fqName:<root> fileName:/enumWithSecondaryCtor.kt
x: CONST Int type=kotlin.Int value=1 x: CONST Int type=kotlin.Int value=1
CONSTRUCTOR visibility:private <> () returnType:<root>.Test1 CONSTRUCTOR visibility:private <> () returnType:<root>.Test1
BLOCK_BODY BLOCK_BODY
ENUM_CONSTRUCTOR_CALL 'private constructor <init> (x: kotlin.Int) [primary] declared in <root>.Test1' DELEGATING_CONSTRUCTOR_CALL 'private constructor <init> (x: kotlin.Int) [primary] declared in <root>.Test1'
x: CONST Int type=kotlin.Int value=0 x: CONST Int type=kotlin.Int value=0
FUN ENUM_CLASS_SPECIAL_MEMBER name:values visibility:public modality:FINAL <> () returnType:kotlin.Array<<root>.Test1> FUN ENUM_CLASS_SPECIAL_MEMBER name:values visibility:public modality:FINAL <> () returnType:kotlin.Array<<root>.Test1>
SYNTHETIC_BODY kind=ENUM_VALUES SYNTHETIC_BODY kind=ENUM_VALUES
@@ -303,7 +303,7 @@ FILE fqName:<root> fileName:/enumWithSecondaryCtor.kt
$this: VALUE_PARAMETER name:<this> type:kotlin.Enum<E of kotlin.Enum> $this: VALUE_PARAMETER name:<this> type:kotlin.Enum<E of kotlin.Enum>
CONSTRUCTOR visibility:private <> () returnType:<root>.Test2 CONSTRUCTOR visibility:private <> () returnType:<root>.Test2
BLOCK_BODY BLOCK_BODY
ENUM_CONSTRUCTOR_CALL 'private constructor <init> (x: kotlin.Int) [primary] declared in <root>.Test2' DELEGATING_CONSTRUCTOR_CALL 'private constructor <init> (x: kotlin.Int) [primary] declared in <root>.Test2'
x: CONST Int type=kotlin.Int value=0 x: CONST Int type=kotlin.Int value=0
FUN name:foo visibility:public modality:ABSTRACT <> ($this:<root>.Test2) returnType:kotlin.Unit FUN name:foo visibility:public modality:ABSTRACT <> ($this:<root>.Test2) returnType:kotlin.Unit
$this: VALUE_PARAMETER name:<this> type:<root>.Test2 $this: VALUE_PARAMETER name:<this> type:<root>.Test2