Skip to content

Commit 18f37dd

Browse files
lrhncommit-bot@chromium.org
authored andcommitted
Add extension name getter on Enum.
We use an extension getter instead of an instance getter because it doesn't conflict with any potential existing or future enums which want an element named `name`. Keeping the namespace for enum elements open is a priority. We currently only reserve `index` and `values`. BUG: dart-lang/language#1511 Fixes language issue #1511, which is a long-standing request, and should replace a number of alternative implementations which are based on parsing the `toString()`. This version has two fields on the shared superclass, the index and private name, and has a separate `toString` for each `enum` class which hard-codes that enum's class name. An earlier version had both `"name"` and `"ClassName.name"` as fields to be able to reuse the same `toString` method on all enum classes, but that cost too much for JS compiled code. Even having just `ClassName.` as a field and then combining inside `toString` requires more code to create the enum instances. Instead this version hardcodes the `ClassName.` string once in the `toString` method, which means each enum class has its own toString (which can *potentially* be tree-shaken then.) This still tree-shakes slightly worse than the previous implementation where every enum class had its own `index` and `_name` fields independent of each other, which could then be tree-shaken independently. However, the `index` was already made an interface member with the addition of the `Enum` interface, so code which accesses `.index` on something of the `Enum` supertype could prevent tree-shaking of all enum classes' `index` fields. Likewise any general access to the "name" of an enum would necessarily do the same for the name. This CL makes up for some of that by sharing more implementation between enum classes. DartVM AOT CodeSize impact: ~0.15% regression on gallery (little less on big g3 app) TEST= New tests added to enum_test.dart Change-Id: Id25334e6c987f470f558de3c141d0e3ff542b020 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/210480 Commit-Queue: Lasse R.H. Nielsen <[email protected]> Reviewed-by: Stephen Adams <[email protected]> Reviewed-by: Martin Kustermann <[email protected]>
1 parent 24c20d4 commit 18f37dd

File tree

104 files changed

+895
-772
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

104 files changed

+895
-772
lines changed

CHANGELOG.md

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
if (!iIsNull) {
3232
print(i + 1); // OK, because `i` is known to be non-null
3333
}
34-
}
34+
}<>
3535
```
3636

3737
Previously, the above program had a compile-time error because type promotion
@@ -82,7 +82,11 @@
8282

8383
### `dart:core`
8484

85+
- Add extension `name` getter on enum values.
8586
- Add `Enum.compareByIndex` helper function for comparing enum values by index.
87+
- Add `Enum.compareByName` helper function for comparing enum values by name.
88+
- Add extension methods on `Iterable<T extends Enum>`, intended for
89+
`SomeEnumType.values` lists, to look up values by name.
8690

8791
### Tools
8892

@@ -130,9 +134,9 @@ Updated the Linter to `1.12.0`, which includes changes that
130134
- update `avoid_print` to allow `kDebugMode`-wrapped print calls.
131135
- fix handling of initializing formals in `prefer_final_parameters`.
132136
- fix `unnecessary_parenthesis` false positive with function expressions.
133-
- adds support for constructor tear-offs to `avoid_redundant_argument_values`,
137+
- adds support for constructor tear-offs to `avoid_redundant_argument_values`,
134138
`unnecessary_lambdas`, and `unnecessary_parenthesis`.
135-
- adds a new lint: `unnecessary_constructor_name` to flag unnecessary uses of
139+
- adds a new lint: `unnecessary_constructor_name` to flag unnecessary uses of
136140
`.new`.
137141
- improves regular expression parsing performance for common checks
138142
(`camel_case_types`, `file_names`, etc.).
@@ -180,9 +184,9 @@ Updated the Linter to `1.12.0`, which includes changes that
180184
[`false_secrets`](https://dart.dev/go/false-secrets) section of your
181185
`pubspec.yaml`.
182186
- Fixes unicode terminal detection windows.
183-
- New flag `--example` to the commands
187+
- New flag `--example` to the commands
184188
`dart pub get/upgrade/downgrade/add/remove` that will result in the `example/`
185-
folder dependencies to be updated after operating in the current directory.
189+
folder dependencies to be updated after operating in the current directory.
186190

187191
## 2.14.2 - 2021-09-16
188192

pkg/analyzer/lib/src/test_utilities/mock_sdk.dart

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -531,6 +531,10 @@ abstract class Enum {
531531
int get index;
532532
}
533533
534+
abstract class _Enum extends Enum {
535+
String _name;
536+
}
537+
534538
abstract class Pattern {
535539
Iterable<Match> allMatches(String string, [int start = 0]);
536540
}

pkg/compiler/lib/src/ssa/builder_kernel.dart

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4499,12 +4499,16 @@ class KernelSsaGraphBuilder extends ir.Visitor<void> with ir.VisitorVoidMixin {
44994499

45004500
int _extractEnumIndexFromConstantValue(
45014501
ConstantValue constant, ClassEntity classElement) {
4502-
if (constant is ConstructedConstantValue) {
4503-
if (constant.type.element == classElement) {
4504-
assert(constant.fields.length == 1 || constant.fields.length == 2);
4505-
ConstantValue indexConstant = constant.fields.values.first;
4506-
if (indexConstant is IntConstantValue) {
4507-
return indexConstant.intValue.toInt();
4502+
if (constant is ConstructedConstantValue &&
4503+
constant.type.element == classElement) {
4504+
assert(constant.fields.length >= 1);
4505+
for (var field in constant.fields.keys) {
4506+
if (field.memberName.text == "index") {
4507+
ConstantValue indexConstant = constant.fields[field];
4508+
if (indexConstant is IntConstantValue) {
4509+
return indexConstant.intValue.toInt();
4510+
}
4511+
break;
45084512
}
45094513
}
45104514
}

pkg/compiler/test/field_analysis/jdata/effectively_constant_state.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ class Class {
2525
/*member: Class.state1:constant=IntConstant(1)*/
2626
final int state1;
2727

28-
/*member: Class.state2:constant=ConstructedConstant(Enum(_name=StringConstant("Enum.c"),index=IntConstant(2)))*/
28+
/*member: Class.state2:constant=ConstructedConstant(Enum(_name=StringConstant("c"),index=IntConstant(2)))*/
2929
final Enum state2;
3030

3131
Class({this.state1: 1, this.state2: Enum.c});

pkg/compiler/test/impact/data/classes.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -264,8 +264,8 @@ enum Enum { A }
264264

265265
/*member: testEnum:
266266
static=[
267-
Enum._name=StringConstant("Enum.A"),
268-
Enum.index=IntConstant(0)],
267+
_Enum._name=StringConstant("A"),
268+
_Enum.index=IntConstant(0)],
269269
type=[
270270
const:Enum,
271271
inst:JSInt,

pkg/compiler/test/inference/data/enum.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ enum Enum4 {
5555
a,
5656
}
5757

58-
/*member: enumToString1:Value([exact=JSString], value: "Enum4.a")*/
58+
/*member: enumToString1:[exact=JSString]*/
5959
enumToString1() {
6060
return Enum4.a. /*invoke: [exact=Enum4]*/ toString();
6161
}

0 commit comments

Comments
 (0)