@@ -361,7 +361,7 @@ class PackageGraph with CommentReferable, Nameable {
361
361
@override
362
362
PackageGraph get packageGraph => this ;
363
363
364
- /// Map of package name to Package.
364
+ /// Map of package name to [ Package] .
365
365
///
366
366
/// This mapping must be complete before [initializePackageGraph] is called.
367
367
final Map <String , Package > packageMap = {};
@@ -497,38 +497,48 @@ class PackageGraph with CommentReferable, Nameable {
497
497
Iterable <Package > get _documentedPackages =>
498
498
packages.where ((p) => p.documentedWhere != DocumentLocation .missing);
499
499
500
- /// A mapping of all the [Library] s that export a given [LibraryElement] .
500
+ /// A mapping from a [LibraryElement] to all of the [Library] s that export it .
501
501
Map <LibraryElement , Set <Library >> _libraryExports = {};
502
502
503
- /// Prevent cycles from breaking our stack.
504
- Set <(Library , LibraryElement ?)> _reexportsTagged = {};
505
-
506
- void _tagReexportsFor (
507
- final Library topLevelLibrary, final LibraryElement ? libraryElement,
508
- [LibraryExportElement ? lastExportedElement]) {
509
- var key = (topLevelLibrary, libraryElement);
510
- if (_reexportsTagged.contains (key)) {
503
+ /// Marks [publicLibrary] as a library that exports [libraryElement] and all
504
+ /// libraries that [libraryElement] transitively exports.
505
+ ///
506
+ /// [alreadyTagged] is used internall to prevent visiting in cycles.
507
+ void _tagExportsFor (
508
+ final Library publicLibrary,
509
+ final LibraryElement libraryElement, {
510
+ Set <(Library , LibraryElement )>? alreadyTagged,
511
+ }) {
512
+ alreadyTagged ?? = {};
513
+ var key = (publicLibrary, libraryElement);
514
+ if (alreadyTagged.contains (key)) {
511
515
return ;
512
516
}
513
- _reexportsTagged .add (key);
514
- if (libraryElement == null ) return ;
515
- _libraryExports.putIfAbsent (libraryElement, () => {}).add (topLevelLibrary );
517
+ alreadyTagged .add (key);
518
+ // Mark that `publicLibrary` exports `libraryElement`.
519
+ _libraryExports.putIfAbsent (libraryElement, () => {}).add (publicLibrary );
516
520
for (var exportedElement in libraryElement.libraryExports) {
517
- _tagReexportsFor (
518
- topLevelLibrary, exportedElement.exportedLibrary, exportedElement);
521
+ var exportedLibrary = exportedElement.exportedLibrary;
522
+ if (exportedLibrary != null ) {
523
+ // Follow the exports down; as `publicLibrary` exports `libraryElement`,
524
+ // it also exports each `exportedLibrary`.
525
+ _tagExportsFor (publicLibrary, exportedLibrary,
526
+ alreadyTagged: alreadyTagged);
527
+ }
519
528
}
520
529
}
521
530
522
531
int _lastSizeOfAllLibraries = 0 ;
523
532
533
+ /// A mapping from a [LibraryElement] to all of the [Library] s that export it,
534
+ /// which is created if it is not yet populated.
524
535
Map <LibraryElement , Set <Library >> get libraryExports {
525
536
// Table must be reset if we're still in the middle of adding libraries.
526
537
if (allLibraries.keys.length != _lastSizeOfAllLibraries) {
527
538
_lastSizeOfAllLibraries = allLibraries.keys.length;
528
539
_libraryExports = {};
529
- _reexportsTagged = {};
530
540
for (var library in publicLibraries) {
531
- _tagReexportsFor (library, library.element);
541
+ _tagExportsFor (library, library.element);
532
542
}
533
543
}
534
544
return _libraryExports;
@@ -621,11 +631,15 @@ class PackageGraph with CommentReferable, Nameable {
621
631
}
622
632
623
633
@visibleForTesting
634
+
635
+ /// The set of all libraries (public and implementation) found across all
636
+ /// [packages] .
624
637
late final List <Library > libraries =
625
638
packages.expand ((p) => p.libraries).toList (growable: false )..sort ();
626
639
627
640
int get libraryCount => libraries.length;
628
641
642
+ /// The set of public libraries found across all [packages] .
629
643
late final Set <Library > publicLibraries = () {
630
644
assert (allLibrariesAdded);
631
645
return libraries.wherePublic.toSet ();
0 commit comments