Version 2.14.0-54.0.dev
Merge commit '3c83032c60ee6b7b705effe397bf5820d076aa5b' into 'dev'
diff --git a/pkg/kernel/bin/size_breakdown.dart b/pkg/kernel/bin/size_breakdown.dart
index 79fbefa..dc4cd9b 100755
--- a/pkg/kernel/bin/size_breakdown.dart
+++ b/pkg/kernel/bin/size_breakdown.dart
@@ -52,9 +52,9 @@
return result;
}
- void readStringTable(List<String> table) {
+ void readStringTable() {
stringTableSize -= byteOffset;
- super.readStringTable(table);
+ super.readStringTable();
stringTableSize += byteOffset;
}
diff --git a/pkg/kernel/lib/ast.dart b/pkg/kernel/lib/ast.dart
index 9f0dc34..24f0361 100644
--- a/pkg/kernel/lib/ast.dart
+++ b/pkg/kernel/lib/ast.dart
@@ -329,9 +329,9 @@
List<String>? problemsAsJson;
@override
- final List<Expression> annotations;
+ List<Expression> annotations;
- final List<LibraryDependency> dependencies;
+ List<LibraryDependency> dependencies;
/// References to nodes exported by `export` declarations that:
/// - aren't ambiguous, or
@@ -339,13 +339,13 @@
final List<Reference> additionalExports = <Reference>[];
@informative
- final List<LibraryPart> parts;
+ List<LibraryPart> parts;
- final List<Typedef> typedefs;
- final List<Class> classes;
- final List<Extension> extensions;
- final List<Procedure> procedures;
- final List<Field> fields;
+ List<Typedef> _typedefs;
+ List<Class> _classes;
+ List<Extension> _extensions;
+ List<Procedure> _procedures;
+ List<Field> _fields;
Library(this.importUri,
{this.name,
@@ -364,19 +364,64 @@
this.annotations = annotations ?? <Expression>[],
this.dependencies = dependencies ?? <LibraryDependency>[],
this.parts = parts ?? <LibraryPart>[],
- this.typedefs = typedefs ?? <Typedef>[],
- this.classes = classes ?? <Class>[],
- this.extensions = extensions ?? <Extension>[],
- this.procedures = procedures ?? <Procedure>[],
- this.fields = fields ?? <Field>[],
+ this._typedefs = typedefs ?? <Typedef>[],
+ this._classes = classes ?? <Class>[],
+ this._extensions = extensions ?? <Extension>[],
+ this._procedures = procedures ?? <Procedure>[],
+ this._fields = fields ?? <Field>[],
super(reference) {
setParents(this.dependencies, this);
setParents(this.parts, this);
- setParents(this.typedefs, this);
- setParents(this.classes, this);
- setParents(this.extensions, this);
- setParents(this.procedures, this);
- setParents(this.fields, this);
+ setParents(this._typedefs, this);
+ setParents(this._classes, this);
+ setParents(this._extensions, this);
+ setParents(this._procedures, this);
+ setParents(this._fields, this);
+ }
+
+ List<Typedef> get typedefs => _typedefs;
+
+ /// Internal. Should *ONLY* be used from within kernel.
+ ///
+ /// Used for adding typedefs when reading the dill file.
+ void set typedefsInternal(List<Typedef> typedefs) {
+ _typedefs = typedefs;
+ }
+
+ List<Class> get classes => _classes;
+
+ /// Internal. Should *ONLY* be used from within kernel.
+ ///
+ /// Used for adding classes when reading the dill file.
+ void set classesInternal(List<Class> classes) {
+ _classes = classes;
+ }
+
+ List<Extension> get extensions => _extensions;
+
+ /// Internal. Should *ONLY* be used from within kernel.
+ ///
+ /// Used for adding extensions when reading the dill file.
+ void set extensionsInternal(List<Extension> extensions) {
+ _extensions = extensions;
+ }
+
+ List<Procedure> get procedures => _procedures;
+
+ /// Internal. Should *ONLY* be used from within kernel.
+ ///
+ /// Used for adding procedures when reading the dill file.
+ void set proceduresInternal(List<Procedure> procedures) {
+ _procedures = procedures;
+ }
+
+ List<Field> get fields => _fields;
+
+ /// Internal. Should *ONLY* be used from within kernel.
+ ///
+ /// Used for adding fields when reading the dill file.
+ void set fieldsInternal(List<Field> fields) {
+ _fields = fields;
}
Nullability get nullable {
@@ -1050,7 +1095,7 @@
Supertype? mixedInType;
/// The types from the `implements` clause.
- final List<Supertype> implementedTypes;
+ List<Supertype> implementedTypes;
/// Internal. Should *ONLY* be used from within kernel.
///
@@ -1070,10 +1115,7 @@
}
}
- /// Internal. Should *ONLY* be used from within kernel.
- ///
- /// Used for adding fields when reading the dill file.
- final List<Field> fieldsInternal;
+ List<Field> _fieldsInternal;
DirtifyingList<Field>? _fieldsView;
/// Fields declared in the class.
@@ -1082,28 +1124,39 @@
List<Field> get fields {
ensureLoaded();
// If already dirty the caller just might as well add stuff directly too.
- if (dirty) return fieldsInternal;
- return _fieldsView ??= new DirtifyingList(this, fieldsInternal);
+ if (dirty) return _fieldsInternal;
+ return _fieldsView ??= new DirtifyingList(this, _fieldsInternal);
}
/// Internal. Should *ONLY* be used from within kernel.
///
- /// Used for adding constructors when reading the dill file.
- final List<Constructor> constructorsInternal;
+ /// Used for adding fields when reading the dill file.
+ void set fieldsInternal(List<Field> fields) {
+ _fieldsInternal = fields;
+ _fieldsView = null;
+ }
+
+ List<Constructor> _constructorsInternal;
DirtifyingList<Constructor>? _constructorsView;
/// Constructors declared in the class.
List<Constructor> get constructors {
ensureLoaded();
// If already dirty the caller just might as well add stuff directly too.
- if (dirty) return constructorsInternal;
- return _constructorsView ??= new DirtifyingList(this, constructorsInternal);
+ if (dirty) return _constructorsInternal;
+ return _constructorsView ??=
+ new DirtifyingList(this, _constructorsInternal);
}
/// Internal. Should *ONLY* be used from within kernel.
///
- /// Used for adding procedures when reading the dill file.
- final List<Procedure> proceduresInternal;
+ /// Used for adding constructors when reading the dill file.
+ void set constructorsInternal(List<Constructor> constructors) {
+ _constructorsInternal = constructors;
+ _constructorsView = null;
+ }
+
+ List<Procedure> _proceduresInternal;
DirtifyingList<Procedure>? _proceduresView;
/// Procedures declared in the class.
@@ -1112,16 +1165,19 @@
List<Procedure> get procedures {
ensureLoaded();
// If already dirty the caller just might as well add stuff directly too.
- if (dirty) return proceduresInternal;
- return _proceduresView ??= new DirtifyingList(this, proceduresInternal);
+ if (dirty) return _proceduresInternal;
+ return _proceduresView ??= new DirtifyingList(this, _proceduresInternal);
}
/// Internal. Should *ONLY* be used from within kernel.
///
- /// Used for adding redirecting factory constructor when reading the dill
- /// file.
- final List<RedirectingFactoryConstructor>
- redirectingFactoryConstructorsInternal;
+ /// Used for adding procedures when reading the dill file.
+ void set proceduresInternal(List<Procedure> procedures) {
+ _proceduresInternal = procedures;
+ _proceduresView = null;
+ }
+
+ List<RedirectingFactoryConstructor> _redirectingFactoryConstructorsInternal;
DirtifyingList<RedirectingFactoryConstructor>?
_redirectingFactoryConstructorsView;
@@ -1131,9 +1187,19 @@
List<RedirectingFactoryConstructor> get redirectingFactoryConstructors {
ensureLoaded();
// If already dirty the caller just might as well add stuff directly too.
- if (dirty) return redirectingFactoryConstructorsInternal;
+ if (dirty) return _redirectingFactoryConstructorsInternal;
return _redirectingFactoryConstructorsView ??=
- new DirtifyingList(this, redirectingFactoryConstructorsInternal);
+ new DirtifyingList(this, _redirectingFactoryConstructorsInternal);
+ }
+
+ /// Internal. Should *ONLY* be used from within kernel.
+ ///
+ /// Used for adding redirecting factory constructor when reading the dill
+ /// file.
+ void set redirectingFactoryConstructorsInternal(
+ List<RedirectingFactoryConstructor> redirectingFactoryConstructors) {
+ _redirectingFactoryConstructorsInternal = redirectingFactoryConstructors;
+ _redirectingFactoryConstructorsView = null;
}
Class(
@@ -1156,17 +1222,17 @@
assert(fileUri != null),
this.typeParameters = typeParameters ?? <TypeParameter>[],
this.implementedTypes = implementedTypes ?? <Supertype>[],
- this.fieldsInternal = fields ?? <Field>[],
- this.constructorsInternal = constructors ?? <Constructor>[],
- this.proceduresInternal = procedures ?? <Procedure>[],
- this.redirectingFactoryConstructorsInternal =
+ this._fieldsInternal = fields ?? <Field>[],
+ this._constructorsInternal = constructors ?? <Constructor>[],
+ this._proceduresInternal = procedures ?? <Procedure>[],
+ this._redirectingFactoryConstructorsInternal =
redirectingFactoryConstructors ?? <RedirectingFactoryConstructor>[],
super(reference) {
setParents(this.typeParameters, this);
- setParents(this.constructorsInternal, this);
- setParents(this.proceduresInternal, this);
- setParents(this.fieldsInternal, this);
- setParents(this.redirectingFactoryConstructorsInternal, this);
+ setParents(this._constructorsInternal, this);
+ setParents(this._proceduresInternal, this);
+ setParents(this._fieldsInternal, this);
+ setParents(this._redirectingFactoryConstructorsInternal, this);
this.isAbstract = isAbstract;
this.isAnonymousMixin = isAnonymousMixin;
}
@@ -1292,21 +1358,21 @@
void addConstructor(Constructor constructor) {
dirty = true;
constructor.parent = this;
- constructorsInternal.add(constructor);
+ _constructorsInternal.add(constructor);
}
/// Adds a procedure to this class.
void addProcedure(Procedure procedure) {
dirty = true;
procedure.parent = this;
- proceduresInternal.add(procedure);
+ _proceduresInternal.add(procedure);
}
/// Adds a field to this class.
void addField(Field field) {
dirty = true;
field.parent = this;
- fieldsInternal.add(field);
+ _fieldsInternal.add(field);
}
/// Adds a field to this class.
@@ -1314,7 +1380,7 @@
RedirectingFactoryConstructor redirectingFactoryConstructor) {
dirty = true;
redirectingFactoryConstructor.parent = this;
- redirectingFactoryConstructorsInternal.add(redirectingFactoryConstructor);
+ _redirectingFactoryConstructorsInternal.add(redirectingFactoryConstructor);
}
@override
@@ -1451,7 +1517,7 @@
///
/// The members are converted into top-level members and only accessible
/// by reference through [ExtensionMemberDescriptor].
- final List<ExtensionMemberDescriptor> members;
+ List<ExtensionMemberDescriptor> members;
@override
List<Expression> annotations = const <Expression>[];
@@ -13566,6 +13632,77 @@
final List<TypeParameter> emptyListOfTypeParameter =
List.filled(0, dummyTypeParameter, growable: false);
+/// Almost const <Constant>[], but not const in an attempt to avoid
+/// polymorphism. See https://dart-review.googlesource.com/c/sdk/+/185828.
+final List<Constant> emptyListOfConstant =
+ List.filled(0, dummyConstant, growable: false);
+
+/// Almost const <String>[], but not const in an attempt to avoid
+/// polymorphism. See https://dart-review.googlesource.com/c/sdk/+/185828.
+final List<String> emptyListOfString = List.filled(0, '', growable: false);
+
+/// Almost const <Typedef>[], but not const in an attempt to avoid
+/// polymorphism. See https://dart-review.googlesource.com/c/sdk/+/185828.
+final List<Typedef> emptyListOfTypedef =
+ List.filled(0, dummyTypedef, growable: false);
+
+/// Almost const <Extension>[], but not const in an attempt to avoid
+/// polymorphism. See https://dart-review.googlesource.com/c/sdk/+/185828.
+final List<Extension> emptyListOfExtension =
+ List.filled(0, dummyExtension, growable: false);
+
+/// Almost const <Field>[], but not const in an attempt to avoid
+/// polymorphism. See https://dart-review.googlesource.com/c/sdk/+/185828.
+final List<Field> emptyListOfField =
+ List.filled(0, dummyField, growable: false);
+
+/// Almost const <LibraryPart>[], but not const in an attempt to avoid
+/// polymorphism. See https://dart-review.googlesource.com/c/sdk/+/185828.
+final List<LibraryPart> emptyListOfLibraryPart =
+ List.filled(0, dummyLibraryPart, growable: false);
+
+/// Almost const <LibraryDependency>[], but not const in an attempt to avoid
+/// polymorphism. See https://dart-review.googlesource.com/c/sdk/+/185828.
+final List<LibraryDependency> emptyListOfLibraryDependency =
+ List.filled(0, dummyLibraryDependency, growable: false);
+
+/// Almost const <Procedure>[], but not const in an attempt to avoid
+/// polymorphism. See https://dart-review.googlesource.com/c/sdk/+/185828.
+final List<Procedure> emptyListOfProcedure =
+ List.filled(0, dummyProcedure, growable: false);
+
+/// Almost const <MapLiteralEntry>[], but not const in an attempt to avoid
+/// polymorphism. See https://dart-review.googlesource.com/c/sdk/+/185828.
+final List<MapLiteralEntry> emptyListOfMapLiteralEntry =
+ List.filled(0, dummyMapLiteralEntry, growable: false);
+
+/// Almost const <Class>[], but not const in an attempt to avoid
+/// polymorphism. See https://dart-review.googlesource.com/c/sdk/+/185828.
+final List<Class> emptyListOfClass =
+ List.filled(0, dummyClass, growable: false);
+
+/// Almost const <ExtensionMemberDescriptor>[], but not const in an attempt to
+/// avoid polymorphism. See https://dart-review.googlesource.com/c/sdk/+/185828.
+final List<ExtensionMemberDescriptor> emptyListOfExtensionMemberDescriptor =
+ List.filled(0, dummyExtensionMemberDescriptor, growable: false);
+
+/// Almost const <Constructor>[], but not const in an attempt to avoid
+/// polymorphism. See https://dart-review.googlesource.com/c/sdk/+/185828.
+final List<Constructor> emptyListOfConstructor =
+ List.filled(0, dummyConstructor, growable: false);
+
+/// Almost const <RedirectingFactoryConstructor>[], but not const in an attempt
+/// to avoid polymorphism. See
+/// https://dart-review.googlesource.com/c/sdk/+/185828.
+final List<RedirectingFactoryConstructor>
+ emptyListOfRedirectingFactoryConstructor =
+ List.filled(0, dummyRedirectingFactoryConstructor, growable: false);
+
+/// Almost const <Initializer>[], but not const in an attempt to avoid
+/// polymorphism. See https://dart-review.googlesource.com/c/sdk/+/185828.
+final List<Initializer> emptyListOfInitializer =
+ List.filled(0, dummyInitializer, growable: false);
+
/// Non-nullable [DartType] dummy value.
///
/// This is used as the removal sentinel in [RemovingTransformer] and can be
@@ -13594,6 +13731,9 @@
/// Non-nullable [Name] dummy value.
final Name dummyName = new _PublicName('');
+/// Non-nullable [Reference] dummy value.
+final Reference dummyReference = new Reference();
+
/// Non-nullable [Library] dummy value.
///
/// This is used as the removal sentinel in [RemovingTransformer] and can be
@@ -13645,6 +13785,17 @@
/// constructor.
final Extension dummyExtension = new Extension(name: '', fileUri: dummyUri);
+/// Non-nullable [ExtensionMemberDescriptor] dummy value.
+///
+/// This is used as the removal sentinel in [RemovingTransformer] and can be
+/// used for instance as a dummy initial value for the `List.filled`
+/// constructor.
+final ExtensionMemberDescriptor dummyExtensionMemberDescriptor =
+ new ExtensionMemberDescriptor(
+ name: dummyName,
+ kind: ExtensionMemberKind.Getter,
+ member: dummyReference);
+
/// Non-nullable [Member] dummy value.
///
/// This can be used for instance as a dummy initial value for the
@@ -13772,6 +13923,13 @@
/// constructor.
final Catch dummyCatch = new Catch(null, dummyStatement);
+/// Non-nullable [Constant] dummy value.
+///
+/// This is used as the removal sentinel in [RemovingTransformer] and can be
+/// used for instance as a dummy initial value for the `List.filled`
+/// constructor.
+final Constant dummyConstant = new NullConstant();
+
/// Sentinel value used to signal that a node cannot be removed through the
/// [RemovingTransformer].
const Null cannotRemoveSentinel = null;
diff --git a/pkg/kernel/lib/binary/ast_from_binary.dart b/pkg/kernel/lib/binary/ast_from_binary.dart
index 2f49538..6c8a87d 100644
--- a/pkg/kernel/lib/binary/ast_from_binary.dart
+++ b/pkg/kernel/lib/binary/ast_from_binary.dart
@@ -120,8 +120,8 @@
final String? filename;
final List<int> _bytes;
int _byteOffset = 0;
- final List<String> _stringTable = <String>[];
- final List<Uri?> _sourceUriTable = <Uri>[];
+ List<String> _stringTable = const [];
+ List<Uri> _sourceUriTable = const [];
Map<int, Constant> _constantTable = <int, Constant>{};
late List<CanonicalName> _linkTable;
int _transformerFlags = 0;
@@ -313,18 +313,18 @@
return node;
}
- void readStringTable(List<String> table) {
+ void readStringTable() {
// Read the table of end offsets.
int length = readUInt30();
List<int> endOffsets =
new List<int>.generate(length, (_) => readUInt30(), growable: false);
// Read the WTF-8 encoded strings.
- table.length = length;
int startOffset = 0;
- for (int i = 0; i < length; ++i) {
- table[i] = readStringEntry(endOffsets[i] - startOffset);
- startOffset = endOffsets[i];
- }
+ _stringTable = new List<String>.generate(length, (int index) {
+ String result = readStringEntry(endOffsets[index] - startOffset);
+ startOffset = endOffsets[index];
+ return result;
+ }, growable: false);
}
void readConstantTable() {
@@ -465,12 +465,17 @@
List<Constant> _readConstantReferenceList() {
final int length = readUInt30();
+ if (!useGrowableLists && length == 0) {
+ // When lists don't have to be growable anyway, we might as well use an
+ // almost constant one for the empty list.
+ return emptyListOfConstant;
+ }
return new List<Constant>.generate(length, (_) => readConstantReference(),
growable: useGrowableLists);
}
Uri readUriReference() {
- return _sourceUriTable[readUInt30()]!;
+ return _sourceUriTable[readUInt30()];
}
String readStringReference() {
@@ -479,6 +484,11 @@
List<String> readStringReferenceList() {
int length = readUInt30();
+ if (!useGrowableLists && length == 0) {
+ // When lists don't have to be growable anyway, we might as well use an
+ // almost constant one for the empty list.
+ return emptyListOfString;
+ }
return new List<String>.generate(length, (_) => readStringReference(),
growable: useGrowableLists);
}
@@ -501,45 +511,16 @@
List<Expression> readAnnotationList([TreeNode? parent]) {
int length = readUInt30();
- if (length == 0) return const <Expression>[];
+ if (!useGrowableLists && length == 0) {
+ // When lists don't have to be growable anyway, we might as well use an
+ // almost constant one for the empty list.
+ return emptyListOfExpression;
+ }
return new List<Expression>.generate(
length, (_) => readExpression()..parent = parent,
growable: useGrowableLists);
}
- void _fillTreeNodeList(
- List<TreeNode> list, TreeNode buildObject(int index), TreeNode parent) {
- int length = readUInt30();
- list.length = length;
- for (int i = 0; i < length; ++i) {
- TreeNode object = buildObject(i);
- list[i] = object..parent = parent;
- }
- }
-
- void _fillNonTreeNodeList(List<Node> list, Node buildObject()) {
- int length = readUInt30();
- list.length = length;
- for (int i = 0; i < length; ++i) {
- Node object = buildObject();
- list[i] = object;
- }
- }
-
- /// Reads a list of named nodes, reusing any existing objects already in the
- /// linking tree. The nodes are merged into [list], and if reading the library
- /// implementation, the order is corrected.
- ///
- /// [readObject] should read the object definition and its canonical name.
- /// If an existing object is bound to the canonical name, the existing object
- /// must be reused and returned.
- void _mergeNamedNodeList(
- List<NamedNode> list, NamedNode readObject(int index), TreeNode parent) {
- // When reading the library implementation, overwrite the whole list
- // with the new one.
- _fillTreeNodeList(list, readObject, parent);
- }
-
void readLinkTable(CanonicalName linkRoot) {
int length = readUInt30();
_linkTable = new List<CanonicalName>.filled(
@@ -806,7 +787,7 @@
mergeCompilationModeOrThrow(compilationMode, index.compiledMode);
_byteOffset = index.binaryOffsetForStringTable;
- readStringTable(_stringTable);
+ readStringTable();
_byteOffset = index.binaryOffsetForCanonicalNames;
readLinkTable(component.root);
@@ -873,7 +854,7 @@
int length = readUint32();
// Read data.
- _sourceUriTable.length = length;
+ _sourceUriTable = new List<Uri>.filled(length, dummyUri, growable: false);
Map<Uri, Source> uriToSource = <Uri, Source>{};
for (int i = 0; i < length; ++i) {
String uriString = readString();
@@ -1073,32 +1054,22 @@
// There is a field for the procedure count.
_byteOffset = endOffset - (1) * 4;
int procedureCount = readUint32();
- List<int> procedureOffsets = new List<int>.filled(
- procedureCount + 1,
- // Use `-1` as a dummy default value.
- -1,
- growable: false);
// There is a field for the procedure count, that number + 1 (for the end)
// offsets, and then the class count (i.e. procedure count + 3 fields).
_byteOffset = endOffset - (procedureCount + 3) * 4;
int classCount = readUint32();
- for (int i = 0; i < procedureCount + 1; i++) {
- procedureOffsets[i] = _componentStartOffset + readUint32();
- }
- List<int> classOffsets = new List<int>.filled(
- classCount + 1,
- // Use `-1` as a dummy default value.
- -1,
+ List<int> procedureOffsets = new List<int>.generate(
+ procedureCount + 1, (int index) => _componentStartOffset + readUint32(),
growable: false);
// There is a field for the procedure count, that number + 1 (for the end)
// offsets, then the class count and that number + 1 (for the end) offsets.
// (i.e. procedure count + class count + 4 fields).
_byteOffset = endOffset - (procedureCount + classCount + 4) * 4;
- for (int i = 0; i < classCount + 1; i++) {
- classOffsets[i] = _componentStartOffset + readUint32();
- }
+ List<int> classOffsets = new List<int>.generate(
+ classCount + 1, (int index) => _componentStartOffset + readUint32(),
+ growable: false);
_byteOffset = savedByteOffset;
int flags = readByte();
@@ -1145,44 +1116,104 @@
return true;
}());
- _fillTreeNodeList(
- library.annotations, (index) => readExpression(), library);
+ library.annotations = readAnnotationList(library);
_readLibraryDependencies(library);
_readAdditionalExports(library);
_readLibraryParts(library);
- _mergeNamedNodeList(library.typedefs, (index) => readTypedef(), library);
-
- _mergeNamedNodeList(library.classes, (index) {
- _byteOffset = classOffsets[index];
- return readClass(classOffsets[index + 1]);
- }, library);
- _byteOffset = classOffsets.last;
-
- _mergeNamedNodeList(library.extensions, (index) {
- return readExtension();
- }, library);
-
- _mergeNamedNodeList(library.fields, (index) => readField(), library);
- _mergeNamedNodeList(library.procedures, (index) {
- _byteOffset = procedureOffsets[index];
- return readProcedure(procedureOffsets[index + 1]);
- }, library);
- _byteOffset = procedureOffsets.last;
+ _readTypedefList(library);
+ _readClassList(library, classOffsets);
+ _readExtensionList(library);
+ library.fieldsInternal = _readFieldList(library);
+ library.proceduresInternal = _readProcedureList(library, procedureOffsets);
assert(((_) => true)(debugPath.removeLast()));
_currentLibrary = null;
return library;
}
- void _readLibraryDependencies(Library library) {
+ void _readTypedefList(Library library) {
int length = readUInt30();
- library.dependencies.length = length;
- for (int i = 0; i < length; ++i) {
- library.dependencies[i] = readLibraryDependency(library);
+ if (!useGrowableLists && length == 0) {
+ // When lists don't have to be growable anyway, we might as well use an
+ // almost constant one for the empty list.
+ library.typedefsInternal = emptyListOfTypedef;
+ } else {
+ library.typedefsInternal = new List<Typedef>.generate(
+ length, (int index) => readTypedef()..parent = library,
+ growable: useGrowableLists);
}
}
- LibraryDependency readLibraryDependency(Library library) {
+ void _readClassList(Library library, List<int> classOffsets) {
+ int length = readUInt30();
+ if (!useGrowableLists && length == 0) {
+ // When lists don't have to be growable anyway, we might as well use an
+ // almost constant one for the empty list.
+ library.classesInternal = emptyListOfClass;
+ } else {
+ library.classesInternal = new List<Class>.generate(length, (int index) {
+ _byteOffset = classOffsets[index];
+ return readClass(classOffsets[index + 1])..parent = library;
+ }, growable: useGrowableLists);
+ _byteOffset = classOffsets.last;
+ }
+ }
+
+ void _readExtensionList(Library library) {
+ int length = readUInt30();
+ if (!useGrowableLists && length == 0) {
+ // When lists don't have to be growable anyway, we might as well use an
+ // almost constant one for the empty list.
+ library.extensionsInternal = emptyListOfExtension;
+ } else {
+ library.extensionsInternal = new List<Extension>.generate(
+ length, (int index) => readExtension()..parent = library,
+ growable: useGrowableLists);
+ }
+ }
+
+ List<Field> _readFieldList(TreeNode parent) {
+ int length = readUInt30();
+ if (!useGrowableLists && length == 0) {
+ // When lists don't have to be growable anyway, we might as well use an
+ // almost constant one for the empty list.
+ return emptyListOfField;
+ }
+ return new List<Field>.generate(
+ length, (int index) => readField()..parent = parent,
+ growable: useGrowableLists);
+ }
+
+ List<Procedure> _readProcedureList(
+ TreeNode parent, List<int> procedureOffsets) {
+ int length = readUInt30();
+ if (!useGrowableLists && length == 0) {
+ // When lists don't have to be growable anyway, we might as well use an
+ // almost constant one for the empty list.
+ return emptyListOfProcedure;
+ }
+ List<Procedure> list = new List<Procedure>.generate(length, (int index) {
+ _byteOffset = procedureOffsets[index];
+ return readProcedure(procedureOffsets[index + 1])..parent = parent;
+ }, growable: useGrowableLists);
+ _byteOffset = procedureOffsets.last;
+ return list;
+ }
+
+ void _readLibraryDependencies(Library library) {
+ int length = readUInt30();
+ if (!useGrowableLists && length == 0) {
+ // When lists don't have to be growable anyway, we might as well use an
+ // almost constant one for the empty list.
+ library.dependencies = emptyListOfLibraryDependency;
+ } else {
+ library.dependencies = new List<LibraryDependency>.generate(
+ length, (int index) => readLibraryDependency()..parent = library,
+ growable: useGrowableLists);
+ }
+ }
+
+ LibraryDependency readLibraryDependency() {
int fileOffset = readOffset();
int flags = readByte();
List<Expression> annotations = readExpressionList();
@@ -1191,8 +1222,7 @@
List<Combinator> names = readCombinatorList();
return new LibraryDependency.byReference(
flags, annotations, targetLibrary, prefixName, names)
- ..fileOffset = fileOffset
- ..parent = library;
+ ..fileOffset = fileOffset;
}
void _readAdditionalExports(Library library) {
@@ -1226,16 +1256,21 @@
void _readLibraryParts(Library library) {
int length = readUInt30();
- library.parts.length = length;
- for (int i = 0; i < length; ++i) {
- library.parts[i] = readLibraryPart(library);
+ if (!useGrowableLists && length == 0) {
+ // When lists don't have to be growable anyway, we might as well use an
+ // almost constant one for the empty list.
+ library.parts = emptyListOfLibraryPart;
+ } else {
+ library.parts = new List<LibraryPart>.generate(
+ length, (int index) => readLibraryPart()..parent = library,
+ growable: useGrowableLists);
}
}
- LibraryPart readLibraryPart(Library library) {
+ LibraryPart readLibraryPart() {
List<Expression> annotations = readExpressionList();
String partUri = readStringReference();
- return new LibraryPart(annotations, partUri)..parent = library;
+ return new LibraryPart(annotations, partUri);
}
Typedef readTypedef() {
@@ -1319,7 +1354,7 @@
readAndPushTypeParameterList(node.typeParameters, node);
Supertype? supertype = readSupertypeOption();
Supertype? mixedInType = readSupertypeOption();
- _fillNonTreeNodeList(node.implementedTypes, readSupertype);
+ node.implementedTypes = readSupertypeList();
if (_disableLazyClassReading) {
readClassPartialContent(node, procedureOffsets);
} else {
@@ -1377,36 +1412,70 @@
node.fileUri = fileUri;
node.onType = onType;
- int length = readUInt30();
- node.members.length = length;
- for (int i = 0; i < length; i++) {
- Name name = readName();
- int kind = readByte();
- int flags = readByte();
- CanonicalName canonicalName = readNonNullCanonicalNameReference();
- node.members[i] = new ExtensionMemberDescriptor(
- name: name,
- kind: ExtensionMemberKind.values[kind],
- member: canonicalName.reference)
- ..flags = flags;
- }
+ node.members = _readExtensionMemberDescriptorList();
+
return node;
}
+ List<ExtensionMemberDescriptor> _readExtensionMemberDescriptorList() {
+ int length = readUInt30();
+ if (!useGrowableLists && length == 0) {
+ // When lists don't have to be growable anyway, we might as well use a
+ // constant one for the empty list.
+ return emptyListOfExtensionMemberDescriptor;
+ }
+ return new List<ExtensionMemberDescriptor>.generate(
+ length, (_) => _readExtensionMemberDescriptor(),
+ growable: useGrowableLists);
+ }
+
+ ExtensionMemberDescriptor _readExtensionMemberDescriptor() {
+ Name name = readName();
+ int kind = readByte();
+ int flags = readByte();
+ CanonicalName canonicalName = readNonNullCanonicalNameReference();
+ return new ExtensionMemberDescriptor(
+ name: name,
+ kind: ExtensionMemberKind.values[kind],
+ member: canonicalName.reference)
+ ..flags = flags;
+ }
+
/// Reads the partial content of a class, namely fields, procedures,
/// constructors and redirecting factory constructors.
void readClassPartialContent(Class node, List<int> procedureOffsets) {
- _mergeNamedNodeList(node.fieldsInternal, (index) => readField(), node);
- _mergeNamedNodeList(
- node.constructorsInternal, (index) => readConstructor(), node);
+ node.fieldsInternal = _readFieldList(node);
+ _readConstructorList(node);
+ node.proceduresInternal = _readProcedureList(node, procedureOffsets);
+ _readRedirectingFactoryConstructorList(node);
+ }
- _mergeNamedNodeList(node.proceduresInternal, (index) {
- _byteOffset = procedureOffsets[index];
- return readProcedure(procedureOffsets[index + 1]);
- }, node);
- _byteOffset = procedureOffsets.last;
- _mergeNamedNodeList(node.redirectingFactoryConstructorsInternal,
- (index) => readRedirectingFactoryConstructor(), node);
+ void _readConstructorList(Class node) {
+ int length = readUInt30();
+ if (!useGrowableLists && length == 0) {
+ // When lists don't have to be growable anyway, we might as well use a
+ // constant one for the empty list.
+ node.constructorsInternal = emptyListOfConstructor;
+ } else {
+ node.constructorsInternal = new List<Constructor>.generate(
+ length, (int index) => readConstructor()..parent = node,
+ growable: useGrowableLists);
+ }
+ }
+
+ void _readRedirectingFactoryConstructorList(Class node) {
+ int length = readUInt30();
+ if (!useGrowableLists && length == 0) {
+ // When lists don't have to be growable anyway, we might as well use a
+ // constant one for the empty list.
+ node.redirectingFactoryConstructorsInternal =
+ emptyListOfRedirectingFactoryConstructor;
+ } else {
+ node.redirectingFactoryConstructorsInternal =
+ new List<RedirectingFactoryConstructor>.generate(length,
+ (int index) => readRedirectingFactoryConstructor()..parent = node,
+ growable: useGrowableLists);
+ }
}
/// Set the lazyBuilder on the class so it can be lazy loaded in the future.
@@ -1513,7 +1582,7 @@
}
pushVariableDeclarations(function.positionalParameters);
pushVariableDeclarations(function.namedParameters);
- _fillTreeNodeList(node.initializers, (index) => readInitializer(), node);
+ _readInitializers(node);
variableStack.length = 0;
int transformerFlags = getAndResetTransformerFlags();
assert(((_) => true)(debugPath.removeLast()));
@@ -1641,6 +1710,19 @@
return node;
}
+ void _readInitializers(Constructor constructor) {
+ int length = readUInt30();
+ if (!useGrowableLists && length == 0) {
+ // When lists don't have to be growable anyway, we might as well use a
+ // constant one for the empty list.
+ constructor.initializers = emptyListOfInitializer;
+ } else {
+ constructor.initializers = new List<Initializer>.generate(
+ length, (int index) => readInitializer()..parent = constructor,
+ growable: useGrowableLists);
+ }
+ }
+
Initializer readInitializer() {
int tag = readByte();
bool isSynthetic = readByte() == 1;
@@ -2442,7 +2524,7 @@
int offset = readOffset();
DartType keyType = readDartType();
DartType valueType = readDartType();
- return new MapLiteral(readMapEntryList(),
+ return new MapLiteral(readMapLiteralEntryList(),
keyType: keyType, valueType: valueType, isConst: false)
..fileOffset = offset;
}
@@ -2451,7 +2533,7 @@
int offset = readOffset();
DartType keyType = readDartType();
DartType valueType = readDartType();
- return new MapLiteral(readMapEntryList(),
+ return new MapLiteral(readMapLiteralEntryList(),
keyType: keyType, valueType: valueType, isConst: true)
..fileOffset = offset;
}
@@ -2496,8 +2578,13 @@
return new ConstantExpression(constant, type)..fileOffset = offset;
}
- List<MapLiteralEntry> readMapEntryList() {
+ List<MapLiteralEntry> readMapLiteralEntryList() {
int length = readUInt30();
+ if (!useGrowableLists && length == 0) {
+ // When lists don't have to be growable anyway, we might as well use an
+ // almost constant one for the empty list.
+ return emptyListOfMapLiteralEntry;
+ }
return new List<MapLiteralEntry>.generate(length, (_) => readMapEntry(),
growable: useGrowableLists);
}
@@ -2732,11 +2819,9 @@
void _readSwitchCaseInto(SwitchCase caseNode) {
int length = readUInt30();
- caseNode.expressions.length = length;
- caseNode.expressionOffsets.length = length;
for (int i = 0; i < length; ++i) {
- caseNode.expressionOffsets[i] = readOffset();
- caseNode.expressions[i] = readExpression()..parent = caseNode;
+ caseNode.expressionOffsets.add(readOffset());
+ caseNode.expressions.add(readExpression()..parent = caseNode);
}
caseNode.isDefault = readByte() == 1;
caseNode.body = readStatement()..parent = caseNode;
@@ -2977,9 +3062,8 @@
length, (_) => new TypeParameter(null, null)..parent = parent,
growable: useGrowableLists);
} else if (list.length != length) {
- list.length = length;
for (int i = 0; i < length; ++i) {
- list[i] = new TypeParameter(null, null)..parent = parent;
+ list.add(new TypeParameter(null, null)..parent = parent);
}
}
typeParameterStack.addAll(list);
@@ -3304,16 +3388,16 @@
}
@override
- LibraryDependency readLibraryDependency(Library library) {
+ LibraryDependency readLibraryDependency() {
final int nodeOffset = _byteOffset;
- final LibraryDependency result = super.readLibraryDependency(library);
+ final LibraryDependency result = super.readLibraryDependency();
return _associateMetadata(result, nodeOffset);
}
@override
- LibraryPart readLibraryPart(Library library) {
+ LibraryPart readLibraryPart() {
final int nodeOffset = _byteOffset;
- final LibraryPart result = super.readLibraryPart(library);
+ final LibraryPart result = super.readLibraryPart();
return _associateMetadata(result, nodeOffset);
}
diff --git a/pkg/kernel/lib/src/tool/command_line_util.dart b/pkg/kernel/lib/src/tool/command_line_util.dart
index 858e1b1..f0e3f56 100644
--- a/pkg/kernel/lib/src/tool/command_line_util.dart
+++ b/pkg/kernel/lib/src/tool/command_line_util.dart
@@ -37,9 +37,9 @@
static Component tryLoadDill(String file) {
try {
return loadComponentFromBinary(file);
- } catch (e) {
- print("$file can't be loaded.");
- print(e);
+ } catch (e, s) {
+ print("$file can't be loaded:");
+ print('$e\n$s');
exit(1);
}
}
diff --git a/pkg/kernel/lib/text/ast_to_text.dart b/pkg/kernel/lib/text/ast_to_text.dart
index dc1c1d6..08e48b1 100644
--- a/pkg/kernel/lib/text/ast_to_text.dart
+++ b/pkg/kernel/lib/text/ast_to_text.dart
@@ -427,9 +427,9 @@
endLine(":");
endLine("//");
for (String s in problemsAsJson) {
- Map<String, Object> decoded = json.decode(s);
- List<Object> plainTextFormatted =
- decoded["plainTextFormatted"] as List<Object>;
+ Map<String, dynamic> decoded = json.decode(s);
+ List<dynamic> plainTextFormatted =
+ decoded["plainTextFormatted"] as List<dynamic>;
List<String> lines = plainTextFormatted.join("\n").split("\n");
for (int i = 0; i < lines.length; i++) {
write("//");
diff --git a/tools/VERSION b/tools/VERSION
index 8d92026..2bb6277 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 2
MINOR 14
PATCH 0
-PRERELEASE 53
+PRERELEASE 54
PRERELEASE_PATCH 0
\ No newline at end of file