@@ -185,22 +185,51 @@ final class ExportRequirementShowCombinator
185185 }
186186}
187187
188+ /// Requirements for [InstanceElementImpl2] .
189+ ///
190+ /// If [InterfaceElementImpl2] , there are additional requirements in form
191+ /// of [InterfaceItemRequirements] .
192+ class InstanceItemRequirements {
193+ /// These are "methods" in wide meaning: methods, getters, setters.
194+ final Map <LookupName , ManifestItemId ?> requestedMethods;
195+
196+ InstanceItemRequirements ({required this .requestedMethods});
197+
198+ factory InstanceItemRequirements .empty () {
199+ return InstanceItemRequirements (requestedMethods: {});
200+ }
201+
202+ factory InstanceItemRequirements .read (SummaryDataReader reader) {
203+ return InstanceItemRequirements (requestedMethods: reader.readNameToIdMap ());
204+ }
205+
206+ void write (BufferedSink sink) {
207+ sink.writeNameToIdMap (requestedMethods);
208+ }
209+ }
210+
211+ /// Requirements for [InterfaceElementImpl2] , in addition to those that
212+ /// we already record as [InstanceItemRequirements] .
213+ ///
188214/// Includes all requirements from class-like items: classes, enums,
189- /// extensions (NB), extension types, mixins.
190- class InterfaceRequirements {
215+ /// extension types, mixins.
216+ class InterfaceItemRequirements {
191217 final Map <LookupName , ManifestItemId ?> constructors;
192218
193219 /// These are "methods" in wide meaning: methods, getters, setters.
194220 final Map <LookupName , ManifestItemId ?> methods;
195221
196- InterfaceRequirements ({required this .constructors, required this .methods});
222+ InterfaceItemRequirements ({
223+ required this .constructors,
224+ required this .methods,
225+ });
197226
198- factory InterfaceRequirements .empty () {
199- return InterfaceRequirements (constructors: {}, methods: {});
227+ factory InterfaceItemRequirements .empty () {
228+ return InterfaceItemRequirements (constructors: {}, methods: {});
200229 }
201230
202- factory InterfaceRequirements .read (SummaryDataReader reader) {
203- return InterfaceRequirements (
231+ factory InterfaceItemRequirements .read (SummaryDataReader reader) {
232+ return InterfaceItemRequirements (
204233 constructors: reader.readNameToIdMap (),
205234 methods: reader.readNameToIdMap (),
206235 );
@@ -216,10 +245,11 @@ class RequirementsManifest {
216245 /// LibraryUri => TopName => ID
217246 final Map <Uri , Map <LookupName , ManifestItemId ?>> topLevels = {};
218247
219- /// LibraryUri => TopName => InterfaceRequirements
220- ///
221- /// These are "methods" in wide meaning: methods, getters, setters.
222- final Map <Uri , Map <LookupName , InterfaceRequirements >> interfaces = {};
248+ /// LibraryUri => TopName => InstanceItemRequirements
249+ final Map <Uri , Map <LookupName , InstanceItemRequirements >> instances = {};
250+
251+ /// LibraryUri => TopName => InterfaceItemRequirements
252+ final Map <Uri , Map <LookupName , InterfaceItemRequirements >> interfaces = {};
223253
224254 final List <ExportRequirement > exportRequirements = [];
225255
@@ -235,13 +265,25 @@ class RequirementsManifest {
235265 ),
236266 );
237267
268+ result.instances.addAll (
269+ reader.readMap (
270+ readKey: () => reader.readUri (),
271+ readValue: () {
272+ return reader.readMap (
273+ readKey: () => LookupName .read (reader),
274+ readValue: () => InstanceItemRequirements .read (reader),
275+ );
276+ },
277+ ),
278+ );
279+
238280 result.interfaces.addAll (
239281 reader.readMap (
240282 readKey: () => reader.readUri (),
241283 readValue: () {
242284 return reader.readMap (
243285 readKey: () => LookupName .read (reader),
244- readValue: () => InterfaceRequirements .read (reader),
286+ readValue: () => InterfaceItemRequirements .read (reader),
245287 );
246288 },
247289 ),
@@ -296,6 +338,43 @@ class RequirementsManifest {
296338 }
297339 }
298340
341+ for (var libraryEntry in instances.entries) {
342+ var libraryUri = libraryEntry.key;
343+
344+ var libraryElement = elementFactory.libraryOfUri (libraryUri);
345+ var libraryManifest = libraryElement? .manifest;
346+ if (libraryManifest == null ) {
347+ return LibraryMissing (uri: libraryUri);
348+ }
349+
350+ for (var instanceEntry in libraryEntry.value.entries) {
351+ var instanceName = instanceEntry.key;
352+ var instanceItem = libraryManifest.items[instanceName];
353+ if (instanceItem is ! InstanceItem ) {
354+ return TopLevelNotInterface (
355+ libraryUri: libraryUri,
356+ name: instanceName,
357+ );
358+ }
359+
360+ var methods = instanceEntry.value.requestedMethods;
361+ for (var methodEntry in methods.entries) {
362+ var methodName = methodEntry.key;
363+ var methodId = instanceItem.getDeclaredMemberId (methodName);
364+ var expectedId = methodEntry.value;
365+ if (expectedId != methodId) {
366+ return InstanceMethodIdMismatch (
367+ libraryUri: libraryUri,
368+ interfaceName: instanceName,
369+ methodName: methodName,
370+ expectedId: expectedId,
371+ actualId: methodId,
372+ );
373+ }
374+ }
375+ }
376+ }
377+
299378 for (var libraryEntry in interfaces.entries) {
300379 var libraryUri = libraryEntry.key;
301380
@@ -365,15 +444,17 @@ class RequirementsManifest {
365444 required InterfaceElementImpl2 element,
366445 required String name,
367446 }) {
368- var interfacePair = _getInterface (element);
369- if (interfacePair == null ) {
447+ var itemRequirements = _getInterfaceItem (element);
448+ if (itemRequirements == null ) {
370449 return ;
371450 }
372451
373- var (interfaceItem, interface ) = interfacePair;
452+ var item = itemRequirements.item;
453+ var requirements = itemRequirements.requirements;
454+
374455 var constructorName = name.asLookupName;
375- var constructorId = interfaceItem .getConstructorId (constructorName);
376- interface .constructors[constructorName] = constructorId;
456+ var constructorId = item .getConstructorId (constructorName);
457+ requirements .constructors[constructorName] = constructorId;
377458 }
378459
379460 /// This method is invoked by [InheritanceManager3] to notify the collector
@@ -388,14 +469,17 @@ class RequirementsManifest {
388469 return ;
389470 }
390471
391- var interfacePair = _getInterface (element);
392- if (interfacePair == null ) {
472+ var itemRequirements = _getInterfaceItem (element);
473+ if (itemRequirements == null ) {
393474 return ;
394475 }
395476
396- var (interfaceItem, interface ) = interfacePair;
477+ var item = itemRequirements.item;
478+ var requirements = itemRequirements.requirements;
479+
397480 var methodName = nameObj.name.asLookupName;
398- var methodId = interfaceItem.getInterfaceMethodId (methodName);
481+ var methodId = item.getInterfaceMethodId (methodName);
482+ requirements.methods[methodName] = methodId;
399483
400484 // Check for consistency between the actual interface and manifest.
401485 if (methodElement != null ) {
@@ -410,7 +494,7 @@ class RequirementsManifest {
410494 }
411495 }
412496
413- interface .methods[methodName] = methodId;
497+ requirements .methods[methodName] = methodId;
414498 }
415499
416500 /// This method is invoked by an import scope to notify the collector that
@@ -427,6 +511,37 @@ class RequirementsManifest {
427511 }
428512 }
429513
514+ void record_instanceElement_getGetter ({
515+ required InstanceElementImpl2 element,
516+ required String name,
517+ }) {
518+ record_instanceElement_getMethod (element: element, name: name);
519+ }
520+
521+ void record_instanceElement_getMethod ({
522+ required InstanceElementImpl2 element,
523+ required String name,
524+ }) {
525+ var itemRequirements = _getInstanceItem (element);
526+ if (itemRequirements == null ) {
527+ return ;
528+ }
529+
530+ var item = itemRequirements.item;
531+ var requirements = itemRequirements.requirements;
532+
533+ var methodName = name.asLookupName;
534+ var methodId = item.getDeclaredMemberId (methodName);
535+ requirements.requestedMethods[methodName] = methodId;
536+ }
537+
538+ void record_instanceElement_getSetter ({
539+ required InstanceElementImpl2 element,
540+ required String name,
541+ }) {
542+ record_instanceElement_getMethod (element: element, name: '$name =' );
543+ }
544+
430545 /// This method is invoked after linking of a library cycle, to exclude
431546 /// requirements to the libraries of this same library cycle. We already
432547 /// link these libraries together, so only requirements to the previous
@@ -453,6 +568,18 @@ class RequirementsManifest {
453568 writeValue: (map) => sink.writeNameToIdMap (map),
454569 );
455570
571+ sink.writeMap (
572+ instances,
573+ writeKey: (uri) => sink.writeUri (uri),
574+ writeValue: (nameToInstanceMap) {
575+ sink.writeMap (
576+ nameToInstanceMap,
577+ writeKey: (name) => name.write (sink),
578+ writeValue: (instance) => instance.write (sink),
579+ );
580+ },
581+ );
582+
456583 sink.writeMap (
457584 interfaces,
458585 writeKey: (uri) => sink.writeUri (uri),
@@ -523,7 +650,36 @@ class RequirementsManifest {
523650 }
524651 }
525652
526- (InterfaceItem , InterfaceRequirements )? _getInterface (
653+ _InstanceItemWithRequirements ? _getInstanceItem (
654+ InstanceElementImpl2 element,
655+ ) {
656+ var libraryElement = element.library2;
657+ var manifest = libraryElement.manifest;
658+
659+ // If we are linking the library, its manifest is not set yet.
660+ // But then we also don't care about this dependency.
661+ if (manifest == null ) {
662+ return null ;
663+ }
664+
665+ // SAFETY: we don't export elements without name.
666+ var instanceName = element.lookupName! .asLookupName;
667+
668+ var instancesMap = instances[libraryElement.uri] ?? = {};
669+ var instanceItem = manifest.items[instanceName];
670+
671+ // SAFETY: every instance element must be in the manifest.
672+ instanceItem as InstanceItem ;
673+
674+ var requirements =
675+ instancesMap[instanceName] ?? = InstanceItemRequirements .empty ();
676+ return _InstanceItemWithRequirements (
677+ item: instanceItem,
678+ requirements: requirements,
679+ );
680+ }
681+
682+ _InterfaceItemWithRequirements ? _getInterfaceItem (
527683 InterfaceElementImpl2 element,
528684 ) {
529685 var libraryElement = element.library2;
@@ -544,23 +700,46 @@ class RequirementsManifest {
544700 // SAFETY: every interface element must be in the manifest.
545701 interfaceItem as InterfaceItem ;
546702
547- var interfaceRequirements =
548- interfacesMap[interfaceName] ?? = InterfaceRequirements .empty ();
549- return (interfaceItem, interfaceRequirements);
703+ var requirements =
704+ interfacesMap[interfaceName] ?? = InterfaceItemRequirements .empty ();
705+ return _InterfaceItemWithRequirements (
706+ item: interfaceItem,
707+ requirements: requirements,
708+ );
550709 }
551710
552711 String _qualifiedMethodName (
553712 InterfaceElementImpl2 element,
554713 LookupName methodName,
555714 ) {
556- return '${element .library2 .uri }'
715+ return '${element .library2 .uri } '
557716 '${element .displayName }.'
558717 '${methodName .asString }' ;
559718 }
560719}
561720
562721enum _ExportRequirementCombinatorKind { hide, show }
563722
723+ class _InstanceItemWithRequirements {
724+ final InstanceItem item;
725+ final InstanceItemRequirements requirements;
726+
727+ _InstanceItemWithRequirements ({
728+ required this .item,
729+ required this .requirements,
730+ });
731+ }
732+
733+ class _InterfaceItemWithRequirements {
734+ final InterfaceItem item;
735+ final InterfaceItemRequirements requirements;
736+
737+ _InterfaceItemWithRequirements ({
738+ required this .item,
739+ required this .requirements,
740+ });
741+ }
742+
564743extension _BufferedSinkExtension on BufferedSink {
565744 void writeNameToIdMap (Map <LookupName , ManifestItemId ?> map) {
566745 writeMap (
0 commit comments