@@ -4,7 +4,7 @@ Author: Bob Nystrom
4
4
5
5
Status: In progress
6
6
7
- Version 1.4 (see [ CHANGELOG] ( #CHANGELOG ) at end)
7
+ Version 1.5 (see [ CHANGELOG] ( #CHANGELOG ) at end)
8
8
9
9
## Motivation
10
10
@@ -121,26 +121,61 @@ compile-time error if a record has any of:
121
121
122
122
### Record type annotations
123
123
124
- In the type system, each record has a corresponding record type. The grammar for
125
- record type annotations is:
124
+ In the type system, each record has a corresponding record type. A record type
125
+ looks similar to a function type's parameter list. The type is surrounded by
126
+ parentheses and may contain comma-separated positional fields:
126
127
128
+ ``` dart
129
+ (int, String name, bool) triple;
130
+ ```
131
+
132
+ Each field is a type annotation and an optional name which isn't meaningful but
133
+ is useful for documentation purposes.
134
+
135
+ Named fields go inside a brace-delimited section of type and name pairs:
136
+
137
+ ``` dart
138
+ ({int n, String s}) pair;
139
+ ```
140
+
141
+ A record type may have both positional and named fields:
142
+
143
+ ``` dart
144
+ (bool, num, {int n, String s}) quad;
127
145
```
128
- // Existing rule:
129
- typeNotVoidNotFunction ::= recordType
130
- | // Existing typeNotVoidNotFunction productions...
131
146
132
- recordType ::= '(' recordTypeFields ','? ')'
133
- | '(' ( recordTypeFields ',' )?
134
- recordTypeNamedFields ')'
135
- | recordTypeNamedFields
147
+ The grammar is:
148
+
149
+ ```
150
+ // Existing rules:
151
+ type ::= functionType '?'? // Existing production.
152
+ | recordType // New production.
153
+ | typeNotFunction // Existing production.
136
154
137
- recordTypeFields ::= type ( ',' type )*
155
+ typeNotFunction ::= 'void' // Existing production.
156
+ | recordType // New production.
157
+ | typeNotVoidNotFunction // Existing production.
158
+
159
+ // New rules:
160
+ recordType ::= '(' recordTypeFields ',' recordTypeNamedFields ')'
161
+ | '(' recordTypeFields ','? ')'
162
+ | '(' recordTypeNamedFields ')'
163
+
164
+ recordTypeFields ::= recordTypeField ( ',' recordTypeField )*
165
+ recordTypeField ::= metadata type identifier?
138
166
139
167
recordTypeNamedFields ::= '{' recordTypeNamedField
140
168
( ',' recordTypeNamedField )* ','? '}'
141
169
recordTypeNamedField ::= type identifier
170
+ recordTypeNamedField ::= metadata typedIdentifier
142
171
```
143
172
173
+ * The grammar is exactly the same as ` parameterTypeList ` in function types but
174
+ without ` () ` , ` required ` , and optional positional parameters since those don't
175
+ apply to record types. A record type can't appear in an ` extends ` , ` implements ` ,
176
+ ` with ` , or mixin ` on ` clause, which is enforced by being a production in ` type `
177
+ and not ` typeNotVoid ` .*
178
+
144
179
It is a compile-time error if a record type has any of:
145
180
146
181
* The same field name more than once.
@@ -154,34 +189,17 @@ It is a compile-time error if a record type has any of:
154
189
155
190
* A field name that starts with an underscore.
156
191
157
- The syntax is similar to a function type's parameter list. You have zero or more
158
- positional fields where each field is a type annotation:
192
+ ### No record type literals
159
193
160
- ``` dart
161
- (int, String, bool) triple;
162
- ```
163
-
164
- Then a brace-delimited section for named fields. Each named field is a type and
165
- name pair:
194
+ There is no record type literal syntax that can be used as an expression, since
195
+ it would be ambiguous with other existing syntax:
166
196
167
197
``` dart
168
- ({ int n , String s}) pair ;
198
+ var t = ( int, String) ;
169
199
```
170
200
171
- A record type can have both positional and named fields:
172
-
173
- ``` dart
174
- (bool, num, {int n, String s}) quad;
175
- ```
176
-
177
- If there are only named fields, you are allowed to omit the surrounding
178
- parentheses:
179
-
180
- ``` dart
181
- {int n, String s} pair;
182
- ```
183
-
184
- Like record expressions, a record type must have at least one field.
201
+ This is a record expression containing two type literals, ` int ` and ` String ` ,
202
+ not a type literal for a record type.
185
203
186
204
## Static semantics
187
205
@@ -360,6 +378,19 @@ covariant in their field types.
360
378
361
379
## CHANGELOG
362
380
381
+ ### 1.5
382
+
383
+ - Make the grammar for record types closer to function type parameter lists.
384
+ Allow metadata before fields and optional names for positional fields.
385
+
386
+ - Weave ` recordType ` into the grammar better. Don't allow it in inheritance
387
+ clauses, but do allow it as the return type of function types.
388
+
389
+ - Remove shorthand syntax that elides parentheses when there are no positional
390
+ fields since that's ambiguous inside a function type (#2302 ).
391
+
392
+ - Clarify that there is no record type literal syntax (#2304 ).
393
+
363
394
### 1.4
364
395
365
396
- Remove the reflective static members on ` Record ` . Like other reflective
0 commit comments