| Index: pkg/kernel/lib/binary/ast_from_binary.dart
|
| diff --git a/pkg/kernel/lib/binary/ast_from_binary.dart b/pkg/kernel/lib/binary/ast_from_binary.dart
|
| index 100fe9886627918ff9ff771dae1c3443e94e0f66..a4520ef07bf4df3172e73faf2a58e05de92fe1de 100644
|
| --- a/pkg/kernel/lib/binary/ast_from_binary.dart
|
| +++ b/pkg/kernel/lib/binary/ast_from_binary.dart
|
| @@ -3,11 +3,11 @@
|
| // BSD-style license that can be found in the LICENSE file.
|
| library kernel.ast_from_binary;
|
|
|
| +import 'dart:convert';
|
| +
|
| import '../ast.dart';
|
| +import '../transformations/flags.dart';
|
| import 'tag.dart';
|
| -import 'loader.dart';
|
| -import 'dart:convert';
|
| -import 'package:kernel/transformations/flags.dart';
|
|
|
| class ParseError {
|
| String filename;
|
| @@ -21,8 +21,6 @@ class ParseError {
|
| }
|
|
|
| class BinaryBuilder {
|
| - final BinaryReferenceLoader loader;
|
| - final List<Library> importTable = <Library>[];
|
| final List<VariableDeclaration> variableStack = <VariableDeclaration>[];
|
| final List<LabeledStatement> labelStack = <LabeledStatement>[];
|
| int labelStackBase = 0;
|
| @@ -31,16 +29,19 @@ class BinaryBuilder {
|
| final String filename;
|
| final List<int> _bytes;
|
| int _byteIndex = 0;
|
| - Library _currentLibrary;
|
| List<String> _stringTable;
|
| List<String> _sourceUriTable;
|
| + List<CanonicalName> _linkTable;
|
| int _transformerFlags = 0;
|
| + Library _currentLibrary;
|
|
|
| // If something goes wrong, this list should indicate what library,
|
| // class, and member was being built.
|
| List<String> debugPath = <String>[];
|
|
|
| - BinaryBuilder(this.loader, this._bytes, [this.filename]);
|
| + bool _isReadingLibraryImplementation = false;
|
| +
|
| + BinaryBuilder(this._bytes, [this.filename]);
|
|
|
| fail(String message) {
|
| throw new ParseError(message,
|
| @@ -126,10 +127,10 @@ class BinaryBuilder {
|
|
|
| InferredValue readOptionalInferredValue() {
|
| if (readAndCheckOptionTag()) {
|
| - Class baseClass = readClassReference(allowNull: true);
|
| + Reference baseClass = readClassReference(allowNull: true);
|
| BaseClassKind baseClassKind = BaseClassKind.values[readByte()];
|
| int valueBits = readByte();
|
| - return new InferredValue(baseClass, baseClassKind, valueBits);
|
| + return new InferredValue.byReference(baseClass, baseClassKind, valueBits);
|
| }
|
| return null;
|
| }
|
| @@ -170,7 +171,82 @@ class BinaryBuilder {
|
| }
|
| }
|
|
|
| - Program readProgramFile() {
|
| + /// 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(), TreeNode parent) {
|
| + if (_isReadingLibraryImplementation) {
|
| + // When reading the library implementation, overwrite the whole list
|
| + // with the new one.
|
| + _fillTreeNodeList(list, readObject, parent);
|
| + } else {
|
| + // When reading an external library, the results should either be:
|
| + // - merged with the existing external library definition (if any)
|
| + // - ignored if the library implementation is already in memory
|
| + int numberOfNodes = readUInt();
|
| + for (int i = 0; i < numberOfNodes; ++i) {
|
| + var value = readObject();
|
| + // We use the parent pointer of a node to determine if it already is in
|
| + // the AST and hence should not be added again.
|
| + if (value.parent == null) {
|
| + list.add(value..parent = parent);
|
| + }
|
| + }
|
| + }
|
| + }
|
| +
|
| + void readLinkTable(CanonicalName linkRoot) {
|
| + int length = readUInt();
|
| + _linkTable = new List<CanonicalName>(length);
|
| + for (int i = 0; i < length; ++i) {
|
| + int biasedParentIndex = readUInt();
|
| + String name = readStringReference();
|
| + var parent =
|
| + biasedParentIndex == 0 ? linkRoot : _linkTable[biasedParentIndex - 1];
|
| + _linkTable[i] = parent.getChild(name);
|
| + }
|
| + }
|
| +
|
| + /// Deserializes a kernel program and stores it in [program].
|
| + ///
|
| + /// When linking with a non-empty program, canonical names must have been
|
| + /// computed ahead of time.
|
| + ///
|
| + /// The input bytes may contain multiple files concatenated.
|
| + void readProgram(Program program) {
|
| + while (_byteIndex < _bytes.length) {
|
| + _readOneProgram(program);
|
| + }
|
| + }
|
| +
|
| + /// Reads a single program file from the input and loads it into [program],
|
| + /// overwriting and reusing any existing data in the program.
|
| + ///
|
| + /// When linking with a non-empty program, canonical names must have been
|
| + /// computed ahead of time.
|
| + ///
|
| + /// This should *only* be used when there is a reason to not allow
|
| + /// concatenated files.
|
| + void readSingleFileProgram(Program program) {
|
| + _readOneProgram(program);
|
| + if (_byteIndex < _bytes.length) {
|
| + if (_byteIndex + 3 < _bytes.length) {
|
| + int magic = readMagicWord();
|
| + if (magic == Tag.ProgramFile) {
|
| + throw 'Concatenated program file given when a single program '
|
| + 'was expected.';
|
| + }
|
| + }
|
| + throw 'Unrecognized bytes following program data';
|
| + }
|
| + }
|
| +
|
| + void _readOneProgram(Program program) {
|
| int magic = readMagicWord();
|
| if (magic != Tag.ProgramFile) {
|
| throw fail('This is not a binary dart file. '
|
| @@ -178,22 +254,21 @@ class BinaryBuilder {
|
| }
|
| readStringTable();
|
| Map<String, Source> uriToSource = readUriToSource();
|
| - importTable.length = readUInt();
|
| - for (int i = 0; i < importTable.length; ++i) {
|
| - importTable[i] = new Library(null);
|
| - }
|
| - for (int i = 0; i < importTable.length; ++i) {
|
| - _currentLibrary = importTable[i];
|
| - readLibrary();
|
| + program.uriToSource.addAll(uriToSource);
|
| + readLinkTable(program.root);
|
| + int numberOfLibraries = readUInt();
|
| + List<Library> libraries = new List<Library>(numberOfLibraries);
|
| + for (int i = 0; i < numberOfLibraries; ++i) {
|
| + libraries[i] = readLibrary(program);
|
| }
|
| var mainMethod = readMemberReference(allowNull: true);
|
| - return new Program(importTable, uriToSource)..mainMethod = mainMethod;
|
| + program.mainMethodName ??= mainMethod;
|
| }
|
|
|
| Map<String, Source> readUriToSource() {
|
| readSourceUriTable();
|
| int length = _sourceUriTable.length;
|
| - Map<String, Source> uriToLineStarts = <String, Source>{};
|
| + Map<String, Source> uriToSource = <String, Source>{};
|
| for (int i = 0; i < length; ++i) {
|
| String uri = _sourceUriTable[i];
|
| String sourceCode = readStringEntry();
|
| @@ -205,24 +280,19 @@ class BinaryBuilder {
|
| lineStarts[j] = lineStart;
|
| previousLineStart = lineStart;
|
| }
|
| - uriToLineStarts[uri] = new Source(lineStarts, sourceCode);
|
| + uriToSource[uri] = new Source(lineStarts, sourceCode);
|
| }
|
| - return uriToLineStarts;
|
| + return uriToSource;
|
| }
|
|
|
| - void _fillLazilyLoadedList(
|
| - List<TreeNode> list, void buildObject(int tag, int index)) {
|
| - int length = readUInt();
|
| - list.length = length;
|
| - for (int i = 0; i < length; ++i) {
|
| - int tag = readByte();
|
| - buildObject(tag, i);
|
| - }
|
| + CanonicalName readCanonicalNameReference() {
|
| + var index = readUInt();
|
| + if (index == 0) return null;
|
| + return _linkTable[index - 1];
|
| }
|
|
|
| - Library readLibraryReference() {
|
| - int index = readUInt();
|
| - return importTable[index];
|
| + Reference readLibraryReference() {
|
| + return readCanonicalNameReference().getReference();
|
| }
|
|
|
| DeferredImport readDeferredImportReference() {
|
| @@ -230,159 +300,120 @@ class BinaryBuilder {
|
| return _currentLibrary.deferredImports[index];
|
| }
|
|
|
| - Class readClassReference({bool allowNull: false}) {
|
| - int tag = readByte();
|
| - if (tag == Tag.NullReference) {
|
| - if (!allowNull) {
|
| - throw 'Expected a class reference to be valid but was `null`.';
|
| - }
|
| - return null;
|
| - } else {
|
| - var library = readLibraryReference();
|
| - int index = readUInt();
|
| - return loader.getClassReference(library, tag, index);
|
| + Reference readClassReference({bool allowNull: false}) {
|
| + var name = readCanonicalNameReference();
|
| + if (name == null && !allowNull) {
|
| + throw 'Expected a class reference to be valid but was `null`.';
|
| }
|
| + return name?.getReference();
|
| }
|
|
|
| - Member readMemberReference({bool allowNull: false}) {
|
| - int tag = readByte();
|
| - switch (tag) {
|
| - case Tag.LibraryFieldReference:
|
| - case Tag.LibraryProcedureReference:
|
| - var library = readLibraryReference();
|
| - var index = readUInt();
|
| - return loader.getLibraryMemberReference(library, tag, index);
|
| -
|
| - case Tag.ClassFieldReference:
|
| - case Tag.ClassConstructorReference:
|
| - case Tag.ClassProcedureReference:
|
| - var classNode = readClassReference();
|
| - var index = readUInt();
|
| - return loader.getClassMemberReference(classNode, tag, index);
|
| -
|
| - case Tag.NullReference:
|
| - if (!allowNull) {
|
| - throw 'Expected a member reference to be valid but was `null`.';
|
| - }
|
| - return null;
|
| -
|
| - default:
|
| - throw fail('Invalid member reference tag: $tag');
|
| + Reference readMemberReference({bool allowNull: false}) {
|
| + var name = readCanonicalNameReference();
|
| + if (name == null && !allowNull) {
|
| + throw 'Expected a member reference to be valid but was `null`.';
|
| }
|
| + return name?.getReference();
|
| }
|
|
|
| Name readName() {
|
| String text = readStringReference();
|
| if (text.isNotEmpty && text[0] == '_') {
|
| - return new Name(text, readLibraryReference());
|
| + return new Name.byReference(text, readLibraryReference());
|
| } else {
|
| return new Name(text);
|
| }
|
| }
|
|
|
| - Uri readImportUri() {
|
| - return Uri.parse(readStringReference());
|
| - }
|
| -
|
| - void readLibrary() {
|
| + Library readLibrary(Program program) {
|
| int flags = readByte();
|
| - _currentLibrary.isExternal = (flags & 0x1) != 0;
|
| - _currentLibrary.name = readStringOrNullIfEmpty();
|
| - _currentLibrary.importUri = readImportUri();
|
| - debugPath.add(_currentLibrary.name ??
|
| - _currentLibrary.importUri?.toString() ??
|
| - 'library');
|
| -
|
| + bool isExternal = (flags & 0x1) != 0;
|
| + _isReadingLibraryImplementation = !isExternal;
|
| + var canonicalName = readCanonicalNameReference();
|
| + Reference reference = canonicalName.getReference();
|
| + Library library = reference.node;
|
| + bool shouldWriteData = library == null || _isReadingLibraryImplementation;
|
| + if (library == null) {
|
| + library =
|
| + new Library(Uri.parse(canonicalName.name), reference: reference);
|
| + program.libraries.add(library..parent = program);
|
| + }
|
| + _currentLibrary = library;
|
| + String name = readStringOrNullIfEmpty();
|
| // TODO(jensj): We currently save (almost the same) uri twice.
|
| - _currentLibrary.fileUri = readUriReference();
|
| -
|
| - _readDeferredImports(_currentLibrary);
|
| - _fillLazilyLoadedList(_currentLibrary.classes, (int tag, int index) {
|
| - readClass(loader.getClassReference(_currentLibrary, tag, index), tag);
|
| - });
|
| - _fillLazilyLoadedList(_currentLibrary.fields, (int tag, int index) {
|
| - readField(
|
| - loader.getLibraryMemberReference(_currentLibrary, tag, index), tag);
|
| - });
|
| - _fillLazilyLoadedList(_currentLibrary.procedures, (int tag, int index) {
|
| - readProcedure(
|
| - loader.getLibraryMemberReference(_currentLibrary, tag, index), tag);
|
| - });
|
| - debugPath.removeLast();
|
| - }
|
| + String fileUri = readUriReference();
|
|
|
| - void _readDeferredImports(Library library) {
|
| - int count = readUInt();
|
| - library.deferredImports.length = count;
|
| - for (int i = 0; i < count; ++i) {
|
| - var importNode = _readDeferredImport();
|
| - library.deferredImports.add(importNode..parent = library);
|
| + if (shouldWriteData) {
|
| + library.isExternal = isExternal;
|
| + library.name = name;
|
| + library.fileUri = fileUri;
|
| }
|
| - }
|
|
|
| - DeferredImport _readDeferredImport() {
|
| - return new DeferredImport(readLibraryReference(), readStringReference());
|
| + _readDeferredImports(library);
|
| +
|
| + debugPath.add(library.name ?? library.importUri?.toString() ?? 'library');
|
| +
|
| + _mergeNamedNodeList(library.classes, readClass, library);
|
| + _mergeNamedNodeList(library.fields, readField, library);
|
| + _mergeNamedNodeList(library.procedures, readProcedure, library);
|
| +
|
| + debugPath.removeLast();
|
| + _currentLibrary = null;
|
| + return library;
|
| }
|
|
|
| - void readClass(Class node, int tag) {
|
| - assert(node != null);
|
| - switch (tag) {
|
| - case Tag.NormalClass:
|
| - readNormalClass(node);
|
| - break;
|
| - case Tag.MixinClass:
|
| - readMixinClass(node);
|
| - break;
|
| - default:
|
| - throw fail('Invalid class tag: $tag');
|
| + void _readDeferredImports(Library library) {
|
| + int length = readUInt();
|
| + if (library.isExternal) {
|
| + assert(length == 0);
|
| + return;
|
| + }
|
| + library.deferredImports.length = length;
|
| + for (int i = 0; i < length; ++i) {
|
| + library.deferredImports[i] = new DeferredImport.byReference(
|
| + readLibraryReference(), readStringReference())..parent = library;
|
| }
|
| }
|
|
|
| - void readNormalClass(Class node) {
|
| + Class readClass() {
|
| + int tag = readByte();
|
| + assert(tag == Tag.Class);
|
| + var canonicalName = readCanonicalNameReference();
|
| + var reference = canonicalName.getReference();
|
| + Class node = reference.node;
|
| + bool shouldWriteData = node == null || _isReadingLibraryImplementation;
|
| + if (node == null) {
|
| + node = new Class(reference: reference)..level = ClassLevel.Temporary;
|
| + }
|
| node.fileOffset = readOffset();
|
| int flags = readByte();
|
| node.isAbstract = flags & 0x1 != 0;
|
| int levelIndex = (flags >> 1) & 0x3;
|
| - node.level = ClassLevel.values[levelIndex + 1];
|
| - node.name = readStringOrNullIfEmpty();
|
| - node.fileUri = readUriReference();
|
| - node.annotations = readAnnotationList(node);
|
| + var level = ClassLevel.values[levelIndex + 1];
|
| + if (level.index >= node.level.index) {
|
| + node.level = level;
|
| + }
|
| + var name = readStringOrNullIfEmpty();
|
| + var fileUri = readUriReference();
|
| + var annotations = readAnnotationList(node);
|
| debugPath.add(node.name ?? 'normal-class');
|
| readAndPushTypeParameterList(node.typeParameters, node);
|
| - node.supertype = readSupertypeOption();
|
| + var supertype = readSupertypeOption();
|
| + var mixedInType = readSupertypeOption();
|
| _fillNonTreeNodeList(node.implementedTypes, readSupertype);
|
| - _fillLazilyLoadedList(node.fields, (int tag, int index) {
|
| - readField(loader.getClassMemberReference(node, tag, index), tag);
|
| - });
|
| - _fillLazilyLoadedList(node.constructors, (int tag, int index) {
|
| - readConstructor(loader.getClassMemberReference(node, tag, index), tag);
|
| - });
|
| - _fillLazilyLoadedList(node.procedures, (int tag, int index) {
|
| - readProcedure(loader.getClassMemberReference(node, tag, index), tag);
|
| - });
|
| - typeParameterStack.length = 0;
|
| - debugPath.removeLast();
|
| - }
|
| -
|
| - void readMixinClass(Class node) {
|
| - node.fileOffset = readOffset();
|
| - int flags = readByte();
|
| - node.isAbstract = flags & 0x1 != 0;
|
| - int levelIndex = (flags >> 1) & 0x3;
|
| - node.level = ClassLevel.values[levelIndex];
|
| - node.name = readStringOrNullIfEmpty();
|
| - node.fileUri = readUriReference();
|
| - node.annotations = readAnnotationList(node);
|
| - debugPath.add(node.name ?? 'mixin-class');
|
| - readAndPushTypeParameterList(node.typeParameters, node);
|
| - node.supertype = readSupertype();
|
| - node.mixedInType = readSupertype();
|
| - _fillNonTreeNodeList(node.implementedTypes, readDartType);
|
| - _fillLazilyLoadedList(node.constructors, (int tag, int index) {
|
| - readConstructor(loader.getClassMemberReference(node, tag, index), tag);
|
| - });
|
| + _mergeNamedNodeList(node.fields, readField, node);
|
| + _mergeNamedNodeList(node.constructors, readConstructor, node);
|
| + _mergeNamedNodeList(node.procedures, readProcedure, node);
|
| typeParameterStack.length = 0;
|
| debugPath.removeLast();
|
| + if (shouldWriteData) {
|
| + node.name = name;
|
| + node.fileUri = fileUri;
|
| + node.annotations = annotations;
|
| + node.supertype = supertype;
|
| + node.mixedInType = mixedInType;
|
| + }
|
| + return node;
|
| }
|
|
|
| int getAndResetTransformerFlags() {
|
| @@ -396,58 +427,114 @@ class BinaryBuilder {
|
| _transformerFlags |= flags;
|
| }
|
|
|
| - void readField(Field node, int tag) {
|
| - // Note: as with readProcedure and readConstructor, the tag parameter
|
| - // is unused, but we pass it in to clarify that the tag has already been
|
| - // consumed from the input.
|
| + Field readField() {
|
| + int tag = readByte();
|
| assert(tag == Tag.Field);
|
| - node.fileOffset = readOffset();
|
| - node.fileEndOffset = readOffset();
|
| - node.flags = readByte();
|
| - node.name = readName();
|
| - node.fileUri = readUriReference();
|
| - node.annotations = readAnnotationList(node);
|
| + var canonicalName = readCanonicalNameReference();
|
| + var reference = canonicalName.getReference();
|
| + Field node = reference.node;
|
| + bool shouldWriteData = node == null || _isReadingLibraryImplementation;
|
| + if (node == null) {
|
| + node = new Field(null, reference: reference);
|
| + }
|
| + int fileOffset = readOffset();
|
| + int fileEndOffset = readOffset();
|
| + int flags = readByte();
|
| + var name = readName();
|
| + var fileUri = readUriReference();
|
| + var annotations = readAnnotationList(node);
|
| debugPath.add(node.name?.name ?? 'field');
|
| - node.type = readDartType();
|
| - node.inferredValue = readOptionalInferredValue();
|
| - node.initializer = readExpressionOption();
|
| - node.initializer?.parent = node;
|
| - node.transformerFlags = getAndResetTransformerFlags();
|
| + var type = readDartType();
|
| + var inferredValue = readOptionalInferredValue();
|
| + var initializer = readExpressionOption();
|
| + int transformerFlags = getAndResetTransformerFlags();
|
| debugPath.removeLast();
|
| + if (shouldWriteData) {
|
| + node.fileOffset = fileOffset;
|
| + node.fileEndOffset = fileEndOffset;
|
| + node.flags = flags;
|
| + node.name = name;
|
| + node.fileUri = fileUri;
|
| + node.annotations = annotations;
|
| + node.type = type;
|
| + node.inferredValue = inferredValue;
|
| + node.initializer = initializer;
|
| + node.initializer?.parent = node;
|
| + node.transformerFlags = transformerFlags;
|
| + }
|
| + return node;
|
| }
|
|
|
| - void readConstructor(Constructor node, int tag) {
|
| + Constructor readConstructor() {
|
| + int tag = readByte();
|
| assert(tag == Tag.Constructor);
|
| - node.fileOffset = readOffset();
|
| - node.fileEndOffset = readOffset();
|
| - node.flags = readByte();
|
| - node.name = readName();
|
| - node.annotations = readAnnotationList(node);
|
| + var canonicalName = readCanonicalNameReference();
|
| + var reference = canonicalName.getReference();
|
| + Constructor node = reference.node;
|
| + bool shouldWriteData = node == null || _isReadingLibraryImplementation;
|
| + if (node == null) {
|
| + node = new Constructor(null, reference: reference);
|
| + }
|
| + var fileOffset = readOffset();
|
| + var fileEndOffset = readOffset();
|
| + var flags = readByte();
|
| + var name = readName();
|
| + var annotations = readAnnotationList(node);
|
| debugPath.add(node.name?.name ?? 'constructor');
|
| - node.function = readFunctionNode()..parent = node;
|
| - pushVariableDeclarations(node.function.positionalParameters);
|
| - pushVariableDeclarations(node.function.namedParameters);
|
| + var function = readFunctionNode();
|
| + pushVariableDeclarations(function.positionalParameters);
|
| + pushVariableDeclarations(function.namedParameters);
|
| _fillTreeNodeList(node.initializers, readInitializer, node);
|
| variableStack.length = 0;
|
| - node.transformerFlags = getAndResetTransformerFlags();
|
| + var transformerFlags = getAndResetTransformerFlags();
|
| debugPath.removeLast();
|
| + if (shouldWriteData) {
|
| + node.fileOffset = fileOffset;
|
| + node.fileEndOffset = fileEndOffset;
|
| + node.flags = flags;
|
| + node.name = name;
|
| + node.annotations = annotations;
|
| + node.function = function..parent = node;
|
| + node.transformerFlags = transformerFlags;
|
| + }
|
| + return node;
|
| }
|
|
|
| - void readProcedure(Procedure node, int tag) {
|
| + Procedure readProcedure() {
|
| + int tag = readByte();
|
| assert(tag == Tag.Procedure);
|
| - node.fileOffset = readOffset();
|
| - node.fileEndOffset = readOffset();
|
| + var canonicalName = readCanonicalNameReference();
|
| + var reference = canonicalName.getReference();
|
| + Procedure node = reference.node;
|
| + bool shouldWriteData = node == null || _isReadingLibraryImplementation;
|
| + if (node == null) {
|
| + node = new Procedure(null, null, null, reference: reference);
|
| + }
|
| + var fileOffset = readOffset();
|
| + var fileEndOffset = readOffset();
|
| int kindIndex = readByte();
|
| - node.kind = ProcedureKind.values[kindIndex];
|
| - node.flags = readByte();
|
| - node.name = readName();
|
| - node.fileUri = readUriReference();
|
| - node.annotations = readAnnotationList(node);
|
| + var kind = ProcedureKind.values[kindIndex];
|
| + var flags = readByte();
|
| + var name = readName();
|
| + var fileUri = readUriReference();
|
| + var annotations = readAnnotationList(node);
|
| debugPath.add(node.name?.name ?? 'procedure');
|
| - node.function = readFunctionNodeOption();
|
| - node.function?.parent = node;
|
| - node.transformerFlags = getAndResetTransformerFlags();
|
| + var function = readFunctionNodeOption();
|
| + var transformerFlags = getAndResetTransformerFlags();
|
| debugPath.removeLast();
|
| + if (shouldWriteData) {
|
| + node.fileOffset = fileOffset;
|
| + node.fileEndOffset = fileEndOffset;
|
| + node.kind = kind;
|
| + node.flags = flags;
|
| + node.name = name;
|
| + node.fileUri = fileUri;
|
| + node.annotations = annotations;
|
| + node.function = function;
|
| + node.function?.parent = node;
|
| + node.transformerFlags = transformerFlags;
|
| + }
|
| + return node;
|
| }
|
|
|
| Initializer readInitializer() {
|
| @@ -456,11 +543,13 @@ class BinaryBuilder {
|
| case Tag.InvalidInitializer:
|
| return new InvalidInitializer();
|
| case Tag.FieldInitializer:
|
| - return new FieldInitializer(readMemberReference(), readExpression());
|
| + return new FieldInitializer.byReference(
|
| + readMemberReference(), readExpression());
|
| case Tag.SuperInitializer:
|
| - return new SuperInitializer(readMemberReference(), readArguments());
|
| + return new SuperInitializer.byReference(
|
| + readMemberReference(), readArguments());
|
| case Tag.RedirectingInitializer:
|
| - return new RedirectingInitializer(
|
| + return new RedirectingInitializer.byReference(
|
| readMemberReference(), readArguments());
|
| case Tag.LocalInitializer:
|
| return new LocalInitializer(readAndPushVariableDeclaration());
|
| @@ -571,34 +660,40 @@ class BinaryBuilder {
|
| ..fileOffset = offset;
|
| case Tag.PropertyGet:
|
| int offset = readOffset();
|
| - return new PropertyGet(
|
| + return new PropertyGet.byReference(
|
| readExpression(), readName(), readMemberReference(allowNull: true))
|
| ..fileOffset = offset;
|
| case Tag.PropertySet:
|
| int offset = readOffset();
|
| - return new PropertySet(readExpression(), readName(), readExpression(),
|
| + return new PropertySet.byReference(
|
| + readExpression(),
|
| + readName(),
|
| + readExpression(),
|
| readMemberReference(allowNull: true))..fileOffset = offset;
|
| case Tag.SuperPropertyGet:
|
| addTransformerFlag(TransformerFlag.superCalls);
|
| - return new SuperPropertyGet(
|
| + return new SuperPropertyGet.byReference(
|
| readName(), readMemberReference(allowNull: true));
|
| case Tag.SuperPropertySet:
|
| addTransformerFlag(TransformerFlag.superCalls);
|
| - return new SuperPropertySet(
|
| + return new SuperPropertySet.byReference(
|
| readName(), readExpression(), readMemberReference(allowNull: true));
|
| case Tag.DirectPropertyGet:
|
| - return new DirectPropertyGet(readExpression(), readMemberReference());
|
| + return new DirectPropertyGet.byReference(
|
| + readExpression(), readMemberReference());
|
| case Tag.DirectPropertySet:
|
| - return new DirectPropertySet(
|
| + return new DirectPropertySet.byReference(
|
| readExpression(), readMemberReference(), readExpression());
|
| case Tag.StaticGet:
|
| int offset = readOffset();
|
| - return new StaticGet(readMemberReference())..fileOffset = offset;
|
| + return new StaticGet.byReference(readMemberReference())
|
| + ..fileOffset = offset;
|
| case Tag.StaticSet:
|
| - return new StaticSet(readMemberReference(), readExpression());
|
| + return new StaticSet.byReference(
|
| + readMemberReference(), readExpression());
|
| case Tag.MethodInvocation:
|
| int offset = readOffset();
|
| - return new MethodInvocation(
|
| + return new MethodInvocation.byReference(
|
| readExpression(),
|
| readName(),
|
| readArguments(),
|
| @@ -606,28 +701,32 @@ class BinaryBuilder {
|
| case Tag.SuperMethodInvocation:
|
| int offset = readOffset();
|
| addTransformerFlag(TransformerFlag.superCalls);
|
| - return new SuperMethodInvocation(
|
| + return new SuperMethodInvocation.byReference(
|
| readName(), readArguments(), readMemberReference(allowNull: true))
|
| ..fileOffset = offset;
|
| case Tag.DirectMethodInvocation:
|
| - return new DirectMethodInvocation(
|
| + return new DirectMethodInvocation.byReference(
|
| readExpression(), readMemberReference(), readArguments());
|
| case Tag.StaticInvocation:
|
| int offset = readOffset();
|
| - return new StaticInvocation(readMemberReference(), readArguments(),
|
| - isConst: false)..fileOffset = offset;
|
| + return new StaticInvocation.byReference(
|
| + readMemberReference(), readArguments(), isConst: false)
|
| + ..fileOffset = offset;
|
| case Tag.ConstStaticInvocation:
|
| int offset = readOffset();
|
| - return new StaticInvocation(readMemberReference(), readArguments(),
|
| - isConst: true)..fileOffset = offset;
|
| + return new StaticInvocation.byReference(
|
| + readMemberReference(), readArguments(), isConst: true)
|
| + ..fileOffset = offset;
|
| case Tag.ConstructorInvocation:
|
| int offset = readOffset();
|
| - return new ConstructorInvocation(readMemberReference(), readArguments(),
|
| - isConst: false)..fileOffset = offset;
|
| + return new ConstructorInvocation.byReference(
|
| + readMemberReference(), readArguments(), isConst: false)
|
| + ..fileOffset = offset;
|
| case Tag.ConstConstructorInvocation:
|
| int offset = readOffset();
|
| - return new ConstructorInvocation(readMemberReference(), readArguments(),
|
| - isConst: true)..fileOffset = offset;
|
| + return new ConstructorInvocation.byReference(
|
| + readMemberReference(), readArguments(), isConst: true)
|
| + ..fileOffset = offset;
|
| case Tag.Not:
|
| return new Not(readExpression());
|
| case Tag.LogicalExpression:
|
| @@ -856,7 +955,7 @@ class BinaryBuilder {
|
|
|
| Supertype readSupertype() {
|
| InterfaceType type = readDartType();
|
| - return new Supertype(type.classNode, type.typeArguments);
|
| + return new Supertype.byReference(type.className, type.typeArguments);
|
| }
|
|
|
| Supertype readSupertypeOption() {
|
| @@ -895,9 +994,11 @@ class BinaryBuilder {
|
| case Tag.VoidType:
|
| return const VoidType();
|
| case Tag.InterfaceType:
|
| - return new InterfaceType(readClassReference(), readDartTypeList());
|
| + return new InterfaceType.byReference(
|
| + readClassReference(), readDartTypeList());
|
| case Tag.SimpleInterfaceType:
|
| - return new InterfaceType(readClassReference(), const <DartType>[]);
|
| + return new InterfaceType.byReference(
|
| + readClassReference(), const <DartType>[]);
|
| case Tag.FunctionType:
|
| int typeParameterStackHeight = typeParameterStack.length;
|
| var typeParameters = readAndPushTypeParameterList();
|
| @@ -929,7 +1030,7 @@ class BinaryBuilder {
|
| if (list == null) {
|
| list = new List<TypeParameter>.generate(
|
| length, (i) => new TypeParameter(null, null)..parent = parent);
|
| - } else {
|
| + } else if (list.length != length) {
|
| list.length = length;
|
| for (int i = 0; i < length; ++i) {
|
| list[i] = new TypeParameter(null, null)..parent = parent;
|
|
|