@@ -4,7 +4,7 @@ Author: Bob Nystrom
4
4
5
5
Status: Accepted
6
6
7
- Version 1.12 (see [ CHANGELOG] ( #CHANGELOG ) at end)
7
+ Version 1.13 (see [ CHANGELOG] ( #CHANGELOG ) at end)
8
8
9
9
## Motivation
10
10
@@ -257,6 +257,80 @@ avoid this ambiguity ([#2469][]).**
257
257
258
258
[ #2469 ] : https://github.com/dart-lang/language/issues/2469
259
259
260
+ ### Ambiguity with metadata annotations
261
+
262
+ A metadata annotation may or may not have an argument list following it. A
263
+ variable declaration may omit a preceding type annotation. Likewise, a function
264
+ declaration may omit a preceding return type. This combination of syntax where
265
+ an optional trailing element is followed by syntax with an optional preceding
266
+ element can lead to ambiguity. In particular:
267
+
268
+ ``` dart
269
+ @metadata (a, b) function() {}
270
+ ```
271
+
272
+ This could be a metadata annotation ` @metadata(a, b) ` associated with a function
273
+ declaration with no return type. Or it could be a metadata annotation
274
+ ` @metadata ` associated with a function whose return type is the record type `(a,
275
+ b)`.
276
+
277
+ In practice, idiomatically written code is clear thanks to whitespace:
278
+
279
+ ``` dart
280
+ @metadata(a, b) function() {}
281
+
282
+ @metadata (a, b) function() {}
283
+ ```
284
+
285
+ The former applies ` (a, b) ` to the metadata annotation and the latter is a
286
+ return type. We disambiguate in the same way, by making whitespace after a
287
+ metadata annotation name significant. Change the grammar to:
288
+
289
+ ```
290
+ metadatum ::= identifier // Existing rule.
291
+ | qualifiedName // Existing rule.
292
+ | constructorDesignation ~WHITESPACE arguments // Changed.
293
+ ```
294
+
295
+ The ` ~WHITESPACE ` lexical rule matches when there are no whitespace characters
296
+ (according to the existing ` WHITESPACE ` lexical rule) between the
297
+ ` constructorDesignation ` and ` arguments ` . Comments do not count as whitespace,
298
+ nor do whitespace characters in comments. The newline at the end of a line
299
+ comment * does* count as whitespace.
300
+
301
+ ``` dart
302
+ // These are argument lists to the annotation:
303
+ @metadata(x,) a;
304
+ @metadata/* a comment */(x,) a;
305
+ @metadata/* a
306
+ multi
307
+ line
308
+ comment */(x,) a;
309
+
310
+ // These are record variable types:
311
+ @metadata (x,) a;
312
+
313
+ @metadata
314
+ (x,) a;
315
+
316
+ @metadata // Comment.
317
+ (x,) a;
318
+
319
+ @metadata/* Comment with newline after. */
320
+ (x,) a;
321
+ ```
322
+
323
+ Note that the no whitespace rule is applied unconditionally, even when the
324
+ metadata annotation appears in a context where no ambiguity with record types
325
+ is possible.
326
+
327
+ ** Breaking change:** Existing metadata annotations with whitespace before their
328
+ argument lists will no longer parse correctly. In a corpus of 18,672,247 lines
329
+ of code containing 409,825 metadata annotations, 46,245 had argument lists and
330
+ none of those had whitespace before the argument list. Note that this analysis
331
+ only captures code that has been committed. Code being written may be less well
332
+ formatted, but we expect problems from this to be rare.
333
+
260
334
## Static semantics
261
335
262
336
We define ** shape** to mean the number of positional fields (the record's
@@ -587,6 +661,10 @@ covariant in their field types.
587
661
588
662
## CHANGELOG
589
663
664
+ ### 1.13
665
+
666
+ - Disambiguate record types following metadata annotations (#2469 ).
667
+
590
668
### 1.12
591
669
592
670
- Include record types in ` typeNotVoid ` . This allows them to appear in ` is ` and
0 commit comments