1
1
# Augmentation Libraries
2
2
3
- Author:
[email protected] , Version: 1.
5 (see
[ Changelog
] ( #Changelog ) at end)
3
+ Author:
[email protected] , Version: 1.
6 (see
[ Changelog
] ( #Changelog ) at end)
4
4
5
5
Augmentation libraries allow splitting a Dart library into files. Unlike part
6
6
files, each augmentation has its [ own imports] [ part imports ] and top-level
@@ -130,10 +130,14 @@ However, augmentations do *not* share an import scope with the main library or
130
130
each other. The libraries one augmentation imports are visible only to that
131
131
file.
132
132
133
- It is a compile-time error if a top-level declaration in an augmentation has the
134
- same name as a declaration in the main library or another of its augmentations
135
- (unless it is an * augmenting* declaration, described below). This is the same
136
- error conceptually as having a name collision in one file.
133
+ It is a compile-time error if:
134
+
135
+ * A top-level declaration in an augmentation has the same name as a
136
+ declaration in the main library or another of its augmentations (unless it
137
+ is an * augmenting* declaration, described below). * This is the same error
138
+ conceptually as having a name collision in one file.*
139
+
140
+ * An augmentation library contains any ` part ` directives.
137
141
138
142
### Applying an augmentation library
139
143
@@ -161,32 +165,81 @@ Since the main library and its augmentation both point to each other, these
161
165
rules imply that a given augmentation file can only be used to augment a single
162
166
library.
163
167
168
+ ### Merge order
169
+
164
170
A library may apply multiple augmentations to itself. Also, augmentation files
165
171
may themselves contain ` import augment ` directives. The entire tree of
166
- augmentations is recursively applied to the main library. In most cases, the
167
- order that augmentations are applied doesn't matter, but it is visible in a
168
- couple of corners where the merge process involves "appending". For those cases,
169
- merge order is defined as a depth-first pre-order traversal of the `import
170
- augment` directives in the main library and its augmentations. So, in :
172
+ augmentations is recursively applied to the main library. The merge order is
173
+ defined as a depth-first pre-order traversal of the ` import augment ` directives
174
+ starting at the main library.
175
+
176
+ For example :
171
177
172
178
```
173
179
// main.dart
174
180
import augment 'a.dart';
175
181
import augment 'c.dart';
176
182
183
+ class C {}
184
+
185
+ void trace() {
186
+ print('main');
187
+ }
188
+
177
189
// a.dart
178
190
library augment 'main.dart';
179
191
180
192
import augment 'b.dart';
181
193
194
+ augment class C {}
195
+
196
+ augment void trace() {
197
+ augment super.trace();
198
+ print('a');
199
+ }
200
+
182
201
// b.dart
183
202
library augment 'a.dart';
184
203
204
+ class D {}
205
+
206
+ augment void trace() {
207
+ augment super.trace();
208
+ print('b');
209
+ }
210
+
185
211
// c.dart
186
212
library augment 'main.dart';
213
+
214
+ augment class D {}
215
+
216
+ augment void trace() {
217
+ augment super.trace();
218
+ print('c');
219
+ }
187
220
```
188
221
189
- The merge order is ` a.dart ` , ` b.dart ` , then ` c.dart ` .
222
+ The merge order is ` main.dart ` , ` a.dart ` , ` b.dart ` , then ` c.dart ` . The
223
+ declarations in those libraries&mdash ; new declarations or augmentations&mdash ;
224
+ are processed in that order.
225
+
226
+ This order is user-visible in two ways:
227
+
228
+ * A non-augmenting declaration must appear first before it can be augmented.
229
+ For example, ` C ` in ` main.dart ` is augmented by ` C ` in ` a.dart ` . Likewise,
230
+ ` D ` in ` b.dart ` is augmented by ` D ` in ` c.dart ` . Note that the latter is
231
+ allowed even though ` b.dart ` does not itself import ` c.dart ` .
232
+
233
+ * When the same declaration is augmented multiple times, merge order
234
+ determines the order that those wrappers are applied. When the ` trace() `
235
+ function is called, it prints:
236
+
237
+ ```
238
+ main
239
+ a
240
+ b
241
+ c
242
+ ```
190
243
191
244
**TODO: Should it be a compile-time error if the main library and augmentation
192
245
are in different packages?**
@@ -215,6 +268,15 @@ The same declaration can be augmented multiple times by separate augmentation
215
268
libraries. When that happens, the merge order defined previously determines
216
269
which order the wrapping is applied.
217
270
271
+ It is a compile-time error if:
272
+
273
+ * An augmenting declaration has no corresponding original declaration to
274
+ apply to.
275
+
276
+ * An augmenting declaration appears in a library before the library where the
277
+ original declaration occurs, according to merge order. *An augmentation
278
+ library can both declare a new declaration and augment it in the same file.*
279
+
218
280
### Augmenting types
219
281
220
282
A class, mixin, enum, or extension declaration can be marked with an `augment`
@@ -230,8 +292,8 @@ This means that instead of creating a new type declaration, the augmentation
230
292
modifies a corresponding declaration in the main library or one of its other
231
293
augmentations.
232
294
233
- A class augmentation may specify ` implements ` and ` with ` clauses. When those
234
- appear, the specified superinterfaces and mixins are appended to the main
295
+ A class or enum augmentation may specify ` implements ` and ` with ` clauses. When
296
+ those appear, the specified superinterfaces and mixins are appended to the main
235
297
class's superinterface and mixin lists, respectively.
236
298
237
299
** TODO: Is appending the right order for mixins?**
@@ -260,14 +322,15 @@ It is a compile-time error if:
260
322
* The augmenting type is marked ` abstract ` . The main library determines
261
323
whether the class is abstract or not.
262
324
263
- * The type parameters of the type augmentation do not exactly match the
264
- original type's type parameters. This means there must be the same number of
265
- type parameters with the same names and same bounds.
325
+ * The type parameters of the type augmentation do not match the original
326
+ type's type parameters. This means there must be the same number of type
327
+ parameters with the same bounds.
266
328
267
329
* Since repeating the type parameters is, by definition, redundant, this
268
330
doesn't accomplish anything semantically. But it ensures that anyone reading
269
331
the augmenting type can see the declarations of any type parameters that it
270
- uses in its body.*
332
+ uses in its body and avoids potential confusion with other top-level
333
+ variables that might be in scope in the augmentation library.*
271
334
272
335
### Augmenting functions
273
336
@@ -656,22 +719,28 @@ process a theoretical Dart implementation could take.
656
719
657
720
To apply an augmentation to the main library:
658
721
722
+ 1 . Merge the augmentation's declarations into the main library's top-level
723
+ namespace using the following procedure.
724
+
659
725
1 . For each ` import augment ` directive in the augmentation library, in
660
726
syntactic order:
661
727
662
728
1 . Apply the imported augmentation to the main library using this
663
729
procedure, recursively.
664
730
665
- 1 . For each declaration in the augmentation :
731
+ To merge a set of declarations ` D ` into a namespace :
666
732
667
- 1 . Merge the declaration into the main library's top-level namespace using
668
- the following procedure.
733
+ 1 . For each non-augmenting declaration in ` D ` :
669
734
670
- To merge a declaration into a namespace:
735
+ 1 . If a declaration with that name already exists in the namespace, error.
736
+ (Exception: setters do not collide with getters and final variables.)
737
+
738
+ 1 . Else, add the declaration to the namespace.
671
739
672
- 1 . If the declaration is marked ` augment ` :
740
+ 1 . For each augmenting declaration in ` D ` :
673
741
674
742
1 . If the namespace does not have a declaration with that name, error.
743
+ * A non-augmenting declaration must occur before it can be augmented.*
675
744
676
745
1 . If the corresponding declaration in the namespace is not the same kind,
677
746
error. "Kind" means class, mixin, function, etc. Getters, setters, and
@@ -706,20 +775,13 @@ To merge a declaration into a namespace:
706
775
** TODO: What is the syntax for calling a prefix operator's original
707
776
code?**
708
777
709
- 1 . Else, if the declaration is a variable:
778
+ 1 . Else, the declaration is a variable:
710
779
711
780
1 . Replace a matching variable, getter, and/or setter in the namespace
712
781
with the declaration. Inside the augmenting variable's initializer
713
782
expression, an ` augment super ` expression invokes the original
714
783
variable initializer.
715
784
716
- 1 . Else, it is a new declaration in the augmentation library:
717
-
718
- 1 . If a declaration with that name already exists in the namespace, error.
719
- (Exception: setters do not collide with getters and final variables.)
720
-
721
- 1 . Else, add the declaration to the namespace.
722
-
723
785
## Deprecating part files
724
786
725
787
Part files have been [ discouraged for many years] [ discourage ] . They are still
@@ -735,6 +797,17 @@ language and our tools.
735
797
736
798
## Changelog
737
799
800
+ ### 1.6
801
+
802
+ * Allow class augmentations to use different names for type parameters. This
803
+ isn't particular valuable, but is consistent with functions augmentations
804
+ which are allowed to change the names of positional parameters.
805
+
806
+ * Specify that a non-augmenting declaration must occur before any
807
+ augmentations of it, in merge order.
808
+
809
+ * Specify that augmentations can't have parts (#2057 ).
810
+
738
811
### 1.5
739
812
740
813
* Augmentation libraries share the same top-level declaration and private
0 commit comments