Skip to content

Commit ae69916

Browse files
[cfe] Add initial support for enum fields
Part of #47453 Change-Id: I39c3d29ef31aa51db4f266c7330ac8e47260d749 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/225727 Reviewed-by: Johnni Winther <[email protected]>
1 parent 098d670 commit ae69916

10 files changed

+386
-8
lines changed

pkg/front_end/lib/src/fasta/source/outline_builder.dart

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3114,21 +3114,15 @@ class OutlineBuilder extends StackListenerImpl {
31143114
int count,
31153115
Token beginToken,
31163116
Token endToken) {
3117-
// TODO(cstefantsova): Call endClassFields instead.
3118-
debugEvent("EnumFields");
3119-
popFieldInfos(count); // field infos
3120-
pop(); // type
3121-
pop(); // metadata
3122-
popDeclarationContext();
3123-
// Skip the declaration. An error as already been produced by the parser.
3124-
31253117
if (!libraryBuilder.enableEnhancedEnumsInLibrary) {
31263118
addProblem(
31273119
templateExperimentNotEnabled.withArguments('enhanced-enums',
31283120
libraryBuilder.enableEnhancedEnumsVersionInLibrary.toText()),
31293121
beginToken.charOffset,
31303122
-1);
31313123
}
3124+
endClassFields(abstractToken, externalToken, staticToken, covariantToken,
3125+
lateToken, varFinalOrConst, count, beginToken, endToken);
31323126
}
31333127

31343128
@override
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
enum E1 {
6+
one(1),
7+
two.named(2);
8+
9+
final int foo;
10+
11+
const E1(this.foo);
12+
13+
const E1.named(int value) : foo = value;
14+
}
15+
16+
enum E2<X, Y> {
17+
one<int, String>(1, "one"),
18+
two.named("two", 2),
19+
three.named("three", "three");
20+
21+
final X foo;
22+
final Y bar;
23+
24+
const E2(this.foo, this.bar);
25+
const E2.named(Y this.bar, X this.foo);
26+
}
27+
28+
main() {}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
library /*isNonNullableByDefault*/;
2+
import self as self;
3+
import "dart:core" as core;
4+
5+
class E1 extends core::_Enum /*isEnum*/ {
6+
static const field core::List<self::E1> values = #C8;
7+
static const field self::E1 one = #C4;
8+
static const field self::E1 two = #C7;
9+
final field core::int foo;
10+
const constructor •(core::int index, core::String name, core::int foo) → self::E1
11+
: self::E1::foo = foo, super core::_Enum::•(index, name)
12+
;
13+
const constructor named(core::int index, core::String name, core::int value) → self::E1
14+
: self::E1::foo = value, super core::_Enum::•(index, name)
15+
;
16+
method toString() → core::String
17+
return "E1.${this.{core::_Enum::_name}{core::String}}";
18+
}
19+
class E2<X extends core::Object? = dynamic, Y extends core::Object? = dynamic> extends core::_Enum /*isEnum*/ {
20+
static const field core::List<self::E2<dynamic, dynamic>> values = #C13;
21+
static const field self::E2<core::int, core::String> one = #C9;
22+
static const field self::E2<core::int, core::String> two = #C10;
23+
static const field self::E2<core::String, core::String> three = #C12;
24+
final field self::E2::X% foo;
25+
final field self::E2::Y% bar;
26+
const constructor •(core::int index, core::String name, self::E2::X% foo, self::E2::Y% bar) → self::E2<self::E2::X%, self::E2::Y%>
27+
: self::E2::foo = foo, self::E2::bar = bar, super core::_Enum::•(index, name)
28+
;
29+
const constructor named(core::int index, core::String name, self::E2::Y% bar, self::E2::X% foo) → self::E2<self::E2::X%, self::E2::Y%>
30+
: self::E2::bar = bar, self::E2::foo = foo, super core::_Enum::•(index, name)
31+
;
32+
method toString() → core::String
33+
return "E2.${this.{core::_Enum::_name}{core::String}}";
34+
}
35+
static method main() → dynamic {}
36+
37+
constants {
38+
#C1 = 1
39+
#C2 = 0
40+
#C3 = "one"
41+
#C4 = self::E1 {foo:#C1, index:#C2, _name:#C3}
42+
#C5 = 2
43+
#C6 = "two"
44+
#C7 = self::E1 {foo:#C5, index:#C1, _name:#C6}
45+
#C8 = <self::E1>[#C4, #C7]
46+
#C9 = self::E2<core::int, core::String> {foo:#C1, bar:#C3, index:#C2, _name:#C3}
47+
#C10 = self::E2<core::int, core::String> {foo:#C5, bar:#C6, index:#C1, _name:#C6}
48+
#C11 = "three"
49+
#C12 = self::E2<core::String, core::String> {foo:#C11, bar:#C11, index:#C5, _name:#C11}
50+
#C13 = <self::E2<dynamic, dynamic>>[#C9, #C10, #C12]
51+
}
52+
53+
54+
Constructor coverage from constants:
55+
org-dartlang-testcase:///simple_fields.dart:
56+
- E1. (from org-dartlang-testcase:///simple_fields.dart:11:9)
57+
- _Enum. (from org-dartlang-sdk:///sdk/lib/core/enum.dart:76:9)
58+
- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
59+
- E1.named (from org-dartlang-testcase:///simple_fields.dart:13:9)
60+
- E2. (from org-dartlang-testcase:///simple_fields.dart:24:9)
61+
- E2.named (from org-dartlang-testcase:///simple_fields.dart:25:9)
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
library /*isNonNullableByDefault*/;
2+
import self as self;
3+
import "dart:core" as core;
4+
5+
class E1 extends core::_Enum /*isEnum*/ {
6+
static const field core::List<self::E1> values = #C8;
7+
static const field self::E1 one = #C4;
8+
static const field self::E1 two = #C7;
9+
final field core::int foo;
10+
const constructor •(core::int index, core::String name, core::int foo) → self::E1
11+
: self::E1::foo = foo, super core::_Enum::•(index, name)
12+
;
13+
const constructor named(core::int index, core::String name, core::int value) → self::E1
14+
: self::E1::foo = value, super core::_Enum::•(index, name)
15+
;
16+
method toString() → core::String
17+
return "E1.${this.{core::_Enum::_name}{core::String}}";
18+
}
19+
class E2<X extends core::Object? = dynamic, Y extends core::Object? = dynamic> extends core::_Enum /*isEnum*/ {
20+
static const field core::List<self::E2<dynamic, dynamic>> values = #C13;
21+
static const field self::E2<core::int, core::String> one = #C9;
22+
static const field self::E2<core::int, core::String> two = #C10;
23+
static const field self::E2<core::String, core::String> three = #C12;
24+
final field self::E2::X% foo;
25+
final field self::E2::Y% bar;
26+
const constructor •(core::int index, core::String name, self::E2::X% foo, self::E2::Y% bar) → self::E2<self::E2::X%, self::E2::Y%>
27+
: self::E2::foo = foo, self::E2::bar = bar, super core::_Enum::•(index, name)
28+
;
29+
const constructor named(core::int index, core::String name, self::E2::Y% bar, self::E2::X% foo) → self::E2<self::E2::X%, self::E2::Y%>
30+
: self::E2::bar = bar, self::E2::foo = foo, super core::_Enum::•(index, name)
31+
;
32+
method toString() → core::String
33+
return "E2.${this.{core::_Enum::_name}{core::String}}";
34+
}
35+
static method main() → dynamic {}
36+
37+
constants {
38+
#C1 = 1
39+
#C2 = 0
40+
#C3 = "one"
41+
#C4 = self::E1 {foo:#C1, index:#C2, _name:#C3}
42+
#C5 = 2
43+
#C6 = "two"
44+
#C7 = self::E1 {foo:#C5, index:#C1, _name:#C6}
45+
#C8 = <self::E1>[#C4, #C7]
46+
#C9 = self::E2<core::int, core::String> {foo:#C1, bar:#C3, index:#C2, _name:#C3}
47+
#C10 = self::E2<core::int, core::String> {foo:#C5, bar:#C6, index:#C1, _name:#C6}
48+
#C11 = "three"
49+
#C12 = self::E2<core::String, core::String> {foo:#C11, bar:#C11, index:#C5, _name:#C11}
50+
#C13 = <self::E2<dynamic, dynamic>>[#C9, #C10, #C12]
51+
}
52+
53+
54+
Constructor coverage from constants:
55+
org-dartlang-testcase:///simple_fields.dart:
56+
- E1. (from org-dartlang-testcase:///simple_fields.dart:11:9)
57+
- _Enum. (from org-dartlang-sdk:///sdk/lib/core/enum.dart:76:9)
58+
- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
59+
- E1.named (from org-dartlang-testcase:///simple_fields.dart:13:9)
60+
- E2. (from org-dartlang-testcase:///simple_fields.dart:24:9)
61+
- E2.named (from org-dartlang-testcase:///simple_fields.dart:25:9)
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
enum E1 { one(1), two.named(2); final int foo; const E1(this.foo); const E1.named(int value) : foo = value; }
2+
enum E2<X, Y> { one<int, String>(1, "one"), two.named("two", 2), three.named("three", "three"); final X foo; final Y bar; const E2(this.foo, this.bar); const E2.named(Y this.bar, X this.foo); }
3+
main() {}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
library /*isNonNullableByDefault*/;
2+
import self as self;
3+
import "dart:core" as core;
4+
5+
class E1 extends core::_Enum /*isEnum*/ {
6+
static const field core::List<self::E1> values = #C8;
7+
static const field self::E1 one = #C4;
8+
static const field self::E1 two = #C7;
9+
final field core::int foo;
10+
const constructor •(core::int index, core::String name, core::int foo) → self::E1
11+
: self::E1::foo = foo, super core::_Enum::•(index, name)
12+
;
13+
const constructor named(core::int index, core::String name, core::int value) → self::E1
14+
: self::E1::foo = value, super core::_Enum::•(index, name)
15+
;
16+
method toString() → core::String
17+
return "E1.${this.{core::_Enum::_name}{core::String}}";
18+
}
19+
class E2<X extends core::Object? = dynamic, Y extends core::Object? = dynamic> extends core::_Enum /*isEnum*/ {
20+
static const field core::List<self::E2<dynamic, dynamic>> values = #C13;
21+
static const field self::E2<core::int, core::String> one = #C9;
22+
static const field self::E2<core::int, core::String> two = #C10;
23+
static const field self::E2<core::String, core::String> three = #C12;
24+
final field self::E2::X% foo;
25+
final field self::E2::Y% bar;
26+
const constructor •(core::int index, core::String name, self::E2::X% foo, self::E2::Y% bar) → self::E2<self::E2::X%, self::E2::Y%>
27+
: self::E2::foo = foo, self::E2::bar = bar, super core::_Enum::•(index, name)
28+
;
29+
const constructor named(core::int index, core::String name, self::E2::Y% bar, self::E2::X% foo) → self::E2<self::E2::X%, self::E2::Y%>
30+
: self::E2::bar = bar, self::E2::foo = foo, super core::_Enum::•(index, name)
31+
;
32+
method toString() → core::String
33+
return "E2.${this.{core::_Enum::_name}{core::String}}";
34+
}
35+
static method main() → dynamic {}
36+
37+
constants {
38+
#C1 = 1
39+
#C2 = 0
40+
#C3 = "one"
41+
#C4 = self::E1 {foo:#C1, index:#C2, _name:#C3}
42+
#C5 = 2
43+
#C6 = "two"
44+
#C7 = self::E1 {foo:#C5, index:#C1, _name:#C6}
45+
#C8 = <self::E1*>[#C4, #C7]
46+
#C9 = self::E2<core::int*, core::String*> {foo:#C1, bar:#C3, index:#C2, _name:#C3}
47+
#C10 = self::E2<core::int*, core::String*> {foo:#C5, bar:#C6, index:#C1, _name:#C6}
48+
#C11 = "three"
49+
#C12 = self::E2<core::String*, core::String*> {foo:#C11, bar:#C11, index:#C5, _name:#C11}
50+
#C13 = <self::E2<dynamic, dynamic>*>[#C9, #C10, #C12]
51+
}
52+
53+
54+
Constructor coverage from constants:
55+
org-dartlang-testcase:///simple_fields.dart:
56+
- E1. (from org-dartlang-testcase:///simple_fields.dart:11:9)
57+
- _Enum. (from org-dartlang-sdk:///sdk/lib/core/enum.dart:76:9)
58+
- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
59+
- E1.named (from org-dartlang-testcase:///simple_fields.dart:13:9)
60+
- E2. (from org-dartlang-testcase:///simple_fields.dart:24:9)
61+
- E2.named (from org-dartlang-testcase:///simple_fields.dart:25:9)
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
library /*isNonNullableByDefault*/;
2+
import self as self;
3+
import "dart:core" as core;
4+
5+
class E1 extends core::_Enum /*isEnum*/ {
6+
static const field core::List<self::E1> values = #C8;
7+
static const field self::E1 one = #C4;
8+
static const field self::E1 two = #C7;
9+
final field core::int foo;
10+
const constructor •(core::int index, core::String name, core::int foo) → self::E1
11+
: self::E1::foo = foo, super core::_Enum::•(index, name)
12+
;
13+
const constructor named(core::int index, core::String name, core::int value) → self::E1
14+
: self::E1::foo = value, super core::_Enum::•(index, name)
15+
;
16+
method toString() → core::String
17+
return "E1.${this.{core::_Enum::_name}{core::String}}";
18+
}
19+
class E2<X extends core::Object? = dynamic, Y extends core::Object? = dynamic> extends core::_Enum /*isEnum*/ {
20+
static const field core::List<self::E2<dynamic, dynamic>> values = #C13;
21+
static const field self::E2<core::int, core::String> one = #C9;
22+
static const field self::E2<core::int, core::String> two = #C10;
23+
static const field self::E2<core::String, core::String> three = #C12;
24+
final field self::E2::X% foo;
25+
final field self::E2::Y% bar;
26+
const constructor •(core::int index, core::String name, self::E2::X% foo, self::E2::Y% bar) → self::E2<self::E2::X%, self::E2::Y%>
27+
: self::E2::foo = foo, self::E2::bar = bar, super core::_Enum::•(index, name)
28+
;
29+
const constructor named(core::int index, core::String name, self::E2::Y% bar, self::E2::X% foo) → self::E2<self::E2::X%, self::E2::Y%>
30+
: self::E2::bar = bar, self::E2::foo = foo, super core::_Enum::•(index, name)
31+
;
32+
method toString() → core::String
33+
return "E2.${this.{core::_Enum::_name}{core::String}}";
34+
}
35+
static method main() → dynamic {}
36+
37+
constants {
38+
#C1 = 1
39+
#C2 = 0
40+
#C3 = "one"
41+
#C4 = self::E1 {foo:#C1, index:#C2, _name:#C3}
42+
#C5 = 2
43+
#C6 = "two"
44+
#C7 = self::E1 {foo:#C5, index:#C1, _name:#C6}
45+
#C8 = <self::E1*>[#C4, #C7]
46+
#C9 = self::E2<core::int*, core::String*> {foo:#C1, bar:#C3, index:#C2, _name:#C3}
47+
#C10 = self::E2<core::int*, core::String*> {foo:#C5, bar:#C6, index:#C1, _name:#C6}
48+
#C11 = "three"
49+
#C12 = self::E2<core::String*, core::String*> {foo:#C11, bar:#C11, index:#C5, _name:#C11}
50+
#C13 = <self::E2<dynamic, dynamic>*>[#C9, #C10, #C12]
51+
}
52+
53+
54+
Constructor coverage from constants:
55+
org-dartlang-testcase:///simple_fields.dart:
56+
- E1. (from org-dartlang-testcase:///simple_fields.dart:11:9)
57+
- _Enum. (from org-dartlang-sdk:///sdk/lib/core/enum.dart:76:9)
58+
- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
59+
- E1.named (from org-dartlang-testcase:///simple_fields.dart:13:9)
60+
- E2. (from org-dartlang-testcase:///simple_fields.dart:24:9)
61+
- E2.named (from org-dartlang-testcase:///simple_fields.dart:25:9)
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
library /*isNonNullableByDefault*/;
2+
import self as self;
3+
import "dart:core" as core;
4+
5+
class E1 extends core::_Enum /*isEnum*/ {
6+
static const field core::List<self::E1> values = const <self::E1>[self::E1::one, self::E1::two];
7+
static const field self::E1 one = const self::E1::•(0, "one", 1);
8+
static const field self::E1 two = const self::E1::named(1, "two", 2);
9+
final field core::int foo;
10+
const constructor •(core::int index, core::String name, core::int foo) → self::E1
11+
: self::E1::foo = foo, super core::_Enum::•(index, name)
12+
;
13+
const constructor named(core::int index, core::String name, core::int value) → self::E1
14+
: self::E1::foo = value, super core::_Enum::•(index, name)
15+
;
16+
method toString() → core::String
17+
return "E1.${this.{core::_Enum::_name}{core::String}}";
18+
}
19+
class E2<X extends core::Object? = dynamic, Y extends core::Object? = dynamic> extends core::_Enum /*isEnum*/ {
20+
static const field core::List<self::E2<dynamic, dynamic>> values = const <self::E2<dynamic, dynamic>>[self::E2::one, self::E2::two, self::E2::three];
21+
static const field self::E2<core::int, core::String> one = const self::E2::•<core::int, core::String>(0, "one", 1, "one");
22+
static const field self::E2<core::int, core::String> two = const self::E2::named<core::int, core::String>(1, "two", "two", 2);
23+
static const field self::E2<core::String, core::String> three = const self::E2::named<core::String, core::String>(2, "three", "three", "three");
24+
final field self::E2::X% foo;
25+
final field self::E2::Y% bar;
26+
const constructor •(core::int index, core::String name, self::E2::X% foo, self::E2::Y% bar) → self::E2<self::E2::X%, self::E2::Y%>
27+
: self::E2::foo = foo, self::E2::bar = bar, super core::_Enum::•(index, name)
28+
;
29+
const constructor named(core::int index, core::String name, self::E2::Y% bar, self::E2::X% foo) → self::E2<self::E2::X%, self::E2::Y%>
30+
: self::E2::bar = bar, self::E2::foo = foo, super core::_Enum::•(index, name)
31+
;
32+
method toString() → core::String
33+
return "E2.${this.{core::_Enum::_name}{core::String}}";
34+
}
35+
static method main() → dynamic
36+
;
37+
38+
39+
Extra constant evaluation status:
40+
Evaluated: ListLiteral @ org-dartlang-testcase:///simple_fields.dart:5:6 -> ListConstant(const <E1*>[const E1{E1.foo: 1, _Enum.index: 0, _Enum._name: "one"}, const E1{E1.foo: 2, _Enum.index: 1, _Enum._name: "two"}])
41+
Evaluated: ConstructorInvocation @ org-dartlang-testcase:///simple_fields.dart:6:3 -> InstanceConstant(const E1{E1.foo: 1, _Enum.index: 0, _Enum._name: "one"})
42+
Evaluated: ConstructorInvocation @ org-dartlang-testcase:///simple_fields.dart:7:3 -> InstanceConstant(const E1{E1.foo: 2, _Enum.index: 1, _Enum._name: "two"})
43+
Evaluated: ListLiteral @ org-dartlang-testcase:///simple_fields.dart:16:6 -> ListConstant(const <E2<dynamic, dynamic>*>[const E2<int*, String*>{E2.foo: 1, E2.bar: "one", _Enum.index: 0, _Enum._name: "one"}, const E2<int*, String*>{E2.foo: 2, E2.bar: "two", _Enum.index: 1, _Enum._name: "two"}, const E2<String*, String*>{E2.foo: "three", E2.bar: "three", _Enum.index: 2, _Enum._name: "three"}])
44+
Evaluated: ConstructorInvocation @ org-dartlang-testcase:///simple_fields.dart:17:3 -> InstanceConstant(const E2<int*, String*>{E2.foo: 1, E2.bar: "one", _Enum.index: 0, _Enum._name: "one"})
45+
Evaluated: ConstructorInvocation @ org-dartlang-testcase:///simple_fields.dart:18:3 -> InstanceConstant(const E2<int*, String*>{E2.foo: 2, E2.bar: "two", _Enum.index: 1, _Enum._name: "two"})
46+
Evaluated: ConstructorInvocation @ org-dartlang-testcase:///simple_fields.dart:19:3 -> InstanceConstant(const E2<String*, String*>{E2.foo: "three", E2.bar: "three", _Enum.index: 2, _Enum._name: "three"})
47+
Extra constant evaluation: evaluated: 27, effectively constant: 7

0 commit comments

Comments
 (0)