1
1
# Part files with imports
2
2
3
3
4
- Version: 1.0 (See [ Changelog] ( #Changelog ) at end)
4
+ Version: 1.1 (See [ Changelog] ( #Changelog ) at end)
5
5
6
- This is a stand-along definition of _ improved part files_ , where the title of
6
+ This is a stand-alone definition of _ enhanced part files_ , where the title of
7
7
this document/feature is highlighting only the most prominent part of the
8
8
feature. This document is extracted and distilled from the [ Augmentations] [ ]
9
9
specification. The original specification introduced special files for
@@ -197,7 +197,7 @@ as a `<partDirective>`, or if its leading `<partHeader>`'s `<uri>` string,
197
197
resolved as a URI reference against the URI * U* , does not denote the library of
198
198
* P* . _ That is, if a Dart file has a part directive, its target must be a part
199
199
file whose “part of” directive points back to the first Dart file. Nothing new,
200
- except that now the parent file may not be a library file.) _
200
+ except that now the parent file may not be a library file._
201
201
202
202
### Resolution and scopes (part and import directives)
203
203
@@ -269,7 +269,7 @@ defined as:
269
269
270
270
That is: The combined import scope of a Dart file is a chain of the combined
271
271
import scopes of the file and its parent files, each step adding two scopes:
272
- The (unnamed, top-level ) import scope of the unprefixed imports and the prefix
272
+ The (unnamed) import scope of the unprefixed imports and the prefix
273
273
scope with prefixed imports, each shadowing names further up in the chain.
274
274
275
275
The * top-level scope* of a Dart file is a library * declaration scope*
@@ -279,14 +279,16 @@ the combined import scope of that Dart file. _Each Dart file has its own copy
279
279
of the library declaration scope, all containing the same declarations, because
280
280
the declaration scopes of different files have different parent scopes._
281
281
282
- ** It’s a compile-time error ** if any file declares an import prefix with the
282
+ ** It’s a compile-time error** if any file declares an import prefix with the
283
283
same base name as a top-level declaration of the library.
284
284
285
285
_ We have split the prefixes out of the top-level scope, but we maintain that
286
- they must not have the same names anyway. Any prefix that has the same name as
287
- a top-level declaration of the library is impossible to reference, because the
288
- library declaration scope always precedes the prefix scope in any scope chain
289
- lookup. This does mean that adding a top-level declaration in one part file may
286
+ they must not have the same names anyway. Not because it's a problem for the
287
+ compiler or language, but because it's probably a sign of a user error.
288
+ Any prefix that has the same name as a top-level declaration of the library
289
+ is impossible to reference, because the library declaration scope
290
+ always precedes the prefix scope in any scope chain lookup.
291
+ This does mean that adding a top-level declaration in one part file may
290
292
conflict with a prefix name in another part file in a completely different
291
293
branch of the library file tree. That is not a conflict with the “other file’s
292
294
imports cannot break your code” principle, rather the error is in the file
@@ -296,14 +298,56 @@ library, so the library author should fix the conflict by renaming the prefix.
296
298
That such a name conflict is a compile-time error, makes it much easier to
297
299
detect if it happens._
298
300
301
+ #### Resolving implicitly applied extensions
302
+
303
+ The only change to implicit extension application in this feature
304
+ is in the definition of whether an extension is * available* .
305
+ Whether an extension is * applicable* , its * specificity* if applicable,
306
+ and how that is used to to choose between multiple available and applicable
307
+ extensions is unchanged.
308
+
309
+ An extension declaration being * available* has been defined as being
310
+ declared or * imported* by the current library.
311
+ Being imported by a library means that the library has at least one
312
+ import directive which * imports the extensions* , which again means that it
313
+ imports a library which has the extension declaration in its export scope,
314
+ and the import directive does not have a ` show ` or ` hide ` combinator
315
+ which hides the name of the extension declaration.
316
+
317
+ With this feature, imports are not global to the entire library,
318
+ and neither is extension availability.
319
+
320
+ Extension availability is defined * per file* , and an extension
321
+ is available * in a Dart file* if any of:
322
+ * The extension is declared by the library of the Dart file.
323
+ * The extension is available * by import* in the Dart file.
324
+
325
+ where an extension is available by import in a Dart file if any of:
326
+ * That file contains an import directive which * imports the extension*
327
+ * That file is a part file and the extension is (recursively) available
328
+ by import in its parent file.
329
+
330
+ (One way to visualize the availability is to associate declared
331
+ or imported extensions with scopes. If a file has an import directive
332
+ which imports an extension, the extension is associated with the
333
+ import scope of that file, or with the prefix import scope
334
+ if the import is prefixed. A declaration in the library itself
335
+ is associated with the top-level scope of each file.
336
+ Then an extension is available in a file if it is associated with
337
+ any scope in the top-level scope chain of that file.)
338
+
339
+ There is no attempt to * prioritize* available extensions based on
340
+ where they are imported. Every extension imported or declared in the
341
+ file's top-level scope chain is equally available.
342
+
299
343
### Export directives
300
344
301
345
Any Dart file can contain an ` export ` directive. It makes no difference which
302
- file an ` export ` is in, its declarations (filtered by any ` hide ` or ` show `
303
- modifiers ) are added to the library’s single export scope, along with those of
304
- any other ` export ` s in the library and the non-private declarations of the
305
- library itself. Conflicts are handled as usual (as an error if it’s not the
306
- * same* declaration).
346
+ file an ` export ` is in, its exported declarations (filtered by any ` hide ` or
347
+ ` show ` combinators ) are added to the library’s single export scope,
348
+ along with those of any other ` export ` directives in the library and
349
+ the all non-private declarations of the library itself. Conflicts are handled
350
+ as usual (as an error if it’s not the * same* declaration).
307
351
308
352
Allowing a part file to have its own export is mainly for consistency.
309
353
Most libraries will likely keep all ` export ` directives in the library file.
@@ -332,20 +376,21 @@ URI denoting that part file.
332
376
* _ It’s a compile-time error if a Dart file has two ` part ` directives with
333
377
the same URI, so each included part file is included exactly once._
334
378
* _ It’s a compile-time error if a ` part ` directive denotes a file which is
335
- not a part file._
379
+ not a Dart part file._
336
380
337
381
The * parent file* of a part file is the file denoted by the URI of the
338
382
` part of ` declaration of the part file. A library file has no parent file.
339
383
340
384
* _ It’s a compile-time error if a part file is included by any Dart file
341
385
other than the part file’s parent file._
342
386
* The * includes* and * is the parent file of* properties are equivalent for
343
- the files of a Dart program. A Dart file includes a part file if, and only
344
- if, the Dart file is the parent file of the part file, otherwise there is a
345
- compile-time error. (There are no restrictions on the parent file of a part
346
- file which is not part of a library of a Dart program. Dart semantics is
347
- only assigned to entire libraries and programs, not individual part files.
348
- We’ll refer to the relation as both one file being included by another, and
387
+ the files of a valid Dart program. A Dart file includes a part file if,
388
+ and only if, the Dart file is the parent file of the part file, otherwise
389
+ there is a compile-time error.
390
+ _ (There are no restrictions on the parent file of a part file which is not
391
+ part of a library of a Dart program. Dart semantics is only assigned to
392
+ entire libraries and programs, not individual part files.)_
393
+ We’ll refer to this relation as both one file being included by another, and
349
394
the former file being the parent (file) of the latter file.
350
395
351
396
Two or more part files are called * sibling part files* (or just
@@ -359,17 +404,17 @@ the Dart file, or if the file is a *sub-part* of a file included by the
359
404
* included by* relation. We’ll refer to it by saying either that one Dart
360
405
file is an ancestor file of another part file, or that a part file is a
361
406
sub-part of another Dart file.
362
- * <a name =" part_cycle " ></a >_ It’s a compile-time error if a part file is a sub-part
363
- of itself._
364
- That is, if the * includes* relation has a cycle. This is not a * necessary*
407
+ * <a name =" part_cycle " ></a >_ It’s a compile-time error if a part file is
408
+ a sub-part of itself._
409
+ That is, if the * includes* relation has a cycle. _ This is not a * necessary*
365
410
error from the language's perspective, since no library can contain such a
366
411
part file without introducing another error; at the first ` part ` directive
367
412
reachable from a library file which includes a file from the cycle,
368
- the including file is not the parent of that file.
369
- The rule is included as a help to tools that try to analyzer Dart code
413
+ the including file is not the parent of that file._
414
+ _ The rule is included as a help to tools that try to analyzer Dart code
370
415
starting at individual files, they can then assume that either a part file
371
416
has an ancestor which is a library file, or there is a compile-time error.
372
- Or an infinite number of part files.)
417
+ Or an infinite number of part files._
373
418
374
419
The * sub-tree* of a Dart file is the set of files containing the file itself
375
420
and all its sub-parts. The * root* of a sub-tree is the Dart file that all other
@@ -399,9 +444,9 @@ least containing sub-tree for any set of nodes._
399
444
included parts or some in the file itself, and then no included part file
400
445
contains all the files, so there is no lesser containing file.)_
401
446
402
- The * files of a library* is the entire sub-tree of the defining library file.
403
- It contains the library file.
404
- The sub-tree of a part file of a library contains no library file .
447
+ The * files of a library* is the entire sub-tree of the defining library file,
448
+ and the only subtree which contains the library file.
449
+ The sub-tree of a part file of a library contains only part files .
405
450
406
451
In short:
407
452
@@ -610,13 +655,29 @@ will already be compatible.
610
655
611
656
[ string_part_of_lint ] : https://dart.dev/tools/linter-rules/use_string_in_part_of_directives " use_string_in_part_of_directives lint "
612
657
658
+ ### Development
659
+
660
+ The experiment name for this feature is ` enhanced-parts ` .
661
+
662
+ The macro feature requires both this feature and the augmentations feature.
663
+ Tools can choose to enable these features automatically when the macros feature
664
+ is enabled, or they can enable it selectively only for code generated by macros.
665
+
666
+ The augmentations feature does not require enhanced parts, it can work
667
+ within the existing part requirements.
668
+
613
669
## Changelog
614
670
671
+ ### 1.1
672
+
673
+ * Specifies resolution of implicit extension declarations.
674
+ * Names the feature "Enhanced parts".
675
+ * Fixes some typos.
676
+
615
677
### 1.0
616
678
617
679
* Initial version. The corresponding version of [ Augmentations] , which refers
618
680
to part files with imports, is version 1.21.
619
-
620
681
* Combines augmentation libraries, libraries and part files into just
621
682
libraries and part files, where the part files can have import, export and
622
683
further part directives. Those part directives can use configurable imports.
0 commit comments