@@ -76,6 +76,7 @@ class BundleReader {
7676 return _LibraryHeader (
7777 uri: uriCache.parse (_reader.readStringReference ()),
7878 offset: _reader.readUInt30 (),
79+ classMembersLengths: _reader.readUInt30List (),
7980 macroGeneratedCode: _reader.readOptionalObject ((reader) {
8081 return _reader.readStringUtf8 ();
8182 }),
@@ -94,6 +95,7 @@ class BundleReader {
9495 referenceReader: referenceReader,
9596 reference: reference,
9697 offset: libraryHeader.offset,
98+ classMembersLengths: libraryHeader.classMembersLengths,
9799 infoDeclarationStore: _infoDeclarationStore,
98100 macroGeneratedCode: libraryHeader.macroGeneratedCode,
99101 );
@@ -103,6 +105,8 @@ class BundleReader {
103105
104106class ClassElementLinkedData extends ElementLinkedData <ClassElementImpl > {
105107 ApplyConstantOffsets ? applyConstantOffsets;
108+ void Function ()? _readMembers;
109+ void Function ()? applyInformativeDataToMembers;
106110
107111 ClassElementLinkedData ({
108112 required Reference reference,
@@ -112,17 +116,14 @@ class ClassElementLinkedData extends ElementLinkedData<ClassElementImpl> {
112116 }) : super (reference, libraryReader, unitElement, offset);
113117
114118 @override
115- void readMembers (InstanceElementImpl element) {
116- if (element is ! ClassElementImpl ) {
117- return ;
118- }
119-
120- // We might read class members before other properties.
121- element.linkedData? .read (element);
122- element.linkedData = null ;
123-
124- if (element.isMixinApplication) {
125- element.constructors;
119+ void readMembers (covariant ClassElementImpl fragment) {
120+ // Read members of all fragments, in order.
121+ // So we always read a method augmentation after its target.
122+ for (var fragment in fragment.element.fragments) {
123+ var linkedData = fragment.linkedData;
124+ if (linkedData is ClassElementLinkedData ) {
125+ linkedData._readSingleFragmentMembers (fragment);
126+ }
126127 }
127128 }
128129
@@ -154,6 +155,22 @@ class ClassElementLinkedData extends ElementLinkedData<ClassElementImpl> {
154155
155156 applyConstantOffsets? .perform ();
156157 }
158+
159+ void _readSingleFragmentMembers (ClassElementImpl element) {
160+ // We might read class members before other properties.
161+ element.linkedData? .read (element);
162+ element.linkedData = null ;
163+
164+ if (element.isMixinApplication) {
165+ element.constructors;
166+ } else {
167+ _readMembers? .call ();
168+ _readMembers = null ;
169+
170+ applyInformativeDataToMembers? .call ();
171+ applyInformativeDataToMembers = null ;
172+ }
173+ }
157174}
158175
159176class CompilationUnitElementLinkedData
@@ -615,6 +632,9 @@ class LibraryReader {
615632 final InfoDeclarationStore _deserializedDataStore;
616633 final String ? macroGeneratedCode;
617634
635+ final Uint32List _classMembersLengths;
636+ int _classMembersLengthsIndex = 0 ;
637+
618638 late final LibraryElementImpl _libraryElement;
619639 late InstanceElementImpl2 _currentInstanceElement;
620640
@@ -627,6 +647,7 @@ class LibraryReader {
627647 required _ReferenceReader referenceReader,
628648 required Reference reference,
629649 required int offset,
650+ required Uint32List classMembersLengths,
630651 required InfoDeclarationStore infoDeclarationStore,
631652 required this .macroGeneratedCode,
632653 }) : _elementFactory = elementFactory,
@@ -636,6 +657,7 @@ class LibraryReader {
636657 _referenceReader = referenceReader,
637658 _reference = reference,
638659 _offset = offset,
660+ _classMembersLengths = classMembersLengths,
639661 _deserializedDataStore = infoDeclarationStore;
640662
641663 LibraryElementImpl readElement ({required Source librarySource}) {
@@ -644,6 +666,11 @@ class LibraryReader {
644666
645667 _reader.offset = _offset;
646668
669+ // TODO(scheglov): https://github.com/dart-lang/sdk/issues/51855
670+ // This should not be needed.
671+ // But I have a suspicion that we attempt to read the library twice.
672+ _classMembersLengthsIndex = 0 ;
673+
647674 // Read enough data to create the library.
648675 var name = _reader.readStringReference ();
649676 var featureSet = _readFeatureSet ();
@@ -754,22 +781,37 @@ class LibraryReader {
754781 fragment.typeParameters = _readTypeParameters ();
755782
756783 if (! fragment.isMixinApplication) {
757- var accessors = < PropertyAccessorElementImpl > [];
758- var fields = < FieldElementImpl > [];
759- _readFields (unitElement, fragment, reference, accessors, fields);
760- _readPropertyAccessors (
761- unitElement, fragment, reference, accessors, fields, '@field' );
762- fragment.fields = fields.toFixedList ();
763- fragment.accessors = accessors.toFixedList ();
764-
765- fragment.constructors =
766- _readConstructors (unitElement, fragment, reference);
767- fragment.methods = _readMethods (unitElement, fragment, reference);
784+ var membersOffset = _reader.offset;
785+ linkedData._readMembers = () {
786+ _reader.offset = membersOffset;
787+ _readClassElementMembers (fragment, reference);
788+ };
789+ _reader.offset += _classMembersLengths[_classMembersLengthsIndex++ ];
768790 }
769791
770792 return fragment;
771793 }
772794
795+ void _readClassElementMembers (
796+ ClassElementImpl fragment,
797+ Reference reference,
798+ ) {
799+ // print('[_readClassElementMembers][reference: $reference]');
800+ var unitElement = fragment.enclosingElement3;
801+ _currentInstanceElement = fragment.element;
802+
803+ var accessors = < PropertyAccessorElementImpl > [];
804+ var fields = < FieldElementImpl > [];
805+ _readFields (unitElement, fragment, reference, accessors, fields);
806+ _readPropertyAccessors (
807+ unitElement, fragment, reference, accessors, fields, '@field' );
808+ fragment.fields = fields.toFixedList ();
809+ fragment.accessors = accessors.toFixedList ();
810+
811+ fragment.constructors = _readConstructors (unitElement, fragment, reference);
812+ fragment.methods = _readMethods (unitElement, fragment, reference);
813+ }
814+
773815 void _readClasses (
774816 CompilationUnitElementImpl unitElement,
775817 Reference unitReference,
@@ -2665,12 +2707,18 @@ class _LibraryHeader {
26652707 final Uri uri;
26662708 final int offset;
26672709
2710+ /// We don't read class members when reading libraries, by performance
2711+ /// reasons - in many cases only some classes of a library are used. But
2712+ /// we need to know how much data to skip for each class.
2713+ final Uint32List classMembersLengths;
2714+
26682715 /// The only (if any) macro generated augmentation code.
26692716 final String ? macroGeneratedCode;
26702717
26712718 _LibraryHeader ({
26722719 required this .uri,
26732720 required this .offset,
2721+ required this .classMembersLengths,
26742722 required this .macroGeneratedCode,
26752723 });
26762724}
0 commit comments