Skip to content

Commit ffd43b2

Browse files
chloestefantsovaCommit Queue
authored and
Commit Queue
committed
[cfe] Report errors on zero or more than one representation fields
Part of #49731 Change-Id: I1009241a0a09a92c0e5b22b3848482b87392a72b Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/331061 Commit-Queue: Chloe Stefantsova <[email protected]> Reviewed-by: Johnni Winther <[email protected]>
1 parent c67f324 commit ffd43b2

24 files changed

+412
-2
lines changed

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

+21
Original file line numberDiff line numberDiff line change
@@ -3783,6 +3783,16 @@ const MessageCode messageExpectedOpenParens = const MessageCode(
37833783
"ExpectedOpenParens",
37843784
problemMessage: r"""Expected '('.""");
37853785

3786+
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
3787+
const Code<Null> codeExpectedRepresentationField =
3788+
messageExpectedRepresentationField;
3789+
3790+
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
3791+
const MessageCode messageExpectedRepresentationField = const MessageCode(
3792+
"ExpectedRepresentationField",
3793+
analyzerCodes: <String>["EXPECTED_REPRESENTATION_FIELD"],
3794+
problemMessage: r"""Expected a representation field.""");
3795+
37863796
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
37873797
const Code<Null> codeExpectedRepresentationType =
37883798
messageExpectedRepresentationType;
@@ -10217,6 +10227,17 @@ const MessageCode messageMultipleOnClauses = const MessageCode(
1021710227
correctionMessage:
1021810228
r"""Try combining all of the on clauses into a single clause.""");
1021910229

10230+
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
10231+
const Code<Null> codeMultipleRepresentationFields =
10232+
messageMultipleRepresentationFields;
10233+
10234+
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
10235+
const MessageCode messageMultipleRepresentationFields = const MessageCode(
10236+
"MultipleRepresentationFields",
10237+
analyzerCodes: <String>["MULTIPLE_REPRESENTATION_FIELDS"],
10238+
problemMessage:
10239+
r"""Each extension type should have exactly one representation field.""");
10240+
1022010241
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
1022110242
const Code<Null> codeMultipleVarianceModifiers =
1022210243
messageMultipleVarianceModifiers;

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

+23-2
Original file line numberDiff line numberDiff line change
@@ -1619,14 +1619,25 @@ class OutlineBuilder extends StackListenerImpl {
16191619
charOffset = identifier.nameOffset;
16201620
constructorName = identifier.name;
16211621
}
1622+
bool inExtensionType =
1623+
declarationContext == DeclarationContext.ExtensionType;
16221624
if (formals != null) {
1625+
if (inExtensionType && formals.isEmpty) {
1626+
libraryBuilder.addProblem(
1627+
messageExpectedRepresentationField, charOffset, 1, uri);
1628+
}
1629+
if (inExtensionType && formals.length > 1) {
1630+
libraryBuilder.addProblem(
1631+
messageMultipleRepresentationFields, charOffset, 1, uri);
1632+
}
16231633
for (int i = 0; i < formals.length; i++) {
16241634
FormalParameterBuilder formal = formals[i];
1625-
if (formal.type is ImplicitTypeBuilder) {
1635+
if (inExtensionType && formal.type is ImplicitTypeBuilder) {
16261636
libraryBuilder.addProblem(messageExpectedRepresentationType,
16271637
formal.charOffset, formal.name.length, formal.fileUri);
16281638
}
1629-
if (Modifier.maskContainsActualModifiers(formal.modifiers)) {
1639+
if (inExtensionType &&
1640+
Modifier.maskContainsActualModifiers(formal.modifiers)) {
16301641
libraryBuilder.addProblem(messageRepresentationFieldModifier,
16311642
formal.charOffset, formal.name.length, formal.fileUri);
16321643
}
@@ -2764,6 +2775,16 @@ class OutlineBuilder extends StackListenerImpl {
27642775
}
27652776
}
27662777
}
2778+
if (formals == null &&
2779+
declarationContext == DeclarationContext.ExtensionType &&
2780+
kind == MemberKind.PrimaryConstructor) {
2781+
// In case of primary constructors of extension types, an error is
2782+
// reported by the parser if the formals together with the parentheses
2783+
// around them are missing. To distinguish that case from the case of the
2784+
// formal parameters present, but lacking the representation field, we
2785+
// pass the empty list further along instead of `null`.
2786+
formals = const [];
2787+
}
27672788
push(beginToken.charOffset);
27682789
push(formals ?? NullValues.FormalParameters);
27692790
}

pkg/front_end/messages.yaml

+14
Original file line numberDiff line numberDiff line change
@@ -7419,3 +7419,17 @@ ExpectedRepresentationType:
74197419
script: |
74207420
extension type E(var foo) {}
74217421
analyzerCode: EXPECTED_REPRESENTATION_TYPE
7422+
7423+
ExpectedRepresentationField:
7424+
problemMessage: "Expected a representation field."
7425+
experiments: inline-class
7426+
script: |
7427+
extension type E() {}
7428+
analyzerCode: EXPECTED_REPRESENTATION_FIELD
7429+
7430+
MultipleRepresentationFields:
7431+
problemMessage: "Each extension type should have exactly one representation field."
7432+
experiments: inline-class
7433+
script: |
7434+
extension type E(int foo, String bar) {}
7435+
analyzerCode: MULTIPLE_REPRESENTATION_FIELDS

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

+4
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@ library;
22
//
33
// Problems in library:
44
//
5+
// pkg/front_end/testcases/extension_types/field_access.dart:83:36: Error: Each extension type should have exactly one representation field.
6+
// extension type ErroneousInlineClass(int a, String b) {
7+
// ^
8+
//
59
// pkg/front_end/testcases/extension_types/field_access.dart:15:21: Error: The static type of the explicit instantiation operand must be a generic function type but is 'int'.
610
// Try changing the operand or remove the type arguments.
711
// var b1 = this.it<int>; // Error

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

+4
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@ library;
22
//
33
// Problems in library:
44
//
5+
// pkg/front_end/testcases/extension_types/field_access.dart:83:36: Error: Each extension type should have exactly one representation field.
6+
// extension type ErroneousInlineClass(int a, String b) {
7+
// ^
8+
//
59
// pkg/front_end/testcases/extension_types/field_access.dart:15:21: Error: The static type of the explicit instantiation operand must be a generic function type but is 'int'.
610
// Try changing the operand or remove the type arguments.
711
// var b1 = this.it<int>; // Error

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

+4
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@ library;
22
//
33
// Problems in library:
44
//
5+
// pkg/front_end/testcases/extension_types/field_access.dart:83:36: Error: Each extension type should have exactly one representation field.
6+
// extension type ErroneousInlineClass(int a, String b) {
7+
// ^
8+
//
59
// pkg/front_end/testcases/extension_types/field_access.dart:15:21: Error: The static type of the explicit instantiation operand must be a generic function type but is 'int'.
610
// Try changing the operand or remove the type arguments.
711
// var b1 = this.it<int>; // Error

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

+4
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@ library;
22
//
33
// Problems in library:
44
//
5+
// pkg/front_end/testcases/extension_types/field_access.dart:83:36: Error: Each extension type should have exactly one representation field.
6+
// extension type ErroneousInlineClass(int a, String b) {
7+
// ^
8+
//
59
// pkg/front_end/testcases/extension_types/field_access.dart:15:21: Error: The static type of the explicit instantiation operand must be a generic function type but is 'int'.
610
// Try changing the operand or remove the type arguments.
711
// var b1 = this.it<int>; // Error

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

+7
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,11 @@
11
library;
2+
//
3+
// Problems in library:
4+
//
5+
// pkg/front_end/testcases/extension_types/field_access.dart:83:36: Error: Each extension type should have exactly one representation field.
6+
// extension type ErroneousInlineClass(int a, String b) {
7+
// ^
8+
//
29
import self as self;
310
import "dart:core" as core;
411

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

+4
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@ library;
22
//
33
// Problems in library:
44
//
5+
// pkg/front_end/testcases/extension_types/field_access.dart:83:36: Error: Each extension type should have exactly one representation field.
6+
// extension type ErroneousInlineClass(int a, String b) {
7+
// ^
8+
//
59
// pkg/front_end/testcases/extension_types/field_access.dart:15:21: Error: The static type of the explicit instantiation operand must be a generic function type but is 'int'.
610
// Try changing the operand or remove the type arguments.
711
// var b1 = this.it<int>; // Error

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

+12
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,25 @@ library;
22
//
33
// Problems in library:
44
//
5+
// pkg/front_end/testcases/extension_types/representation.dart:5:23: Error: Expected a representation field.
6+
// extension type Missing() {} // Error
7+
// ^
8+
//
9+
// pkg/front_end/testcases/extension_types/representation.dart:7:24: Error: Each extension type should have exactly one representation field.
10+
// extension type Multiple(bool instanceField1, int instanceField2) {} // Error
11+
// ^
12+
//
513
// pkg/front_end/testcases/extension_types/representation.dart:9:50: Error: Duplicated parameter name 'instanceField'.
614
// extension type Duplicate(bool instanceField, int instanceField) {} // Error
715
// ^^^^^^^^^^^^^
816
// pkg/front_end/testcases/extension_types/representation.dart:9:31: Context: Other parameter named 'instanceField'.
917
// extension type Duplicate(bool instanceField, int instanceField) {} // Error
1018
// ^^^^^^^^^^^^^
1119
//
20+
// pkg/front_end/testcases/extension_types/representation.dart:9:25: Error: Each extension type should have exactly one representation field.
21+
// extension type Duplicate(bool instanceField, int instanceField) {} // Error
22+
// ^
23+
//
1224
// pkg/front_end/testcases/extension_types/representation.dart:9:50: Error: 'instanceField' is already declared in this scope.
1325
// extension type Duplicate(bool instanceField, int instanceField) {} // Error
1426
// ^^^^^^^^^^^^^

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

+12
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,25 @@ library;
22
//
33
// Problems in library:
44
//
5+
// pkg/front_end/testcases/extension_types/representation.dart:5:23: Error: Expected a representation field.
6+
// extension type Missing() {} // Error
7+
// ^
8+
//
9+
// pkg/front_end/testcases/extension_types/representation.dart:7:24: Error: Each extension type should have exactly one representation field.
10+
// extension type Multiple(bool instanceField1, int instanceField2) {} // Error
11+
// ^
12+
//
513
// pkg/front_end/testcases/extension_types/representation.dart:9:50: Error: Duplicated parameter name 'instanceField'.
614
// extension type Duplicate(bool instanceField, int instanceField) {} // Error
715
// ^^^^^^^^^^^^^
816
// pkg/front_end/testcases/extension_types/representation.dart:9:31: Context: Other parameter named 'instanceField'.
917
// extension type Duplicate(bool instanceField, int instanceField) {} // Error
1018
// ^^^^^^^^^^^^^
1119
//
20+
// pkg/front_end/testcases/extension_types/representation.dart:9:25: Error: Each extension type should have exactly one representation field.
21+
// extension type Duplicate(bool instanceField, int instanceField) {} // Error
22+
// ^
23+
//
1224
// pkg/front_end/testcases/extension_types/representation.dart:9:50: Error: 'instanceField' is already declared in this scope.
1325
// extension type Duplicate(bool instanceField, int instanceField) {} // Error
1426
// ^^^^^^^^^^^^^

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

+12
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,25 @@ library;
22
//
33
// Problems in library:
44
//
5+
// pkg/front_end/testcases/extension_types/representation.dart:5:23: Error: Expected a representation field.
6+
// extension type Missing() {} // Error
7+
// ^
8+
//
9+
// pkg/front_end/testcases/extension_types/representation.dart:7:24: Error: Each extension type should have exactly one representation field.
10+
// extension type Multiple(bool instanceField1, int instanceField2) {} // Error
11+
// ^
12+
//
513
// pkg/front_end/testcases/extension_types/representation.dart:9:50: Error: Duplicated parameter name 'instanceField'.
614
// extension type Duplicate(bool instanceField, int instanceField) {} // Error
715
// ^^^^^^^^^^^^^
816
// pkg/front_end/testcases/extension_types/representation.dart:9:31: Context: Other parameter named 'instanceField'.
917
// extension type Duplicate(bool instanceField, int instanceField) {} // Error
1018
// ^^^^^^^^^^^^^
1119
//
20+
// pkg/front_end/testcases/extension_types/representation.dart:9:25: Error: Each extension type should have exactly one representation field.
21+
// extension type Duplicate(bool instanceField, int instanceField) {} // Error
22+
// ^
23+
//
1224
// pkg/front_end/testcases/extension_types/representation.dart:9:50: Error: 'instanceField' is already declared in this scope.
1325
// extension type Duplicate(bool instanceField, int instanceField) {} // Error
1426
// ^^^^^^^^^^^^^

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

+12
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,25 @@ library;
22
//
33
// Problems in library:
44
//
5+
// pkg/front_end/testcases/extension_types/representation.dart:5:23: Error: Expected a representation field.
6+
// extension type Missing() {} // Error
7+
// ^
8+
//
9+
// pkg/front_end/testcases/extension_types/representation.dart:7:24: Error: Each extension type should have exactly one representation field.
10+
// extension type Multiple(bool instanceField1, int instanceField2) {} // Error
11+
// ^
12+
//
513
// pkg/front_end/testcases/extension_types/representation.dart:9:50: Error: Duplicated parameter name 'instanceField'.
614
// extension type Duplicate(bool instanceField, int instanceField) {} // Error
715
// ^^^^^^^^^^^^^
816
// pkg/front_end/testcases/extension_types/representation.dart:9:31: Context: Other parameter named 'instanceField'.
917
// extension type Duplicate(bool instanceField, int instanceField) {} // Error
1018
// ^^^^^^^^^^^^^
1119
//
20+
// pkg/front_end/testcases/extension_types/representation.dart:9:25: Error: Each extension type should have exactly one representation field.
21+
// extension type Duplicate(bool instanceField, int instanceField) {} // Error
22+
// ^
23+
//
1224
// pkg/front_end/testcases/extension_types/representation.dart:9:50: Error: 'instanceField' is already declared in this scope.
1325
// extension type Duplicate(bool instanceField, int instanceField) {} // Error
1426
// ^^^^^^^^^^^^^

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

+12
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,25 @@ library;
22
//
33
// Problems in library:
44
//
5+
// pkg/front_end/testcases/extension_types/representation.dart:5:23: Error: Expected a representation field.
6+
// extension type Missing() {} // Error
7+
// ^
8+
//
9+
// pkg/front_end/testcases/extension_types/representation.dart:7:24: Error: Each extension type should have exactly one representation field.
10+
// extension type Multiple(bool instanceField1, int instanceField2) {} // Error
11+
// ^
12+
//
513
// pkg/front_end/testcases/extension_types/representation.dart:9:50: Error: Duplicated parameter name 'instanceField'.
614
// extension type Duplicate(bool instanceField, int instanceField) {} // Error
715
// ^^^^^^^^^^^^^
816
// pkg/front_end/testcases/extension_types/representation.dart:9:31: Context: Other parameter named 'instanceField'.
917
// extension type Duplicate(bool instanceField, int instanceField) {} // Error
1018
// ^^^^^^^^^^^^^
1119
//
20+
// pkg/front_end/testcases/extension_types/representation.dart:9:25: Error: Each extension type should have exactly one representation field.
21+
// extension type Duplicate(bool instanceField, int instanceField) {} // Error
22+
// ^
23+
//
1224
// pkg/front_end/testcases/extension_types/representation.dart:9:50: Error: 'instanceField' is already declared in this scope.
1325
// extension type Duplicate(bool instanceField, int instanceField) {} // Error
1426
// ^^^^^^^^^^^^^

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

+12
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,25 @@ library;
22
//
33
// Problems in library:
44
//
5+
// pkg/front_end/testcases/extension_types/representation.dart:5:23: Error: Expected a representation field.
6+
// extension type Missing() {} // Error
7+
// ^
8+
//
9+
// pkg/front_end/testcases/extension_types/representation.dart:7:24: Error: Each extension type should have exactly one representation field.
10+
// extension type Multiple(bool instanceField1, int instanceField2) {} // Error
11+
// ^
12+
//
513
// pkg/front_end/testcases/extension_types/representation.dart:9:50: Error: Duplicated parameter name 'instanceField'.
614
// extension type Duplicate(bool instanceField, int instanceField) {} // Error
715
// ^^^^^^^^^^^^^
816
// pkg/front_end/testcases/extension_types/representation.dart:9:31: Context: Other parameter named 'instanceField'.
917
// extension type Duplicate(bool instanceField, int instanceField) {} // Error
1018
// ^^^^^^^^^^^^^
1119
//
20+
// pkg/front_end/testcases/extension_types/representation.dart:9:25: Error: Each extension type should have exactly one representation field.
21+
// extension type Duplicate(bool instanceField, int instanceField) {} // Error
22+
// ^
23+
//
1224
// pkg/front_end/testcases/extension_types/representation.dart:9:50: Error: 'instanceField' is already declared in this scope.
1325
// extension type Duplicate(bool instanceField, int instanceField) {} // Error
1426
// ^^^^^^^^^^^^^

pkg/front_end/testcases/extension_types/representation_field_error.dart

+3
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,6 @@ extension type E4(covariant num foo) {} // Error.
99
extension type E5(const bool foo) {} // Error.
1010
extension type E6(covariant final double foo) {} // Error.
1111
extension type E7(const var foo) {} // Error.
12+
extension type E8() {} // Error.
13+
extension type E9(int foo, String bar) {} // Error.
14+
extension type E10(num foo, bool bar, double baz) {} // Error.

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

+42
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,18 @@ library;
5353
// extension type E7(const var foo) {} // Error.
5454
// ^^^
5555
//
56+
// pkg/front_end/testcases/extension_types/representation_field_error.dart:12:18: Error: Expected a representation field.
57+
// extension type E8() {} // Error.
58+
// ^
59+
//
60+
// pkg/front_end/testcases/extension_types/representation_field_error.dart:13:18: Error: Each extension type should have exactly one representation field.
61+
// extension type E9(int foo, String bar) {} // Error.
62+
// ^
63+
//
64+
// pkg/front_end/testcases/extension_types/representation_field_error.dart:14:19: Error: Each extension type should have exactly one representation field.
65+
// extension type E10(num foo, bool bar, double baz) {} // Error.
66+
// ^
67+
//
5668
import self as self;
5769
import "dart:core" as core;
5870

@@ -84,6 +96,18 @@ extension type E7(dynamic foo) {
8496
constructor • = self::E7|constructor#;
8597
constructor tearoff • = self::E7|constructor#_#new#tearOff;
8698
}
99+
extension type E8(invalid-type #) {
100+
constructor • = self::E8|constructor#;
101+
constructor tearoff • = self::E8|constructor#_#new#tearOff;
102+
}
103+
extension type E9(core::int foo) {
104+
constructor • = self::E9|constructor#;
105+
constructor tearoff • = self::E9|constructor#_#new#tearOff;
106+
}
107+
extension type E10(core::num foo) {
108+
constructor • = self::E10|constructor#;
109+
constructor tearoff • = self::E10|constructor#_#new#tearOff;
110+
}
87111
static inline-class-member method E1|constructor#(dynamic foo) → self::E1 /* = dynamic */ {
88112
lowered final self::E1 /* = dynamic */ #this = foo;
89113
return #this;
@@ -126,3 +150,21 @@ static inline-class-member method E7|constructor#(dynamic foo) → self::E7 /* =
126150
}
127151
static inline-class-member method E7|constructor#_#new#tearOff(dynamic foo) → self::E7 /* = dynamic */
128152
return self::E7|constructor#(foo);
153+
static inline-class-member method E8|constructor#() → self::E8 /* = invalid-type */ {
154+
lowered final self::E8 /* = invalid-type */ #this;
155+
return #this;
156+
}
157+
static inline-class-member method E8|constructor#_#new#tearOff() → self::E8 /* = invalid-type */
158+
return self::E8|constructor#();
159+
static inline-class-member method E9|constructor#(core::int foo, core::String bar) → self::E9 /* = core::int */ {
160+
lowered final self::E9 /* = core::int */ #this = bar;
161+
return #this;
162+
}
163+
static inline-class-member method E9|constructor#_#new#tearOff(core::int foo, core::String bar) → self::E9 /* = core::int */
164+
return self::E9|constructor#(foo, bar);
165+
static inline-class-member method E10|constructor#(core::num foo, core::bool bar, core::double baz) → self::E10 /* = core::num */ {
166+
lowered final self::E10 /* = core::num */ #this = baz;
167+
return #this;
168+
}
169+
static inline-class-member method E10|constructor#_#new#tearOff(core::num foo, core::bool bar, core::double baz) → self::E10 /* = core::num */
170+
return self::E10|constructor#(foo, bar, baz);

0 commit comments

Comments
 (0)