Chromium Code Reviews| 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 8c940f69fe5586c80a9aab09cc9354c5f8db56a9..0a6fed69c258a05f556fb4ad15eb53e4807063e0 100644 |
| --- a/pkg/kernel/lib/binary/ast_from_binary.dart |
| +++ b/pkg/kernel/lib/binary/ast_from_binary.dart |
| @@ -5,7 +5,6 @@ library kernel.ast_from_binary; |
| import '../ast.dart'; |
| import 'tag.dart'; |
| -import 'loader.dart'; |
| import 'dart:convert'; |
| import 'package:kernel/transformations/flags.dart'; |
| @@ -21,8 +20,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 +28,18 @@ 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; |
| // 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 +125,10 @@ class BinaryBuilder { |
| InferredValue readOptionalInferredValue() { |
| if (readAndCheckOptionTag()) { |
| - Class baseClass = readClassReference(allowNull: true); |
| + CanonicalName baseClass = readClassReference(allowNull: true); |
| BaseClassKind baseClassKind = BaseClassKind.values[readByte()]; |
| int valueBits = readByte(); |
| - return new InferredValue(baseClass, baseClassKind, valueBits); |
| + return new InferredValue.byName(baseClass, baseClassKind, valueBits); |
| } |
| return null; |
| } |
| @@ -170,7 +169,73 @@ class BinaryBuilder { |
| } |
| } |
| - Program readProgramFile() { |
| + /// Reads a list of linked 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. |
|
ahe
2017/02/13 10:07:07
I suggest that you add some documentation of what
asgerf
2017/02/16 14:22:42
Done.
|
| + void _mergeLinkedNodeList( |
| + List<LinkedNode> list, LinkedNode 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 impementation is already in memory |
| + // |
| + // We use the parent pointer of a node to determine if it already is in |
| + // the AST and hence should not be added again. |
| + int numberOfNodes = readUInt(); |
| + for (int i = 0; i < numberOfNodes; ++i) { |
| + var value = readObject(); |
| + 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]. |
| + /// |
| + /// The input bytes may contain multiple files concatenated. |
| + void readMultiFile(Program program) { |
| + while (_byteIndex < _bytes.length) { |
| + _readProgram(program); |
| + } |
| + } |
| + |
| + /// Reads a single program file from the input and loads it into [program], |
| + /// overwriting and reusing any existing data in the program. |
| + /// |
| + /// This should *only* be used when there is a reason to not allow |
| + /// concatenated files. |
| + void readSingleFile(Program program) { |
| + _readProgram(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 _readProgram(Program program) { |
| int magic = readMagicWord(); |
| if (magic != Tag.ProgramFile) { |
| throw fail('This is not a binary dart file. ' |
| @@ -178,23 +243,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(); |
| @@ -206,167 +269,118 @@ 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]; |
| + CanonicalName readLibraryReference() { |
| + return readCanonicalNameReference(); |
| } |
| - 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); |
| + CanonicalName readClassReference({bool allowNull: false}) { |
| + var name = readCanonicalNameReference(); |
| + if (name == null && !allowNull) { |
| + throw 'Expected a class reference to be valid but was `null`.'; |
| } |
| + return name; |
| } |
| - 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'); |
| + CanonicalName readMemberReference({bool allowNull: false}) { |
| + var name = readCanonicalNameReference(); |
| + if (name == null && !allowNull) { |
| + throw 'Expected a member reference to be valid but was `null`.'; |
| } |
| + return name; |
| } |
| 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(); |
| + Library library = canonicalName.definition; |
| + bool shouldWriteData = library == null || _isReadingLibraryImplementation; |
| + if (library == null) { |
| + library = new Library(Uri.parse(canonicalName.name)); |
| + canonicalName.linkTo(library); |
| + program.libraries.add(library..parent = program); |
| + } |
| + String name = readStringOrNullIfEmpty(); |
| // TODO(jensj): We currently save (almost the same) uri twice. |
| - _currentLibrary.fileUri = readUriReference(); |
| - |
| - _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 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'); |
| + if (shouldWriteData) { |
| + library.isExternal = isExternal; |
| + library.name = name; |
| + library.fileUri = fileUri; |
| } |
| - } |
| - void readNormalClass(Class node) { |
| - node.fileOffset = readOffset(); |
| - int flags = readByte(); |
| - node.isAbstract = flags & 0x1 != 0; |
| - node.level = _currentLibrary.isExternal |
| - ? (flags & 0x2 != 0) ? ClassLevel.Type : ClassLevel.Hierarchy |
| - : ClassLevel.Body; |
| - node.name = readStringOrNullIfEmpty(); |
| - node.fileUri = readUriReference(); |
| - node.annotations = readAnnotationList(node); |
| - debugPath.add(node.name ?? 'normal-class'); |
| - readAndPushTypeParameterList(node.typeParameters, node); |
| - node.supertype = 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.add(library.name ?? library.importUri?.toString() ?? 'library'); |
| + |
| + _mergeLinkedNodeList(library.classes, readClass, library); |
| + _mergeLinkedNodeList(library.fields, readField, library); |
| + _mergeLinkedNodeList(library.procedures, readProcedure, library); |
| + |
| debugPath.removeLast(); |
| + return library; |
| } |
| - void readMixinClass(Class node) { |
| + Class readClass() { |
| + int tag = readByte(); |
| + assert(tag == Tag.Class); |
| + var canonicalName = readCanonicalNameReference(); |
| + Class node = canonicalName.definition; |
| + bool shouldWriteData = node == null || _isReadingLibraryImplementation; |
| + if (node == null) { |
| + node = new Class()..level = ClassLevel.Temporary; |
| + canonicalName.linkTo(node); |
| + } |
| node.fileOffset = readOffset(); |
| int flags = readByte(); |
| node.isAbstract = flags & 0x1 != 0; |
| - node.level = _currentLibrary.isExternal |
| - ? (flags & 0x2 != 0) ? ClassLevel.Type : ClassLevel.Hierarchy |
| - : ClassLevel.Body; |
| - node.name = readStringOrNullIfEmpty(); |
| - node.fileUri = readUriReference(); |
| - node.annotations = readAnnotationList(node); |
| - debugPath.add(node.name ?? 'mixin-class'); |
| + var level = _isReadingLibraryImplementation |
| + ? ClassLevel.Body |
| + : (flags & 0x2 != 0) ? ClassLevel.Type : ClassLevel.Hierarchy; |
| + 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 = readSupertype(); |
| - node.mixedInType = readSupertype(); |
| - _fillNonTreeNodeList(node.implementedTypes, readDartType); |
| - _fillLazilyLoadedList(node.constructors, (int tag, int index) { |
| - readConstructor(loader.getClassMemberReference(node, tag, index), tag); |
| - }); |
| + var supertype = readSupertypeOption(); |
| + var mixedInType = readSupertypeOption(); |
| + _fillNonTreeNodeList(node.implementedTypes, readSupertype); |
| + _mergeLinkedNodeList(node.fields, readField, node); |
| + _mergeLinkedNodeList(node.constructors, readConstructor, node); |
| + _mergeLinkedNodeList(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() { |
| @@ -380,58 +394,120 @@ 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(); |
| + Field node = canonicalName.definition; |
| + bool shouldWriteData = node == null || _isReadingLibraryImplementation; |
| + if (node == null) { |
| + node = new Field(null); |
| + canonicalName.linkTo(node); |
| + } |
| + 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(); |
| + Constructor node = canonicalName.definition; |
| + bool shouldWriteData = node == null || _isReadingLibraryImplementation; |
| + if (node == null) { |
| + node = new Constructor(null); |
| + canonicalName.linkTo(node); |
| + } |
| + 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); |
| - _fillTreeNodeList(node.initializers, readInitializer, node); |
| - variableStack.length = 0; |
| - node.transformerFlags = getAndResetTransformerFlags(); |
| + var function = readFunctionNode(); |
| + if (_isReadingLibraryImplementation) { |
| + pushVariableDeclarations(function.positionalParameters); |
| + pushVariableDeclarations(function.namedParameters); |
| + _fillTreeNodeList(node.initializers, readInitializer, node); |
| + variableStack.length = 0; |
| + } else { |
| + // External libraries should not contain constructor initializers. |
| + int numberOfInitializers = readUInt(); |
| + assert(numberOfInitializers == 0); |
| + } |
| + 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(); |
| + Procedure node = canonicalName.definition; |
| + bool shouldWriteData = node == null || _isReadingLibraryImplementation; |
| + if (node == null) { |
| + node = new Procedure(null, null, null); |
| + canonicalName.linkTo(node); |
| + } |
| + 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() { |
| @@ -440,11 +516,13 @@ class BinaryBuilder { |
| case Tag.InvalidInitializer: |
| return new InvalidInitializer(); |
| case Tag.FieldInitializer: |
| - return new FieldInitializer(readMemberReference(), readExpression()); |
| + return new FieldInitializer.byName( |
| + readMemberReference(), readExpression()); |
| case Tag.SuperInitializer: |
| - return new SuperInitializer(readMemberReference(), readArguments()); |
| + return new SuperInitializer.byName( |
| + readMemberReference(), readArguments()); |
| case Tag.RedirectingInitializer: |
| - return new RedirectingInitializer( |
| + return new RedirectingInitializer.byName( |
| readMemberReference(), readArguments()); |
| case Tag.LocalInitializer: |
| return new LocalInitializer(readAndPushVariableDeclaration()); |
| @@ -551,34 +629,38 @@ class BinaryBuilder { |
| ..fileOffset = offset; |
| case Tag.PropertyGet: |
| int offset = readOffset(); |
| - return new PropertyGet( |
| + return new PropertyGet.byName( |
| readExpression(), readName(), readMemberReference(allowNull: true)) |
| ..fileOffset = offset; |
| case Tag.PropertySet: |
| int offset = readOffset(); |
| - return new PropertySet(readExpression(), readName(), readExpression(), |
| + return new PropertySet.byName( |
| + readExpression(), |
| + readName(), |
| + readExpression(), |
| readMemberReference(allowNull: true))..fileOffset = offset; |
| case Tag.SuperPropertyGet: |
| addTransformerFlag(TransformerFlag.superCalls); |
| - return new SuperPropertyGet( |
| + return new SuperPropertyGet.byName( |
| readName(), readMemberReference(allowNull: true)); |
| case Tag.SuperPropertySet: |
| addTransformerFlag(TransformerFlag.superCalls); |
| - return new SuperPropertySet( |
| + return new SuperPropertySet.byName( |
| readName(), readExpression(), readMemberReference(allowNull: true)); |
| case Tag.DirectPropertyGet: |
| - return new DirectPropertyGet(readExpression(), readMemberReference()); |
| + return new DirectPropertyGet.byName( |
| + readExpression(), readMemberReference()); |
| case Tag.DirectPropertySet: |
| - return new DirectPropertySet( |
| + return new DirectPropertySet.byName( |
| readExpression(), readMemberReference(), readExpression()); |
| case Tag.StaticGet: |
| int offset = readOffset(); |
| - return new StaticGet(readMemberReference())..fileOffset = offset; |
| + return new StaticGet.byName(readMemberReference())..fileOffset = offset; |
| case Tag.StaticSet: |
| - return new StaticSet(readMemberReference(), readExpression()); |
| + return new StaticSet.byName(readMemberReference(), readExpression()); |
| case Tag.MethodInvocation: |
| int offset = readOffset(); |
| - return new MethodInvocation( |
| + return new MethodInvocation.byName( |
| readExpression(), |
| readName(), |
| readArguments(), |
| @@ -586,28 +668,32 @@ class BinaryBuilder { |
| case Tag.SuperMethodInvocation: |
| int offset = readOffset(); |
| addTransformerFlag(TransformerFlag.superCalls); |
| - return new SuperMethodInvocation( |
| + return new SuperMethodInvocation.byName( |
| readName(), readArguments(), readMemberReference(allowNull: true)) |
| ..fileOffset = offset; |
| case Tag.DirectMethodInvocation: |
| - return new DirectMethodInvocation( |
| + return new DirectMethodInvocation.byName( |
| readExpression(), readMemberReference(), readArguments()); |
| case Tag.StaticInvocation: |
| int offset = readOffset(); |
| - return new StaticInvocation(readMemberReference(), readArguments(), |
| - isConst: false)..fileOffset = offset; |
| + return new StaticInvocation.byName( |
| + readMemberReference(), readArguments(), isConst: false) |
| + ..fileOffset = offset; |
| case Tag.ConstStaticInvocation: |
| int offset = readOffset(); |
| - return new StaticInvocation(readMemberReference(), readArguments(), |
| - isConst: true)..fileOffset = offset; |
| + return new StaticInvocation.byName( |
| + readMemberReference(), readArguments(), isConst: true) |
| + ..fileOffset = offset; |
| case Tag.ConstructorInvocation: |
| int offset = readOffset(); |
| - return new ConstructorInvocation(readMemberReference(), readArguments(), |
| - isConst: false)..fileOffset = offset; |
| + return new ConstructorInvocation.byName( |
| + readMemberReference(), readArguments(), isConst: false) |
| + ..fileOffset = offset; |
| case Tag.ConstConstructorInvocation: |
| int offset = readOffset(); |
| - return new ConstructorInvocation(readMemberReference(), readArguments(), |
| - isConst: true)..fileOffset = offset; |
| + return new ConstructorInvocation.byName( |
| + readMemberReference(), readArguments(), isConst: true) |
| + ..fileOffset = offset; |
| case Tag.Not: |
| return new Not(readExpression()); |
| case Tag.LogicalExpression: |
| @@ -836,7 +922,7 @@ class BinaryBuilder { |
| Supertype readSupertype() { |
| InterfaceType type = readDartType(); |
| - return new Supertype(type.classNode, type.typeArguments); |
| + return new Supertype.byName(type.className, type.typeArguments); |
| } |
| Supertype readSupertypeOption() { |
| @@ -875,9 +961,11 @@ class BinaryBuilder { |
| case Tag.VoidType: |
| return const VoidType(); |
| case Tag.InterfaceType: |
| - return new InterfaceType(readClassReference(), readDartTypeList()); |
| + return new InterfaceType.byName( |
| + readClassReference(), readDartTypeList()); |
| case Tag.SimpleInterfaceType: |
| - return new InterfaceType(readClassReference(), const <DartType>[]); |
| + return new InterfaceType.byName( |
| + readClassReference(), const <DartType>[]); |
| case Tag.FunctionType: |
| int typeParameterStackHeight = typeParameterStack.length; |
| var typeParameters = readAndPushTypeParameterList(); |
| @@ -909,7 +997,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; |