Skip to content

Commit f5e11c2

Browse files
chloestefantsovaCommit Bot
authored and
Commit Bot
committed
[cfe] Create non-trivial constructor scope for enums
Part of #47453 Change-Id: I785c0c26dea8ad9443a531cf372db4e7f3b999bb Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/224954 Reviewed-by: Johnni Winther <[email protected]> Commit-Queue: Chloe Stefantsova <[email protected]>
1 parent 7270a7d commit f5e11c2

15 files changed

+204
-40
lines changed

pkg/front_end/lib/src/fasta/builder/enum_builder.dart

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,8 @@ class EnumBuilder extends SourceClassBuilder {
121121
int charOffset,
122122
int charEndOffset,
123123
IndexedClass? referencesFromIndexed,
124-
Scope scope) {
124+
Scope scope,
125+
ConstructorScope constructorScope) {
125126
assert(enumConstantInfos == null || enumConstantInfos.isNotEmpty);
126127

127128
Uri fileUri = parent.fileUri;
@@ -374,7 +375,7 @@ class EnumBuilder extends SourceClassBuilder {
374375
parent: parent.scope,
375376
debugName: "enum $name",
376377
isModifiable: false),
377-
new ConstructorScope(name, constructors),
378+
constructorScope..local.addAll(constructors),
378379
cls,
379380
enumConstantInfos,
380381
intType,

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

Lines changed: 15 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1775,6 +1775,7 @@ class OutlineBuilder extends StackListenerImpl {
17751775
case _MethodKind.classConstructor:
17761776
case _MethodKind.mixinConstructor:
17771777
case _MethodKind.extensionConstructor:
1778+
case _MethodKind.enumConstructor:
17781779
constructorName = libraryBuilder.computeAndValidateConstructorName(
17791780
name, charOffset) ??
17801781
name as String?;
@@ -2340,6 +2341,14 @@ class OutlineBuilder extends StackListenerImpl {
23402341
@override
23412342
void handleEnumElements(Token elementsEndToken, int elementsCount) {
23422343
debugEvent("EnumElements");
2344+
push(elementsCount);
2345+
}
2346+
2347+
@override
2348+
void endEnum(Token enumKeyword, Token leftBrace, int memberCount) {
2349+
debugEvent("Enum");
2350+
2351+
int elementsCount = pop() as int;
23432352
List<EnumConstantInfo?>? enumConstantInfos =
23442353
const FixedNullableList<EnumConstantInfo>().pop(stack, elementsCount);
23452354
int endCharOffset = popCharOffset();
@@ -2354,19 +2363,15 @@ class OutlineBuilder extends StackListenerImpl {
23542363
checkEmpty(startCharOffset);
23552364

23562365
if (name is! ParserRecovery) {
2357-
libraryBuilder.addEnum(metadata, name as String, enumConstantInfos,
2358-
startCharOffset, charOffset, endCharOffset);
2366+
libraryBuilder.addEnum(metadata, name as String, typeVariables,
2367+
enumConstantInfos, startCharOffset, charOffset, endCharOffset);
23592368
} else {
23602369
libraryBuilder
23612370
.endNestedDeclaration(
23622371
TypeParameterScopeKind.enumDeclaration, "<syntax-error>")
23632372
.resolveNamedTypes(typeVariables, libraryBuilder);
23642373
}
2365-
}
23662374

2367-
@override
2368-
void endEnum(Token enumKeyword, Token leftBrace, int memberCount) {
2369-
debugEvent("Enum");
23702375
checkEmpty(enumKeyword.charOffset);
23712376
popDeclarationContext(DeclarationContext.Enum);
23722377
}
@@ -3029,7 +3034,6 @@ class OutlineBuilder extends StackListenerImpl {
30293034
pop(); // name
30303035
pop(); // modifiers
30313036
pop(); // metadata
3032-
checkEmpty(beginToken.charOffset);
30333037
popDeclarationContext();
30343038
// TODO(cstefantsova): Use actual type parameters.
30353039
libraryBuilder
@@ -3068,7 +3072,6 @@ class OutlineBuilder extends StackListenerImpl {
30683072
int modifiers = Modifier.toMask(pop() as List<Modifier>?);
30693073
popCharOffset(); // final or const offset
30703074
pop(); // metadata
3071-
checkEmpty(beginToken.charOffset);
30723075
popDeclarationContext();
30733076
TypeParameterScopeKind scopeKind;
30743077
if ((modifiers & staticMask) != 0) {
@@ -3107,7 +3110,6 @@ class OutlineBuilder extends StackListenerImpl {
31073110
popFieldInfos(count); // field infos
31083111
pop(); // type
31093112
pop(); // metadata
3110-
checkEmpty(beginToken.charOffset);
31113113
popDeclarationContext();
31123114
// Skip the declaration. An error as already been produced by the parser.
31133115

@@ -3123,36 +3125,15 @@ class OutlineBuilder extends StackListenerImpl {
31233125
@override
31243126
void endEnumConstructor(Token? getOrSet, Token beginToken, Token beginParam,
31253127
Token? beginInitializers, Token endToken) {
3126-
// TODO(cstefantsova): Call endClassConstructor instead.
3127-
debugEvent("EnumMethod");
3128-
MethodBody bodyKind = pop() as MethodBody;
3129-
if (bodyKind == MethodBody.RedirectingFactoryBody) {
3130-
pop(); // reference
3131-
}
3132-
pop(); // async marker
3133-
pop(); // formals
3134-
popCharOffset(); // formals char offset
3135-
pop(); // type variables
3136-
popCharOffset(); // char offset
3137-
pop(); // name
3138-
pop(); // return type
3139-
pop(); // modifiers
3140-
popCharOffset(); // final or const offset
3141-
pop(); // metadata
3142-
checkEmpty(beginToken.charOffset);
3143-
popDeclarationContext();
3144-
// TODO(cstefantsova): Use actual type parameters.
3145-
libraryBuilder
3146-
.endNestedDeclaration(TypeParameterScopeKind.instanceMethod, "#method")
3147-
.resolveNamedTypes([], libraryBuilder);
3148-
// Skip the declaration. An error as already been produced by the parser.
3149-
31503128
if (!libraryBuilder.enableEnhancedEnumsInLibrary) {
31513129
addProblem(
31523130
templateExperimentNotEnabled.withArguments('enhanced-enums',
31533131
libraryBuilder.enableEnhancedEnumsVersionInLibrary.toText()),
31543132
beginToken.charOffset,
31553133
-1);
3134+
} else {
3135+
_endClassMethod(getOrSet, beginToken, beginParam, beginInitializers,
3136+
endToken, _MethodKind.enumConstructor);
31563137
}
31573138
}
31583139

@@ -3337,4 +3318,5 @@ enum _MethodKind {
33373318
mixinMethod,
33383319
extensionConstructor,
33393320
extensionMethod,
3321+
enumConstructor,
33403322
}

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

Lines changed: 42 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2815,6 +2815,7 @@ class SourceLibraryBuilder extends LibraryBuilderImpl {
28152815
void addEnum(
28162816
List<MetadataBuilder>? metadata,
28172817
String name,
2818+
List<TypeVariableBuilder>? typeVariables,
28182819
List<EnumConstantInfo?>? enumConstantInfos,
28192820
int startCharOffset,
28202821
int charOffset,
@@ -2829,7 +2830,11 @@ class SourceLibraryBuilder extends LibraryBuilderImpl {
28292830
TypeParameterScopeBuilder declaration =
28302831
endNestedDeclaration(TypeParameterScopeKind.enumDeclaration, name)
28312832
..resolveNamedTypes([], this);
2832-
EnumBuilder builder = new EnumBuilder(
2833+
Map<String, Builder> members = declaration.members!;
2834+
Map<String, MemberBuilder> constructors = declaration.constructors!;
2835+
Map<String, MemberBuilder> setters = declaration.setters!;
2836+
2837+
EnumBuilder enumBuilder = new EnumBuilder(
28332838
metadata,
28342839
name,
28352840
enumConstantInfos,
@@ -2839,12 +2844,44 @@ class SourceLibraryBuilder extends LibraryBuilderImpl {
28392844
charEndOffset,
28402845
referencesFromIndexedClass,
28412846
new Scope(
2842-
local: declaration.members!,
2843-
setters: declaration.setters!,
2847+
local: members,
2848+
setters: setters,
28442849
parent: scope.withTypeVariables(<TypeVariableBuilder>[]),
28452850
debugName: "enum $name",
2846-
isModifiable: false));
2847-
addBuilder(name, builder, charOffset,
2851+
isModifiable: false),
2852+
new ConstructorScope(name, constructors));
2853+
2854+
Map<String, TypeVariableBuilder>? typeVariablesByName =
2855+
checkTypeVariables(typeVariables, enumBuilder);
2856+
2857+
void setParent(String name, MemberBuilder? member) {
2858+
while (member != null) {
2859+
member.parent = enumBuilder;
2860+
member = member.next as MemberBuilder?;
2861+
}
2862+
}
2863+
2864+
void setParentAndCheckConflicts(String name, Builder member) {
2865+
if (typeVariablesByName != null) {
2866+
TypeVariableBuilder? tv = typeVariablesByName[name];
2867+
if (tv != null) {
2868+
enumBuilder.addProblem(
2869+
templateConflictsWithTypeVariable.withArguments(name),
2870+
member.charOffset,
2871+
name.length,
2872+
context: [
2873+
messageConflictsWithTypeVariableCause.withLocation(
2874+
tv.fileUri!, tv.charOffset, name.length)
2875+
]);
2876+
}
2877+
}
2878+
setParent(name, member as MemberBuilder);
2879+
}
2880+
2881+
members.forEach(setParentAndCheckConflicts);
2882+
constructors.forEach(setParentAndCheckConflicts);
2883+
setters.forEach(setParentAndCheckConflicts);
2884+
addBuilder(name, enumBuilder, charOffset,
28482885
getterReference: referencesFromIndexedClass?.cls.reference);
28492886
}
28502887

pkg/front_end/testcases/enhanced_enums/entries_with_type_arguments.dart.strong.expect

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,11 @@
11
library /*isNonNullableByDefault*/;
2+
//
3+
// Problems in library:
4+
//
5+
// pkg/front_end/testcases/enhanced_enums/entries_with_type_arguments.dart:11:9: Error: The superclass, '_Enum', has no unnamed constructor that takes no arguments.
6+
// const E.named(int value);
7+
// ^^^^^
8+
//
29
import self as self;
310
import "dart:core" as core;
411

@@ -10,6 +17,11 @@ class E extends core::_Enum /*isEnum*/ {
1017
const constructor •(core::int index, core::String name) → self::E
1118
: super core::_Enum::•(index, name)
1219
;
20+
const constructor named(core::int value) → self::E
21+
: final dynamic #t1 = invalid-expression "pkg/front_end/testcases/enhanced_enums/entries_with_type_arguments.dart:11:9: Error: The superclass, '_Enum', has no unnamed constructor that takes no arguments.
22+
const E.named(int value);
23+
^^^^^"
24+
;
1325
method toString() → core::String
1426
return "E.${this.{core::_Enum::_name}{core::String}}";
1527
}

pkg/front_end/testcases/enhanced_enums/entries_with_type_arguments.dart.strong.transformed.expect

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,11 @@
11
library /*isNonNullableByDefault*/;
2+
//
3+
// Problems in library:
4+
//
5+
// pkg/front_end/testcases/enhanced_enums/entries_with_type_arguments.dart:11:9: Error: The superclass, '_Enum', has no unnamed constructor that takes no arguments.
6+
// const E.named(int value);
7+
// ^^^^^
8+
//
29
import self as self;
310
import "dart:core" as core;
411

@@ -10,6 +17,11 @@ class E extends core::_Enum /*isEnum*/ {
1017
const constructor •(core::int index, core::String name) → self::E
1118
: super core::_Enum::•(index, name)
1219
;
20+
const constructor named(core::int value) → self::E
21+
: final dynamic #t1 = invalid-expression "pkg/front_end/testcases/enhanced_enums/entries_with_type_arguments.dart:11:9: Error: The superclass, '_Enum', has no unnamed constructor that takes no arguments.
22+
const E.named(int value);
23+
^^^^^"
24+
;
1325
method toString() → core::String
1426
return "E.${this.{core::_Enum::_name}{core::String}}";
1527
}

pkg/front_end/testcases/enhanced_enums/entries_with_type_arguments.dart.weak.expect

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,11 @@
11
library /*isNonNullableByDefault*/;
2+
//
3+
// Problems in library:
4+
//
5+
// pkg/front_end/testcases/enhanced_enums/entries_with_type_arguments.dart:11:9: Error: The superclass, '_Enum', has no unnamed constructor that takes no arguments.
6+
// const E.named(int value);
7+
// ^^^^^
8+
//
29
import self as self;
310
import "dart:core" as core;
411

@@ -10,6 +17,11 @@ class E extends core::_Enum /*isEnum*/ {
1017
const constructor •(core::int index, core::String name) → self::E
1118
: super core::_Enum::•(index, name)
1219
;
20+
const constructor named(core::int value) → self::E
21+
: final dynamic #t1 = invalid-expression "pkg/front_end/testcases/enhanced_enums/entries_with_type_arguments.dart:11:9: Error: The superclass, '_Enum', has no unnamed constructor that takes no arguments.
22+
const E.named(int value);
23+
^^^^^"
24+
;
1325
method toString() → core::String
1426
return "E.${this.{core::_Enum::_name}{core::String}}";
1527
}

pkg/front_end/testcases/enhanced_enums/entries_with_type_arguments.dart.weak.modular.expect

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,11 @@
11
library /*isNonNullableByDefault*/;
2+
//
3+
// Problems in library:
4+
//
5+
// pkg/front_end/testcases/enhanced_enums/entries_with_type_arguments.dart:11:9: Error: The superclass, '_Enum', has no unnamed constructor that takes no arguments.
6+
// const E.named(int value);
7+
// ^^^^^
8+
//
29
import self as self;
310
import "dart:core" as core;
411

@@ -10,6 +17,11 @@ class E extends core::_Enum /*isEnum*/ {
1017
const constructor •(core::int index, core::String name) → self::E
1118
: super core::_Enum::•(index, name)
1219
;
20+
const constructor named(core::int value) → self::E
21+
: final dynamic #t1 = invalid-expression "pkg/front_end/testcases/enhanced_enums/entries_with_type_arguments.dart:11:9: Error: The superclass, '_Enum', has no unnamed constructor that takes no arguments.
22+
const E.named(int value);
23+
^^^^^"
24+
;
1325
method toString() → core::String
1426
return "E.${this.{core::_Enum::_name}{core::String}}";
1527
}

pkg/front_end/testcases/enhanced_enums/entries_with_type_arguments.dart.weak.outline.expect

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,11 @@
11
library /*isNonNullableByDefault*/;
2+
//
3+
// Problems in library:
4+
//
5+
// pkg/front_end/testcases/enhanced_enums/entries_with_type_arguments.dart:11:9: Error: The superclass, '_Enum', has no unnamed constructor that takes no arguments.
6+
// const E.named(int value);
7+
// ^^^^^
8+
//
29
import self as self;
310
import "dart:core" as core;
411

@@ -10,6 +17,11 @@ class E extends core::_Enum /*isEnum*/ {
1017
const constructor •(core::int index, core::String name) → self::E
1118
: super core::_Enum::•(index, name)
1219
;
20+
const constructor named(core::int value) → self::E
21+
: final dynamic #t1 = invalid-expression "pkg/front_end/testcases/enhanced_enums/entries_with_type_arguments.dart:11:9: Error: The superclass, '_Enum', has no unnamed constructor that takes no arguments.
22+
const E.named(int value);
23+
^^^^^"
24+
;
1325
method toString() → core::String
1426
return "E.${this.{core::_Enum::_name}{core::String}}";
1527
}

pkg/front_end/testcases/enhanced_enums/entries_with_type_arguments.dart.weak.transformed.expect

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,11 @@
11
library /*isNonNullableByDefault*/;
2+
//
3+
// Problems in library:
4+
//
5+
// pkg/front_end/testcases/enhanced_enums/entries_with_type_arguments.dart:11:9: Error: The superclass, '_Enum', has no unnamed constructor that takes no arguments.
6+
// const E.named(int value);
7+
// ^^^^^
8+
//
29
import self as self;
310
import "dart:core" as core;
411

@@ -10,6 +17,11 @@ class E extends core::_Enum /*isEnum*/ {
1017
const constructor •(core::int index, core::String name) → self::E
1118
: super core::_Enum::•(index, name)
1219
;
20+
const constructor named(core::int value) → self::E
21+
: final dynamic #t1 = invalid-expression "pkg/front_end/testcases/enhanced_enums/entries_with_type_arguments.dart:11:9: Error: The superclass, '_Enum', has no unnamed constructor that takes no arguments.
22+
const E.named(int value);
23+
^^^^^"
24+
;
1325
method toString() → core::String
1426
return "E.${this.{core::_Enum::_name}{core::String}}";
1527
}

pkg/front_end/testcases/enhanced_enums/qualified_names_with_no_type_arguments.dart.strong.expect

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,22 @@
11
library /*isNonNullableByDefault*/;
2+
//
3+
// Problems in library:
4+
//
5+
// pkg/front_end/testcases/enhanced_enums/qualified_names_with_no_type_arguments.dart:8:9: Error: The superclass, '_Enum', has no unnamed constructor that takes no arguments.
6+
// const E.b();
7+
// ^
8+
//
29
import self as self;
310
import "dart:core" as core;
411

512
class E extends core::_Enum /*isEnum*/ {
613
static const field core::List<self::E> values = #C4;
714
static const field self::E a = #C3;
15+
const constructor b() → self::E
16+
: final dynamic #t1 = invalid-expression "pkg/front_end/testcases/enhanced_enums/qualified_names_with_no_type_arguments.dart:8:9: Error: The superclass, '_Enum', has no unnamed constructor that takes no arguments.
17+
const E.b();
18+
^"
19+
;
820
const constructor •(core::int index, core::String name) → self::E
921
: super core::_Enum::•(index, name)
1022
;

pkg/front_end/testcases/enhanced_enums/qualified_names_with_no_type_arguments.dart.strong.transformed.expect

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,22 @@
11
library /*isNonNullableByDefault*/;
2+
//
3+
// Problems in library:
4+
//
5+
// pkg/front_end/testcases/enhanced_enums/qualified_names_with_no_type_arguments.dart:8:9: Error: The superclass, '_Enum', has no unnamed constructor that takes no arguments.
6+
// const E.b();
7+
// ^
8+
//
29
import self as self;
310
import "dart:core" as core;
411

512
class E extends core::_Enum /*isEnum*/ {
613
static const field core::List<self::E> values = #C4;
714
static const field self::E a = #C3;
15+
const constructor b() → self::E
16+
: final dynamic #t1 = invalid-expression "pkg/front_end/testcases/enhanced_enums/qualified_names_with_no_type_arguments.dart:8:9: Error: The superclass, '_Enum', has no unnamed constructor that takes no arguments.
17+
const E.b();
18+
^"
19+
;
820
const constructor •(core::int index, core::String name) → self::E
921
: super core::_Enum::•(index, name)
1022
;

0 commit comments

Comments
 (0)