KT-7897 Do not require to call enum constructor for each entry if all parameters have default values
Do not report an error on enum entry without initializer if all parameters have default values (error is still reported if there is no such constructor, or if the constructor call is ambiguous). Record resolved call on KtEnumEntry. NB is the enum entry has a corresponding subclass, we still have to generate the "default" constructor call, because FE doesn't know about the platform-specific representation of that class and its constructors. See also KT-14097, KT-15900
This commit is contained in:
+6
@@ -0,0 +1,6 @@
|
||||
enum class Test(val str: String = "OK") {
|
||||
OK
|
||||
}
|
||||
|
||||
fun box(): String =
|
||||
Test.OK.str
|
||||
@@ -0,0 +1,9 @@
|
||||
// IGNORE_BACKEND: JS
|
||||
|
||||
enum class Test(vararg xs: Int) {
|
||||
OK;
|
||||
val values = xs
|
||||
}
|
||||
|
||||
fun box(): String =
|
||||
if (Test.OK.values.size == 0) "OK" else "Fail"
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
// IGNORE_BACKEND: JS
|
||||
// see KT-14097
|
||||
|
||||
enum class Test(val x: Int, val str: String) {
|
||||
OK;
|
||||
constructor(x: Int = 0) : this(x, "OK")
|
||||
}
|
||||
|
||||
fun box(): String =
|
||||
Test.OK.str
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
// IGNORE_BACKEND: JS
|
||||
// see KT-14097
|
||||
|
||||
enum class Test(val x: Int, val str: String) {
|
||||
OK;
|
||||
constructor(vararg xs: Int) : this(xs.size + 42, "OK")
|
||||
}
|
||||
|
||||
fun box(): String =
|
||||
if (Test.OK.x == 42)
|
||||
Test.OK.str
|
||||
else
|
||||
"Fail"
|
||||
Vendored
+15
@@ -0,0 +1,15 @@
|
||||
@kotlin.Metadata
|
||||
public final class ConstructorWithDefaultArgumentsKt {
|
||||
public final static @org.jetbrains.annotations.NotNull method box(): java.lang.String
|
||||
}
|
||||
|
||||
@kotlin.Metadata
|
||||
public enum class Test {
|
||||
public final static field OK: Test
|
||||
private final @org.jetbrains.annotations.NotNull field str: java.lang.String
|
||||
protected method <init>(@java.lang.Synthetic p0: java.lang.String, @java.lang.Synthetic p1: int, @org.jetbrains.annotations.NotNull p2: java.lang.String): void
|
||||
synthetic method <init>(p0: java.lang.String, p1: int, p2: java.lang.String, p3: int, p4: kotlin.jvm.internal.DefaultConstructorMarker): void
|
||||
public final @org.jetbrains.annotations.NotNull method getStr(): java.lang.String
|
||||
public static method valueOf(p0: java.lang.String): Test
|
||||
public static method values(): Test[]
|
||||
}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
@kotlin.Metadata
|
||||
public final class ConstructorWithVarargKt {
|
||||
public final static @org.jetbrains.annotations.NotNull method box(): java.lang.String
|
||||
}
|
||||
|
||||
@kotlin.Metadata
|
||||
public enum class Test {
|
||||
public final static field OK: Test
|
||||
private final @org.jetbrains.annotations.NotNull field values: int[]
|
||||
protected method <init>(@java.lang.Synthetic p0: java.lang.String, @java.lang.Synthetic p1: int, @org.jetbrains.annotations.NotNull p2: int[]): void
|
||||
public final @org.jetbrains.annotations.NotNull method getValues(): int[]
|
||||
public static method valueOf(p0: java.lang.String): Test
|
||||
public static method values(): Test[]
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
@kotlin.Metadata
|
||||
public final class SecondaryConstructorWithDefaultArgumentsKt {
|
||||
public final static @org.jetbrains.annotations.NotNull method box(): java.lang.String
|
||||
}
|
||||
|
||||
@kotlin.Metadata
|
||||
public enum class Test {
|
||||
public final static field OK: Test
|
||||
private final @org.jetbrains.annotations.NotNull field str: java.lang.String
|
||||
private final field x: int
|
||||
protected method <init>(@java.lang.Synthetic p0: java.lang.String, @java.lang.Synthetic p1: int, p2: int, @org.jetbrains.annotations.NotNull p3: java.lang.String): void
|
||||
protected method <init>(p0: java.lang.String, p1: int, p2: int): void
|
||||
synthetic method <init>(p0: java.lang.String, p1: int, p2: int, p3: int, p4: kotlin.jvm.internal.DefaultConstructorMarker): void
|
||||
public final @org.jetbrains.annotations.NotNull method getStr(): java.lang.String
|
||||
public final method getX(): int
|
||||
public static method valueOf(p0: java.lang.String): Test
|
||||
public static method values(): Test[]
|
||||
}
|
||||
Vendored
+17
@@ -0,0 +1,17 @@
|
||||
@kotlin.Metadata
|
||||
public final class SecondaryConstructorWithVarargKt {
|
||||
public final static @org.jetbrains.annotations.NotNull method box(): java.lang.String
|
||||
}
|
||||
|
||||
@kotlin.Metadata
|
||||
public enum class Test {
|
||||
public final static field OK: Test
|
||||
private final @org.jetbrains.annotations.NotNull field str: java.lang.String
|
||||
private final field x: int
|
||||
protected method <init>(@java.lang.Synthetic p0: java.lang.String, @java.lang.Synthetic p1: int, @org.jetbrains.annotations.NotNull p2: int[]): void
|
||||
protected method <init>(@java.lang.Synthetic p0: java.lang.String, @java.lang.Synthetic p1: int, p2: int, @org.jetbrains.annotations.NotNull p3: java.lang.String): void
|
||||
public final @org.jetbrains.annotations.NotNull method getStr(): java.lang.String
|
||||
public final method getX(): int
|
||||
public static method valueOf(p0: java.lang.String): Test
|
||||
public static method values(): Test[]
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
enum class TestOk(val x: String = "OK") {
|
||||
TEST1,
|
||||
TEST2(),
|
||||
TEST3("Hello")
|
||||
}
|
||||
|
||||
enum class TestErrors(val x: String) {
|
||||
<!ENUM_ENTRY_SHOULD_BE_INITIALIZED!>TEST1,<!>
|
||||
TEST2(<!NO_VALUE_FOR_PARAMETER!>)<!>,
|
||||
TEST3("Hello")
|
||||
}
|
||||
|
||||
enum class TestMultipleConstructors(val x: String = "", val y: Int = 0) {
|
||||
<!ENUM_ENTRY_SHOULD_BE_INITIALIZED!>TEST;<!>
|
||||
constructor(x: String = "") : this(x, 0)
|
||||
}
|
||||
|
||||
enum class TestVarargs(val x: Int) {
|
||||
TEST;
|
||||
constructor(vararg xs: Any) : this(xs.size)
|
||||
}
|
||||
+92
@@ -0,0 +1,92 @@
|
||||
package
|
||||
|
||||
public final enum class TestErrors : kotlin.Enum<TestErrors> {
|
||||
enum entry TEST1
|
||||
|
||||
enum entry TEST2
|
||||
|
||||
enum entry TEST3
|
||||
|
||||
private constructor TestErrors(/*0*/ x: kotlin.String)
|
||||
public final override /*1*/ /*fake_override*/ val name: kotlin.String
|
||||
public final override /*1*/ /*fake_override*/ val ordinal: kotlin.Int
|
||||
public final val x: kotlin.String
|
||||
protected final override /*1*/ /*fake_override*/ fun clone(): kotlin.Any
|
||||
public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: TestErrors): kotlin.Int
|
||||
public final override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
protected/*protected and package*/ final override /*1*/ /*fake_override*/ /*isHiddenForResolutionEverywhereBesideSupercalls*/ fun finalize(): kotlin.Unit
|
||||
public final override /*1*/ /*fake_override*/ /*isHiddenForResolutionEverywhereBesideSupercalls*/ fun getDeclaringClass(): java.lang.Class<TestErrors!>!
|
||||
public final override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
|
||||
// Static members
|
||||
public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): TestErrors
|
||||
public final /*synthesized*/ fun values(): kotlin.Array<TestErrors>
|
||||
}
|
||||
|
||||
public final enum class TestMultipleConstructors : kotlin.Enum<TestMultipleConstructors> {
|
||||
enum entry TEST
|
||||
|
||||
private constructor TestMultipleConstructors(/*0*/ x: kotlin.String = ...)
|
||||
private constructor TestMultipleConstructors(/*0*/ x: kotlin.String = ..., /*1*/ y: kotlin.Int = ...)
|
||||
public final override /*1*/ /*fake_override*/ val name: kotlin.String
|
||||
public final override /*1*/ /*fake_override*/ val ordinal: kotlin.Int
|
||||
public final val x: kotlin.String
|
||||
public final val y: kotlin.Int
|
||||
protected final override /*1*/ /*fake_override*/ fun clone(): kotlin.Any
|
||||
public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: TestMultipleConstructors): kotlin.Int
|
||||
public final override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
protected/*protected and package*/ final override /*1*/ /*fake_override*/ /*isHiddenForResolutionEverywhereBesideSupercalls*/ fun finalize(): kotlin.Unit
|
||||
public final override /*1*/ /*fake_override*/ /*isHiddenForResolutionEverywhereBesideSupercalls*/ fun getDeclaringClass(): java.lang.Class<TestMultipleConstructors!>!
|
||||
public final override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
|
||||
// Static members
|
||||
public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): TestMultipleConstructors
|
||||
public final /*synthesized*/ fun values(): kotlin.Array<TestMultipleConstructors>
|
||||
}
|
||||
|
||||
public final enum class TestOk : kotlin.Enum<TestOk> {
|
||||
enum entry TEST1
|
||||
|
||||
enum entry TEST2
|
||||
|
||||
enum entry TEST3
|
||||
|
||||
private constructor TestOk(/*0*/ x: kotlin.String = ...)
|
||||
public final override /*1*/ /*fake_override*/ val name: kotlin.String
|
||||
public final override /*1*/ /*fake_override*/ val ordinal: kotlin.Int
|
||||
public final val x: kotlin.String
|
||||
protected final override /*1*/ /*fake_override*/ fun clone(): kotlin.Any
|
||||
public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: TestOk): kotlin.Int
|
||||
public final override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
protected/*protected and package*/ final override /*1*/ /*fake_override*/ /*isHiddenForResolutionEverywhereBesideSupercalls*/ fun finalize(): kotlin.Unit
|
||||
public final override /*1*/ /*fake_override*/ /*isHiddenForResolutionEverywhereBesideSupercalls*/ fun getDeclaringClass(): java.lang.Class<TestOk!>!
|
||||
public final override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
|
||||
// Static members
|
||||
public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): TestOk
|
||||
public final /*synthesized*/ fun values(): kotlin.Array<TestOk>
|
||||
}
|
||||
|
||||
public final enum class TestVarargs : kotlin.Enum<TestVarargs> {
|
||||
enum entry TEST
|
||||
|
||||
private constructor TestVarargs(/*0*/ vararg xs: kotlin.Any /*kotlin.Array<out kotlin.Any>*/)
|
||||
private constructor TestVarargs(/*0*/ x: kotlin.Int)
|
||||
public final override /*1*/ /*fake_override*/ val name: kotlin.String
|
||||
public final override /*1*/ /*fake_override*/ val ordinal: kotlin.Int
|
||||
public final val x: kotlin.Int
|
||||
protected final override /*1*/ /*fake_override*/ fun clone(): kotlin.Any
|
||||
public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: TestVarargs): kotlin.Int
|
||||
public final override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
protected/*protected and package*/ final override /*1*/ /*fake_override*/ /*isHiddenForResolutionEverywhereBesideSupercalls*/ fun finalize(): kotlin.Unit
|
||||
public final override /*1*/ /*fake_override*/ /*isHiddenForResolutionEverywhereBesideSupercalls*/ fun getDeclaringClass(): java.lang.Class<TestVarargs!>!
|
||||
public final override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
|
||||
// Static members
|
||||
public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): TestVarargs
|
||||
public final /*synthesized*/ fun values(): kotlin.Array<TestVarargs>
|
||||
}
|
||||
+4
@@ -37,4 +37,8 @@ enum class TestEnum4(val x: Int) {
|
||||
}
|
||||
;
|
||||
abstract fun foo()
|
||||
}
|
||||
|
||||
enum class TestEnum5(val x: Int = 0) {
|
||||
TEST1, TEST2(), TEST3(0)
|
||||
}
|
||||
+27
@@ -116,3 +116,30 @@ FILE /enum.kt
|
||||
SYNTHETIC_BODY kind=ENUM_VALUES
|
||||
FUN ENUM_CLASS_SPECIAL_MEMBER public final fun valueOf(value: kotlin.String): TestEnum4
|
||||
SYNTHETIC_BODY kind=ENUM_VALUEOF
|
||||
CLASS ENUM_CLASS TestEnum5
|
||||
CONSTRUCTOR private constructor TestEnum5(x: kotlin.Int = ...)
|
||||
x: EXPRESSION_BODY
|
||||
CONST Int type=kotlin.Int value='0'
|
||||
BLOCK_BODY
|
||||
ENUM_CONSTRUCTOR_CALL 'constructor Enum(String, Int)'
|
||||
INSTANCE_INITIALIZER_CALL classDescriptor='TestEnum5'
|
||||
PROPERTY public final val x: kotlin.Int
|
||||
FIELD PROPERTY_BACKING_FIELD public final val x: kotlin.Int
|
||||
EXPRESSION_BODY
|
||||
GET_VAR 'value-parameter x: Int = ...' type=kotlin.Int origin=INITIALIZE_PROPERTY_FROM_PARAMETER
|
||||
FUN DEFAULT_PROPERTY_ACCESSOR public final fun <get-x>(): kotlin.Int
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='<get-x>(): Int'
|
||||
GET_FIELD 'x: Int' type=kotlin.Int origin=null
|
||||
receiver: GET_VAR '<receiver: TestEnum5>' type=TestEnum5 origin=null
|
||||
ENUM_ENTRY enum entry TEST1
|
||||
init: ENUM_CONSTRUCTOR_CALL 'constructor TestEnum5(Int = ...)'
|
||||
ENUM_ENTRY enum entry TEST2
|
||||
init: ENUM_CONSTRUCTOR_CALL 'constructor TestEnum5(Int = ...)'
|
||||
ENUM_ENTRY enum entry TEST3
|
||||
init: ENUM_CONSTRUCTOR_CALL 'constructor TestEnum5(Int = ...)'
|
||||
x: CONST Int type=kotlin.Int value='0'
|
||||
FUN ENUM_CLASS_SPECIAL_MEMBER public final fun values(): kotlin.Array<TestEnum5>
|
||||
SYNTHETIC_BODY kind=ENUM_VALUES
|
||||
FUN ENUM_CLASS_SPECIAL_MEMBER public final fun valueOf(value: kotlin.String): TestEnum5
|
||||
SYNTHETIC_BODY kind=ENUM_VALUEOF
|
||||
|
||||
Reference in New Issue
Block a user