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