@@ -25,6 +25,7 @@ RequirementsManifest? globalResultRequirements;
2525/// This cannot be `const` because we change it in tests.
2626bool withFineDependencies = false ;
2727
28+ /// Requirements for a single `export` .
2829@visibleForTesting
2930class ExportRequirement {
3031 final Uri fragmentUri;
@@ -53,41 +54,40 @@ class ExportRequirement {
5354 );
5455 }
5556
56- ExportFailure ? isSatisfied ({required LinkedElementFactory elementFactory}) {
57+ ExportFailure ? isSatisfied ({
58+ required LinkedElementFactory elementFactory,
59+ required Set <LookupName > declaredTopNames,
60+ }) {
5761 var libraryElement = elementFactory.libraryOfUri (exportedUri);
58- var libraryManifest = libraryElement? .manifest;
59- if (libraryManifest == null ) {
62+ if (libraryElement == null ) {
6063 return ExportLibraryMissing (uri: exportedUri);
6164 }
6265
66+ // SAFETY: every library has the manifest.
67+ var libraryManifest = libraryElement.manifest! ;
68+
6369 // Every now exported ID must be previously exported.
6470 var actualCount = 0 ;
65- var declaredTopEntries = < MapEntry <LookupName , TopLevelItem >> [
66- ...libraryManifest.declaredClasses.entries,
67- ...libraryManifest.declaredEnums.entries,
68- ...libraryManifest.declaredMixins.entries,
69- ...libraryManifest.declaredGetters.entries,
70- ...libraryManifest.declaredSetters.entries,
71- ...libraryManifest.declaredFunctions.entries,
72- ];
73- for (var topEntry in declaredTopEntries) {
74- var name = topEntry.key;
75- if (name.isPrivate) {
71+ for (var topEntry in libraryManifest.exportedIds.entries) {
72+ var lookupName = topEntry.key;
73+
74+ // If declared locally, export is no-op.
75+ if (declaredTopNames.contains (lookupName)) {
7676 continue ;
7777 }
7878
79- if (! _passCombinators (name )) {
79+ if (! _passCombinators (lookupName )) {
8080 continue ;
8181 }
8282
8383 actualCount++ ;
84- var actualId = topEntry.value.id ;
85- var expectedId = exportedIds[topEntry.key ];
84+ var actualId = topEntry.value;
85+ var expectedId = exportedIds[lookupName ];
8686 if (actualId != expectedId) {
8787 return ExportIdMismatch (
8888 fragmentUri: fragmentUri,
8989 exportedUri: exportedUri,
90- name: name ,
90+ name: lookupName ,
9191 expectedId: expectedId,
9292 actualId: actualId,
9393 );
@@ -269,6 +269,47 @@ class InterfaceItemRequirements {
269269 }
270270}
271271
272+ /// Requirements for all `export` s of a library.
273+ @visibleForTesting
274+ class LibraryExportRequirements {
275+ final Uri libraryUri;
276+ final Set <LookupName > declaredTopNames;
277+ final List <ExportRequirement > exports;
278+
279+ LibraryExportRequirements ({
280+ required this .libraryUri,
281+ required this .declaredTopNames,
282+ required this .exports,
283+ });
284+
285+ factory LibraryExportRequirements .read (SummaryDataReader reader) {
286+ return LibraryExportRequirements (
287+ libraryUri: reader.readUri (),
288+ declaredTopNames: reader.readLookupNameSet (),
289+ exports: reader.readTypedList (() => ExportRequirement .read (reader)),
290+ );
291+ }
292+
293+ ExportFailure ? isSatisfied ({required LinkedElementFactory elementFactory}) {
294+ for (var export in exports) {
295+ var failure = export.isSatisfied (
296+ elementFactory: elementFactory,
297+ declaredTopNames: declaredTopNames,
298+ );
299+ if (failure != null ) {
300+ return failure;
301+ }
302+ }
303+ return null ;
304+ }
305+
306+ void write (BufferedSink sink) {
307+ sink.writeUri (libraryUri);
308+ declaredTopNames.write (sink);
309+ sink.writeList (exports, (export) => export.write (sink));
310+ }
311+ }
312+
272313class RequirementsManifest {
273314 /// LibraryUri => TopName => ID
274315 final Map <Uri , Map <LookupName , ManifestItemId ?>> topLevels = {};
@@ -279,7 +320,7 @@ class RequirementsManifest {
279320 /// LibraryUri => TopName => InterfaceItemRequirements
280321 final Map <Uri , Map <LookupName , InterfaceItemRequirements >> interfaces = {};
281322
282- final List <ExportRequirement > exportRequirements = [];
323+ final List <LibraryExportRequirements > exportRequirements = [];
283324
284325 RequirementsManifest ();
285326
@@ -318,7 +359,7 @@ class RequirementsManifest {
318359 );
319360
320361 result.exportRequirements.addAll (
321- reader.readTypedList (() => ExportRequirement .read (reader)),
362+ reader.readTypedList (() => LibraryExportRequirements .read (reader)),
322363 );
323364
324365 return result;
@@ -700,9 +741,12 @@ class RequirementsManifest {
700741 /// libraries are interesting.
701742 void removeReqForLibs (Set <Uri > bundleLibraryUriList) {
702743 var uriSet = bundleLibraryUriList.toSet ();
703- exportRequirements.removeWhere ((export) {
704- return uriSet.contains (export.exportedUri);
705- });
744+
745+ for (var exportRequirement in exportRequirements) {
746+ exportRequirement.exports.removeWhere ((export) {
747+ return uriSet.contains (export.exportedUri);
748+ });
749+ }
706750
707751 for (var libUri in bundleLibraryUriList) {
708752 topLevels.remove (libUri);
@@ -751,6 +795,15 @@ class RequirementsManifest {
751795 }
752796
753797 void _addExports (LibraryElementImpl libraryElement) {
798+ var declaredTopNames =
799+ libraryElement.children2
800+ .map ((element) => element.lookupName)
801+ .nonNulls
802+ .map ((nameStr) => nameStr.asLookupName)
803+ .toSet ();
804+
805+ var fragments = < ExportRequirement > [];
806+
754807 for (var fragment in libraryElement.fragments) {
755808 for (var export in fragment.libraryExports) {
756809 var exportedLibrary = export.exportedLibrary2;
@@ -783,14 +836,17 @@ class RequirementsManifest {
783836 );
784837 for (var entry in exportMap.definedNames2.entries) {
785838 var lookupName = entry.key.asLookupName;
839+ if (declaredTopNames.contains (lookupName)) {
840+ continue ;
841+ }
786842 // TODO(scheglov): must always be not null.
787843 var id = manifest.getExportedId (lookupName);
788844 if (id != null ) {
789845 exportedIds[lookupName] = id;
790846 }
791847 }
792848
793- exportRequirements .add (
849+ fragments .add (
794850 ExportRequirement (
795851 fragmentUri: fragment.source.uri,
796852 exportedUri: exportedLibrary.uri,
@@ -800,6 +856,16 @@ class RequirementsManifest {
800856 );
801857 }
802858 }
859+
860+ if (fragments.isNotEmpty) {
861+ exportRequirements.add (
862+ LibraryExportRequirements (
863+ libraryUri: libraryElement.uri,
864+ declaredTopNames: declaredTopNames,
865+ exports: fragments,
866+ ),
867+ );
868+ }
803869 }
804870
805871 _InstanceItemWithRequirements ? _getInstanceItem (
0 commit comments