[FIR2IR] Correctly generate delegating constructor call for secondary constructors in enums
^KT-56927 Fxied
This commit is contained in:
committed by
Space Team
parent
a818c543a9
commit
7958a9debd
+12
-1
@@ -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;
|
||||||
@@ -14,4 +12,4 @@ fun box(): String =
|
|||||||
if (Test.A.n == Test.B.n)
|
if (Test.A.n == Test.B.n)
|
||||||
"OK"
|
"OK"
|
||||||
else
|
else
|
||||||
"Fail"
|
"Fail"
|
||||||
|
|||||||
+1
-2
@@ -1,8 +1,7 @@
|
|||||||
// 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")
|
||||||
}
|
}
|
||||||
|
|
||||||
fun box(): String =
|
fun box(): String =
|
||||||
Test.OK.str
|
Test.OK.str
|
||||||
|
|||||||
+1
-2
@@ -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")
|
||||||
@@ -8,4 +7,4 @@ fun box(): String =
|
|||||||
if (Test.OK.x == 42)
|
if (Test.OK.x == 42)
|
||||||
Test.OK.str
|
Test.OK.str
|
||||||
else
|
else
|
||||||
"Fail"
|
"Fail"
|
||||||
|
|||||||
@@ -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
-2
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND_K2: JS_IR, NATIVE
|
|
||||||
// WITH_STDLIB
|
// WITH_STDLIB
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
@@ -16,4 +15,4 @@ fun box(): String {
|
|||||||
assertEquals(TestEnumClass.ZERO.x, 0)
|
assertEquals(TestEnumClass.ZERO.x, 0)
|
||||||
|
|
||||||
return "OK"
|
return "OK"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user