OLD | NEW |
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 library dart2js.serialization; | 5 library dart2js.serialization; |
6 | 6 |
7 import '../elements/elements.dart'; | 7 import '../elements/elements.dart'; |
8 import '../constants/expressions.dart'; | 8 import '../constants/expressions.dart'; |
9 import '../dart_types.dart'; | 9 import '../dart_types.dart'; |
10 import '../util/enumset.dart'; | 10 import '../util/enumset.dart'; |
11 | 11 |
12 import 'constant_serialization.dart'; | 12 import 'constant_serialization.dart'; |
13 import 'element_serialization.dart'; | 13 import 'element_serialization.dart'; |
14 import 'json_serializer.dart'; | 14 import 'json_serializer.dart'; |
15 import 'keys.dart'; | 15 import 'keys.dart'; |
16 import 'type_serialization.dart'; | 16 import 'type_serialization.dart'; |
17 import 'values.dart'; | 17 import 'values.dart'; |
18 | 18 |
19 export 'task.dart' show LibraryDeserializer; | 19 export 'task.dart' show LibraryDeserializer; |
20 | 20 |
21 /// An object that supports the encoding an [ObjectValue] for serialization. | 21 /// An object that supports the encoding an [ObjectValue] for serialization. |
22 /// | 22 /// |
23 /// The [ObjectEncoder] ensures that nominality and circularities of | 23 /// The [ObjectEncoder] ensures that nominality and circularities of |
24 /// non-primitive values like [Element], [DartType] and [ConstantExpression] are | 24 /// non-primitive values like [Element], [DartType] and [ConstantExpression] are |
25 /// handled. | 25 /// handled. |
26 class ObjectEncoder extends AbstractEncoder<Key> { | 26 class ObjectEncoder extends AbstractEncoder<Key> { |
27 /// Creates an [ObjectEncoder] in the scope of [serializer] that uses [map] | 27 /// Creates an [ObjectEncoder] in the scope of [serializer] that uses [map] |
28 /// as its internal storage. | 28 /// as its internal storage. |
29 ObjectEncoder(Serializer serializer, Map<dynamic, Value> map) | 29 ObjectEncoder(Serializer serializer, Map<dynamic, Value> map) |
30 : super(serializer, map); | 30 : super(serializer, map); |
31 | 31 |
32 String get _name => 'Object'; | 32 String get _name => 'Object'; |
33 } | 33 } |
34 | 34 |
35 /// An object that supports the encoding a [MapValue] for serialization. | 35 /// An object that supports the encoding a [MapValue] for serialization. |
36 /// | 36 /// |
37 /// The [MapEncoder] ensures that nominality and circularities of | 37 /// The [MapEncoder] ensures that nominality and circularities of |
38 /// non-primitive values like [Element], [DartType] and [ConstantExpression] are | 38 /// non-primitive values like [Element], [DartType] and [ConstantExpression] are |
39 /// handled. | 39 /// handled. |
40 class MapEncoder extends AbstractEncoder<String> { | 40 class MapEncoder extends AbstractEncoder<String> { |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
90 throw new StateError("$_name value '$key' already in $_map."); | 90 throw new StateError("$_name value '$key' already in $_map."); |
91 } | 91 } |
92 } | 92 } |
93 | 93 |
94 /// Maps the [key] entry to the [value] in the encoded object. | 94 /// Maps the [key] entry to the [value] in the encoded object. |
95 void setValue(K key, Value value) { | 95 void setValue(K key, Value value) { |
96 _checkKey(key); | 96 _checkKey(key); |
97 _map[key] = value; | 97 _map[key] = value; |
98 } | 98 } |
99 | 99 |
100 | |
101 /// Maps the [key] entry to the enum [value] in the encoded object. | 100 /// Maps the [key] entry to the enum [value] in the encoded object. |
102 void setEnum(K key, var value) { | 101 void setEnum(K key, var value) { |
103 _checkKey(key); | 102 _checkKey(key); |
104 _map[key] = new EnumValue(value); | 103 _map[key] = new EnumValue(value); |
105 } | 104 } |
106 | 105 |
107 /// Maps the [key] entry to the set of enum [values] in the encoded object. | 106 /// Maps the [key] entry to the set of enum [values] in the encoded object. |
108 void setEnums(K key, Iterable values) { | 107 void setEnums(K key, Iterable values) { |
109 setEnumSet(key, new EnumSet.fromValues(values)); | 108 setEnumSet(key, new EnumSet.fromValues(values)); |
110 } | 109 } |
111 | 110 |
112 /// Maps the [key] entry to the enum [set] in the encoded object. | 111 /// Maps the [key] entry to the enum [set] in the encoded object. |
113 void setEnumSet(K key, EnumSet set) { | 112 void setEnumSet(K key, EnumSet set) { |
114 _checkKey(key); | 113 _checkKey(key); |
115 _map[key] = new IntValue(set.value); | 114 _map[key] = new IntValue(set.value); |
116 } | 115 } |
117 | 116 |
118 /// Maps the [key] entry to the [element] in the encoded object. | 117 /// Maps the [key] entry to the [element] in the encoded object. |
119 void setElement(K key, Element element) { | 118 void setElement(K key, Element element) { |
120 _checkKey(key); | 119 _checkKey(key); |
121 _map[key] = _serializer.createElementValue(element); | 120 _map[key] = _serializer.createElementValue(element); |
122 } | 121 } |
123 | 122 |
124 /// Maps the [key] entry to the [elements] in the encoded object. | 123 /// Maps the [key] entry to the [elements] in the encoded object. |
125 /// | 124 /// |
126 /// If [elements] is empty, it is skipped. | 125 /// If [elements] is empty, it is skipped. |
127 void setElements(K key, Iterable<Element> elements) { | 126 void setElements(K key, Iterable<Element> elements) { |
128 _checkKey(key); | 127 _checkKey(key); |
129 if (elements.isNotEmpty) { | 128 if (elements.isNotEmpty) { |
130 _map[key] = new ListValue( | 129 _map[key] = |
131 elements.map(_serializer.createElementValue).toList()); | 130 new ListValue(elements.map(_serializer.createElementValue).toList()); |
132 } | 131 } |
133 } | 132 } |
134 | 133 |
135 /// Maps the [key] entry to the [constant] in the encoded object. | 134 /// Maps the [key] entry to the [constant] in the encoded object. |
136 void setConstant(K key, ConstantExpression constant) { | 135 void setConstant(K key, ConstantExpression constant) { |
137 _checkKey(key); | 136 _checkKey(key); |
138 _map[key] = _serializer.createConstantValue(constant); | 137 _map[key] = _serializer.createConstantValue(constant); |
139 } | 138 } |
140 | 139 |
141 /// Maps the [key] entry to the [constants] in the encoded object. | 140 /// Maps the [key] entry to the [constants] in the encoded object. |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
245 } | 244 } |
246 | 245 |
247 String toString() => _map.toString(); | 246 String toString() => _map.toString(); |
248 } | 247 } |
249 | 248 |
250 /// [ObjectDecoder] reads serialized values from a [Map] encoded from an | 249 /// [ObjectDecoder] reads serialized values from a [Map] encoded from an |
251 /// [ObjectValue] where properties are stored using [Key] values as keys. | 250 /// [ObjectValue] where properties are stored using [Key] values as keys. |
252 class ObjectDecoder extends AbstractDecoder<Key> { | 251 class ObjectDecoder extends AbstractDecoder<Key> { |
253 /// Creates an [ObjectDecoder] that decodes [map] into deserialized values | 252 /// Creates an [ObjectDecoder] that decodes [map] into deserialized values |
254 /// using [deserializer] to create canonicalized values. | 253 /// using [deserializer] to create canonicalized values. |
255 ObjectDecoder(Deserializer deserializer, Map map) | 254 ObjectDecoder(Deserializer deserializer, Map map) : super(deserializer, map); |
256 : super(deserializer, map); | |
257 | 255 |
258 @override | 256 @override |
259 _getKeyValue(Key key) => _deserializer.decoder.getObjectPropertyValue(key); | 257 _getKeyValue(Key key) => _deserializer.decoder.getObjectPropertyValue(key); |
260 } | 258 } |
261 | 259 |
262 /// [MapDecoder] reads serialized values from a [Map] encoded from an | 260 /// [MapDecoder] reads serialized values from a [Map] encoded from an |
263 /// [MapValue] where entries are stored using [String] values as keys. | 261 /// [MapValue] where entries are stored using [String] values as keys. |
264 class MapDecoder extends AbstractDecoder<String> { | 262 class MapDecoder extends AbstractDecoder<String> { |
265 /// Creates an [MapDecoder] that decodes [map] into deserialized values | 263 /// Creates an [MapDecoder] that decodes [map] into deserialized values |
266 /// using [deserializer] to create canonicalized values. | 264 /// using [deserializer] to create canonicalized values. |
(...skipping 421 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
688 if (dataObject == null) { | 686 if (dataObject == null) { |
689 if (!shouldInclude(element)) { | 687 if (!shouldInclude(element)) { |
690 if (element.isLibrary) { | 688 if (element.isLibrary) { |
691 LibraryElement library = element; | 689 LibraryElement library = element; |
692 _elementMap[element] = dataObject = new DataObject( | 690 _elementMap[element] = dataObject = new DataObject( |
693 new IntValue(_elementMap.length), | 691 new IntValue(_elementMap.length), |
694 new EnumValue(SerializedElementKind.EXTERNAL_LIBRARY)); | 692 new EnumValue(SerializedElementKind.EXTERNAL_LIBRARY)); |
695 ObjectEncoder encoder = new ObjectEncoder(this, dataObject.map); | 693 ObjectEncoder encoder = new ObjectEncoder(this, dataObject.map); |
696 encoder.setUri(Key.URI, library.canonicalUri, library.canonicalUri); | 694 encoder.setUri(Key.URI, library.canonicalUri, library.canonicalUri); |
697 } else if (element.isStatic) { | 695 } else if (element.isStatic) { |
698 Value classId =_getElementId(element.enclosingClass); | 696 Value classId = _getElementId(element.enclosingClass); |
699 _elementMap[element] = dataObject = new DataObject( | 697 _elementMap[element] = dataObject = new DataObject( |
700 new IntValue(_elementMap.length), | 698 new IntValue(_elementMap.length), |
701 new EnumValue(SerializedElementKind.EXTERNAL_STATIC_MEMBER)); | 699 new EnumValue(SerializedElementKind.EXTERNAL_STATIC_MEMBER)); |
702 ObjectEncoder encoder = new ObjectEncoder(this, dataObject.map); | 700 ObjectEncoder encoder = new ObjectEncoder(this, dataObject.map); |
703 encoder.setValue(Key.CLASS, classId); | 701 encoder.setValue(Key.CLASS, classId); |
704 encoder.setString(Key.NAME, element.name); | 702 encoder.setString(Key.NAME, element.name); |
705 } else if (element.isConstructor) { | 703 } else if (element.isConstructor) { |
706 Value classId =_getElementId(element.enclosingClass); | 704 Value classId = _getElementId(element.enclosingClass); |
707 _elementMap[element] = dataObject = new DataObject( | 705 _elementMap[element] = dataObject = new DataObject( |
708 new IntValue(_elementMap.length), | 706 new IntValue(_elementMap.length), |
709 new EnumValue(SerializedElementKind.EXTERNAL_CONSTRUCTOR)); | 707 new EnumValue(SerializedElementKind.EXTERNAL_CONSTRUCTOR)); |
710 ObjectEncoder encoder = new ObjectEncoder(this, dataObject.map); | 708 ObjectEncoder encoder = new ObjectEncoder(this, dataObject.map); |
711 encoder.setValue(Key.CLASS, classId); | 709 encoder.setValue(Key.CLASS, classId); |
712 encoder.setString(Key.NAME, element.name); | 710 encoder.setString(Key.NAME, element.name); |
713 } else { | 711 } else { |
714 Value libraryId =_getElementId(element.library); | 712 Value libraryId = _getElementId(element.library); |
715 _elementMap[element] = dataObject = new DataObject( | 713 _elementMap[element] = dataObject = new DataObject( |
716 new IntValue(_elementMap.length), | 714 new IntValue(_elementMap.length), |
717 new EnumValue(SerializedElementKind.EXTERNAL_LIBRARY_MEMBER)); | 715 new EnumValue(SerializedElementKind.EXTERNAL_LIBRARY_MEMBER)); |
718 ObjectEncoder encoder = new ObjectEncoder(this, dataObject.map); | 716 ObjectEncoder encoder = new ObjectEncoder(this, dataObject.map); |
719 encoder.setValue(Key.LIBRARY, libraryId); | 717 encoder.setValue(Key.LIBRARY, libraryId); |
720 encoder.setString(Key.NAME, element.name); | 718 encoder.setString(Key.NAME, element.name); |
721 } | 719 } |
722 } else { | 720 } else { |
723 // Run through [ELEMENT_SERIALIZERS] sequentially to find the one that | 721 // Run through [ELEMENT_SERIALIZERS] sequentially to find the one that |
724 // deals with [element]. | 722 // deals with [element]. |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
773 new IntValue(_constantMap.length), new EnumValue(constant.kind)); | 771 new IntValue(_constantMap.length), new EnumValue(constant.kind)); |
774 // Delay the serialization of the constant itself to avoid loops, and to | 772 // Delay the serialization of the constant itself to avoid loops, and to |
775 // keep the call stack small. | 773 // keep the call stack small. |
776 _pendingList.add(() => _encodeConstant(constant, dataObject)); | 774 _pendingList.add(() => _encodeConstant(constant, dataObject)); |
777 return dataObject; | 775 return dataObject; |
778 }).id; | 776 }).id; |
779 } | 777 } |
780 | 778 |
781 /// Encodes [constant] into the [ObjectValue] of [dataObject]. | 779 /// Encodes [constant] into the [ObjectValue] of [dataObject]. |
782 void _encodeConstant(ConstantExpression constant, DataObject dataObject) { | 780 void _encodeConstant(ConstantExpression constant, DataObject dataObject) { |
783 const ConstantSerializer().visit(constant, | 781 const ConstantSerializer() |
784 new ObjectEncoder(this, dataObject.map)); | 782 .visit(constant, new ObjectEncoder(this, dataObject.map)); |
785 } | 783 } |
786 | 784 |
787 /// Creates the [ConstantValue] for [constant]. | 785 /// Creates the [ConstantValue] for [constant]. |
788 /// | 786 /// |
789 /// If [constant] has not already been serialized, it is added to the work | 787 /// If [constant] has not already been serialized, it is added to the work |
790 /// queue of this serializer. | 788 /// queue of this serializer. |
791 ConstantValue createConstantValue(ConstantExpression constant) { | 789 ConstantValue createConstantValue(ConstantExpression constant) { |
792 return new ConstantValue(constant, _getConstantId(constant)); | 790 return new ConstantValue(constant, _getConstantId(constant)); |
793 } | 791 } |
794 | 792 |
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
990 } else { | 988 } else { |
991 element = ElementDeserializer.deserialize(decoder, elementKind); | 989 element = ElementDeserializer.deserialize(decoder, elementKind); |
992 } | 990 } |
993 _elementMap[id] = element; | 991 _elementMap[id] = element; |
994 | 992 |
995 MapDecoder pluginData = decoder.getMap(Key.DATA, isOptional: true); | 993 MapDecoder pluginData = decoder.getMap(Key.DATA, isOptional: true); |
996 // Call plugins even when there is no data, so they can take action in | 994 // Call plugins even when there is no data, so they can take action in |
997 // this case. | 995 // this case. |
998 for (DeserializerPlugin plugin in plugins) { | 996 for (DeserializerPlugin plugin in plugins) { |
999 plugin.onElement(element, | 997 plugin.onElement(element, |
1000 (String tag) => pluginData?.getObject(tag, isOptional: true)); | 998 (String tag) => pluginData?.getObject(tag, isOptional: true)); |
1001 } | 999 } |
1002 } | 1000 } |
1003 return element; | 1001 return element; |
1004 } | 1002 } |
1005 | 1003 |
1006 /// Returns the deserialized [DartType] for [id]. | 1004 /// Returns the deserialized [DartType] for [id]. |
1007 DartType deserializeType(int id) { | 1005 DartType deserializeType(int id) { |
1008 if (id == null) throw new ArgumentError('Deserializer.getType(null)'); | 1006 if (id == null) throw new ArgumentError('Deserializer.getType(null)'); |
1009 return _typeMap.putIfAbsent(id, () { | 1007 return _typeMap.putIfAbsent(id, () { |
1010 return TypeDeserializer.deserialize(types.getObject(id)); | 1008 return TypeDeserializer.deserialize(types.getObject(id)); |
(...skipping 24 matching lines...) Expand all Loading... |
1035 | 1033 |
1036 /// Returns the value used to store [key] as a property in the encoding an | 1034 /// Returns the value used to store [key] as a property in the encoding an |
1037 /// [ObjectValue]. | 1035 /// [ObjectValue]. |
1038 /// | 1036 /// |
1039 /// Different encodings have different restrictions and capabilities as how | 1037 /// Different encodings have different restrictions and capabilities as how |
1040 /// to store a [Key] value. For instance: A JSON encoding needs to convert | 1038 /// to store a [Key] value. For instance: A JSON encoding needs to convert |
1041 /// [Key] to a [String] to store it in a JSON object; a Dart encoding can | 1039 /// [Key] to a [String] to store it in a JSON object; a Dart encoding can |
1042 /// choose to store a [Key] as an [int] or as the [Key] itself. | 1040 /// choose to store a [Key] as an [int] or as the [Key] itself. |
1043 getObjectPropertyValue(Key key); | 1041 getObjectPropertyValue(Key key); |
1044 } | 1042 } |
OLD | NEW |