Chromium Code Reviews| 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..9beb44055dd83077b91f211d9fbc3f4c84a70c75 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,21 @@ 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 +709,44 @@ 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 +754,9 @@ class Serializer { |
| ObjectEncoder encoder = new ObjectEncoder(this, dataObject.map); |
| encoder.setValue(Key.LIBRARY, libraryId); |
| encoder.setString(Key.NAME, element.name); |
| + if (element.isAccessor) { |
|
Siggi Cherem (dart-lang)
2016/05/24 18:08:15
are the changes about Key.GETTER needed for suppor
Johnni Winther
2016/05/25 07:54:46
These are needed. It turned out that because of th
|
| + encoder.setBool(Key.GETTER, element.isGetter); |
| + } |
| } |
| } else { |
| // Run through [ELEMENT_SERIALIZERS] sequentially to find the one that |
| @@ -878,19 +918,30 @@ 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}); |
|
Siggi Cherem (dart-lang)
2016/05/24 18:08:15
dartfmt
Johnni Winther
2016/05/25 07:54:46
Done.
|
| + } |
| + foundUri = deserializer.sourceUri; |
| + foundLibrary = library; |
| } |
| } |
| - return null; |
| + return foundLibrary; |
| }); |
| } |
| } |
| @@ -901,6 +952,7 @@ class DeserializationContext { |
| class Deserializer { |
| final DeserializationContext context; |
| final SerializationDecoder decoder; |
| + final Uri sourceUri; |
| ObjectDecoder _headerObject; |
| ListDecoder _elementList; |
| ListDecoder _typeList; |
| @@ -909,7 +961,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 +1026,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); |