Skip to content

Commit 75920dd

Browse files
chloestefantsovaCommit Queue
authored and
Commit Queue
committed
[cfe] Report error on trailing comma in extension type declarations
Part of #53625 Part of #49731 Change-Id: I793ef6329d99b1a4e829491f454f42c2ede941b4 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/331185 Commit-Queue: Chloe Stefantsova <[email protected]> Reviewed-by: Johnni Winther <[email protected]>
1 parent 67d4561 commit 75920dd

12 files changed

+259
-0
lines changed

pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart

+11
Original file line numberDiff line numberDiff line change
@@ -12476,6 +12476,17 @@ const MessageCode messageRepresentationFieldModifier = const MessageCode(
1247612476
analyzerCodes: <String>["REPRESENTATION_FIELD_MODIFIER"],
1247712477
problemMessage: r"""Representation fields can't have modifiers.""");
1247812478

12479+
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
12480+
const Code<Null> codeRepresentationFieldTrailingComma =
12481+
messageRepresentationFieldTrailingComma;
12482+
12483+
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
12484+
const MessageCode messageRepresentationFieldTrailingComma = const MessageCode(
12485+
"RepresentationFieldTrailingComma",
12486+
analyzerCodes: <String>["REPRESENTATION_FIELD_TRAILING_COMMA"],
12487+
problemMessage:
12488+
r"""The representation field can't have a trailing comma.""");
12489+
1247912490
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
1248012491
const Template<Message Function(String name)>
1248112492
templateRequiredNamedParameterHasDefaultValueError =

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

+9
Original file line numberDiff line numberDiff line change
@@ -2721,6 +2721,15 @@ class OutlineBuilder extends StackListenerImpl {
27212721
assert(last != null);
27222722
formals = [last as FormalParameterBuilder];
27232723
}
2724+
2725+
Token? tokenBeforeEnd = endToken.previous;
2726+
if (tokenBeforeEnd != null &&
2727+
optional(",", tokenBeforeEnd) &&
2728+
kind == MemberKind.PrimaryConstructor &&
2729+
declarationContext == DeclarationContext.ExtensionType) {
2730+
libraryBuilder.addProblem(messageRepresentationFieldTrailingComma,
2731+
tokenBeforeEnd.charOffset, 1, uri);
2732+
}
27242733
} else if (count > 1) {
27252734
Object? last = pop();
27262735
count--;

pkg/front_end/messages.yaml

+7
Original file line numberDiff line numberDiff line change
@@ -7447,3 +7447,10 @@ ExtensionTypeRepresentationTypeBottom:
74477447
script: |
74487448
extension type E1(Never foo) {}
74497449
analyzerCode: EXTENSION_TYPE_REPRESENTATION_TYPE_BOTTOM
7450+
7451+
RepresentationFieldTrailingComma:
7452+
problemMessage: "The representation field can't have a trailing comma."
7453+
experiments: inline-class
7454+
script: |
7455+
extension type E(int foo,) {}
7456+
analyzerCode: REPRESENTATION_FIELD_TRAILING_COMMA

pkg/front_end/testcases/extension_types/representation_field_error.dart

+2
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,5 @@ extension type E7(const var foo) {} // Error.
1212
extension type E8() {} // Error.
1313
extension type E9(int foo, String bar) {} // Error.
1414
extension type E10(num foo, bool bar, double baz) {} // Error.
15+
extension type E11(bool foo,) {} // Error.
16+
extension type E12(bool foo = false,) {} // Error.

pkg/front_end/testcases/extension_types/representation_field_error.dart.strong.expect

+39
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,19 @@ library;
6565
// extension type E10(num foo, bool bar, double baz) {} // Error.
6666
// ^
6767
//
68+
// pkg/front_end/testcases/extension_types/representation_field_error.dart:15:28: Error: The representation field can't have a trailing comma.
69+
// extension type E11(bool foo,) {} // Error.
70+
// ^
71+
//
72+
// pkg/front_end/testcases/extension_types/representation_field_error.dart:16:29: Error: Non-optional parameters can't have a default value.
73+
// Try removing the default value or making the parameter optional.
74+
// extension type E12(bool foo = false,) {} // Error.
75+
// ^
76+
//
77+
// pkg/front_end/testcases/extension_types/representation_field_error.dart:16:36: Error: The representation field can't have a trailing comma.
78+
// extension type E12(bool foo = false,) {} // Error.
79+
// ^
80+
//
6881
import self as self;
6982
import "dart:core" as core;
7083

@@ -120,6 +133,16 @@ extension type E10(core::num foo) {
120133
constructor • = self::E10|constructor#;
121134
constructor tearoff • = self::E10|constructor#_#new#tearOff;
122135
}
136+
extension type E11(core::bool foo) {
137+
abstract inline-class-member representation-field get foo() → core::bool;
138+
constructor • = self::E11|constructor#;
139+
constructor tearoff • = self::E11|constructor#_#new#tearOff;
140+
}
141+
extension type E12(core::bool foo) {
142+
abstract inline-class-member representation-field get foo() → core::bool;
143+
constructor • = self::E12|constructor#;
144+
constructor tearoff • = self::E12|constructor#_#new#tearOff;
145+
}
123146
static inline-class-member method E1|constructor#(dynamic foo) → self::E1 /* = dynamic */ {
124147
lowered final self::E1 /* = dynamic */ #this = foo;
125148
return #this;
@@ -180,3 +203,19 @@ static inline-class-member method E10|constructor#(core::num foo, core::bool bar
180203
}
181204
static inline-class-member method E10|constructor#_#new#tearOff(core::num foo, core::bool bar, core::double baz) → self::E10 /* = core::num */
182205
return self::E10|constructor#(foo, bar, baz);
206+
static inline-class-member method E11|constructor#(core::bool foo) → self::E11 /* = core::bool */ {
207+
lowered final self::E11 /* = core::bool */ #this = foo;
208+
return #this;
209+
}
210+
static inline-class-member method E11|constructor#_#new#tearOff(core::bool foo) → self::E11 /* = core::bool */
211+
return self::E11|constructor#(foo);
212+
static inline-class-member method E12|constructor#(core::bool foo = #C1) → self::E12 /* = core::bool */ {
213+
lowered final self::E12 /* = core::bool */ #this = foo;
214+
return #this;
215+
}
216+
static inline-class-member method E12|constructor#_#new#tearOff(has-declared-initializer core::bool foo) → self::E12 /* = core::bool */
217+
return self::E12|constructor#(foo);
218+
219+
constants {
220+
#C1 = false
221+
}

pkg/front_end/testcases/extension_types/representation_field_error.dart.strong.transformed.expect

+39
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,19 @@ library;
6565
// extension type E10(num foo, bool bar, double baz) {} // Error.
6666
// ^
6767
//
68+
// pkg/front_end/testcases/extension_types/representation_field_error.dart:15:28: Error: The representation field can't have a trailing comma.
69+
// extension type E11(bool foo,) {} // Error.
70+
// ^
71+
//
72+
// pkg/front_end/testcases/extension_types/representation_field_error.dart:16:29: Error: Non-optional parameters can't have a default value.
73+
// Try removing the default value or making the parameter optional.
74+
// extension type E12(bool foo = false,) {} // Error.
75+
// ^
76+
//
77+
// pkg/front_end/testcases/extension_types/representation_field_error.dart:16:36: Error: The representation field can't have a trailing comma.
78+
// extension type E12(bool foo = false,) {} // Error.
79+
// ^
80+
//
6881
import self as self;
6982
import "dart:core" as core;
7083

@@ -120,6 +133,16 @@ extension type E10(core::num foo) {
120133
constructor • = self::E10|constructor#;
121134
constructor tearoff • = self::E10|constructor#_#new#tearOff;
122135
}
136+
extension type E11(core::bool foo) {
137+
abstract inline-class-member representation-field get foo() → core::bool;
138+
constructor • = self::E11|constructor#;
139+
constructor tearoff • = self::E11|constructor#_#new#tearOff;
140+
}
141+
extension type E12(core::bool foo) {
142+
abstract inline-class-member representation-field get foo() → core::bool;
143+
constructor • = self::E12|constructor#;
144+
constructor tearoff • = self::E12|constructor#_#new#tearOff;
145+
}
123146
static inline-class-member method E1|constructor#(dynamic foo) → self::E1 /* = dynamic */ {
124147
lowered final self::E1 /* = dynamic */ #this = foo;
125148
return #this;
@@ -180,3 +203,19 @@ static inline-class-member method E10|constructor#(core::num foo, core::bool bar
180203
}
181204
static inline-class-member method E10|constructor#_#new#tearOff(core::num foo, core::bool bar, core::double baz) → self::E10 /* = core::num */
182205
return self::E10|constructor#(foo, bar, baz);
206+
static inline-class-member method E11|constructor#(core::bool foo) → self::E11 /* = core::bool */ {
207+
lowered final self::E11 /* = core::bool */ #this = foo;
208+
return #this;
209+
}
210+
static inline-class-member method E11|constructor#_#new#tearOff(core::bool foo) → self::E11 /* = core::bool */
211+
return self::E11|constructor#(foo);
212+
static inline-class-member method E12|constructor#(core::bool foo = #C1) → self::E12 /* = core::bool */ {
213+
lowered final self::E12 /* = core::bool */ #this = foo;
214+
return #this;
215+
}
216+
static inline-class-member method E12|constructor#_#new#tearOff(has-declared-initializer core::bool foo) → self::E12 /* = core::bool */
217+
return self::E12|constructor#(foo);
218+
219+
constants {
220+
#C1 = false
221+
}

pkg/front_end/testcases/extension_types/representation_field_error.dart.textual_outline.expect

+2
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,5 @@ extension type E7(const var foo) {}
88
extension type E8() {}
99
extension type E9(int foo, String bar) {}
1010
extension type E10(num foo, bool bar, double baz) {}
11+
extension type E11(bool foo,) {}
12+
extension type E12(bool foo = false,) {}

pkg/front_end/testcases/extension_types/representation_field_error.dart.textual_outline_modelled.expect

+2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
extension type E1(var foo) {}
22
extension type E10(num foo, bool bar, double baz) {}
3+
extension type E11(bool foo,) {}
4+
extension type E12(bool foo = false,) {}
35
extension type E2(final foo) {}
46
extension type E3(final String foo) {}
57
extension type E4(covariant num foo) {}

pkg/front_end/testcases/extension_types/representation_field_error.dart.weak.expect

+39
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,19 @@ library;
6565
// extension type E10(num foo, bool bar, double baz) {} // Error.
6666
// ^
6767
//
68+
// pkg/front_end/testcases/extension_types/representation_field_error.dart:15:28: Error: The representation field can't have a trailing comma.
69+
// extension type E11(bool foo,) {} // Error.
70+
// ^
71+
//
72+
// pkg/front_end/testcases/extension_types/representation_field_error.dart:16:29: Error: Non-optional parameters can't have a default value.
73+
// Try removing the default value or making the parameter optional.
74+
// extension type E12(bool foo = false,) {} // Error.
75+
// ^
76+
//
77+
// pkg/front_end/testcases/extension_types/representation_field_error.dart:16:36: Error: The representation field can't have a trailing comma.
78+
// extension type E12(bool foo = false,) {} // Error.
79+
// ^
80+
//
6881
import self as self;
6982
import "dart:core" as core;
7083

@@ -120,6 +133,16 @@ extension type E10(core::num foo) {
120133
constructor • = self::E10|constructor#;
121134
constructor tearoff • = self::E10|constructor#_#new#tearOff;
122135
}
136+
extension type E11(core::bool foo) {
137+
abstract inline-class-member representation-field get foo() → core::bool;
138+
constructor • = self::E11|constructor#;
139+
constructor tearoff • = self::E11|constructor#_#new#tearOff;
140+
}
141+
extension type E12(core::bool foo) {
142+
abstract inline-class-member representation-field get foo() → core::bool;
143+
constructor • = self::E12|constructor#;
144+
constructor tearoff • = self::E12|constructor#_#new#tearOff;
145+
}
123146
static inline-class-member method E1|constructor#(dynamic foo) → self::E1 /* = dynamic */ {
124147
lowered final self::E1 /* = dynamic */ #this = foo;
125148
return #this;
@@ -180,3 +203,19 @@ static inline-class-member method E10|constructor#(core::num foo, core::bool bar
180203
}
181204
static inline-class-member method E10|constructor#_#new#tearOff(core::num foo, core::bool bar, core::double baz) → self::E10 /* = core::num */
182205
return self::E10|constructor#(foo, bar, baz);
206+
static inline-class-member method E11|constructor#(core::bool foo) → self::E11 /* = core::bool */ {
207+
lowered final self::E11 /* = core::bool */ #this = foo;
208+
return #this;
209+
}
210+
static inline-class-member method E11|constructor#_#new#tearOff(core::bool foo) → self::E11 /* = core::bool */
211+
return self::E11|constructor#(foo);
212+
static inline-class-member method E12|constructor#(core::bool foo = #C1) → self::E12 /* = core::bool */ {
213+
lowered final self::E12 /* = core::bool */ #this = foo;
214+
return #this;
215+
}
216+
static inline-class-member method E12|constructor#_#new#tearOff(has-declared-initializer core::bool foo) → self::E12 /* = core::bool */
217+
return self::E12|constructor#(foo);
218+
219+
constants {
220+
#C1 = false
221+
}

pkg/front_end/testcases/extension_types/representation_field_error.dart.weak.modular.expect

+39
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,19 @@ library;
6565
// extension type E10(num foo, bool bar, double baz) {} // Error.
6666
// ^
6767
//
68+
// pkg/front_end/testcases/extension_types/representation_field_error.dart:15:28: Error: The representation field can't have a trailing comma.
69+
// extension type E11(bool foo,) {} // Error.
70+
// ^
71+
//
72+
// pkg/front_end/testcases/extension_types/representation_field_error.dart:16:29: Error: Non-optional parameters can't have a default value.
73+
// Try removing the default value or making the parameter optional.
74+
// extension type E12(bool foo = false,) {} // Error.
75+
// ^
76+
//
77+
// pkg/front_end/testcases/extension_types/representation_field_error.dart:16:36: Error: The representation field can't have a trailing comma.
78+
// extension type E12(bool foo = false,) {} // Error.
79+
// ^
80+
//
6881
import self as self;
6982
import "dart:core" as core;
7083

@@ -120,6 +133,16 @@ extension type E10(core::num foo) {
120133
constructor • = self::E10|constructor#;
121134
constructor tearoff • = self::E10|constructor#_#new#tearOff;
122135
}
136+
extension type E11(core::bool foo) {
137+
abstract inline-class-member representation-field get foo() → core::bool;
138+
constructor • = self::E11|constructor#;
139+
constructor tearoff • = self::E11|constructor#_#new#tearOff;
140+
}
141+
extension type E12(core::bool foo) {
142+
abstract inline-class-member representation-field get foo() → core::bool;
143+
constructor • = self::E12|constructor#;
144+
constructor tearoff • = self::E12|constructor#_#new#tearOff;
145+
}
123146
static inline-class-member method E1|constructor#(dynamic foo) → self::E1 /* = dynamic */ {
124147
lowered final self::E1 /* = dynamic */ #this = foo;
125148
return #this;
@@ -180,3 +203,19 @@ static inline-class-member method E10|constructor#(core::num foo, core::bool bar
180203
}
181204
static inline-class-member method E10|constructor#_#new#tearOff(core::num foo, core::bool bar, core::double baz) → self::E10 /* = core::num */
182205
return self::E10|constructor#(foo, bar, baz);
206+
static inline-class-member method E11|constructor#(core::bool foo) → self::E11 /* = core::bool */ {
207+
lowered final self::E11 /* = core::bool */ #this = foo;
208+
return #this;
209+
}
210+
static inline-class-member method E11|constructor#_#new#tearOff(core::bool foo) → self::E11 /* = core::bool */
211+
return self::E11|constructor#(foo);
212+
static inline-class-member method E12|constructor#(core::bool foo = #C1) → self::E12 /* = core::bool */ {
213+
lowered final self::E12 /* = core::bool */ #this = foo;
214+
return #this;
215+
}
216+
static inline-class-member method E12|constructor#_#new#tearOff(has-declared-initializer core::bool foo) → self::E12 /* = core::bool */
217+
return self::E12|constructor#(foo);
218+
219+
constants {
220+
#C1 = false
221+
}

pkg/front_end/testcases/extension_types/representation_field_error.dart.weak.outline.expect

+31
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,19 @@ library;
6565
// extension type E10(num foo, bool bar, double baz) {} // Error.
6666
// ^
6767
//
68+
// pkg/front_end/testcases/extension_types/representation_field_error.dart:15:28: Error: The representation field can't have a trailing comma.
69+
// extension type E11(bool foo,) {} // Error.
70+
// ^
71+
//
72+
// pkg/front_end/testcases/extension_types/representation_field_error.dart:16:29: Error: Non-optional parameters can't have a default value.
73+
// Try removing the default value or making the parameter optional.
74+
// extension type E12(bool foo = false,) {} // Error.
75+
// ^
76+
//
77+
// pkg/front_end/testcases/extension_types/representation_field_error.dart:16:36: Error: The representation field can't have a trailing comma.
78+
// extension type E12(bool foo = false,) {} // Error.
79+
// ^
80+
//
6881
import self as self;
6982
import "dart:core" as core;
7083

@@ -120,6 +133,16 @@ extension type E10(core::num foo) {
120133
constructor • = self::E10|constructor#;
121134
constructor tearoff • = self::E10|constructor#_#new#tearOff;
122135
}
136+
extension type E11(core::bool foo) {
137+
abstract inline-class-member representation-field get foo() → core::bool;
138+
constructor • = self::E11|constructor#;
139+
constructor tearoff • = self::E11|constructor#_#new#tearOff;
140+
}
141+
extension type E12(core::bool foo) {
142+
abstract inline-class-member representation-field get foo() → core::bool;
143+
constructor • = self::E12|constructor#;
144+
constructor tearoff • = self::E12|constructor#_#new#tearOff;
145+
}
123146
static inline-class-member method E1|constructor#(dynamic foo) → self::E1 /* = dynamic */
124147
;
125148
static inline-class-member method E1|constructor#_#new#tearOff(dynamic foo) → self::E1 /* = dynamic */
@@ -160,3 +183,11 @@ static inline-class-member method E10|constructor#(core::num foo, core::bool bar
160183
;
161184
static inline-class-member method E10|constructor#_#new#tearOff(core::num foo, core::bool bar, core::double baz) → self::E10 /* = core::num */
162185
return self::E10|constructor#(foo, bar, baz);
186+
static inline-class-member method E11|constructor#(core::bool foo) → self::E11 /* = core::bool */
187+
;
188+
static inline-class-member method E11|constructor#_#new#tearOff(core::bool foo) → self::E11 /* = core::bool */
189+
return self::E11|constructor#(foo);
190+
static inline-class-member method E12|constructor#(has-declared-initializer core::bool foo) → self::E12 /* = core::bool */
191+
;
192+
static inline-class-member method E12|constructor#_#new#tearOff(has-declared-initializer core::bool foo) → self::E12 /* = core::bool */
193+
return self::E12|constructor#(foo);

pkg/front_end/testcases/extension_types/representation_field_error.dart.weak.transformed.expect

+39
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,19 @@ library;
6565
// extension type E10(num foo, bool bar, double baz) {} // Error.
6666
// ^
6767
//
68+
// pkg/front_end/testcases/extension_types/representation_field_error.dart:15:28: Error: The representation field can't have a trailing comma.
69+
// extension type E11(bool foo,) {} // Error.
70+
// ^
71+
//
72+
// pkg/front_end/testcases/extension_types/representation_field_error.dart:16:29: Error: Non-optional parameters can't have a default value.
73+
// Try removing the default value or making the parameter optional.
74+
// extension type E12(bool foo = false,) {} // Error.
75+
// ^
76+
//
77+
// pkg/front_end/testcases/extension_types/representation_field_error.dart:16:36: Error: The representation field can't have a trailing comma.
78+
// extension type E12(bool foo = false,) {} // Error.
79+
// ^
80+
//
6881
import self as self;
6982
import "dart:core" as core;
7083

@@ -120,6 +133,16 @@ extension type E10(core::num foo) {
120133
constructor • = self::E10|constructor#;
121134
constructor tearoff • = self::E10|constructor#_#new#tearOff;
122135
}
136+
extension type E11(core::bool foo) {
137+
abstract inline-class-member representation-field get foo() → core::bool;
138+
constructor • = self::E11|constructor#;
139+
constructor tearoff • = self::E11|constructor#_#new#tearOff;
140+
}
141+
extension type E12(core::bool foo) {
142+
abstract inline-class-member representation-field get foo() → core::bool;
143+
constructor • = self::E12|constructor#;
144+
constructor tearoff • = self::E12|constructor#_#new#tearOff;
145+
}
123146
static inline-class-member method E1|constructor#(dynamic foo) → self::E1 /* = dynamic */ {
124147
lowered final self::E1 /* = dynamic */ #this = foo;
125148
return #this;
@@ -180,3 +203,19 @@ static inline-class-member method E10|constructor#(core::num foo, core::bool bar
180203
}
181204
static inline-class-member method E10|constructor#_#new#tearOff(core::num foo, core::bool bar, core::double baz) → self::E10 /* = core::num */
182205
return self::E10|constructor#(foo, bar, baz);
206+
static inline-class-member method E11|constructor#(core::bool foo) → self::E11 /* = core::bool */ {
207+
lowered final self::E11 /* = core::bool */ #this = foo;
208+
return #this;
209+
}
210+
static inline-class-member method E11|constructor#_#new#tearOff(core::bool foo) → self::E11 /* = core::bool */
211+
return self::E11|constructor#(foo);
212+
static inline-class-member method E12|constructor#(core::bool foo = #C1) → self::E12 /* = core::bool */ {
213+
lowered final self::E12 /* = core::bool */ #this = foo;
214+
return #this;
215+
}
216+
static inline-class-member method E12|constructor#_#new#tearOff(has-declared-initializer core::bool foo) → self::E12 /* = core::bool */
217+
return self::E12|constructor#(foo);
218+
219+
constants {
220+
#C1 = false
221+
}

0 commit comments

Comments
 (0)