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); |