| Index: pkg/compiler/lib/src/serialization/serialization.dart
|
| diff --git a/pkg/compiler/lib/src/serialization/serialization.dart b/pkg/compiler/lib/src/serialization/serialization.dart
|
| index a2f08a77500483c89662693edd3ea3065b1f60cb..74dd4a09509557d3553e62c595fcb051206306b4 100644
|
| --- a/pkg/compiler/lib/src/serialization/serialization.dart
|
| +++ b/pkg/compiler/lib/src/serialization/serialization.dart
|
| @@ -4,9 +4,10 @@
|
|
|
| library dart2js.serialization;
|
|
|
| -import '../elements/elements.dart';
|
| +import '../common.dart';
|
| import '../constants/expressions.dart';
|
| import '../dart_types.dart';
|
| +import '../elements/elements.dart';
|
| import '../util/enumset.dart';
|
|
|
| import 'constant_serialization.dart';
|
| @@ -686,6 +687,20 @@ class Serializer {
|
| DataObject dataObject = _elementMap[element];
|
| if (dataObject == null) {
|
| if (!shouldInclude(element)) {
|
| + /// Helper used to check that external references are serialized by
|
| + /// the right kind.
|
| + bool verifyElement(var found, var expected) {
|
| + found = found.declaration;
|
| + if (found == expected) return true;
|
| + if (found.isAbstractField && expected.isGetter) {
|
| + return found.getter == expected;
|
| + }
|
| + if (found.isAbstractField && expected.isSetter) {
|
| + return found.setter == expected;
|
| + }
|
| + return false;
|
| + }
|
| +
|
| if (element.isLibrary) {
|
| LibraryElement library = element;
|
| _elementMap[element] = dataObject = new DataObject(
|
| @@ -693,23 +708,47 @@ class Serializer {
|
| new EnumValue(SerializedElementKind.EXTERNAL_LIBRARY));
|
| ObjectEncoder encoder = new ObjectEncoder(this, dataObject.map);
|
| encoder.setUri(Key.URI, library.canonicalUri, library.canonicalUri);
|
| - } else if (element.isStatic) {
|
| + } else if (element.isConstructor) {
|
| + assert(invariant(
|
| + element,
|
| + verifyElement(
|
| + element.enclosingClass.implementation
|
| + .lookupConstructor(element.name),
|
| + element),
|
| + message: "Element $element is not found as a "
|
| + "constructor of ${element.enclosingClass.implementation}."));
|
| Value classId = _getElementId(element.enclosingClass);
|
| _elementMap[element] = dataObject = new DataObject(
|
| new IntValue(_elementMap.length),
|
| - new EnumValue(SerializedElementKind.EXTERNAL_STATIC_MEMBER));
|
| + new EnumValue(SerializedElementKind.EXTERNAL_CONSTRUCTOR));
|
| ObjectEncoder encoder = new ObjectEncoder(this, dataObject.map);
|
| encoder.setValue(Key.CLASS, classId);
|
| encoder.setString(Key.NAME, element.name);
|
| - } else if (element.isConstructor) {
|
| + } else if (element.isClassMember) {
|
| + assert(invariant(
|
| + element,
|
| + verifyElement(
|
| + element.enclosingClass.lookupLocalMember(element.name),
|
| + element),
|
| + message: "Element $element is not found as a "
|
| + "class member of ${element.enclosingClass}."));
|
| Value classId = _getElementId(element.enclosingClass);
|
| _elementMap[element] = dataObject = new DataObject(
|
| new IntValue(_elementMap.length),
|
| - new EnumValue(SerializedElementKind.EXTERNAL_CONSTRUCTOR));
|
| + new EnumValue(SerializedElementKind.EXTERNAL_CLASS_MEMBER));
|
| ObjectEncoder encoder = new ObjectEncoder(this, dataObject.map);
|
| encoder.setValue(Key.CLASS, classId);
|
| encoder.setString(Key.NAME, element.name);
|
| + if (element.isAccessor) {
|
| + encoder.setBool(Key.GETTER, element.isGetter);
|
| + }
|
| } else {
|
| + assert(invariant(
|
| + element,
|
| + verifyElement(
|
| + element.library.implementation.find(element.name), element),
|
| + message: "Element $element is not found as a "
|
| + "library member of ${element.library.implementation}."));
|
| Value libraryId = _getElementId(element.library);
|
| _elementMap[element] = dataObject = new DataObject(
|
| new IntValue(_elementMap.length),
|
| @@ -717,6 +756,9 @@ class Serializer {
|
| ObjectEncoder encoder = new ObjectEncoder(this, dataObject.map);
|
| encoder.setValue(Key.LIBRARY, libraryId);
|
| encoder.setString(Key.NAME, element.name);
|
| + if (element.isAccessor) {
|
| + encoder.setBool(Key.GETTER, element.isGetter);
|
| + }
|
| }
|
| } else {
|
| // Run through [ELEMENT_SERIALIZERS] sequentially to find the one that
|
| @@ -878,19 +920,33 @@ class DeserializerPlugin {
|
|
|
| /// Context for parallel deserialization.
|
| class DeserializationContext {
|
| + final DiagnosticReporter reporter;
|
| Map<Uri, LibraryElement> _uriMap = <Uri, LibraryElement>{};
|
| List<Deserializer> deserializers = <Deserializer>[];
|
| List<DeserializerPlugin> plugins = <DeserializerPlugin>[];
|
|
|
| + DeserializationContext(this.reporter);
|
| +
|
| LibraryElement lookupLibrary(Uri uri) {
|
| return _uriMap.putIfAbsent(uri, () {
|
| + Uri foundUri;
|
| + LibraryElement foundLibrary;
|
| for (Deserializer deserializer in deserializers) {
|
| LibraryElement library = deserializer.lookupLibrary(uri);
|
| if (library != null) {
|
| - return library;
|
| + if (foundLibrary != null) {
|
| + reporter.reportErrorMessage(NO_LOCATION_SPANNABLE,
|
| + MessageKind.DUPLICATE_SERIALIZED_LIBRARY, {
|
| + 'libraryUri': uri,
|
| + 'sourceUri1': foundUri,
|
| + 'sourceUri2': deserializer.sourceUri
|
| + });
|
| + }
|
| + foundUri = deserializer.sourceUri;
|
| + foundLibrary = library;
|
| }
|
| }
|
| - return null;
|
| + return foundLibrary;
|
| });
|
| }
|
| }
|
| @@ -901,6 +957,7 @@ class DeserializationContext {
|
| class Deserializer {
|
| final DeserializationContext context;
|
| final SerializationDecoder decoder;
|
| + final Uri sourceUri;
|
| ObjectDecoder _headerObject;
|
| ListDecoder _elementList;
|
| ListDecoder _typeList;
|
| @@ -909,7 +966,8 @@ class Deserializer {
|
| Map<int, DartType> _typeMap = {};
|
| Map<int, ConstantExpression> _constantMap = {};
|
|
|
| - Deserializer.fromText(this.context, String text, this.decoder) {
|
| + Deserializer.fromText(
|
| + this.context, this.sourceUri, String text, this.decoder) {
|
| _headerObject = new ObjectDecoder(this, decoder.decode(text));
|
| }
|
|
|
| @@ -973,16 +1031,35 @@ class Deserializer {
|
| } else if (elementKind == SerializedElementKind.EXTERNAL_LIBRARY_MEMBER) {
|
| LibraryElement library = decoder.getElement(Key.LIBRARY);
|
| String name = decoder.getString(Key.NAME);
|
| + bool isGetter = decoder.getBool(Key.GETTER, isOptional: true);
|
| element = library.find(name);
|
| if (element == null) {
|
| throw new StateError("Missing library member for $name in $library.");
|
| }
|
| - } else if (elementKind == SerializedElementKind.EXTERNAL_STATIC_MEMBER) {
|
| + if (isGetter != null) {
|
| + AbstractFieldElement abstractField = element;
|
| + element = isGetter ? abstractField.getter : abstractField.setter;
|
| + if (element == null) {
|
| + throw new StateError(
|
| + "Missing ${isGetter ? 'getter' : 'setter'} for "
|
| + "$name in $library.");
|
| + }
|
| + }
|
| + } else if (elementKind == SerializedElementKind.EXTERNAL_CLASS_MEMBER) {
|
| ClassElement cls = decoder.getElement(Key.CLASS);
|
| String name = decoder.getString(Key.NAME);
|
| + bool isGetter = decoder.getBool(Key.GETTER, isOptional: true);
|
| element = cls.lookupLocalMember(name);
|
| if (element == null) {
|
| - throw new StateError("Missing static member for $name in $cls.");
|
| + throw new StateError("Missing class member for $name in $cls.");
|
| + }
|
| + if (isGetter != null) {
|
| + AbstractFieldElement abstractField = element;
|
| + element = isGetter ? abstractField.getter : abstractField.setter;
|
| + if (element == null) {
|
| + throw new StateError(
|
| + "Missing ${isGetter ? 'getter' : 'setter'} for $name in $cls.");
|
| + }
|
| }
|
| } else if (elementKind == SerializedElementKind.EXTERNAL_CONSTRUCTOR) {
|
| ClassElement cls = decoder.getElement(Key.CLASS);
|
|
|