Skip to content

Commit 8a9315e

Browse files
authored
add support for augmenting enum values, specify language versioning constraints (#3042)
1 parent 961ed40 commit 8a9315e

File tree

1 file changed

+89
-15
lines changed

1 file changed

+89
-15
lines changed

working/augmentation-libraries/feature-specification.md

Lines changed: 89 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# Augmentation Libraries
22

33
4-
Version: 1.7 (see [Changelog](#Changelog) at end)
4+
Version: 1.8 (see [Changelog](#Changelog) at end)
55

66
Augmentation libraries allow splitting a Dart library into files. Unlike part
77
files, each augmentation has its [own imports][part imports] and top-level
@@ -94,13 +94,17 @@ file.
9494

9595
Augmentations have a few features unique to them:
9696

97-
* An augmentation may add new members to existing types in the main library.
97+
* An augmentation may add new members to existing types in the main library,
98+
including adding new values to enums.
9899

99100
* A function in the augmentation may wrap the body of a function in the main
100-
library.
101+
library, or provide a body if none was present.
101102

102103
* A variable in the augmentation may wrap the initializer of a variable in the
103-
main library.
104+
main library, or provide an initializer if none was present.
105+
106+
* An enum value in the augmentation may replace the argument list of an enum
107+
value in the main library, or provide an argument list if none was present.
104108

105109
These can't be expressed today using only imports, exports, and part files.
106110

@@ -162,6 +166,13 @@ merge its declarations into this library. It is a compile-time error if:
162166
you can't have redundant `import augment` directives that point to the same
163167
library.*
164168

169+
* The main library and its augmentations do not all have the same language
170+
version. There is only one user-visible library at the end, and it should
171+
have a consistent version across its entire surface area. *An augmentation
172+
library does not automatically inherit any language version from the main
173+
library and may need an explicit language version comment of its own in
174+
order to adhere to this requirement.*
175+
165176
Since the main library and its augmentation both point to each other, these
166177
rules imply that a given augmentation file can only be used to augment a single
167178
library.
@@ -245,9 +256,6 @@ This order is user-visible in two ways:
245256
**TODO: Should it be a compile-time error if the main library and augmentation
246257
are in different packages?**
247258
248-
**TODO: Can the main library and augmentations have different language
249-
versions?**
250-
251259
## Augmenting declarations
252260
253261
Unlike part files, which can only add entirely new declarations, an augmentation
@@ -304,11 +312,10 @@ class's superinterface and mixin lists, respectively.
304312

305313
**TODO: Is appending the right order for mixins?**
306314

307-
Any instance or static members defined in the body of the type are added to the
308-
instance or static namespace of the corresponding type in the main library. In
309-
other words, the augmentation can add new members to an existing type.
310-
311-
**TODO: Can an augmentation on enums add new enum cases?**
315+
Any instance or static members defined in the body of the type, including enum
316+
values, are added to the instance or static namespace of the corresponding type
317+
in the main library. In other words, the augmentation can add new members to an
318+
existing type.
312319

313320
Instance and static members inside a type may themselves be augmentations. In
314321
that case, they augment the corresponding members in the original type
@@ -331,7 +338,7 @@ It is a compile-time error if:
331338

332339
* The type parameters of the type augmentation do not match the original
333340
type's type parameters. This means there must be the same number of type
334-
parameters with the same bounds.
341+
parameters with the same bounds and names.
335342

336343
*Since repeating the type parameters is, by definition, redundant, this
337344
doesn't accomplish anything semantically. But it ensures that anyone reading
@@ -357,7 +364,8 @@ augment int slowCalculation(int a, int b) {
357364
The augmentation replaces the original function body with the augmenting code.
358365
Inside the augmentation body, a special `augment super()` expression may be used
359366
to execute the original function body. That expression takes an argument list
360-
matching the original function's parameter list and returns the function's type.
367+
matching the original function's parameter list and returns the function's
368+
return type.
361369

362370
**TODO: Better syntax than `augment super`?**
363371

@@ -393,7 +401,7 @@ It is a compile-time error if:
393401
**TODO: Should we allow augmenting functions to add parameters? If so, how does
394402
this interact with type checking calls to the function?**
395403

396-
### Augmenting variables, getter, and setters
404+
### Augmenting variables, getters, and setters
397405

398406
Augmentations on variables, getters, and setters are more complex because the
399407
language treats those as [mostly interchangeable][uniform]. We want to preserve
@@ -494,6 +502,64 @@ It is a compile-time error if:
494502
This means a `late` variable's initializer can't be called from a non-`late`
495503
variable's initializer.*
496504

505+
### Augmenting enum values
506+
507+
Enum values can _only_ be augmented by enum values, and the implicit getter
508+
introduced by them is not augmentable. The one thing you are allowed to do is to
509+
replace the argument list. There is no way to refer to the original argument
510+
list (although a macro may be able introspect on it and copy over some or all of
511+
the arguments).
512+
513+
An augmenting enum value is allowed to invoke a different constructor than
514+
the original enum value, or provide an argument list where none was present
515+
before.
516+
517+
New enum values may also be defined in the augmenting library, and they will
518+
be appended to the original values in source and augmentation traversal order.
519+
Augmenting an existing enum value never changes the order in which it appears in
520+
`values`.
521+
522+
For example:
523+
524+
```
525+
// main.dart
526+
import augment 'a.dart';
527+
import augment 'c.dart';
528+
529+
enum A {
530+
first;
531+
}
532+
533+
// a.dart
534+
library augment 'main.dart';
535+
536+
import augment 'b.dart';
537+
538+
augment enum A {
539+
second;
540+
augment first; // This is still `first` in values.
541+
}
542+
// b.dart
543+
library augment 'a.dart';
544+
545+
augment enum A {
546+
augment third;
547+
}
548+
549+
// c.dart
550+
library augment 'main.dart';
551+
552+
augment enum A {
553+
augment fourth;
554+
}
555+
```
556+
557+
Then `A.values` is `[A.first, A.second, A.third, A.fourth]`.
558+
559+
It is a compile-time error if:
560+
561+
* An augmenting getter is defined for an enum value.
562+
497563
### Augmenting constructors
498564

499565
Constructors are (as always) more complex. A constructor marked `augment`
@@ -804,6 +870,14 @@ language and our tools.
804870

805871
## Changelog
806872

873+
### 1.8
874+
875+
* Specify that main libraries and thier augmentations must have the same
876+
language version.
877+
878+
* Specifically call out that augmentations can add and augment enum values,
879+
and specify how that works.
880+
807881
### 1.7
808882

809883
* Specify that augmentations must contain all the same keywords as the

0 commit comments

Comments
 (0)