You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This is a formal specification for a language feature which allows `enum` declarations to declare classes with fields, methods and `const` constructors initializing those fields. Further, `enum` declarations can implement interfaces and apply mixins.
6
6
@@ -54,12 +54,16 @@ It is a **compile-time error** if the initializer list of a non-redirecting gene
54
54
55
55
_We will introduce the necessary super-invocation ourselves as an implementation detail. From the user’s perspective, they extend `Enum` which has no public constructors. We could allow `super()`, which would then be a constructor of `Enum`, but it's simpler to just disallow super invocations entirely._
56
56
57
+
It is a **compile-time error** if the argument list of a non-redirecting generative constructor includes a `super` parameter.
58
+
59
+
_Super parameters (a feature introduced in the same release as enhanced enums) implicitly adds arguments to the `super` constructor invocation of a non-redirecting generative constructor, and such enum constructors do not have a known superclass constructor expecting such arguments._
60
+
57
61
It is a **compile-time error** to refer to a declared or default generative constructor of an `enum` declaration in any way, other than:
58
62
59
-
* As the target of a redirecting generative constructor of the same `enum` declaration, or
60
-
* Implicitly in the enum value declarations of the same `enum`.
63
+
* As the target of a redirecting generative constructor of the same `enum` declaration (`: this(...);`/`: this.targetName(...);`), or
64
+
* Implicitly in the enum value declarations of the same `enum` (`enumValueName(args)`/`enumValueName.targetName(args)`).
61
65
62
-
_No-one is allowed to invoke a generative constructor and create another instance of the `enum`.
66
+
_No-one is allowed to invoke a generative constructor and create an instance of the `enum` other than the enumerated enum values.
63
67
That also means that a redirecting *factory* constructor cannot redirect to a generative constructor of an `enum`,
64
68
and therefore no factory constructor of an `enum` declaration can be `const`, because a `const` factory constructor must redirect to a generative constructor._
65
69
@@ -81,13 +85,13 @@ We intend to (at least pretend to) let `enum` classes extend `Enum`, and let mix
81
85
82
86
This all makes it look as if `Enum` would be a valid superclass for the mixin applications and methods of the enhanced `enum` class.
83
87
84
-
The semantics of such an enum declaration, *E*, is defined as introducing a (semantic) *class*, *C*, just like a similar `class` declaration.
88
+
The semantics of such an enum declaration, *E* with name *N*, is defined as introducing a (semantic) *class*, *C*, just like a similar `class` declaration.
85
89
86
-
***Name**: The name of the class *C* and its implicit interface is the name of the `enum` declaration.
90
+
***Name**: The name of the class *C* and its implicit interface is the name *N*of the `enum` declaration.
87
91
88
92
***Superclass**: The superclass of *C* is an implementation-specific built-in class *`EnumImpl`*, with the mixins declared by *E* applied. _(The `EnumImpl` class may be the `Enum` class itself or it may be another class which extends or implements `Enum`, but as seen from a non-platform library the interface of *`EnumImpl`* is the same as that of `Enum`, and its methods work as specified for `Enum` )_
89
93
90
-
* If *E* is declared as `enum Name with Mixin1, Mixin2 …` then the superclass of *C* is the mixin application <Code>*EnumImpl* with Mixin1, Mixin2</code>.
94
+
* If *E* is declared as <code>enum *N* with *Mixin1*, *Mixin2* …</code> then the superclass of *C* is the mixin application <Code>*EnumImpl* with *Mixin1*, *Mixin2*</code>.
91
95
92
96
It’s a **compile-time error** if such a mixin application introduces any instance variables. _We need to be able to call an implementation specific superclass `const` constructor of `Enum`, and a mixin application of a mixin with a field does not make its forwarding constructor `const`. Currently that’s the only restriction, but if we add further restrictions on mixin applications having `const` forwarding constructors, those should also apply here._
93
97
@@ -97,49 +101,49 @@ The semantics of such an enum declaration, *E*, is defined as introducing a (sem
97
101
98
102
-**Declared members**: For each member declaration of the `enum` declaration *E*, the same member is added to the class *C*. This includes constructors (which must be `const` generative or non-`const` factory constructors.)
99
103
100
-
-**Default constructor**: If no generative constructors were declared, and no unnamed factory constructor was added,
104
+
-**Default constructor**: If no generative constructors were declared, and also no factory constructor with name *N*was declared,
101
105
a default generative constructor is added:
102
106
103
107
```dart
104
108
const Name();
105
109
```
106
110
107
-
_(This differs from the default constructor of a normal `class` declaration by being constant, and by being added even if a factory constructor is present. If no generative constructor is declared, and the unnamed constructor is taken by a factory constructor, there is no way for the enum declaration to compile successfully, since the declaration must contain at least one enum value, and that enum value must refer to a generative constructor.)_
111
+
_(This differs from the default constructor of a normal `class` declaration by being constant, and by being added even if a factory constructor is present. If no generative constructor is declared, and the unnamed constructor name is taken by a factory constructor, there is no way for the enum declaration to compile successfully, since the declaration must contain at least one enum value, and that enum value must refer to a generative constructor.)_
108
112
109
-
-**Enum values**: For each `<enumEntry>` with name `id` and index *i* in the comma-separated list of enum entries, a constant value is created, and a static constant variable named `id` is created in *C* with that value. All the constant values are associated, in some implementation dependent way, with
113
+
-**Enum values**: For each `<enumEntry>` with name *id* and index *i* in the comma-separated list of enum entries, a constant value is created, and a static constant variable named *id* is created in *C* with that value. All the constant values are associated, in some implementation dependent way, with
110
114
111
-
- their name `id` as a string `"id"`,
115
+
- their name *id* as a string `"id"`,
112
116
- their index *i* as an `int`, and
113
-
- their `enum` class’s name as a string, `"Name"`,
117
+
- their `enum` class’s name as a string, <code>"*N*"</code>,
114
118
115
119
all of which are accessible to the `toString` and `index` member of `Enum`, and to the `EnumName.name` extension getter. The values are computed as by the following constant constructor invocations.
116
120
117
-
-`id`↦`const Name()` (no arguments, equivalent to empty argument list)
where `args` are considered as occurring in a `const` context, and it’s a **compile-time error** if they are then not compile-time constants.
127
+
where *args* are considered as occurring in a `const` context, and it’s a **compile-time error** if they are then not compile-time constants.
124
128
125
129
The resulting constructor invocations are subject to type inference, using the empty context type. *This implies that inferred type arguments to the constructor invocation itself may depend on the types of the argument expressions of `args`.* The type of the constant variable is the static type of the resulting constant object creation expression.
126
130
127
131
The objects created here are *not canonicalized* like other constant object creations. _(In practice, the index value is considered part of the object, so no two objects will have the same state.)_
128
132
129
-
-**Static `values` list**: A static constant variable named `values` is added as by the declaration `static const List<Name> values = [id1, …, idn];`
130
-
where `id1`…`idn` are the names of the enum entries of the `enum` declaration in source/index order.
131
-
_If `Name` is generic, the `List<Name>` instantiates `Name` to its bounds._
133
+
-**Static `values` list**: A static constant variable named `values` is added as by the declaration <code>static const List<*N*> values = [*id*<sub>1</sub>, …, *id*<sub>*n*</sub>];</code>
134
+
where <code>*id*<sub>1<sub></code>…<code>*id*<sub>*n*</sub></code> are the names of the enum entries of the `enum` declaration in source/index order.
135
+
_If *C* is a generic class (*E* is a generic enum), the <code>List<N></code> instantiates <code>*N*</code> to its bounds._
132
136
133
-
It's a **compile-time error** if an `enum` declaration declares or inherits a concrete member named `index` which overrides the `index` getter of the `Enum` class. _Such an inherited `index` member would necessarily have been introduced by a mixin application of the `enum` declaration._
137
+
It's a **compile-time error** if an `enum` declaration declares or inherits a concrete member named `index` which overrides the `index` getter of the `Enum` class. _Such an inherited `index` member would necessarily have been introduced by a mixin application of the `enum` declaration._
134
138
135
-
It's a **compile-time error** if an `enum` declaration declares or inherits a concrete member named `hashCode` or `==`*(an `operator ==` declaration)* which overrides the `hashCode` getter or `==` operator of the `Object` class. (The `Enum` class does not override `hashCode` or `operator==` from `Object`). _This ensures that enum values can be used as switch statement case values, which is the main advantage of using an enum over just writing a normal class._
139
+
It's a **compile-time error** if an `enum` declaration declares or inherits a concrete member named `hashCode` or `==`*(an `operator ==` declaration)* which overrides the `hashCode` getter or `==` operator of the `Object` class. (The `Enum` class does not override `hashCode` or `operator==` from `Object`). _This ensures that enum values can be used as switch statement case values, which is the main advantage of using an enum over just writing a normal class._
136
140
137
141
If the resulting class would have any naming conflicts, or other compile-time errors, the `enum` declaration is invalid and a compile-time error occurs. Such errors include, but are not limited to:
138
142
139
143
- Declaring or inheriting (from `Enum` or from a declared mixin or interface) any member with the same basename as an enum value which is not a static setter. _(The introduced static declarations would have a conflict.)_
140
144
- Declaring or mixing in a member which is not a valid override of a super-interface member declaration, including the `runtimeType`, `noSuchMethod` and `toString` members of `Object`, or any members introduced by mixin applications.
141
145
- Declaring or inheriting an member signature with no corresponding implementation. _(For example declaring an abstract `String toString([int optional])`, but not providing an implementation.)_
142
-
- Declaring a generic `enum` which does not have a valid well-bounded instantiate-to-bounds result. _(The automatically introduced `static const List<EnumName> values` requires a well-bounded instantiate-to-bounds result)_.
146
+
- Declaring a generic `enum` which does not have a valid well-bounded instantiate-to-bounds result. _(The automatically introduced <code>static const List<*N*> values</code> requires a well-bounded instantiate-to-bounds result)_.
143
147
- Declaring a generic `enum` which does not have a regular-bounded instantiate-to-bounds result *and* that has an enum value declaration omitting the type arguments and not having arguments from which type arguments can be inferred. _(For example `enum EnumName<F extends C<F>> { foo; }` would introduce an implicit `static const foo = EnumName(0, "foo");` declaration where the constructor invocation requires a regular-bounded instantiate-to-bounds result)_.
144
148
- Using a non-constant expression as an argument of an enum value declaration.
145
149
- Declaring a static member and inheriting an instance member with the same base-name.
@@ -453,3 +457,4 @@ There is a chance that people will start using `enum` declarations to declare si
453
457
1.5, 2021-12-07: Say that `index` and `toString` are inherited from the superclass, `values` is omitted if it would conflict. Rephrase specification in terms of defining a semantic class, not a syntactic one.
454
458
1.6, 2022-01-27: Disallow overriding `index` or conflicting with `values`.
455
459
1.7, 2022-02-16: Disallow overriding `operator==` and `hashCode` too.
460
+
1.8, 2022-03-08: Make it explicit that an enum constructor cannot use the new super-parameters.
0 commit comments