Skip to content

Commit

Permalink
[cfe] Report error on trailing comma in extension type declarations
Browse files Browse the repository at this point in the history
Part of #53625
Part of #49731

Change-Id: I793ef6329d99b1a4e829491f454f42c2ede941b4
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/331185
Commit-Queue: Chloe Stefantsova <cstefantsova@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
  • Loading branch information
chloestefantsova authored and Commit Queue committed Oct 24, 2023
1 parent 67d4561 commit 75920dd
Show file tree
Hide file tree
Showing 12 changed files with 259 additions and 0 deletions.
11 changes: 11 additions & 0 deletions pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart
Original file line number Diff line number Diff line change
Expand Up @@ -12476,6 +12476,17 @@ const MessageCode messageRepresentationFieldModifier = const MessageCode(
analyzerCodes: <String>["REPRESENTATION_FIELD_MODIFIER"],
problemMessage: r"""Representation fields can't have modifiers.""");

// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const Code<Null> codeRepresentationFieldTrailingComma =
messageRepresentationFieldTrailingComma;

// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const MessageCode messageRepresentationFieldTrailingComma = const MessageCode(
"RepresentationFieldTrailingComma",
analyzerCodes: <String>["REPRESENTATION_FIELD_TRAILING_COMMA"],
problemMessage:
r"""The representation field can't have a trailing comma.""");

// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const Template<Message Function(String name)>
templateRequiredNamedParameterHasDefaultValueError =
Expand Down
9 changes: 9 additions & 0 deletions pkg/front_end/lib/src/fasta/source/outline_builder.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2721,6 +2721,15 @@ class OutlineBuilder extends StackListenerImpl {
assert(last != null);
formals = [last as FormalParameterBuilder];
}

Token? tokenBeforeEnd = endToken.previous;
if (tokenBeforeEnd != null &&
optional(",", tokenBeforeEnd) &&
kind == MemberKind.PrimaryConstructor &&
declarationContext == DeclarationContext.ExtensionType) {
libraryBuilder.addProblem(messageRepresentationFieldTrailingComma,
tokenBeforeEnd.charOffset, 1, uri);
}
} else if (count > 1) {
Object? last = pop();
count--;
Expand Down
7 changes: 7 additions & 0 deletions pkg/front_end/messages.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7447,3 +7447,10 @@ ExtensionTypeRepresentationTypeBottom:
script: |
extension type E1(Never foo) {}
analyzerCode: EXTENSION_TYPE_REPRESENTATION_TYPE_BOTTOM

RepresentationFieldTrailingComma:
problemMessage: "The representation field can't have a trailing comma."
experiments: inline-class
script: |
extension type E(int foo,) {}
analyzerCode: REPRESENTATION_FIELD_TRAILING_COMMA
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,5 @@ extension type E7(const var foo) {} // Error.
extension type E8() {} // Error.
extension type E9(int foo, String bar) {} // Error.
extension type E10(num foo, bool bar, double baz) {} // Error.
extension type E11(bool foo,) {} // Error.
extension type E12(bool foo = false,) {} // Error.
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,19 @@ library;
// extension type E10(num foo, bool bar, double baz) {} // Error.
// ^
//
// pkg/front_end/testcases/extension_types/representation_field_error.dart:15:28: Error: The representation field can't have a trailing comma.
// extension type E11(bool foo,) {} // Error.
// ^
//
// pkg/front_end/testcases/extension_types/representation_field_error.dart:16:29: Error: Non-optional parameters can't have a default value.
// Try removing the default value or making the parameter optional.
// extension type E12(bool foo = false,) {} // Error.
// ^
//
// pkg/front_end/testcases/extension_types/representation_field_error.dart:16:36: Error: The representation field can't have a trailing comma.
// extension type E12(bool foo = false,) {} // Error.
// ^
//
import self as self;
import "dart:core" as core;

Expand Down Expand Up @@ -120,6 +133,16 @@ extension type E10(core::num foo) {
constructor • = self::E10|constructor#;
constructor tearoff • = self::E10|constructor#_#new#tearOff;
}
extension type E11(core::bool foo) {
abstract inline-class-member representation-field get foo() → core::bool;
constructor • = self::E11|constructor#;
constructor tearoff • = self::E11|constructor#_#new#tearOff;
}
extension type E12(core::bool foo) {
abstract inline-class-member representation-field get foo() → core::bool;
constructor • = self::E12|constructor#;
constructor tearoff • = self::E12|constructor#_#new#tearOff;
}
static inline-class-member method E1|constructor#(dynamic foo) → self::E1 /* = dynamic */ {
lowered final self::E1 /* = dynamic */ #this = foo;
return #this;
Expand Down Expand Up @@ -180,3 +203,19 @@ static inline-class-member method E10|constructor#(core::num foo, core::bool bar
}
static inline-class-member method E10|constructor#_#new#tearOff(core::num foo, core::bool bar, core::double baz) → self::E10 /* = core::num */
return self::E10|constructor#(foo, bar, baz);
static inline-class-member method E11|constructor#(core::bool foo) → self::E11 /* = core::bool */ {
lowered final self::E11 /* = core::bool */ #this = foo;
return #this;
}
static inline-class-member method E11|constructor#_#new#tearOff(core::bool foo) → self::E11 /* = core::bool */
return self::E11|constructor#(foo);
static inline-class-member method E12|constructor#(core::bool foo = #C1) → self::E12 /* = core::bool */ {
lowered final self::E12 /* = core::bool */ #this = foo;
return #this;
}
static inline-class-member method E12|constructor#_#new#tearOff(has-declared-initializer core::bool foo) → self::E12 /* = core::bool */
return self::E12|constructor#(foo);

constants {
#C1 = false
}
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,19 @@ library;
// extension type E10(num foo, bool bar, double baz) {} // Error.
// ^
//
// pkg/front_end/testcases/extension_types/representation_field_error.dart:15:28: Error: The representation field can't have a trailing comma.
// extension type E11(bool foo,) {} // Error.
// ^
//
// pkg/front_end/testcases/extension_types/representation_field_error.dart:16:29: Error: Non-optional parameters can't have a default value.
// Try removing the default value or making the parameter optional.
// extension type E12(bool foo = false,) {} // Error.
// ^
//
// pkg/front_end/testcases/extension_types/representation_field_error.dart:16:36: Error: The representation field can't have a trailing comma.
// extension type E12(bool foo = false,) {} // Error.
// ^
//
import self as self;
import "dart:core" as core;

Expand Down Expand Up @@ -120,6 +133,16 @@ extension type E10(core::num foo) {
constructor • = self::E10|constructor#;
constructor tearoff • = self::E10|constructor#_#new#tearOff;
}
extension type E11(core::bool foo) {
abstract inline-class-member representation-field get foo() → core::bool;
constructor • = self::E11|constructor#;
constructor tearoff • = self::E11|constructor#_#new#tearOff;
}
extension type E12(core::bool foo) {
abstract inline-class-member representation-field get foo() → core::bool;
constructor • = self::E12|constructor#;
constructor tearoff • = self::E12|constructor#_#new#tearOff;
}
static inline-class-member method E1|constructor#(dynamic foo) → self::E1 /* = dynamic */ {
lowered final self::E1 /* = dynamic */ #this = foo;
return #this;
Expand Down Expand Up @@ -180,3 +203,19 @@ static inline-class-member method E10|constructor#(core::num foo, core::bool bar
}
static inline-class-member method E10|constructor#_#new#tearOff(core::num foo, core::bool bar, core::double baz) → self::E10 /* = core::num */
return self::E10|constructor#(foo, bar, baz);
static inline-class-member method E11|constructor#(core::bool foo) → self::E11 /* = core::bool */ {
lowered final self::E11 /* = core::bool */ #this = foo;
return #this;
}
static inline-class-member method E11|constructor#_#new#tearOff(core::bool foo) → self::E11 /* = core::bool */
return self::E11|constructor#(foo);
static inline-class-member method E12|constructor#(core::bool foo = #C1) → self::E12 /* = core::bool */ {
lowered final self::E12 /* = core::bool */ #this = foo;
return #this;
}
static inline-class-member method E12|constructor#_#new#tearOff(has-declared-initializer core::bool foo) → self::E12 /* = core::bool */
return self::E12|constructor#(foo);

constants {
#C1 = false
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,5 @@ extension type E7(const var foo) {}
extension type E8() {}
extension type E9(int foo, String bar) {}
extension type E10(num foo, bool bar, double baz) {}
extension type E11(bool foo,) {}
extension type E12(bool foo = false,) {}
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
extension type E1(var foo) {}
extension type E10(num foo, bool bar, double baz) {}
extension type E11(bool foo,) {}
extension type E12(bool foo = false,) {}
extension type E2(final foo) {}
extension type E3(final String foo) {}
extension type E4(covariant num foo) {}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,19 @@ library;
// extension type E10(num foo, bool bar, double baz) {} // Error.
// ^
//
// pkg/front_end/testcases/extension_types/representation_field_error.dart:15:28: Error: The representation field can't have a trailing comma.
// extension type E11(bool foo,) {} // Error.
// ^
//
// pkg/front_end/testcases/extension_types/representation_field_error.dart:16:29: Error: Non-optional parameters can't have a default value.
// Try removing the default value or making the parameter optional.
// extension type E12(bool foo = false,) {} // Error.
// ^
//
// pkg/front_end/testcases/extension_types/representation_field_error.dart:16:36: Error: The representation field can't have a trailing comma.
// extension type E12(bool foo = false,) {} // Error.
// ^
//
import self as self;
import "dart:core" as core;

Expand Down Expand Up @@ -120,6 +133,16 @@ extension type E10(core::num foo) {
constructor • = self::E10|constructor#;
constructor tearoff • = self::E10|constructor#_#new#tearOff;
}
extension type E11(core::bool foo) {
abstract inline-class-member representation-field get foo() → core::bool;
constructor • = self::E11|constructor#;
constructor tearoff • = self::E11|constructor#_#new#tearOff;
}
extension type E12(core::bool foo) {
abstract inline-class-member representation-field get foo() → core::bool;
constructor • = self::E12|constructor#;
constructor tearoff • = self::E12|constructor#_#new#tearOff;
}
static inline-class-member method E1|constructor#(dynamic foo) → self::E1 /* = dynamic */ {
lowered final self::E1 /* = dynamic */ #this = foo;
return #this;
Expand Down Expand Up @@ -180,3 +203,19 @@ static inline-class-member method E10|constructor#(core::num foo, core::bool bar
}
static inline-class-member method E10|constructor#_#new#tearOff(core::num foo, core::bool bar, core::double baz) → self::E10 /* = core::num */
return self::E10|constructor#(foo, bar, baz);
static inline-class-member method E11|constructor#(core::bool foo) → self::E11 /* = core::bool */ {
lowered final self::E11 /* = core::bool */ #this = foo;
return #this;
}
static inline-class-member method E11|constructor#_#new#tearOff(core::bool foo) → self::E11 /* = core::bool */
return self::E11|constructor#(foo);
static inline-class-member method E12|constructor#(core::bool foo = #C1) → self::E12 /* = core::bool */ {
lowered final self::E12 /* = core::bool */ #this = foo;
return #this;
}
static inline-class-member method E12|constructor#_#new#tearOff(has-declared-initializer core::bool foo) → self::E12 /* = core::bool */
return self::E12|constructor#(foo);

constants {
#C1 = false
}
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,19 @@ library;
// extension type E10(num foo, bool bar, double baz) {} // Error.
// ^
//
// pkg/front_end/testcases/extension_types/representation_field_error.dart:15:28: Error: The representation field can't have a trailing comma.
// extension type E11(bool foo,) {} // Error.
// ^
//
// pkg/front_end/testcases/extension_types/representation_field_error.dart:16:29: Error: Non-optional parameters can't have a default value.
// Try removing the default value or making the parameter optional.
// extension type E12(bool foo = false,) {} // Error.
// ^
//
// pkg/front_end/testcases/extension_types/representation_field_error.dart:16:36: Error: The representation field can't have a trailing comma.
// extension type E12(bool foo = false,) {} // Error.
// ^
//
import self as self;
import "dart:core" as core;

Expand Down Expand Up @@ -120,6 +133,16 @@ extension type E10(core::num foo) {
constructor • = self::E10|constructor#;
constructor tearoff • = self::E10|constructor#_#new#tearOff;
}
extension type E11(core::bool foo) {
abstract inline-class-member representation-field get foo() → core::bool;
constructor • = self::E11|constructor#;
constructor tearoff • = self::E11|constructor#_#new#tearOff;
}
extension type E12(core::bool foo) {
abstract inline-class-member representation-field get foo() → core::bool;
constructor • = self::E12|constructor#;
constructor tearoff • = self::E12|constructor#_#new#tearOff;
}
static inline-class-member method E1|constructor#(dynamic foo) → self::E1 /* = dynamic */ {
lowered final self::E1 /* = dynamic */ #this = foo;
return #this;
Expand Down Expand Up @@ -180,3 +203,19 @@ static inline-class-member method E10|constructor#(core::num foo, core::bool bar
}
static inline-class-member method E10|constructor#_#new#tearOff(core::num foo, core::bool bar, core::double baz) → self::E10 /* = core::num */
return self::E10|constructor#(foo, bar, baz);
static inline-class-member method E11|constructor#(core::bool foo) → self::E11 /* = core::bool */ {
lowered final self::E11 /* = core::bool */ #this = foo;
return #this;
}
static inline-class-member method E11|constructor#_#new#tearOff(core::bool foo) → self::E11 /* = core::bool */
return self::E11|constructor#(foo);
static inline-class-member method E12|constructor#(core::bool foo = #C1) → self::E12 /* = core::bool */ {
lowered final self::E12 /* = core::bool */ #this = foo;
return #this;
}
static inline-class-member method E12|constructor#_#new#tearOff(has-declared-initializer core::bool foo) → self::E12 /* = core::bool */
return self::E12|constructor#(foo);

constants {
#C1 = false
}
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,19 @@ library;
// extension type E10(num foo, bool bar, double baz) {} // Error.
// ^
//
// pkg/front_end/testcases/extension_types/representation_field_error.dart:15:28: Error: The representation field can't have a trailing comma.
// extension type E11(bool foo,) {} // Error.
// ^
//
// pkg/front_end/testcases/extension_types/representation_field_error.dart:16:29: Error: Non-optional parameters can't have a default value.
// Try removing the default value or making the parameter optional.
// extension type E12(bool foo = false,) {} // Error.
// ^
//
// pkg/front_end/testcases/extension_types/representation_field_error.dart:16:36: Error: The representation field can't have a trailing comma.
// extension type E12(bool foo = false,) {} // Error.
// ^
//
import self as self;
import "dart:core" as core;

Expand Down Expand Up @@ -120,6 +133,16 @@ extension type E10(core::num foo) {
constructor • = self::E10|constructor#;
constructor tearoff • = self::E10|constructor#_#new#tearOff;
}
extension type E11(core::bool foo) {
abstract inline-class-member representation-field get foo() → core::bool;
constructor • = self::E11|constructor#;
constructor tearoff • = self::E11|constructor#_#new#tearOff;
}
extension type E12(core::bool foo) {
abstract inline-class-member representation-field get foo() → core::bool;
constructor • = self::E12|constructor#;
constructor tearoff • = self::E12|constructor#_#new#tearOff;
}
static inline-class-member method E1|constructor#(dynamic foo) → self::E1 /* = dynamic */
;
static inline-class-member method E1|constructor#_#new#tearOff(dynamic foo) → self::E1 /* = dynamic */
Expand Down Expand Up @@ -160,3 +183,11 @@ static inline-class-member method E10|constructor#(core::num foo, core::bool bar
;
static inline-class-member method E10|constructor#_#new#tearOff(core::num foo, core::bool bar, core::double baz) → self::E10 /* = core::num */
return self::E10|constructor#(foo, bar, baz);
static inline-class-member method E11|constructor#(core::bool foo) → self::E11 /* = core::bool */
;
static inline-class-member method E11|constructor#_#new#tearOff(core::bool foo) → self::E11 /* = core::bool */
return self::E11|constructor#(foo);
static inline-class-member method E12|constructor#(has-declared-initializer core::bool foo) → self::E12 /* = core::bool */
;
static inline-class-member method E12|constructor#_#new#tearOff(has-declared-initializer core::bool foo) → self::E12 /* = core::bool */
return self::E12|constructor#(foo);
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,19 @@ library;
// extension type E10(num foo, bool bar, double baz) {} // Error.
// ^
//
// pkg/front_end/testcases/extension_types/representation_field_error.dart:15:28: Error: The representation field can't have a trailing comma.
// extension type E11(bool foo,) {} // Error.
// ^
//
// pkg/front_end/testcases/extension_types/representation_field_error.dart:16:29: Error: Non-optional parameters can't have a default value.
// Try removing the default value or making the parameter optional.
// extension type E12(bool foo = false,) {} // Error.
// ^
//
// pkg/front_end/testcases/extension_types/representation_field_error.dart:16:36: Error: The representation field can't have a trailing comma.
// extension type E12(bool foo = false,) {} // Error.
// ^
//
import self as self;
import "dart:core" as core;

Expand Down Expand Up @@ -120,6 +133,16 @@ extension type E10(core::num foo) {
constructor • = self::E10|constructor#;
constructor tearoff • = self::E10|constructor#_#new#tearOff;
}
extension type E11(core::bool foo) {
abstract inline-class-member representation-field get foo() → core::bool;
constructor • = self::E11|constructor#;
constructor tearoff • = self::E11|constructor#_#new#tearOff;
}
extension type E12(core::bool foo) {
abstract inline-class-member representation-field get foo() → core::bool;
constructor • = self::E12|constructor#;
constructor tearoff • = self::E12|constructor#_#new#tearOff;
}
static inline-class-member method E1|constructor#(dynamic foo) → self::E1 /* = dynamic */ {
lowered final self::E1 /* = dynamic */ #this = foo;
return #this;
Expand Down Expand Up @@ -180,3 +203,19 @@ static inline-class-member method E10|constructor#(core::num foo, core::bool bar
}
static inline-class-member method E10|constructor#_#new#tearOff(core::num foo, core::bool bar, core::double baz) → self::E10 /* = core::num */
return self::E10|constructor#(foo, bar, baz);
static inline-class-member method E11|constructor#(core::bool foo) → self::E11 /* = core::bool */ {
lowered final self::E11 /* = core::bool */ #this = foo;
return #this;
}
static inline-class-member method E11|constructor#_#new#tearOff(core::bool foo) → self::E11 /* = core::bool */
return self::E11|constructor#(foo);
static inline-class-member method E12|constructor#(core::bool foo = #C1) → self::E12 /* = core::bool */ {
lowered final self::E12 /* = core::bool */ #this = foo;
return #this;
}
static inline-class-member method E12|constructor#_#new#tearOff(has-declared-initializer core::bool foo) → self::E12 /* = core::bool */
return self::E12|constructor#(foo);

constants {
#C1 = false
}

0 comments on commit 75920dd

Please sign in to comment.