| // Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file | 
 | // for details. All rights reserved. Use of this source code is governed by a | 
 | // BSD-style license that can be found in the LICENSE file. | 
 |  | 
 | import 'dart:typed_data'; | 
 |  | 
 | import 'package:_fe_analyzer_shared/src/type_inference/type_analyzer_operations.dart'; | 
 | import 'package:analyzer/dart/analysis/features.dart'; | 
 | import 'package:analyzer/dart/ast/ast.dart'; | 
 | import 'package:analyzer/dart/element/element.dart'; | 
 | import 'package:analyzer/dart/element/element2.dart'; | 
 | import 'package:analyzer/dart/element/nullability_suffix.dart'; | 
 | import 'package:analyzer/dart/element/type.dart'; | 
 | import 'package:analyzer/source/source_range.dart'; | 
 | import 'package:analyzer/src/dart/analysis/experiments.dart'; | 
 | import 'package:analyzer/src/dart/element/element.dart'; | 
 | import 'package:analyzer/src/dart/element/field_name_non_promotability_info.dart'; | 
 | import 'package:analyzer/src/dart/element/member.dart'; | 
 | import 'package:analyzer/src/dart/element/type.dart'; | 
 | import 'package:analyzer/src/dart/element/type_algebra.dart'; | 
 | import 'package:analyzer/src/summary2/ast_binary_tag.dart'; | 
 | import 'package:analyzer/src/summary2/ast_binary_writer.dart'; | 
 | import 'package:analyzer/src/summary2/data_writer.dart'; | 
 | import 'package:analyzer/src/summary2/element_flags.dart'; | 
 | import 'package:analyzer/src/summary2/export.dart'; | 
 | import 'package:analyzer/src/summary2/macro_application_error.dart'; | 
 | import 'package:analyzer/src/summary2/macro_type_location_storage.dart'; | 
 | import 'package:analyzer/src/summary2/reference.dart'; | 
 | import 'package:analyzer/src/task/inference_error.dart'; | 
 |  | 
 | class BundleWriter { | 
 |   late final _BundleWriterReferences _references; | 
 |  | 
 |   /// The declaration sink - any data that can be read without a need to | 
 |   /// have any other elements to be available. For example declarations of | 
 |   /// classes, methods, functions, etc. But not supertypes of classes, or | 
 |   /// return types of methods - these might reference other classes that we | 
 |   /// have not read yet. Such resolution data is stored into [_resolutionSink]. | 
 |   /// | 
 |   /// Some resolution data is still written into this sink, if it does not | 
 |   /// require any other declaration read it later. For example type inference | 
 |   /// errors, or whether a parameter inherits `covariant`, or a class is | 
 |   /// simply bounded. | 
 |   late final _SummaryDataWriter _sink = _SummaryDataWriter( | 
 |     sink: ByteSink(), | 
 |     stringIndexer: _stringIndexer, | 
 |   ); | 
 |  | 
 |   /// The resolution sink - any data that references elements, so can only | 
 |   /// be read after elements are created and available via its [Reference]s. | 
 |   late final ResolutionSink _resolutionSink = ResolutionSink( | 
 |     sink: ByteSink(), | 
 |     stringIndexer: _stringIndexer, | 
 |     references: _references, | 
 |   ); | 
 |  | 
 |   /// [_writeClassElement] remembers the length of data written into [_sink] | 
 |   /// while writing members. So, when we read, we can skip members initially, | 
 |   /// and read them later on demand. | 
 |   List<int> _classMembersLengths = []; | 
 |  | 
 |   /// [_writePropertyAccessorElement] adds augmentations here, so that after | 
 |   /// reading the library we can read them, and while doing this, update | 
 |   /// `getter` and `setter` of augmented variables. | 
 |   List<PropertyAccessorElementImpl> _accessorAugmentations = []; | 
 |  | 
 |   /// [_writeFieldElement] adds augmentations here, so that after | 
 |   /// reading the library we can read them, and while doing this, update | 
 |   /// getters and setter to point at this property augmentation, and set | 
 |   /// `getter` and `setter` of the augmentation. | 
 |   List<PropertyInducingElementImpl> _propertyAugmentations = []; | 
 |  | 
 |   final StringIndexer _stringIndexer = StringIndexer(); | 
 |  | 
 |   final List<_Library> _libraries = []; | 
 |  | 
 |   BundleWriter(Reference dynamicReference) { | 
 |     _references = _BundleWriterReferences(dynamicReference); | 
 |   } | 
 |  | 
 |   BundleWriterResult finish() { | 
 |     var baseResolutionOffset = _sink.offset; | 
 |     _sink.addBytes(_resolutionSink.flushAndTake()); | 
 |  | 
 |     var librariesOffset = _sink.offset; | 
 |     _sink.writeList<_Library>(_libraries, (library) { | 
 |       _sink._writeStringReference(library.uriStr); | 
 |       _sink.writeUInt30(library.offset); | 
 |       _sink.writeUint30List(library.classMembersOffsets); | 
 |       _sink.writeOptionalObject(library.macroGenerated, (it) { | 
 |         _sink.writeStringUtf8(it.code); | 
 |       }); | 
 |     }); | 
 |  | 
 |     var referencesOffset = _sink.offset; | 
 |     _sink.writeUint30List(_references._referenceParents); | 
 |     _sink._writeStringList(_references._referenceNames); | 
 |     _references._clearIndexes(); | 
 |  | 
 |     var stringTableOffset = _stringIndexer.write(_sink); | 
 |  | 
 |     // Write as Uint32 so that we know where it is. | 
 |     _sink.writeUInt32(baseResolutionOffset); | 
 |     _sink.writeUInt32(librariesOffset); | 
 |     _sink.writeUInt32(referencesOffset); | 
 |     _sink.writeUInt32(stringTableOffset); | 
 |  | 
 |     var bytes = _sink.flushAndTake(); | 
 |     return BundleWriterResult( | 
 |       resolutionBytes: bytes, | 
 |     ); | 
 |   } | 
 |  | 
 |   void writeLibraryElement(LibraryElementImpl libraryElement) { | 
 |     var libraryOffset = _sink.offset; | 
 |     _classMembersLengths = []; | 
 |     _accessorAugmentations = []; | 
 |     _propertyAugmentations = []; | 
 |  | 
 |     // Write non-resolution data for the library. | 
 |     _sink._writeStringReference(libraryElement.name); | 
 |     _writeFeatureSet(libraryElement.featureSet); | 
 |     LibraryElementFlags.write(_sink, libraryElement); | 
 |     _writeLanguageVersion(libraryElement.languageVersion); | 
 |     _writeExportedReferences(libraryElement.exportedReferences); | 
 |     _sink.writeUint30List(libraryElement.nameUnion.mask); | 
 |  | 
 |     // Write the library units. | 
 |     // This will write also resolution data, e.g. for classes. | 
 |     _writeUnitElement(libraryElement.definingCompilationUnit); | 
 |  | 
 |     // Write resolution data for the library. | 
 |     _sink.writeUInt30(_resolutionSink.offset); | 
 |     _resolutionSink._writeAnnotationList(libraryElement.metadata); | 
 |     _resolutionSink.writeMacroDiagnostics(libraryElement.macroDiagnostics); | 
 |     _resolutionSink.writeElement(libraryElement.entryPoint); | 
 |     _writeFieldNameNonPromotabilityInfo( | 
 |         libraryElement.fieldNameNonPromotabilityInfo); | 
 |  | 
 |     _writePropertyAccessorAugmentations(); | 
 |  | 
 |     var lastUnit = libraryElement.units.lastOrNull; | 
 |     var macroGenerated = lastUnit?.macroGenerated; | 
 |  | 
 |     _libraries.add( | 
 |       _Library( | 
 |         uriStr: '${libraryElement.source.uri}', | 
 |         offset: libraryOffset, | 
 |         classMembersOffsets: _classMembersLengths, | 
 |         macroGenerated: macroGenerated, | 
 |       ), | 
 |     ); | 
 |   } | 
 |  | 
 |   void _writeClassElement(ClassElementImpl element) { | 
 |     _sink.writeUInt30(_resolutionSink.offset); | 
 |  | 
 |     _writeReference(element); | 
 |     _writeReference2(element.augmented.reference); | 
 |     _sink.writeBool(element.augmentedInternal is AugmentedClassElementImpl); | 
 |     _writeFragmentName(element.name2); | 
 |     ClassElementFlags.write(_sink, element); | 
 |  | 
 |     _resolutionSink._writeAnnotationList(element.metadata); | 
 |  | 
 |     _writeTypeParameters(element.typeParameters, () { | 
 |       _resolutionSink.writeMacroDiagnostics(element.macroDiagnostics); | 
 |       _resolutionSink.writeType(element.supertype); | 
 |       _resolutionSink._writeTypeList(element.mixins); | 
 |       _resolutionSink._writeTypeList(element.interfaces); | 
 |       _resolutionSink.writeElement(element.augmentationTargetAny); | 
 |       _resolutionSink.writeElement(element.augmentation); | 
 |       if (element.augmentationTarget == null) { | 
 |         _resolutionSink.writeIfType<AugmentedClassElementImpl>( | 
 |           element.augmented, | 
 |           (augmented) { | 
 |             _resolutionSink._writeTypeList(augmented.mixins); | 
 |             _resolutionSink._writeTypeList(augmented.interfaces); | 
 |             _resolutionSink._writeElementList(augmented.fields); | 
 |             _resolutionSink._writeElementList(augmented.constructors); | 
 |             _resolutionSink._writeElementList(augmented.accessors); | 
 |             _resolutionSink._writeElementList(augmented.methods); | 
 |           }, | 
 |         ); | 
 |       } | 
 |  | 
 |       if (!element.isMixinApplication) { | 
 |         var membersOffset = _sink.offset; | 
 |         _writeList( | 
 |           element.fields.where((e) => !e.isSynthetic).toList(), | 
 |           _writeFieldElement, | 
 |         ); | 
 |         _writeList( | 
 |           element.accessors.where((e) => !e.isSynthetic).toList(), | 
 |           _writePropertyAccessorElement, | 
 |         ); | 
 |         _writeList(element.constructors, _writeConstructorElement); | 
 |         _writeList(element.methods, _writeMethodElement); | 
 |         _classMembersLengths.add(_sink.offset - membersOffset); | 
 |       } | 
 |     }); | 
 |   } | 
 |  | 
 |   void _writeConstructorElement(ConstructorElementImpl element) { | 
 |     _sink.writeUInt30(_resolutionSink.offset); | 
 |     _writeReference(element); | 
 |     _writeFragmentName(element.name2); | 
 |     ConstructorElementFlags.write(_sink, element); | 
 |     _resolutionSink._writeAnnotationList(element.metadata); | 
 |  | 
 |     _resolutionSink.localElements.withElements(element.parameters, () { | 
 |       _resolutionSink.writeMacroDiagnostics(element.macroDiagnostics); | 
 |       _writeList(element.parameters, _writeParameterElement); | 
 |       _resolutionSink.writeElement(element.superConstructor); | 
 |       _resolutionSink.writeElement(element.redirectedConstructor); | 
 |       _resolutionSink._writeNodeList(element.constantInitializers); | 
 |       _resolutionSink.writeElement(element.augmentation); | 
 |       _resolutionSink.writeElement(element.augmentationTargetAny); | 
 |     }); | 
 |   } | 
 |  | 
 |   void _writeDirectiveUri(DirectiveUri element) { | 
 |     void writeWithUriString(DirectiveUriWithRelativeUriString element) { | 
 |       _sink._writeStringReference(element.relativeUriString); | 
 |     } | 
 |  | 
 |     void writeWithRelativeUri(DirectiveUriWithRelativeUri element) { | 
 |       writeWithUriString(element); | 
 |       _sink._writeStringReference('${element.relativeUri}'); | 
 |     } | 
 |  | 
 |     void writeWithSource(DirectiveUriWithSource element) { | 
 |       writeWithRelativeUri(element); | 
 |       _sink._writeStringReference('${element.source.uri}'); | 
 |     } | 
 |  | 
 |     if (element is DirectiveUriWithLibrary) { | 
 |       _sink.writeByte(DirectiveUriKind.withLibrary.index); | 
 |       writeWithSource(element); | 
 |     } else if (element is DirectiveUriWithUnitImpl) { | 
 |       _sink.writeByte(DirectiveUriKind.withUnit.index); | 
 |       writeWithSource(element); | 
 |       _writeUnitElement(element.unit); | 
 |     } else if (element is DirectiveUriWithSource) { | 
 |       _sink.writeByte(DirectiveUriKind.withSource.index); | 
 |       writeWithSource(element); | 
 |     } else if (element is DirectiveUriWithRelativeUri) { | 
 |       _sink.writeByte(DirectiveUriKind.withRelativeUri.index); | 
 |       writeWithRelativeUri(element); | 
 |     } else if (element is DirectiveUriWithRelativeUriString) { | 
 |       _sink.writeByte(DirectiveUriKind.withRelativeUriString.index); | 
 |       writeWithUriString(element); | 
 |     } else { | 
 |       _sink.writeByte(DirectiveUriKind.withNothing.index); | 
 |     } | 
 |   } | 
 |  | 
 |   void _writeEnumElement(EnumElementImpl element) { | 
 |     _sink.writeUInt30(_resolutionSink.offset); | 
 |     _writeReference(element); | 
 |     _writeFragmentName(element.name2); | 
 |     EnumElementFlags.write(_sink, element); | 
 |     _resolutionSink._writeAnnotationList(element.metadata); | 
 |  | 
 |     _writeTypeParameters(element.typeParameters, () { | 
 |       _resolutionSink.writeType(element.supertype); | 
 |       _resolutionSink._writeTypeList(element.mixins); | 
 |       _resolutionSink._writeTypeList(element.interfaces); | 
 |       _resolutionSink.writeElement(element.augmentationTargetAny); | 
 |       _resolutionSink.writeElement(element.augmentation); | 
 |       if (element.augmentationTarget == null) { | 
 |         _resolutionSink.writeIfType<AugmentedEnumElementImpl>( | 
 |           element.augmented, | 
 |           (augmented) { | 
 |             _resolutionSink._writeTypeList(augmented.mixins); | 
 |             _resolutionSink._writeTypeList(augmented.interfaces); | 
 |             _resolutionSink._writeElementList(augmented.fields); | 
 |             _resolutionSink._writeElementList(augmented.constructors); | 
 |             _resolutionSink._writeElementList(augmented.accessors); | 
 |             _resolutionSink._writeElementList(augmented.methods); | 
 |           }, | 
 |         ); | 
 |       } | 
 |  | 
 |       _writeList( | 
 |         element.fields.where((e) { | 
 |           return !e.isSynthetic || e.isSyntheticEnumField; | 
 |         }).toList(), | 
 |         _writeFieldElement, | 
 |       ); | 
 |       _writeList( | 
 |         element.accessors.where((e) => !e.isSynthetic).toList(), | 
 |         _writePropertyAccessorElement, | 
 |       ); | 
 |       _writeList(element.constructors, _writeConstructorElement); | 
 |       _writeList(element.methods, _writeMethodElement); | 
 |     }); | 
 |   } | 
 |  | 
 |   void _writeExportedReferences(List<ExportedReference> elements) { | 
 |     _writeList<ExportedReference>(elements, (exported) { | 
 |       var index = _references._indexOfReference(exported.reference); | 
 |       if (exported is ExportedReferenceDeclared) { | 
 |         _sink.writeByte(0); | 
 |         _sink.writeUInt30(index); | 
 |       } else if (exported is ExportedReferenceExported) { | 
 |         _sink.writeByte(1); | 
 |         _sink.writeUInt30(index); | 
 |         _sink.writeList(exported.locations, _writeExportLocation); | 
 |       } else { | 
 |         throw UnimplementedError('(${exported.runtimeType}) $exported'); | 
 |       } | 
 |     }); | 
 |   } | 
 |  | 
 |   void _writeExportElement(LibraryExportElementImpl element) { | 
 |     _resolutionSink._writeAnnotationList(element.metadata); | 
 |     _sink.writeList(element.combinators, _writeNamespaceCombinator); | 
 |     _writeDirectiveUri(element.uri); | 
 |   } | 
 |  | 
 |   void _writeExportLocation(ExportLocation location) { | 
 |     _sink.writeUInt30(location.fragmentIndex); | 
 |     _sink.writeUInt30(location.exportIndex); | 
 |   } | 
 |  | 
 |   void _writeExtensionElement(ExtensionElementImpl element) { | 
 |     _sink.writeUInt30(_resolutionSink.offset); | 
 |  | 
 |     _writeReference(element); | 
 |     _writeFragmentName(element.name2); | 
 |     ExtensionElementFlags.write(_sink, element); | 
 |  | 
 |     _resolutionSink._writeAnnotationList(element.metadata); | 
 |  | 
 |     _writeTypeParameters(element.typeParameters, () { | 
 |       _resolutionSink.writeElement(element.augmentationTargetAny); | 
 |       _resolutionSink.writeElement(element.augmentation); | 
 |       if (element.augmentationTarget == null) { | 
 |         _resolutionSink.writeType(element.augmented.extendedType); | 
 |         _resolutionSink.writeIfType<AugmentedExtensionElementImpl>( | 
 |           element.augmented, | 
 |           (augmented) { | 
 |             _resolutionSink._writeElementList(augmented.fields); | 
 |             _resolutionSink._writeElementList(augmented.accessors); | 
 |             _resolutionSink._writeElementList(augmented.methods); | 
 |           }, | 
 |         ); | 
 |       } | 
 |  | 
 |       _writeList( | 
 |         element.accessors.where((e) => !e.isSynthetic).toList(), | 
 |         _writePropertyAccessorElement, | 
 |       ); | 
 |       _writeList( | 
 |         element.fields.where((e) => !e.isSynthetic).toList(), | 
 |         _writeFieldElement, | 
 |       ); | 
 |       _writeList(element.methods, _writeMethodElement); | 
 |     }); | 
 |   } | 
 |  | 
 |   void _writeExtensionTypeElement(ExtensionTypeElementImpl element) { | 
 |     _sink.writeUInt30(_resolutionSink.offset); | 
 |     _writeReference(element); | 
 |     _writeFragmentName(element.name2); | 
 |     ExtensionTypeElementFlags.write(_sink, element); | 
 |     _resolutionSink._writeAnnotationList(element.metadata); | 
 |  | 
 |     _writeTypeParameters(element.typeParameters, () { | 
 |       _resolutionSink._writeTypeList(element.interfaces); | 
 |       _resolutionSink.writeElement(element.augmentationTargetAny); | 
 |       _resolutionSink.writeElement(element.augmentation); | 
 |       if (element.augmentationTarget == null) { | 
 |         _resolutionSink.writeIfType<AugmentedExtensionTypeElementImpl>( | 
 |           element.augmented, | 
 |           (augmented) { | 
 |             _resolutionSink._writeTypeList(augmented.interfaces); | 
 |             _resolutionSink._writeElementList(augmented.fields); | 
 |             _resolutionSink._writeElementList(augmented.accessors); | 
 |             _resolutionSink._writeElementList(augmented.constructors); | 
 |             _resolutionSink._writeElementList(augmented.methods); | 
 |           }, | 
 |         ); | 
 |         _resolutionSink.writeType(element.augmented.typeErasure); | 
 |       } | 
 |  | 
 |       _writeList( | 
 |         element.fields.where((e) => !e.isSynthetic).toList(), | 
 |         _writeFieldElement, | 
 |       ); | 
 |       _writeList( | 
 |         element.accessors.where((e) => !e.isSynthetic).toList(), | 
 |         _writePropertyAccessorElement, | 
 |       ); | 
 |       _writeList(element.constructors, _writeConstructorElement); | 
 |       _writeList(element.methods, _writeMethodElement); | 
 |     }); | 
 |   } | 
 |  | 
 |   void _writeFeatureSet(FeatureSet featureSet) { | 
 |     var experimentStatus = featureSet as ExperimentStatus; | 
 |     var encoded = experimentStatus.toStorage(); | 
 |     _sink.writeUint8List(encoded); | 
 |   } | 
 |  | 
 |   void _writeFieldElement(FieldElementImpl element) { | 
 |     _sink.writeUInt30(_resolutionSink.offset); | 
 |     _writeReference(element); | 
 |     _writeOptionalReference(element.getter?.reference); | 
 |     _writeOptionalReference(element.setter?.reference); | 
 |     _writeFragmentName(element.name2); | 
 |     _sink._writeStringReference(element.name); | 
 |     _sink.writeBool(element is ConstFieldElementImpl); | 
 |     FieldElementFlags.write(_sink, element); | 
 |     _sink._writeTopLevelInferenceError(element.typeInferenceError); | 
 |     _resolutionSink._writeAnnotationList(element.metadata); | 
 |     _resolutionSink.writeMacroDiagnostics(element.macroDiagnostics); | 
 |     _resolutionSink.writeType(element.type); | 
 |  | 
 |     _resolutionSink.writeElement(element.augmentationTargetAny); | 
 |     if (element.isAugmentation) { | 
 |       _propertyAugmentations.add(element); | 
 |     } | 
 |  | 
 |     _resolutionSink._writeOptionalNode(element.constantInitializer); | 
 |   } | 
 |  | 
 |   void _writeFieldNameNonPromotabilityInfo( | 
 |       Map<String, FieldNameNonPromotabilityInfo>? info) { | 
 |     _resolutionSink.writeOptionalObject(info, (info) { | 
 |       _resolutionSink.writeMap( | 
 |         info, | 
 |         writeKey: (key) { | 
 |           _resolutionSink._writeStringReference(key); | 
 |         }, | 
 |         writeValue: (value) { | 
 |           _resolutionSink._writeElementList(value.conflictingFields); | 
 |           _resolutionSink._writeElementList(value.conflictingGetters); | 
 |           _resolutionSink._writeElementList(value.conflictingNsmClasses); | 
 |         }, | 
 |       ); | 
 |     }); | 
 |   } | 
 |  | 
 |   void _writeFragmentName(FragmentName? fragmentName) { | 
 |     _sink.writeOptionalObject(fragmentName, (fragmentName) { | 
 |       _sink._writeStringReference(fragmentName.name); | 
 |     }); | 
 |   } | 
 |  | 
 |   void _writeFunctionElement(FunctionElementImpl element) { | 
 |     _sink.writeUInt30(_resolutionSink.offset); | 
 |     _writeReference(element); | 
 |     _writeFragmentName(element.name2); | 
 |     FunctionElementFlags.write(_sink, element); | 
 |  | 
 |     _resolutionSink._writeAnnotationList(element.metadata); | 
 |  | 
 |     _writeTypeParameters(element.typeParameters, () { | 
 |       _resolutionSink.writeMacroDiagnostics(element.macroDiagnostics); | 
 |       _resolutionSink.writeType(element.returnType); | 
 |       _writeList(element.parameters, _writeParameterElement); | 
 |     }); | 
 |  | 
 |     _resolutionSink.writeElement(element.augmentation); | 
 |     _resolutionSink.writeElement(element.augmentationTargetAny); | 
 |   } | 
 |  | 
 |   void _writeImportElement(LibraryImportElementImpl element) { | 
 |     _resolutionSink._writeAnnotationList(element.metadata); | 
 |     _sink.writeList(element.combinators, _writeNamespaceCombinator); | 
 |     _writeImportElementPrefix(element.prefix); | 
 |     _writeLibraryImportPrefixFragment(element.prefix2); | 
 |     _writeDirectiveUri(element.uri); | 
 |     LibraryImportElementFlags.write(_sink, element); | 
 |   } | 
 |  | 
 |   void _writeImportElementPrefix(ImportElementPrefixImpl? prefix) { | 
 |     if (prefix is DeferredImportElementPrefixImpl) { | 
 |       _sink.writeByte(ImportElementPrefixKind.isDeferred.index); | 
 |       _sink._writeStringReference(prefix.element.name); | 
 |       _writeReference(prefix.element); | 
 |     } else if (prefix is ImportElementPrefixImpl) { | 
 |       _sink.writeByte(ImportElementPrefixKind.isNotDeferred.index); | 
 |       _sink._writeStringReference(prefix.element.name); | 
 |       _writeReference(prefix.element); | 
 |     } else { | 
 |       _sink.writeByte(ImportElementPrefixKind.isNull.index); | 
 |     } | 
 |   } | 
 |  | 
 |   void _writeLanguageVersion(LibraryLanguageVersion version) { | 
 |     _sink.writeUInt30(version.package.major); | 
 |     _sink.writeUInt30(version.package.minor); | 
 |  | 
 |     var override = version.override; | 
 |     if (override != null) { | 
 |       _sink.writeBool(true); | 
 |       _sink.writeUInt30(override.major); | 
 |       _sink.writeUInt30(override.minor); | 
 |     } else { | 
 |       _sink.writeBool(false); | 
 |     } | 
 |   } | 
 |  | 
 |   void _writeLibraryImportPrefixFragment(PrefixFragmentImpl? fragment) { | 
 |     _sink.writeOptionalObject(fragment, (fragment) { | 
 |       _writeFragmentName(fragment.name2); | 
 |       _writeReference2(fragment.element.reference); | 
 |       _sink.writeBool(fragment.isDeferred); | 
 |     }); | 
 |   } | 
 |  | 
 |   void _writeList<T>(List<T> elements, void Function(T) writeElement) { | 
 |     _sink.writeUInt30(elements.length); | 
 |     for (var element in elements) { | 
 |       writeElement(element); | 
 |     } | 
 |   } | 
 |  | 
 |   void _writeMethodElement(MethodElementImpl element) { | 
 |     _sink.writeUInt30(_resolutionSink.offset); | 
 |     _writeReference(element); | 
 |     _writeFragmentName(element.name2); | 
 |     _sink._writeStringReference(element.name); | 
 |     MethodElementFlags.write(_sink, element); | 
 |  | 
 |     _resolutionSink._writeAnnotationList(element.metadata); | 
 |  | 
 |     _writeTypeParameters(element.typeParameters, () { | 
 |       _resolutionSink.writeMacroDiagnostics(element.macroDiagnostics); | 
 |       _writeList(element.parameters, _writeParameterElement); | 
 |       _sink._writeTopLevelInferenceError(element.typeInferenceError); | 
 |       _resolutionSink.writeType(element.returnType); | 
 |       _resolutionSink.writeElement(element.augmentation); | 
 |       _resolutionSink.writeElement(element.augmentationTargetAny); | 
 |     }); | 
 |   } | 
 |  | 
 |   void _writeMixinElement(MixinElementImpl element) { | 
 |     _sink.writeUInt30(_resolutionSink.offset); | 
 |  | 
 |     _writeReference(element); | 
 |     _writeFragmentName(element.name2); | 
 |     MixinElementFlags.write(_sink, element); | 
 |     _resolutionSink._writeAnnotationList(element.metadata); | 
 |  | 
 |     _writeTypeParameters(element.typeParameters, () { | 
 |       _resolutionSink.writeMacroDiagnostics(element.macroDiagnostics); | 
 |       _resolutionSink._writeTypeList(element.superclassConstraints); | 
 |       _resolutionSink._writeTypeList(element.interfaces); | 
 |       _resolutionSink.writeElement(element.augmentationTargetAny); | 
 |       _resolutionSink.writeElement(element.augmentation); | 
 |       if (element.augmentationTarget == null) { | 
 |         _resolutionSink.writeIfType<AugmentedMixinElementImpl>( | 
 |           element.augmented, | 
 |           (augmented) { | 
 |             _resolutionSink._writeTypeList(augmented.superclassConstraints); | 
 |             _resolutionSink._writeTypeList(augmented.interfaces); | 
 |             _resolutionSink._writeElementList(augmented.fields); | 
 |             _resolutionSink._writeElementList(augmented.accessors); | 
 |             _resolutionSink._writeElementList(augmented.methods); | 
 |           }, | 
 |         ); | 
 |       } | 
 |  | 
 |       _writeList( | 
 |         element.fields.where((e) => !e.isSynthetic).toList(), | 
 |         _writeFieldElement, | 
 |       ); | 
 |       _writeList( | 
 |         element.accessors.where((e) => !e.isSynthetic).toList(), | 
 |         _writePropertyAccessorElement, | 
 |       ); | 
 |       _writeList(element.constructors, _writeConstructorElement); | 
 |       _writeList(element.methods, _writeMethodElement); | 
 |       _sink._writeStringList(element.superInvokedNames); | 
 |     }); | 
 |   } | 
 |  | 
 |   void _writeNamespaceCombinator(NamespaceCombinator combinator) { | 
 |     switch (combinator) { | 
 |       case HideElementCombinator(): | 
 |         _sink.writeByte(Tag.HideCombinator); | 
 |         _sink.writeList<String>(combinator.hiddenNames, (name) { | 
 |           _sink._writeStringReference(name); | 
 |         }); | 
 |       case ShowElementCombinator(): | 
 |         _sink.writeByte(Tag.ShowCombinator); | 
 |         _sink.writeList<String>(combinator.shownNames, (name) { | 
 |           _sink._writeStringReference(name); | 
 |         }); | 
 |     } | 
 |   } | 
 |  | 
 |   void _writeOptionalReference(Reference? reference) { | 
 |     _sink.writeOptionalObject(reference, (reference) { | 
 |       var index = _references._indexOfReference(reference); | 
 |       _sink.writeUInt30(index); | 
 |     }); | 
 |   } | 
 |  | 
 |   // TODO(scheglov): Deduplicate parameter writing implementation. | 
 |   void _writeParameterElement(ParameterElement element) { | 
 |     element as ParameterElementImpl; | 
 |     _writeFragmentName(element.name2); | 
 |     _sink._writeStringReference(element.name); | 
 |     _sink.writeBool(element is ConstVariableElement); | 
 |     _sink.writeBool(element.isInitializingFormal); | 
 |     _sink.writeBool(element.isSuperFormal); | 
 |     _writeOptionalReference(element.reference); | 
 |     _sink._writeFormalParameterKind(element); | 
 |     ParameterElementFlags.write(_sink, element); | 
 |  | 
 |     _resolutionSink._writeAnnotationList(element.metadata); | 
 |  | 
 |     _writeTypeParameters(element.typeParameters, () { | 
 |       _writeList(element.parameters, _writeParameterElement); | 
 |       _resolutionSink.writeType(element.type); | 
 |  | 
 |       if (element is ConstVariableElement) { | 
 |         var constElement = element as ConstVariableElement; | 
 |         _resolutionSink._writeOptionalNode(constElement.constantInitializer); | 
 |       } | 
 |       if (element is FieldFormalParameterElementImpl) { | 
 |         _resolutionSink.writeElement(element.field); | 
 |       } | 
 |     }); | 
 |   } | 
 |  | 
 |   void _writePartElement(PartElement element) { | 
 |     _writeDirectiveUri(element.uri); | 
 |   } | 
 |  | 
 |   /// We write metadata here, to keep it inside [unitElement] resolution | 
 |   /// data, because [_writePartElement] recursively writes included unit | 
 |   /// elements. But the bundle reader wants all metadata for `parts` | 
 |   /// sequentially. | 
 |   void _writePartElementsMetadata(CompilationUnitElementImpl unitElement) { | 
 |     for (var element in unitElement.parts) { | 
 |       _resolutionSink._writeAnnotationList(element.metadata); | 
 |     } | 
 |   } | 
 |  | 
 |   /// Write information to update `getter` and `setter` properties of | 
 |   /// augmented variables to use the corresponding augmentations. | 
 |   void _writePropertyAccessorAugmentations() { | 
 |     var offset = _resolutionSink.offset; | 
 |     _resolutionSink._writeElementList(_accessorAugmentations); | 
 |     _resolutionSink._writeElementList(_propertyAugmentations); | 
 |     _sink.writeUInt30(offset); | 
 |   } | 
 |  | 
 |   void _writePropertyAccessorElement(PropertyAccessorElementImpl element) { | 
 |     _sink.writeUInt30(_resolutionSink.offset); | 
 |     _writeReference(element); | 
 |     _writeFragmentName(element.name2); | 
 |     PropertyAccessorElementFlags.write(_sink, element); | 
 |  | 
 |     _resolutionSink._writeAnnotationList(element.metadata); | 
 |     _resolutionSink.writeType(element.returnType); | 
 |     _writeList(element.parameters, _writeParameterElement); | 
 |  | 
 |     // Write the reference for the variable, the reader will use it. | 
 |     if (!element.isAugmentation) { | 
 |       _writeReference(element.variable2!); | 
 |     } | 
 |  | 
 |     _resolutionSink.writeElement(element.augmentationTargetAny); | 
 |     if (element.isAugmentation) { | 
 |       _accessorAugmentations.add(element); | 
 |     } | 
 |   } | 
 |  | 
 |   /// Write the reference of a non-local element. | 
 |   void _writeReference(ElementImpl element) { | 
 |     _writeReference2(element.reference); | 
 |   } | 
 |  | 
 |   void _writeReference2(Reference? reference) { | 
 |     var index = _references._indexOfReference(reference); | 
 |     _sink.writeUInt30(index); | 
 |   } | 
 |  | 
 |   void _writeTopLevelVariableElement(TopLevelVariableElementImpl element) { | 
 |     _sink.writeUInt30(_resolutionSink.offset); | 
 |     _writeReference(element); | 
 |     _writeOptionalReference(element.getter?.reference); | 
 |     _writeOptionalReference(element.setter?.reference); | 
 |     _writeFragmentName(element.name2); | 
 |     _sink._writeStringReference(element.name); | 
 |     _sink.writeBool(element.isConst); | 
 |     TopLevelVariableElementFlags.write(_sink, element); | 
 |     _sink._writeTopLevelInferenceError(element.typeInferenceError); | 
 |     _resolutionSink._writeAnnotationList(element.metadata); | 
 |     _resolutionSink.writeMacroDiagnostics(element.macroDiagnostics); | 
 |     _resolutionSink.writeType(element.type); | 
 |  | 
 |     _resolutionSink.writeElement(element.augmentationTargetAny); | 
 |     if (element.isAugmentation) { | 
 |       _propertyAugmentations.add(element); | 
 |     } | 
 |  | 
 |     _resolutionSink._writeOptionalNode(element.constantInitializer); | 
 |   } | 
 |  | 
 |   void _writeTypeAliasElement(TypeAliasElementImpl element) { | 
 |     _sink.writeUInt30(_resolutionSink.offset); | 
 |  | 
 |     _writeReference(element); | 
 |     _writeFragmentName(element.name2); | 
 |     _sink._writeStringReference(element.name); | 
 |     _sink.writeBool(element.isFunctionTypeAliasBased); | 
 |     TypeAliasElementFlags.write(_sink, element); | 
 |  | 
 |     _resolutionSink.writeElement(element.augmentationTargetAny); | 
 |     _resolutionSink.writeElement(element.augmentation); | 
 |  | 
 |     _resolutionSink._writeAnnotationList(element.metadata); | 
 |  | 
 |     _writeTypeParameters(element.typeParameters, () { | 
 |       _resolutionSink.writeMacroDiagnostics(element.macroDiagnostics); | 
 |       _resolutionSink._writeAliasedElement(element.aliasedElement); | 
 |       _resolutionSink.writeType(element.aliasedType); | 
 |     }); | 
 |   } | 
 |  | 
 |   void _writeTypeParameterElement(TypeParameterElement element) { | 
 |     element as TypeParameterElementImpl; | 
 |     _sink._writeStringReference(element.name); | 
 |     _writeFragmentName(element.name2); | 
 |     _sink.writeByte(_encodeVariance(element).index); | 
 |     _resolutionSink._writeAnnotationList(element.metadata); | 
 |     _resolutionSink.writeType(element.bound); | 
 |     _resolutionSink.writeType(element.defaultType); | 
 |   } | 
 |  | 
 |   /// Add [typeParameters] to the indexing scope, so make them available | 
 |   /// when writing types that might reference them, and write the elements. | 
 |   void _writeTypeParameters( | 
 |     List<TypeParameterElement> typeParameters, | 
 |     void Function() f, | 
 |   ) { | 
 |     _resolutionSink.localElements.withElements(typeParameters, () { | 
 |       _sink.writeList(typeParameters, _writeTypeParameterElement); | 
 |       f(); | 
 |     }); | 
 |   } | 
 |  | 
 |   void _writeUnitElement(CompilationUnitElementImpl unitElement) { | 
 |     _sink.writeUInt30(_resolutionSink.offset); | 
 |  | 
 |     _sink._writeOptionalStringReference(unitElement.uri); | 
 |     _sink.writeBool(unitElement.isSynthetic); | 
 |  | 
 |     _writeList(unitElement.libraryImports, _writeImportElement); | 
 |     _writeList(unitElement.libraryExports, _writeExportElement); | 
 |  | 
 |     // Write the metadata for parts here, even though we write parts below. | 
 |     // The reason is that resolution data must be in a single chunk. | 
 |     _writePartElementsMetadata(unitElement); | 
 |  | 
 |     _writeList(unitElement.classes, _writeClassElement); | 
 |     _writeList(unitElement.enums, _writeEnumElement); | 
 |     _writeList(unitElement.extensions, _writeExtensionElement); | 
 |     _writeList(unitElement.extensionTypes, _writeExtensionTypeElement); | 
 |     _writeList(unitElement.functions, _writeFunctionElement); | 
 |     _writeList(unitElement.mixins, _writeMixinElement); | 
 |     _writeList(unitElement.typeAliases, _writeTypeAliasElement); | 
 |  | 
 |     _writeList( | 
 |       unitElement.topLevelVariables | 
 |           .where((element) => !element.isSynthetic) | 
 |           .toList(), | 
 |       _writeTopLevelVariableElement, | 
 |     ); | 
 |     _writeList( | 
 |       unitElement.accessors.where((e) => !e.isSynthetic).toList(), | 
 |       _writePropertyAccessorElement, | 
 |     ); | 
 |  | 
 |     _sink.writeOptionalObject(unitElement.macroGenerated, (macroGenerated) { | 
 |       _sink.writeStringUtf8(macroGenerated.code); | 
 |       _sink.writeUint8List(macroGenerated.informativeBytes); | 
 |     }); | 
 |  | 
 |     // Write parts after this library fragment, so that when we read, we | 
 |     // process fragments of declarations in the same order as we build them. | 
 |     _writeList(unitElement.parts, _writePartElement); | 
 |   } | 
 |  | 
 |   static TypeParameterVarianceTag _encodeVariance( | 
 |       TypeParameterElementImpl element) { | 
 |     if (element.isLegacyCovariant) { | 
 |       return TypeParameterVarianceTag.legacy; | 
 |     } | 
 |  | 
 |     var variance = element.variance; | 
 |     if (variance == Variance.unrelated) { | 
 |       return TypeParameterVarianceTag.unrelated; | 
 |     } else if (variance == Variance.covariant) { | 
 |       return TypeParameterVarianceTag.covariant; | 
 |     } else if (variance == Variance.contravariant) { | 
 |       return TypeParameterVarianceTag.contravariant; | 
 |     } else if (variance == Variance.invariant) { | 
 |       return TypeParameterVarianceTag.invariant; | 
 |     } else { | 
 |       throw UnimplementedError('$variance'); | 
 |     } | 
 |   } | 
 | } | 
 |  | 
 | class BundleWriterResult { | 
 |   final Uint8List resolutionBytes; | 
 |  | 
 |   BundleWriterResult({ | 
 |     required this.resolutionBytes, | 
 |   }); | 
 | } | 
 |  | 
 | class ResolutionSink extends _SummaryDataWriter { | 
 |   final _BundleWriterReferences _references; | 
 |   final _LocalElementIndexer localElements = _LocalElementIndexer(); | 
 |  | 
 |   ResolutionSink({ | 
 |     required super.sink, | 
 |     required super.stringIndexer, | 
 |     required _BundleWriterReferences references, | 
 |   }) : _references = references; | 
 |  | 
 |   // TODO(scheglov): Triage places where we write elements. | 
 |   // Some of then cannot be members, e.g. type names. | 
 |   void writeElement(Element? element) { | 
 |     if (element is Member) { | 
 |       var declaration = element.declaration; | 
 |  | 
 |       var typeArguments = _enclosingClassTypeArguments( | 
 |         declaration, | 
 |         element.substitution.map, | 
 |       ); | 
 |  | 
 |       writeByte(Tag.MemberWithTypeArguments); | 
 |       _writeElement(declaration); | 
 |       _writeTypeList(typeArguments); | 
 |     } else { | 
 |       writeByte(Tag.RawElement); | 
 |       _writeElement(element); | 
 |     } | 
 |   } | 
 |  | 
 |   void writeMacroDiagnostics(List<AnalyzerMacroDiagnostic> elements) { | 
 |     writeList(elements, _writeMacroDiagnostic); | 
 |   } | 
 |  | 
 |   void writeOptionalTypeList(List<DartType>? types) { | 
 |     if (types != null) { | 
 |       writeBool(true); | 
 |       _writeTypeList(types); | 
 |     } else { | 
 |       writeBool(false); | 
 |     } | 
 |   } | 
 |  | 
 |   void writeType(DartType? type) { | 
 |     if (type == null) { | 
 |       writeByte(Tag.NullType); | 
 |     } else if (type is DynamicType) { | 
 |       writeByte(Tag.DynamicType); | 
 |       _writeTypeAliasElementArguments(type); | 
 |     } else if (type is FunctionType) { | 
 |       _writeFunctionType(type); | 
 |       _writeTypeAliasElementArguments(type); | 
 |     } else if (type is InterfaceType) { | 
 |       var typeArguments = type.typeArguments; | 
 |       var nullabilitySuffix = type.nullabilitySuffix; | 
 |       if (typeArguments.isEmpty) { | 
 |         if (nullabilitySuffix == NullabilitySuffix.none) { | 
 |           writeByte(Tag.InterfaceType_noTypeArguments_none); | 
 |         } else if (nullabilitySuffix == NullabilitySuffix.question) { | 
 |           writeByte(Tag.InterfaceType_noTypeArguments_question); | 
 |         } | 
 |         // TODO(scheglov): Write raw | 
 |         writeElement(type.element); | 
 |       } else { | 
 |         writeByte(Tag.InterfaceType); | 
 |         // TODO(scheglov): Write raw | 
 |         writeElement(type.element); | 
 |         writeUInt30(typeArguments.length); | 
 |         for (var i = 0; i < typeArguments.length; ++i) { | 
 |           writeType(typeArguments[i]); | 
 |         } | 
 |         _writeNullabilitySuffix(nullabilitySuffix); | 
 |       } | 
 |       _writeTypeAliasElementArguments(type); | 
 |     } else if (type is InvalidType) { | 
 |       writeByte(Tag.InvalidType); | 
 |       _writeTypeAliasElementArguments(type); | 
 |     } else if (type is NeverType) { | 
 |       writeByte(Tag.NeverType); | 
 |       _writeNullabilitySuffix(type.nullabilitySuffix); | 
 |       _writeTypeAliasElementArguments(type); | 
 |     } else if (type is RecordTypeImpl) { | 
 |       _writeRecordType(type); | 
 |       _writeTypeAliasElementArguments(type); | 
 |     } else if (type is TypeParameterType) { | 
 |       writeByte(Tag.TypeParameterType); | 
 |       writeElement(type.element); | 
 |       _writeNullabilitySuffix(type.nullabilitySuffix); | 
 |       _writeTypeAliasElementArguments(type); | 
 |     } else if (type is VoidType) { | 
 |       writeByte(Tag.VoidType); | 
 |       _writeTypeAliasElementArguments(type); | 
 |     } else { | 
 |       throw UnimplementedError('${type.runtimeType}'); | 
 |     } | 
 |   } | 
 |  | 
 |   int _indexOfElement(Element? element) { | 
 |     if (element == null) return 0; | 
 |     if (element is MultiplyDefinedElement) return 0; | 
 |     assert(element is! Member); | 
 |  | 
 |     // Positional parameters cannot be referenced outside of their scope, | 
 |     // so don't have a reference, so are stored as local elements. | 
 |     if (element is ParameterElementImpl && element.reference == null) { | 
 |       return localElements[element] << 1 | 0x1; | 
 |     } | 
 |  | 
 |     // Type parameters cannot be referenced outside of their scope, | 
 |     // so don't have a reference, so are stored as local elements. | 
 |     if (element is TypeParameterElement) { | 
 |       return localElements[element] << 1 | 0x1; | 
 |     } | 
 |  | 
 |     if (identical(element, DynamicElementImpl.instance)) { | 
 |       return _references._dynamicReferenceIndex << 1; | 
 |     } | 
 |  | 
 |     var reference = (element as ElementImpl).reference; | 
 |     return _references._indexOfReference(reference) << 1; | 
 |   } | 
 |  | 
 |   void _writeAliasedElement(Element? element) { | 
 |     if (element == null) { | 
 |       writeByte(AliasedElementTag.nothing); | 
 |     } else if (element is GenericFunctionTypeElement) { | 
 |       writeByte(AliasedElementTag.genericFunctionElement); | 
 |       _writeTypeParameters(element.typeParameters, () { | 
 |         _writeFormalParameters(element.parameters, withAnnotations: true); | 
 |         writeType(element.returnType); | 
 |       }, withAnnotations: true); | 
 |     } else { | 
 |       throw UnimplementedError('${element.runtimeType}'); | 
 |     } | 
 |   } | 
 |  | 
 |   void _writeAnnotationList(List<ElementAnnotation> annotations) { | 
 |     writeUInt30(annotations.length); | 
 |     for (var annotation in annotations) { | 
 |       annotation as ElementAnnotationImpl; | 
 |       _writeNode(annotation.annotationAst); | 
 |     } | 
 |   } | 
 |  | 
 |   void _writeElement(Element? element) { | 
 |     assert(element is! Member, 'Use writeMemberOrElement()'); | 
 |     var elementIndex = _indexOfElement(element); | 
 |     writeUInt30(elementIndex); | 
 |   } | 
 |  | 
 |   void _writeElementList(List<Element> elements) { | 
 |     writeUInt30(elements.length); | 
 |     for (var element in elements) { | 
 |       writeElement(element); | 
 |     } | 
 |   } | 
 |  | 
 |   void _writeFormalParameters( | 
 |     List<ParameterElement> parameters, { | 
 |     required bool withAnnotations, | 
 |   }) { | 
 |     writeUInt30(parameters.length); | 
 |     for (var parameter in parameters) { | 
 |       _writeFormalParameterKind(parameter); | 
 |       writeBool(parameter is ConstVariableElement); | 
 |       writeBool(parameter.hasImplicitType); | 
 |       writeBool(parameter.isInitializingFormal); | 
 |       _writeTypeParameters(parameter.typeParameters, () { | 
 |         writeType(parameter.type); | 
 |         _writeStringReference(parameter.name); | 
 |         _writeFormalParameters( | 
 |           parameter.parameters, | 
 |           withAnnotations: withAnnotations, | 
 |         ); | 
 |       }, withAnnotations: withAnnotations); | 
 |       if (withAnnotations) { | 
 |         _writeAnnotationList(parameter.metadata); | 
 |       } | 
 |     } | 
 |   } | 
 |  | 
 |   void _writeFunctionType(FunctionType type) { | 
 |     type = _toSyntheticFunctionType(type); | 
 |  | 
 |     writeByte(Tag.FunctionType); | 
 |  | 
 |     _writeTypeParameters(type.typeFormals, () { | 
 |       writeType(type.returnType); | 
 |       _writeFormalParameters(type.parameters, withAnnotations: false); | 
 |     }, withAnnotations: false); | 
 |     _writeNullabilitySuffix(type.nullabilitySuffix); | 
 |   } | 
 |  | 
 |   void _writeMacroDiagnostic(AnalyzerMacroDiagnostic diagnostic) { | 
 |     switch (diagnostic) { | 
 |       case ArgumentMacroDiagnostic(): | 
 |         writeEnum(MacroDiagnosticKind.argument); | 
 |         writeUInt30(diagnostic.annotationIndex); | 
 |         writeUInt30(diagnostic.argumentIndex); | 
 |         writeStringUtf8(diagnostic.message); | 
 |       case DeclarationsIntrospectionCycleDiagnostic(): | 
 |         writeEnum(MacroDiagnosticKind.introspectionCycle); | 
 |         writeUInt30(diagnostic.annotationIndex); | 
 |         writeElement(diagnostic.introspectedElement); | 
 |         writeList(diagnostic.components, (component) { | 
 |           writeElement(component.element); | 
 |           writeUInt30(component.annotationIndex); | 
 |           writeElement(component.introspectedElement); | 
 |         }); | 
 |       case ExceptionMacroDiagnostic(): | 
 |         writeEnum(MacroDiagnosticKind.exception); | 
 |         writeUInt30(diagnostic.annotationIndex); | 
 |         writeStringUtf8(diagnostic.message); | 
 |         writeStringUtf8(diagnostic.stackTrace); | 
 |       case InvalidMacroTargetDiagnostic(): | 
 |         writeEnum(MacroDiagnosticKind.invalidTarget); | 
 |         writeUInt30(diagnostic.annotationIndex); | 
 |         writeStringUtf8Iterable(diagnostic.supportedKinds); | 
 |       case MacroDiagnostic(): | 
 |         writeEnum(MacroDiagnosticKind.macro); | 
 |         writeEnum(diagnostic.severity); | 
 |         _writeMacroDiagnosticMessage(diagnostic.message); | 
 |         writeList( | 
 |           diagnostic.contextMessages, | 
 |           _writeMacroDiagnosticMessage, | 
 |         ); | 
 |         writeOptionalStringUtf8(diagnostic.correctionMessage); | 
 |       case NotAllowedDeclarationDiagnostic(): | 
 |         writeEnum(MacroDiagnosticKind.notAllowedDeclaration); | 
 |         writeUInt30(diagnostic.annotationIndex); | 
 |         writeEnum(diagnostic.phase); | 
 |         writeStringUtf8(diagnostic.code); | 
 |         writeList(diagnostic.nodeRanges, _writeSourceRange); | 
 |     } | 
 |   } | 
 |  | 
 |   void _writeMacroDiagnosticMessage(MacroDiagnosticMessage object) { | 
 |     writeStringUtf8(object.message); | 
 |  | 
 |     var target = object.target; | 
 |     switch (target) { | 
 |       case ApplicationMacroDiagnosticTarget(): | 
 |         writeEnum(MacroDiagnosticTargetKind.application); | 
 |         writeUInt30(target.annotationIndex); | 
 |       case ElementMacroDiagnosticTarget(): | 
 |         writeEnum(MacroDiagnosticTargetKind.element); | 
 |         writeElement(target.element); | 
 |       case ElementAnnotationMacroDiagnosticTarget(): | 
 |         writeEnum(MacroDiagnosticTargetKind.elementAnnotation); | 
 |         writeElement(target.element); | 
 |         writeUInt30(target.annotationIndex); | 
 |       case TypeAnnotationMacroDiagnosticTarget(): | 
 |         writeEnum(MacroDiagnosticTargetKind.type); | 
 |         TypeAnnotationLocationWriter( | 
 |           sink: this, | 
 |           writeElement: writeElement, | 
 |         ).write(target.location); | 
 |     } | 
 |   } | 
 |  | 
 |   void _writeNode(AstNode node) { | 
 |     var astWriter = AstBinaryWriter( | 
 |       sink: this, | 
 |       stringIndexer: _stringIndexer, | 
 |     ); | 
 |     node.accept(astWriter); | 
 |   } | 
 |  | 
 |   void _writeNodeList(List<AstNode> nodes) { | 
 |     writeUInt30(nodes.length); | 
 |     for (var node in nodes) { | 
 |       _writeNode(node); | 
 |     } | 
 |   } | 
 |  | 
 |   void _writeNullabilitySuffix(NullabilitySuffix suffix) { | 
 |     writeByte(suffix.index); | 
 |   } | 
 |  | 
 |   void _writeOptionalNode(Expression? node) { | 
 |     if (node != null) { | 
 |       writeBool(true); | 
 |       _writeNode(node); | 
 |     } else { | 
 |       writeBool(false); | 
 |     } | 
 |   } | 
 |  | 
 |   void _writeRecordType(RecordTypeImpl type) { | 
 |     writeByte(Tag.RecordType); | 
 |  | 
 |     writeList<RecordTypePositionalField>(type.positionalFields, (field) { | 
 |       writeType(field.type); | 
 |     }); | 
 |  | 
 |     writeList<RecordTypeNamedField>(type.namedFields, (field) { | 
 |       _writeStringReference(field.name); | 
 |       writeType(field.type); | 
 |     }); | 
 |  | 
 |     _writeNullabilitySuffix(type.nullabilitySuffix); | 
 |   } | 
 |  | 
 |   void _writeSourceRange(SourceRange range) { | 
 |     writeUInt30(range.offset); | 
 |     writeUInt30(range.length); | 
 |   } | 
 |  | 
 |   void _writeTypeAliasElementArguments(DartType type) { | 
 |     var alias = type.alias; | 
 |     _writeElement(alias?.element); | 
 |     if (alias != null) { | 
 |       _writeTypeList(alias.typeArguments); | 
 |     } | 
 |   } | 
 |  | 
 |   void _writeTypeList(List<DartType> types) { | 
 |     writeUInt30(types.length); | 
 |     for (var type in types) { | 
 |       writeType(type); | 
 |     } | 
 |   } | 
 |  | 
 |   void _writeTypeParameters( | 
 |     List<TypeParameterElement> typeParameters, | 
 |     void Function() f, { | 
 |     required bool withAnnotations, | 
 |   }) { | 
 |     localElements.withElements(typeParameters, () { | 
 |       writeUInt30(typeParameters.length); | 
 |       for (var typeParameter in typeParameters) { | 
 |         _writeStringReference(typeParameter.name); | 
 |       } | 
 |       for (var typeParameter in typeParameters) { | 
 |         writeType(typeParameter.bound); | 
 |         if (withAnnotations) { | 
 |           _writeAnnotationList(typeParameter.metadata); | 
 |         } | 
 |       } | 
 |       f(); | 
 |     }); | 
 |   } | 
 |  | 
 |   static List<DartType> _enclosingClassTypeArguments( | 
 |     Element declaration, | 
 |     Map<TypeParameterElement, DartType> substitution, | 
 |   ) { | 
 |     // TODO(scheglov): Just keep it null in class Member? | 
 |     if (substitution.isEmpty) { | 
 |       return const []; | 
 |     } | 
 |  | 
 |     var enclosing = declaration.enclosingElement3; | 
 |     if (enclosing is InstanceElement) { | 
 |       var typeParameters = enclosing.typeParameters; | 
 |       if (typeParameters.isEmpty) { | 
 |         return const <DartType>[]; | 
 |       } | 
 |  | 
 |       return typeParameters | 
 |           .map((typeParameter) => substitution[typeParameter]) | 
 |           .nonNulls | 
 |           .toList(growable: false); | 
 |     } | 
 |  | 
 |     return const <DartType>[]; | 
 |   } | 
 |  | 
 |   static FunctionType _toSyntheticFunctionType(FunctionType type) { | 
 |     var typeParameters = type.typeFormals; | 
 |     if (typeParameters.isEmpty) return type; | 
 |  | 
 |     var fresh = getFreshTypeParameters(typeParameters); | 
 |     return fresh.applyToFunctionType(type); | 
 |   } | 
 | } | 
 |  | 
 | class StringIndexer { | 
 |   final Map<String, int> _index = {}; | 
 |  | 
 |   int operator [](String string) { | 
 |     var result = _index[string]; | 
 |  | 
 |     if (result == null) { | 
 |       result = _index.length; | 
 |       _index[string] = result; | 
 |     } | 
 |  | 
 |     return result; | 
 |   } | 
 |  | 
 |   int write(BufferedSink sink) { | 
 |     var bytesOffset = sink.offset; | 
 |  | 
 |     var length = _index.length; | 
 |     var lengths = Uint32List(length); | 
 |     var lengthsIndex = 0; | 
 |     for (var key in _index.keys) { | 
 |       var stringStart = sink.offset; | 
 |       _writeWtf8(sink, key); | 
 |       lengths[lengthsIndex++] = sink.offset - stringStart; | 
 |     } | 
 |  | 
 |     var resultOffset = sink.offset; | 
 |  | 
 |     var lengthOfBytes = sink.offset - bytesOffset; | 
 |     sink.writeUInt30(lengthOfBytes); | 
 |     sink.writeUint30List(lengths); | 
 |  | 
 |     return resultOffset; | 
 |   } | 
 |  | 
 |   /// Write [source] string into [sink]. | 
 |   static void _writeWtf8(BufferedSink sink, String source) { | 
 |     var end = source.length; | 
 |     if (end == 0) { | 
 |       return; | 
 |     } | 
 |  | 
 |     int i = 0; | 
 |     do { | 
 |       var codeUnit = source.codeUnitAt(i++); | 
 |       if (codeUnit < 128) { | 
 |         // ASCII. | 
 |         sink.addByte(codeUnit); | 
 |       } else if (codeUnit < 0x800) { | 
 |         // Two-byte sequence (11-bit unicode value). | 
 |         sink.addByte(0xC0 | (codeUnit >> 6)); | 
 |         sink.addByte(0x80 | (codeUnit & 0x3f)); | 
 |       } else if ((codeUnit & 0xFC00) == 0xD800 && | 
 |           i < end && | 
 |           (source.codeUnitAt(i) & 0xFC00) == 0xDC00) { | 
 |         // Surrogate pair -> four-byte sequence (non-BMP unicode value). | 
 |         int codeUnit2 = source.codeUnitAt(i++); | 
 |         int unicode = | 
 |             0x10000 + ((codeUnit & 0x3FF) << 10) + (codeUnit2 & 0x3FF); | 
 |         sink.addByte(0xF0 | (unicode >> 18)); | 
 |         sink.addByte(0x80 | ((unicode >> 12) & 0x3F)); | 
 |         sink.addByte(0x80 | ((unicode >> 6) & 0x3F)); | 
 |         sink.addByte(0x80 | (unicode & 0x3F)); | 
 |       } else { | 
 |         // Three-byte sequence (16-bit unicode value), including lone | 
 |         // surrogates. | 
 |         sink.addByte(0xE0 | (codeUnit >> 12)); | 
 |         sink.addByte(0x80 | ((codeUnit >> 6) & 0x3f)); | 
 |         sink.addByte(0x80 | (codeUnit & 0x3f)); | 
 |       } | 
 |     } while (i < end); | 
 |   } | 
 | } | 
 |  | 
 | class UnitToWriteAst { | 
 |   final CompilationUnit node; | 
 |  | 
 |   UnitToWriteAst({ | 
 |     required this.node, | 
 |   }); | 
 | } | 
 |  | 
 | class _BundleWriterReferences { | 
 |   /// The `dynamic` class is declared in `dart:core`, but is not a class. | 
 |   /// Also, it is static, so we cannot set `reference` for it. | 
 |   /// So, we have to push it in a separate way. | 
 |   final Reference _dynamicReference; | 
 |  | 
 |   /// References used in all libraries being linked. | 
 |   /// Element references in nodes are indexes in this list. | 
 |   final List<Reference?> _references = [null]; | 
 |  | 
 |   final List<int> _referenceParents = [0]; | 
 |   final List<String> _referenceNames = ['']; | 
 |  | 
 |   _BundleWriterReferences(this._dynamicReference); | 
 |  | 
 |   /// The index for the `dynamic` element. | 
 |   int get _dynamicReferenceIndex { | 
 |     return _indexOfReference(_dynamicReference); | 
 |   } | 
 |  | 
 |   /// We need indexes for references during linking, but once we are done, | 
 |   /// we must clear indexes to make references ready for linking a next bundle. | 
 |   void _clearIndexes() { | 
 |     for (var reference in _references) { | 
 |       if (reference != null) { | 
 |         reference.index = null; | 
 |       } | 
 |     } | 
 |   } | 
 |  | 
 |   int _indexOfReference(Reference? reference) { | 
 |     if (reference == null) return 0; | 
 |     if (reference.parent == null) return 0; | 
 |  | 
 |     var index = reference.index; | 
 |     if (index != null) return index; | 
 |  | 
 |     var parentIndex = _indexOfReference(reference.parent); | 
 |     _referenceParents.add(parentIndex); | 
 |     _referenceNames.add(reference.name); | 
 |  | 
 |     index = _references.length; | 
 |     reference.index = index; | 
 |     _references.add(reference); | 
 |     return index; | 
 |   } | 
 | } | 
 |  | 
 | class _Library { | 
 |   final String uriStr; | 
 |   final int offset; | 
 |   final List<int> classMembersOffsets; | 
 |  | 
 |   /// The only (if any) macro generated fragment. | 
 |   final MacroGeneratedLibraryFragment? macroGenerated; | 
 |  | 
 |   _Library({ | 
 |     required this.uriStr, | 
 |     required this.offset, | 
 |     required this.classMembersOffsets, | 
 |     required this.macroGenerated, | 
 |   }); | 
 | } | 
 |  | 
 | class _LocalElementIndexer { | 
 |   final Map<Element, int> _index = Map.identity(); | 
 |   int _stackHeight = 0; | 
 |  | 
 |   int operator [](Element element) { | 
 |     return _index[element] ?? | 
 |         (throw ArgumentError('Unexpectedly not indexed: $element')); | 
 |   } | 
 |  | 
 |   void withElements(List<Element> elements, void Function() f) { | 
 |     for (var element in elements) { | 
 |       _index[element] = _stackHeight++; | 
 |     } | 
 |  | 
 |     f(); | 
 |  | 
 |     _stackHeight -= elements.length; | 
 |     for (var element in elements) { | 
 |       _index.remove(element); | 
 |     } | 
 |   } | 
 | } | 
 |  | 
 | class _SummaryDataWriter extends BufferedSink { | 
 |   final StringIndexer _stringIndexer; | 
 |  | 
 |   _SummaryDataWriter({ | 
 |     required ByteSink sink, | 
 |     required StringIndexer stringIndexer, | 
 |   })  : _stringIndexer = stringIndexer, | 
 |         super(sink); | 
 |  | 
 |   void _writeFormalParameterKind(ParameterElement p) { | 
 |     if (p.isRequiredPositional) { | 
 |       writeByte(Tag.ParameterKindRequiredPositional); | 
 |     } else if (p.isOptionalPositional) { | 
 |       writeByte(Tag.ParameterKindOptionalPositional); | 
 |     } else if (p.isRequiredNamed) { | 
 |       writeByte(Tag.ParameterKindRequiredNamed); | 
 |     } else if (p.isOptionalNamed) { | 
 |       writeByte(Tag.ParameterKindOptionalNamed); | 
 |     } else { | 
 |       throw StateError('Unexpected parameter kind: $p'); | 
 |     } | 
 |   } | 
 |  | 
 |   void _writeOptionalStringReference(String? value) { | 
 |     if (value != null) { | 
 |       writeBool(true); | 
 |       _writeStringReference(value); | 
 |     } else { | 
 |       writeBool(false); | 
 |     } | 
 |   } | 
 |  | 
 |   void _writeStringList(List<String> values) { | 
 |     writeUInt30(values.length); | 
 |     for (var value in values) { | 
 |       _writeStringReference(value); | 
 |     } | 
 |   } | 
 |  | 
 |   void _writeStringReference(String string) { | 
 |     var index = _stringIndexer[string]; | 
 |     writeUInt30(index); | 
 |   } | 
 |  | 
 |   void _writeTopLevelInferenceError(TopLevelInferenceError? error) { | 
 |     if (error != null) { | 
 |       writeByte(error.kind.index); | 
 |       _writeStringList(error.arguments); | 
 |     } else { | 
 |       writeByte(TopLevelInferenceErrorKind.none.index); | 
 |     } | 
 |   } | 
 | } |