Skip to content

Commit be36f24

Browse files
chloestefantsovaCommit Queue
authored and
Commit Queue
committed
[cfe] Report error on representation type modifiers and missing type
This CL addresses some of the failures reported in #53074 Part of #49731 Change-Id: I2b23a9d0c095856139563f9e500e88bebadc1ce3 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/331042 Reviewed-by: Johnni Winther <[email protected]> Commit-Queue: Chloe Stefantsova <[email protected]>
1 parent 871d0b1 commit be36f24

20 files changed

+892
-0
lines changed

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

+20
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> codeExpectedRepresentationType =
3788+
messageExpectedRepresentationType;
3789+
3790+
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
3791+
const MessageCode messageExpectedRepresentationType = const MessageCode(
3792+
"ExpectedRepresentationType",
3793+
analyzerCodes: <String>["EXPECTED_REPRESENTATION_TYPE"],
3794+
problemMessage: r"""Expected a representation type.""");
3795+
37863796
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
37873797
const Code<Null> codeExpectedStatement = messageExpectedStatement;
37883798

@@ -12412,6 +12422,16 @@ const MessageCode messageRefutablePatternInIrrefutableContext = const MessageCod
1241212422
correctionMessage:
1241312423
r"""Try using an if-case, a 'switch' statement, or a 'switch' expression instead.""");
1241412424

12425+
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
12426+
const Code<Null> codeRepresentationFieldModifier =
12427+
messageRepresentationFieldModifier;
12428+
12429+
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
12430+
const MessageCode messageRepresentationFieldModifier = const MessageCode(
12431+
"RepresentationFieldModifier",
12432+
analyzerCodes: <String>["REPRESENTATION_FIELD_MODIFIER"],
12433+
problemMessage: r"""Representation fields can't have modifiers.""");
12434+
1241512435
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
1241612436
const Template<Message Function(String name)>
1241712437
templateRequiredNamedParameterHasDefaultValueError =

pkg/front_end/lib/src/fasta/modifier.dart

+19
Original file line numberDiff line numberDiff line change
@@ -126,4 +126,23 @@ class Modifier {
126126
}
127127
return modifiers;
128128
}
129+
130+
/// Returns `true` if the modifier mask contains modifier bits
131+
///
132+
/// Some of the bits stored in modified masks don't represent actual
133+
/// modifiers, as noted in their comments (see [mixinDeclarationMask],
134+
/// [hasInitializerMask], [initializingFormalMask],
135+
/// [declaresConstConstructorMask], [superInitializingFormalMask], [varMask]).
136+
/// Method [maskContainsActualModifiers] returns `true` if the mask has any of
137+
/// the actual modifier bits set, and `false` otherwise.
138+
static bool maskContainsActualModifiers(int mask) {
139+
mask &= ~(1 << mixinDeclarationMask);
140+
mask &= ~(1 << hasInitializerMask);
141+
mask &= ~(1 << initializingFormalMask);
142+
mask &= ~(1 << declaresConstConstructorMask);
143+
mask &= ~(1 << superInitializingFormalMask);
144+
mask &= ~(1 << varMask);
145+
146+
return mask != 0;
147+
}
129148
}

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

+8
Original file line numberDiff line numberDiff line change
@@ -1622,6 +1622,14 @@ class OutlineBuilder extends StackListenerImpl {
16221622
if (formals != null) {
16231623
for (int i = 0; i < formals.length; i++) {
16241624
FormalParameterBuilder formal = formals[i];
1625+
if (formal.type is ImplicitTypeBuilder) {
1626+
libraryBuilder.addProblem(messageExpectedRepresentationType,
1627+
formal.charOffset, formal.name.length, formal.fileUri);
1628+
}
1629+
if (Modifier.maskContainsActualModifiers(formal.modifiers)) {
1630+
libraryBuilder.addProblem(messageRepresentationFieldModifier,
1631+
formal.charOffset, formal.name.length, formal.fileUri);
1632+
}
16251633
libraryBuilder.addPrimaryConstructorField(
16261634
// TODO(johnniwinther): Support annotations on annotations on fields
16271635
// defined through a primary constructor. This is not needed for

pkg/front_end/messages.yaml

+14
Original file line numberDiff line numberDiff line change
@@ -7405,3 +7405,17 @@ ImplementMultipleExtensionTypeMembers:
74057405
void method() {}
74067406
}
74077407
extension type ExtensionType3(int i) implements ExtensionType1, ExtensionType2 {}
7408+
7409+
RepresentationFieldModifier:
7410+
problemMessage: "Representation fields can't have modifiers."
7411+
experiments: inline-class
7412+
script: |
7413+
extension type E(final int foo) {}
7414+
analyzerCode: REPRESENTATION_FIELD_MODIFIER
7415+
7416+
ExpectedRepresentationType:
7417+
problemMessage: "Expected a representation type."
7418+
experiments: inline-class
7419+
script: |
7420+
extension type E(var foo) {}
7421+
analyzerCode: EXPECTED_REPRESENTATION_TYPE

pkg/front_end/test/spell_checking_list_common.txt

+1
Original file line numberDiff line numberDiff line change
@@ -2049,6 +2049,7 @@ normally
20492049
not
20502050
notation
20512051
note
2052+
noted
20522053
notes
20532054
nothing
20542055
notice

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

+8
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,14 @@ library;
22
//
33
// Problems in library:
44
//
5+
// pkg/front_end/testcases/extension_types/issue52119.dart:15:30: Error: Expected a representation type.
6+
// extension type Bar<T>._(this.i) {
7+
// ^
8+
//
9+
// pkg/front_end/testcases/extension_types/issue52119.dart:15:30: Error: Representation fields can't have modifiers.
10+
// extension type Bar<T>._(this.i) {
11+
// ^
12+
//
513
// pkg/front_end/testcases/extension_types/issue52119.dart:12:26: Error: Couldn't find constructor 'Foo.unresolved'.
614
// Foo.erroneous() : this.unresolved(); // Error
715
// ^^^^^^^^^^

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

+8
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,14 @@ library;
22
//
33
// Problems in library:
44
//
5+
// pkg/front_end/testcases/extension_types/issue52119.dart:15:30: Error: Expected a representation type.
6+
// extension type Bar<T>._(this.i) {
7+
// ^
8+
//
9+
// pkg/front_end/testcases/extension_types/issue52119.dart:15:30: Error: Representation fields can't have modifiers.
10+
// extension type Bar<T>._(this.i) {
11+
// ^
12+
//
513
// pkg/front_end/testcases/extension_types/issue52119.dart:12:26: Error: Couldn't find constructor 'Foo.unresolved'.
614
// Foo.erroneous() : this.unresolved(); // Error
715
// ^^^^^^^^^^

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

+8
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,14 @@ library;
22
//
33
// Problems in library:
44
//
5+
// pkg/front_end/testcases/extension_types/issue52119.dart:15:30: Error: Expected a representation type.
6+
// extension type Bar<T>._(this.i) {
7+
// ^
8+
//
9+
// pkg/front_end/testcases/extension_types/issue52119.dart:15:30: Error: Representation fields can't have modifiers.
10+
// extension type Bar<T>._(this.i) {
11+
// ^
12+
//
513
// pkg/front_end/testcases/extension_types/issue52119.dart:12:26: Error: Couldn't find constructor 'Foo.unresolved'.
614
// Foo.erroneous() : this.unresolved(); // Error
715
// ^^^^^^^^^^

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

+8
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,14 @@ library;
22
//
33
// Problems in library:
44
//
5+
// pkg/front_end/testcases/extension_types/issue52119.dart:15:30: Error: Expected a representation type.
6+
// extension type Bar<T>._(this.i) {
7+
// ^
8+
//
9+
// pkg/front_end/testcases/extension_types/issue52119.dart:15:30: Error: Representation fields can't have modifiers.
10+
// extension type Bar<T>._(this.i) {
11+
// ^
12+
//
513
// pkg/front_end/testcases/extension_types/issue52119.dart:12:26: Error: Couldn't find constructor 'Foo.unresolved'.
614
// Foo.erroneous() : this.unresolved(); // Error
715
// ^^^^^^^^^^

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

+11
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,15 @@
11
library;
2+
//
3+
// Problems in library:
4+
//
5+
// pkg/front_end/testcases/extension_types/issue52119.dart:15:30: Error: Expected a representation type.
6+
// extension type Bar<T>._(this.i) {
7+
// ^
8+
//
9+
// pkg/front_end/testcases/extension_types/issue52119.dart:15:30: Error: Representation fields can't have modifiers.
10+
// extension type Bar<T>._(this.i) {
11+
// ^
12+
//
213
import self as self;
314
import "dart:core" as core;
415

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

+8
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,14 @@ library;
22
//
33
// Problems in library:
44
//
5+
// pkg/front_end/testcases/extension_types/issue52119.dart:15:30: Error: Expected a representation type.
6+
// extension type Bar<T>._(this.i) {
7+
// ^
8+
//
9+
// pkg/front_end/testcases/extension_types/issue52119.dart:15:30: Error: Representation fields can't have modifiers.
10+
// extension type Bar<T>._(this.i) {
11+
// ^
12+
//
513
// pkg/front_end/testcases/extension_types/issue52119.dart:12:26: Error: Couldn't find constructor 'Foo.unresolved'.
614
// Foo.erroneous() : this.unresolved(); // Error
715
// ^^^^^^^^^^
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by b
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
extension type E1(var foo) {} // Error.
6+
extension type E2(final foo) {} // Error.
7+
extension type E3(final String foo) {} // Error.
8+
extension type E4(covariant num foo) {} // Error.
9+
extension type E5(const bool foo) {} // Error.
10+
extension type E6(covariant final double foo) {} // Error.
11+
extension type E7(const var foo) {} // Error.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
library;
2+
//
3+
// Problems in library:
4+
//
5+
// pkg/front_end/testcases/extension_types/representation_field_error.dart:5:23: Error: Expected a representation type.
6+
// extension type E1(var foo) {} // Error.
7+
// ^^^
8+
//
9+
// pkg/front_end/testcases/extension_types/representation_field_error.dart:6:25: Error: Expected a representation type.
10+
// extension type E2(final foo) {} // Error.
11+
// ^^^
12+
//
13+
// pkg/front_end/testcases/extension_types/representation_field_error.dart:6:25: Error: Representation fields can't have modifiers.
14+
// extension type E2(final foo) {} // Error.
15+
// ^^^
16+
//
17+
// pkg/front_end/testcases/extension_types/representation_field_error.dart:7:32: Error: Representation fields can't have modifiers.
18+
// extension type E3(final String foo) {} // Error.
19+
// ^^^
20+
//
21+
// pkg/front_end/testcases/extension_types/representation_field_error.dart:8:33: Error: Representation fields can't have modifiers.
22+
// extension type E4(covariant num foo) {} // Error.
23+
// ^^^
24+
//
25+
// pkg/front_end/testcases/extension_types/representation_field_error.dart:9:19: Error: Can't have modifier 'const' here.
26+
// Try removing 'const'.
27+
// extension type E5(const bool foo) {} // Error.
28+
// ^^^^^
29+
//
30+
// pkg/front_end/testcases/extension_types/representation_field_error.dart:9:30: Error: Representation fields can't have modifiers.
31+
// extension type E5(const bool foo) {} // Error.
32+
// ^^^
33+
//
34+
// pkg/front_end/testcases/extension_types/representation_field_error.dart:10:42: Error: Representation fields can't have modifiers.
35+
// extension type E6(covariant final double foo) {} // Error.
36+
// ^^^
37+
//
38+
// pkg/front_end/testcases/extension_types/representation_field_error.dart:11:25: Error: Members can't be declared to be both 'var' and 'const'.
39+
// Try removing one of the keywords.
40+
// extension type E7(const var foo) {} // Error.
41+
// ^^^
42+
//
43+
// pkg/front_end/testcases/extension_types/representation_field_error.dart:11:19: Error: Can't have modifier 'const' here.
44+
// Try removing 'const'.
45+
// extension type E7(const var foo) {} // Error.
46+
// ^^^^^
47+
//
48+
// pkg/front_end/testcases/extension_types/representation_field_error.dart:11:29: Error: Expected a representation type.
49+
// extension type E7(const var foo) {} // Error.
50+
// ^^^
51+
//
52+
// pkg/front_end/testcases/extension_types/representation_field_error.dart:11:29: Error: Representation fields can't have modifiers.
53+
// extension type E7(const var foo) {} // Error.
54+
// ^^^
55+
//
56+
import self as self;
57+
import "dart:core" as core;
58+
59+
extension type E1(dynamic foo) {
60+
constructor • = self::E1|constructor#;
61+
constructor tearoff • = self::E1|constructor#_#new#tearOff;
62+
}
63+
extension type E2(dynamic foo) {
64+
constructor • = self::E2|constructor#;
65+
constructor tearoff • = self::E2|constructor#_#new#tearOff;
66+
}
67+
extension type E3(core::String foo) {
68+
constructor • = self::E3|constructor#;
69+
constructor tearoff • = self::E3|constructor#_#new#tearOff;
70+
}
71+
extension type E4(core::num foo) {
72+
constructor • = self::E4|constructor#;
73+
constructor tearoff • = self::E4|constructor#_#new#tearOff;
74+
}
75+
extension type E5(core::bool foo) {
76+
constructor • = self::E5|constructor#;
77+
constructor tearoff • = self::E5|constructor#_#new#tearOff;
78+
}
79+
extension type E6(core::double foo) {
80+
constructor • = self::E6|constructor#;
81+
constructor tearoff • = self::E6|constructor#_#new#tearOff;
82+
}
83+
extension type E7(dynamic foo) {
84+
constructor • = self::E7|constructor#;
85+
constructor tearoff • = self::E7|constructor#_#new#tearOff;
86+
}
87+
static inline-class-member method E1|constructor#(dynamic foo) → self::E1 /* = dynamic */ {
88+
lowered final self::E1 /* = dynamic */ #this = foo;
89+
return #this;
90+
}
91+
static inline-class-member method E1|constructor#_#new#tearOff(dynamic foo) → self::E1 /* = dynamic */
92+
return self::E1|constructor#(foo);
93+
static inline-class-member method E2|constructor#(final dynamic foo) → self::E2 /* = dynamic */ {
94+
lowered final self::E2 /* = dynamic */ #this = foo;
95+
return #this;
96+
}
97+
static inline-class-member method E2|constructor#_#new#tearOff(dynamic foo) → self::E2 /* = dynamic */
98+
return self::E2|constructor#(foo);
99+
static inline-class-member method E3|constructor#(final core::String foo) → self::E3 /* = core::String */ {
100+
lowered final self::E3 /* = core::String */ #this = foo;
101+
return #this;
102+
}
103+
static inline-class-member method E3|constructor#_#new#tearOff(core::String foo) → self::E3 /* = core::String */
104+
return self::E3|constructor#(foo);
105+
static inline-class-member method E4|constructor#(covariant-by-declaration core::num foo) → self::E4 /* = core::num */ {
106+
lowered final self::E4 /* = core::num */ #this = foo;
107+
return #this;
108+
}
109+
static inline-class-member method E4|constructor#_#new#tearOff(core::num foo) → self::E4 /* = core::num */
110+
return self::E4|constructor#(foo);
111+
static inline-class-member method E5|constructor#(core::bool foo) → self::E5 /* = core::bool */ {
112+
lowered final self::E5 /* = core::bool */ #this = foo;
113+
return #this;
114+
}
115+
static inline-class-member method E5|constructor#_#new#tearOff(core::bool foo) → self::E5 /* = core::bool */
116+
return self::E5|constructor#(foo);
117+
static inline-class-member method E6|constructor#(covariant-by-declaration final core::double foo) → self::E6 /* = core::double */ {
118+
lowered final self::E6 /* = core::double */ #this = foo;
119+
return #this;
120+
}
121+
static inline-class-member method E6|constructor#_#new#tearOff(core::double foo) → self::E6 /* = core::double */
122+
return self::E6|constructor#(foo);
123+
static inline-class-member method E7|constructor#(dynamic foo) → self::E7 /* = dynamic */ {
124+
lowered final self::E7 /* = dynamic */ #this = foo;
125+
return #this;
126+
}
127+
static inline-class-member method E7|constructor#_#new#tearOff(dynamic foo) → self::E7 /* = dynamic */
128+
return self::E7|constructor#(foo);

0 commit comments

Comments
 (0)