Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 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 | |
| 3 // BSD-style license that can be found in the LICENSE file. | |
| 4 | |
| 5 library dart2js.serialization; | |
| 6 | |
| 7 import '../elements/elements.dart'; | |
| 8 import '../constants/expressions.dart'; | |
| 9 import '../dart_types.dart'; | |
| 10 | |
| 11 import 'element_serialization.dart'; | |
| 12 import 'constant_serialization.dart'; | |
| 13 import 'type_serialization.dart'; | |
| 14 import 'keys.dart'; | |
| 15 import 'json_serializer.dart'; | |
| 16 import 'values.dart'; | |
| 17 | |
| 18 /// Abstract base interface for [ObjectSerializer] and [MapSerializer]. | |
|
floitsch
2015/06/26 20:54:05
Misses documentation.
Johnni Winther
2015/07/03 12:13:45
Done.
| |
| 19 abstract class AbstractSerializer<K> { | |
| 20 /// Maps the [key] entry to the enum [value] in this serializer. | |
| 21 void setEnum(K key, var value); | |
| 22 | |
| 23 /// Maps the [key] entry to the [element] in this serializer. | |
| 24 void setElement(K key, Element element); | |
| 25 | |
| 26 /// Maps the [key] entry to the [elements] in this serializer. | |
| 27 /// | |
| 28 /// If [elements] is empty, it is skipped. | |
| 29 void setElements(K key, Iterable<Element> elements); | |
| 30 | |
| 31 /// Maps the [key] entry to the [constant] in this serializer. | |
| 32 void setConstant(K key, ConstantExpression constant); | |
| 33 | |
| 34 /// Maps the [key] entry to the [constants] in this serializer. | |
| 35 /// | |
| 36 /// If [constants] is empty, it is skipped. | |
| 37 void setConstants(K key, Iterable<ConstantExpression> constants); | |
| 38 | |
| 39 /// Maps the [key] entry to the [type] in this serializer. | |
| 40 void setType(K key, DartType type); | |
| 41 | |
| 42 /// Maps the [key] entry to the [types] in this serializer. | |
| 43 /// | |
| 44 /// If [types] is empty, it is skipped. | |
| 45 void setTypes(K key, Iterable<DartType> types); | |
| 46 | |
| 47 /// Maps the [key] entry to the [uri] in this serializer using [baseUri] to | |
| 48 /// relatives the encoding. | |
| 49 /// | |
| 50 /// For instance, a source file like `sdk/lib/core/string.dart` should be | |
| 51 /// serialized relative to the library root. | |
| 52 void setUri(K key, Uri baseUri, Uri uri); | |
| 53 | |
| 54 /// Maps the [key] entry to the string [value] in this serializer. | |
| 55 void setString(K key, String value); | |
| 56 | |
| 57 /// Maps the [key] entry to the string [values] in this serializer. | |
| 58 /// | |
| 59 /// If [values] is empty, it is skipped. | |
| 60 void setStrings(K key, Iterable<String> values); | |
| 61 | |
| 62 /// Maps the [key] entry to the bool [value] in this serializer. | |
| 63 void setBool(K key, bool value); | |
| 64 | |
| 65 /// Maps the [key] entry to the int [value] in this serializer. | |
| 66 void setInt(K key, int value); | |
| 67 | |
| 68 /// Maps the [key] entry to the int [values] in this serializer. | |
| 69 /// | |
| 70 /// If [values] is empty, it is skipped. | |
| 71 void setInts(K key, Iterable<int> values); | |
| 72 | |
| 73 /// Maps the [key] entry to the double [value] in this serializer. | |
| 74 void setDouble(K key, double value); | |
| 75 | |
| 76 /// Creates and returns an [ObjectSerializer] that is mapped to the [key] | |
| 77 /// entry in this serializer. | |
| 78 ObjectSerializer createObject(K key); | |
| 79 | |
| 80 /// Creates and returns a [MapSerializer] that is mapped to the [key] entry in | |
| 81 /// this serializer. | |
| 82 MapSerializer createMap(K key); | |
| 83 | |
| 84 /// Creates and returns a [ListSerializer] that is mapped to the [key] entry | |
| 85 /// in this serializer. | |
| 86 ListSerializer createList(K key); | |
| 87 } | |
| 88 | |
| 89 /// A serializer that associates values with [Key]s. | |
|
floitsch
2015/06/26 20:54:05
Documentation.
Johnni Winther
2015/07/03 12:13:45
Done.
| |
| 90 abstract class ObjectSerializer implements AbstractSerializer<Key> { | |
| 91 | |
| 92 } | |
| 93 | |
| 94 /// A serializer that associates values with [String]s. | |
| 95 abstract class MapSerializer implements AbstractSerializer<String> { | |
| 96 | |
| 97 } | |
| 98 | |
| 99 /// A serializer that contains a list of [ObjectSerializer]s or | |
| 100 /// [MapSerializer]s. | |
|
floitsch
2015/06/26 20:54:05
this doesn't help.
Why would I have a list of Obje
Johnni Winther
2015/07/03 12:13:45
Done.
| |
| 101 abstract class ListSerializer { | |
| 102 /// Creates an [ObjectSerializer] and adds it to this serializer. | |
| 103 ObjectSerializer createObject(); | |
| 104 | |
| 105 /// Creates an [ObjectSerializer] and adds it to this serializer. | |
| 106 MapSerializer createMap(); | |
| 107 } | |
| 108 | |
| 109 /// Abstract base interface for [ObjectDeserializer] and [MapDeserializer]. | |
| 110 abstract class AbstractDeserializer<K> { | |
| 111 /// Returns `true` if [key] has an associated value in this deserializer. | |
| 112 bool containsKey(K key); | |
| 113 | |
| 114 /// Returns the enum value from the [enumValues] associated with [key] in this | |
| 115 /// deserializer. | |
| 116 /// | |
| 117 /// If no value is associated with [key], then if [isOptional] is `true`, | |
| 118 /// [defaultValue] is returned, otherwise an exception is thrown. | |
| 119 getEnum(K key, Iterable enumValues, {bool isOptional: false, defaultValue}); | |
| 120 | |
| 121 /// Returns the [Element] value associated with [key] in this deserializer. | |
| 122 /// | |
| 123 /// If no value is associated with [key], then if [isOptional] is `true`, | |
| 124 /// `null` is returned, otherwise an exception is thrown. | |
| 125 Element getElement(K key, {bool isOptional: false}); | |
| 126 | |
| 127 /// Returns the list of [Element] values associated with [key] in this | |
| 128 /// deserializer. | |
| 129 /// | |
| 130 /// If no value is associated with [key], then if [isOptional] is `true`, | |
| 131 /// and empty [List] is returned, otherwise an exception is thrown. | |
| 132 List<Element> getElements(K key, {bool isOptional: false}); | |
| 133 | |
| 134 /// Returns the [ConstantExpression] value associated with [key] in this | |
| 135 /// deserializer. | |
| 136 /// | |
| 137 /// If no value is associated with [key], then if [isOptional] is `true`, | |
| 138 /// `null` is returned, otherwise an exception is thrown. | |
| 139 ConstantExpression getConstant(K key, {bool isOptional: false}); | |
| 140 | |
| 141 /// Returns the list of [ConstantExpression] values associated with [key] in | |
| 142 /// this deserializer. | |
| 143 /// | |
| 144 /// If no value is associated with [key], then if [isOptional] is `true`, | |
| 145 /// and empty [List] is returned, otherwise an exception is thrown. | |
| 146 List<ConstantExpression> getConstants(K key, {bool isOptional: false}); | |
| 147 | |
| 148 /// Returns the [DartType] value associated with [key] in this deserializer. | |
| 149 /// | |
| 150 /// If no value is associated with [key], then if [isOptional] is `true`, | |
| 151 /// `null` is returned, otherwise an exception is thrown. | |
| 152 DartType getType(K key, {bool isOptional: false}); | |
| 153 | |
| 154 /// Returns the list of [DartType] values associated with [key] in this | |
| 155 /// deserializer. | |
| 156 /// | |
| 157 /// If no value is associated with [key], then if [isOptional] is `true`, | |
| 158 /// and empty [List] is returned, otherwise an exception is thrown. | |
| 159 List<DartType> getTypes(K key, {bool isOptional: false}); | |
| 160 | |
| 161 /// Returns the [Uri] value associated with [key] in this deserializer. | |
| 162 /// | |
| 163 /// If no value is associated with [key], then if [isOptional] is `true`, | |
| 164 /// [defaultValue] is returned, otherwise an exception is thrown. | |
| 165 Uri getUri(K key, {bool isOptional: false, Uri defaultValue}); | |
| 166 | |
| 167 /// Returns the [String] value associated with [key] in this deserializer. | |
| 168 /// | |
| 169 /// If no value is associated with [key], then if [isOptional] is `true`, | |
| 170 /// [defaultValue] is returned, otherwise an exception is thrown. | |
| 171 String getString(K key, {bool isOptional: false, String defaultValue}); | |
| 172 | |
| 173 /// Returns the list of [String] values associated with [key] in this | |
| 174 /// deserializer. | |
| 175 /// | |
| 176 /// If no value is associated with [key], then if [isOptional] is `true`, | |
| 177 /// and empty [List] is returned, otherwise an exception is thrown. | |
| 178 List<String> getStrings(K key, {bool isOptional: false}); | |
| 179 | |
| 180 /// Returns the [bool] value associated with [key] in this deserializer. | |
| 181 /// | |
| 182 /// If no value is associated with [key], then if [isOptional] is `true`, | |
| 183 /// [defaultValue] is returned, otherwise an exception is thrown. | |
| 184 bool getBool(K key, {bool isOptional: false, bool defaultValue}); | |
| 185 | |
| 186 /// Returns the [int] value associated with [key] in this deserializer. | |
| 187 /// | |
| 188 /// If no value is associated with [key], then if [isOptional] is `true`, | |
| 189 /// [defaultValue] is returned, otherwise an exception is thrown. | |
| 190 int getInt(K key, {bool isOptional: false, int defaultValue}); | |
| 191 | |
| 192 /// Returns the list of [int] values associated with [key] in this | |
| 193 /// deserializer. | |
| 194 /// | |
| 195 /// If no value is associated with [key], then if [isOptional] is `true`, | |
| 196 /// and empty [List] is returned, otherwise an exception is thrown. | |
| 197 List<int> getInts(K key, {bool isOptional: false}); | |
| 198 | |
| 199 /// Returns the [double] value associated with [key] in this deserializer. | |
| 200 /// | |
| 201 /// If no value is associated with [key], then if [isOptional] is `true`, | |
| 202 /// [defaultValue] is returned, otherwise an exception is thrown. | |
| 203 double getDouble(K key, {bool isOptional: false, double defaultValue}); | |
| 204 | |
| 205 /// Returns an [ObjectDeserializer] for the map value associated with [key] in | |
| 206 /// this deserializer. | |
| 207 /// | |
| 208 /// If no value is associated with [key], then if [isOptional] is `true`, | |
| 209 /// `null` is returned, otherwise an exception is thrown. | |
| 210 ObjectDeserializer getObject(K key, {bool isOptional: false}); | |
| 211 | |
| 212 /// Returns an [MapDeserializer] for the map value associated with [key] in | |
| 213 /// this deserializer. | |
| 214 /// | |
| 215 /// If no value is associated with [key], then if [isOptional] is `true`, | |
| 216 /// `null` is returned, otherwise an exception is thrown. | |
| 217 MapDeserializer getMap(K key, {bool isOptional: false}); | |
| 218 | |
| 219 /// Returns an [ListDeserializer] for the list value associated with [key] in | |
| 220 /// this deserializer. | |
| 221 /// | |
| 222 /// If no value is associated with [key], then if [isOptional] is `true`, | |
| 223 /// `null` is returned, otherwise an exception is thrown. | |
| 224 ListDeserializer getList(K key, {bool isOptional: false}); | |
| 225 } | |
| 226 | |
| 227 /// A deserializer where values are associated with [Key]s. | |
| 228 abstract class ObjectDeserializer implements AbstractDeserializer<Key> { | |
| 229 | |
| 230 } | |
| 231 | |
| 232 /// A deserializer where values are associated with [String]s. | |
| 233 abstract class MapDeserializer implements AbstractDeserializer<String> { | |
| 234 /// Applies [f] to every key in the deserializer. | |
| 235 void forEachKey(f(String key)); | |
| 236 } | |
| 237 | |
| 238 /// A deserializer of a list of map values. | |
|
floitsch
2015/06/26 20:54:05
what "map" values?
Johnni Winther
2015/07/03 12:13:45
Done.
| |
| 239 abstract class ListDeserializer { | |
| 240 /// The number of values in this deserializer. | |
| 241 int get length; | |
| 242 | |
| 243 /// Returns an [ObjectDeserializer] for the [index]th map value in | |
| 244 /// this deserializer. | |
| 245 ObjectDeserializer getObject(int index); | |
| 246 | |
| 247 /// Returns an [MapDeserializer] for the [index]th map value in | |
| 248 /// this deserializer. | |
| 249 MapDeserializer getMap(int index); | |
| 250 } | |
| 251 | |
| 252 /// A nominal object containing its serialized value. | |
| 253 abstract class DataObject { | |
| 254 /// The id for the object. | |
| 255 get id; | |
| 256 | |
| 257 /// The serialized value of the object. | |
| 258 ObjectValue get objectValue; | |
| 259 } | |
| 260 | |
| 261 /// Serializer for the transitive closure of a collection of libraries. | |
| 262 // TODO(johnniwinther): Support per-library serialization and dependencies | |
| 263 // between serialized subcomponent. | |
| 264 class Serializer { | |
| 265 final SerializationEncoder _encoder; | |
| 266 | |
| 267 Map<Element, DataObject> _elementMap = <Element, DataObject>{}; | |
| 268 Map<ConstantExpression, DataObject> _constantMap = | |
| 269 <ConstantExpression, DataObject>{}; | |
| 270 Map<DartType, DataObject> _typeMap = <DartType, DataObject>{}; | |
| 271 List _pendingList = []; | |
| 272 | |
| 273 Serializer(this._encoder); | |
| 274 | |
| 275 /// Add the transitive closure of [library] to this serializer. | |
| 276 void serialize(LibraryElement library) { | |
| 277 _getElementValue(library); | |
|
floitsch
2015/06/26 20:54:05
Add comment, why we don't care for the ElementValu
Johnni Winther
2015/07/03 12:13:45
Done.
| |
| 278 _emptyWorklist(); | |
| 279 } | |
| 280 | |
| 281 void _emptyWorklist() { | |
| 282 while (_pendingList.isNotEmpty) { | |
| 283 _pendingList.removeLast()(); | |
| 284 } | |
| 285 } | |
| 286 | |
| 287 DataObject _createDataObject(IntValue id, EnumValue kind) { | |
| 288 return _encoder.createDataObject(id, kind); | |
| 289 } | |
| 290 | |
| 291 ObjectSerializer _createObjectSerializer(Serializer serializer, | |
| 292 DataObject dataObject) { | |
| 293 return _encoder.createObjectSerializer(serializer, dataObject); | |
| 294 } | |
| 295 | |
| 296 DataObject _getElementData(Element element) { | |
| 297 if (element == null) { | |
| 298 throw new ArgumentError('Serializer._getElementData(null)'); | |
| 299 } | |
| 300 return _elementMap.putIfAbsent(element, () { | |
| 301 for (ElementSerializer serializer in ELEMENT_SERIALIZERS) { | |
| 302 SerializedElementKind kind = serializer.getSerializedKind(element); | |
| 303 if (kind != null) { | |
| 304 DataObject dataObject = _createDataObject( | |
| 305 new IntValue(_elementMap.length), new EnumValue(kind)); | |
| 306 _pendingList.add(() { | |
| 307 serializer.serialize( | |
|
floitsch
2015/06/26 20:54:05
Ideally (especially if we decide not to use the en
Johnni Winther
2015/07/03 12:13:45
You would need to pass the [Serializer] around the
| |
| 308 element, _createObjectSerializer(this, dataObject), kind); | |
| 309 }); | |
| 310 return dataObject; | |
| 311 } | |
| 312 } | |
| 313 throw new UnsupportedError( | |
| 314 'Unsupported element: $element (${element.kind})'); | |
| 315 }); | |
| 316 } | |
| 317 | |
| 318 ElementValue _getElementValue(Element element) { | |
| 319 return new ElementValue(element, _getElementData(element).id); | |
| 320 } | |
| 321 | |
| 322 void setElement(Map<dynamic, Value> map, key, Element element) { | |
| 323 map[key] = _getElementValue(element); | |
| 324 } | |
| 325 | |
| 326 void setElements(Map<dynamic, Value> map, key, List<Element> elements) { | |
| 327 if (elements.isNotEmpty) { | |
| 328 map[key] = new ListValue(elements.map(_getElementValue).toList()); | |
| 329 } | |
| 330 } | |
| 331 | |
| 332 DataObject _getConstantData(ConstantExpression constant) { | |
| 333 return _constantMap.putIfAbsent(constant, () { | |
| 334 DataObject dataObject = _createDataObject( | |
| 335 new IntValue(_constantMap.length), new EnumValue(constant.kind)); | |
| 336 _pendingList.add(() => _serializeConstant(constant, dataObject)); | |
| 337 return dataObject; | |
| 338 }); | |
| 339 } | |
| 340 | |
| 341 void _serializeConstant(ConstantExpression constant, DataObject dataObject) { | |
| 342 const ConstantSerializer().apply(constant, | |
| 343 _createObjectSerializer(this, dataObject)); | |
| 344 } | |
| 345 | |
| 346 ConstantValue _getConstantValue(ConstantExpression constant) { | |
| 347 return new ConstantValue(constant, _getConstantData(constant).id); | |
| 348 } | |
| 349 | |
| 350 void setConstant(Map<dynamic, Value> map, key, ConstantExpression constant) { | |
| 351 map[key] = _getConstantValue(constant); | |
| 352 } | |
| 353 | |
| 354 void setConstants(Map<dynamic, Value> map, | |
|
floitsch
2015/06/26 20:54:05
There is no reason to be imperative here. Return t
Johnni Winther
2015/07/03 12:13:45
Done.
| |
| 355 key, | |
| 356 List<ConstantExpression> constants) { | |
| 357 if (constants.isNotEmpty) { | |
| 358 map[key] = new ListValue(constants.map(_getConstantValue).toList()); | |
| 359 } | |
| 360 } | |
| 361 | |
| 362 DataObject _getTypeData(DartType type) { | |
| 363 return _typeMap.putIfAbsent(type, () { | |
| 364 DataObject dataObject = _createDataObject( | |
| 365 new IntValue(_typeMap.length), new EnumValue(type.kind)); | |
| 366 _pendingList.add(() => _serializeType(type, dataObject)); | |
| 367 return dataObject; | |
| 368 }); | |
| 369 } | |
| 370 | |
| 371 void _serializeType(DartType type, DataObject dataObject) { | |
| 372 const TypeSerializer().apply(type, | |
| 373 _createObjectSerializer(this, dataObject)); | |
| 374 } | |
| 375 | |
| 376 TypeValue _getTypeValue(DartType type) { | |
| 377 return new TypeValue(type, _getTypeData(type).id); | |
| 378 } | |
| 379 | |
| 380 void setType(Map<dynamic, Value> map, key, DartType type) { | |
| 381 map[key] = _getTypeValue(type); | |
| 382 } | |
| 383 | |
| 384 void setTypes(Map<dynamic, Value> map, key, List<DartType> types) { | |
| 385 if (types.isNotEmpty) { | |
| 386 map[key] = new ListValue(types.map(_getTypeValue).toList()); | |
| 387 } | |
| 388 } | |
| 389 | |
| 390 void setBool(Map<dynamic, Value> map, key, bool value) { | |
| 391 map[key] = new BoolValue(value); | |
| 392 } | |
| 393 | |
| 394 void setInt(Map<dynamic, Value> map, key, int value) { | |
| 395 map[key] = new IntValue(value); | |
| 396 } | |
| 397 | |
| 398 void setInts(Map<dynamic, Value> map, key, List<int> values) { | |
| 399 if (values.isNotEmpty) { | |
| 400 map[key] = new ListValue( | |
| 401 values.map((v) => new IntValue(v)).toList()); | |
| 402 } | |
| 403 } | |
| 404 | |
| 405 void setDouble(Map<dynamic, Value> map, key, double value) { | |
| 406 map[key] = new DoubleValue(value); | |
| 407 } | |
| 408 | |
| 409 void setString(Map<dynamic, Value> map, key, String value) { | |
| 410 map[key] = new StringValue(value); | |
| 411 } | |
| 412 | |
| 413 void setStrings(Map<dynamic, Value> map, key, List<String> values) { | |
| 414 if (values.isNotEmpty) { | |
| 415 map[key] = new ListValue( | |
| 416 values.map((v) => new StringValue(v)).toList()); | |
| 417 } | |
| 418 } | |
| 419 | |
| 420 void setEnum(Map<dynamic, Value> map, key, value) { | |
| 421 map[key] = new EnumValue(value); | |
| 422 } | |
| 423 | |
| 424 void setUri(Map<dynamic, Value> map, key, Uri baseUri, Uri value) { | |
| 425 map[key] = new UriValue(baseUri, value); | |
| 426 } | |
| 427 | |
| 428 ObjectValue get objectValue { | |
| 429 Map<Key, Value> map = <Key, Value>{}; | |
| 430 map[Key.ELEMENTS] = | |
| 431 new ListValue(_elementMap.values.map((l) => l.objectValue).toList()); | |
| 432 if (_typeMap.isNotEmpty) { | |
| 433 map[Key.TYPES] = | |
| 434 new ListValue(_typeMap.values.map((l) => l.objectValue).toList()); | |
| 435 } | |
| 436 if (_constantMap.isNotEmpty) { | |
| 437 map[Key.CONSTANTS] = | |
| 438 new ListValue(_constantMap.values.map((l) => l.objectValue).toList()); | |
| 439 } | |
| 440 return new ObjectValue(map); | |
| 441 } | |
| 442 | |
| 443 String toText() { | |
| 444 return _encoder.encode(objectValue); | |
| 445 } | |
| 446 | |
| 447 String prettyPrint() { | |
| 448 PrettyPrintEncoder encoder = new PrettyPrintEncoder(); | |
| 449 return encoder.toText(objectValue); | |
| 450 } | |
| 451 } | |
| 452 | |
| 453 /// Deserializer for a closed collection of libraries. | |
| 454 // TODO(johnniwinther): Support per-library deserialization and dependencies | |
| 455 // between deserialized subcomponent. | |
| 456 class Deserializer { | |
| 457 final SerializationDecoder _decoder; | |
| 458 final _mainData; | |
|
floitsch
2015/06/26 20:54:05
mainData is not a good name.
Johnni Winther
2015/07/03 12:13:45
'mainData' -> 'headerObject'.
| |
| 459 Map<int, Element> _elementMap = {}; | |
| 460 Map<int, DartType> _typeMap = {}; | |
| 461 Map<int, ConstantExpression> _constantMap = {}; | |
| 462 | |
| 463 Deserializer.fromText(String text, SerializationDecoder decoder) | |
| 464 : this._mainData = decoder.decode(text), | |
| 465 this._decoder = decoder; | |
| 466 | |
| 467 List _readMainData(Key key) { | |
| 468 return _decoder.readMainData(_mainData, key); | |
| 469 } | |
| 470 | |
| 471 _readEntry(data, key) { | |
| 472 return _decoder.readEntry(data, key); | |
| 473 } | |
| 474 | |
| 475 /// Returns the [LibraryElement] for [uri] if part of the deserializer. | |
| 476 LibraryElement lookupLibrary(Uri uri) { | |
| 477 for (var data in _readMainData(Key.ELEMENTS)) { | |
| 478 SerializedElementKind kind = | |
| 479 getEnum(data, Key.KIND, SerializedElementKind.values); | |
| 480 if (kind == SerializedElementKind.LIBRARY) { | |
| 481 Uri libraryUri = getUri(data, Key.CANONICAL_URI); | |
| 482 if (libraryUri == uri) { | |
| 483 return getElement(data, Key.ID); | |
| 484 } | |
| 485 } | |
| 486 } | |
| 487 return null; | |
| 488 } | |
| 489 | |
| 490 Element getElement(data, key, {bool isOptional: false}) { | |
| 491 int id = _readEntry(data, key); | |
| 492 if (id == null) { | |
| 493 if (isOptional) { | |
| 494 return null; | |
| 495 } | |
| 496 throw new StateError("Element value '$key' not found in $data."); | |
| 497 } | |
| 498 return _getElementById(id); | |
| 499 } | |
| 500 | |
| 501 Element _getElementById(int id) { | |
| 502 if (id == null) throw new ArgumentError('Deserializer.getElement(null)'); | |
| 503 return _elementMap.putIfAbsent(id, () { | |
| 504 return ElementDeserializer.deserialize( | |
| 505 new JsonObjectDeserializer(this, _readMainData(Key.ELEMENTS)[id])); | |
| 506 }); | |
| 507 } | |
| 508 | |
| 509 List<Element> getElements(data, key, {bool isOptional: false}) { | |
| 510 List list = _readEntry(data, key); | |
| 511 if (list == null) { | |
| 512 if (isOptional) { | |
| 513 return const []; | |
| 514 } | |
| 515 throw new StateError("Elements value '$key' not found in $data."); | |
| 516 } | |
| 517 return list.map(_getElementById).toList(); | |
| 518 } | |
| 519 | |
| 520 DartType getType(data, key, {bool isOptional: false}) { | |
| 521 int id = _readEntry(data, key); | |
| 522 if (id == null) { | |
| 523 if (isOptional) { | |
| 524 return null; | |
| 525 } | |
| 526 throw new StateError("Type value '$key' not found in $data."); | |
| 527 } | |
| 528 return _getTypeById(id); | |
| 529 } | |
| 530 | |
| 531 DartType _getTypeById(int id) { | |
| 532 if (id == null) throw new ArgumentError('Deserializer.getType(null)'); | |
| 533 return _typeMap.putIfAbsent(id, () { | |
| 534 return TypeDeserializer.deserialize( | |
| 535 new JsonObjectDeserializer(this, _readMainData(Key.TYPES)[id])); | |
| 536 }); | |
| 537 } | |
| 538 | |
| 539 List<DartType> getTypes(data, key, {bool isOptional: false}) { | |
| 540 List list = _readEntry(data, key); | |
| 541 if (list == null) { | |
| 542 if (isOptional) { | |
| 543 return const []; | |
| 544 } | |
| 545 throw new StateError("Types value '$key' not found in $data."); | |
| 546 } | |
| 547 return list.map(_getTypeById).toList(); | |
| 548 } | |
| 549 | |
| 550 ConstantExpression getConstant(data, key, {bool isOptional: false}) { | |
| 551 int id = _readEntry(data, key); | |
| 552 if (id == null) { | |
| 553 if (isOptional) { | |
| 554 return null; | |
| 555 } | |
| 556 throw new StateError("Constant value '$key' not found in $data."); | |
| 557 } | |
| 558 return _getConstantById(id); | |
| 559 } | |
| 560 | |
| 561 ConstantExpression _getConstantById(int id) { | |
| 562 if (id == null) throw new ArgumentError('Deserializer.getConstant(null)'); | |
| 563 return _constantMap.putIfAbsent(id, () { | |
| 564 return ConstantDeserializer.deserialize( | |
| 565 new JsonObjectDeserializer(this, _readMainData(Key.CONSTANTS)[id])); | |
| 566 }); | |
| 567 } | |
| 568 | |
| 569 List<ConstantExpression> getConstants(data, key, {bool isOptional: false}) { | |
| 570 List list = _readEntry(data, key); | |
| 571 if (list == null) { | |
| 572 if (isOptional) { | |
| 573 return const []; | |
| 574 } | |
| 575 throw new StateError("Constants value '$key' not found in $data."); | |
| 576 } | |
| 577 return list.map(_getConstantById).toList(); | |
| 578 } | |
| 579 | |
| 580 bool getBool(data, key, {bool isOptional: false, bool defaultValue}) { | |
| 581 bool value = _readEntry(data, key); | |
| 582 if (value == null) { | |
| 583 if (isOptional || defaultValue != null) { | |
| 584 return defaultValue; | |
| 585 } | |
| 586 throw new StateError("bool value '$key' not found in $data."); | |
| 587 } | |
| 588 return value; | |
| 589 } | |
| 590 | |
| 591 int getInt(data, key, {bool isOptional: false, int defaultValue}) { | |
| 592 int value = _readEntry(data, key); | |
| 593 if (value == null) { | |
| 594 if (isOptional || defaultValue != null) { | |
| 595 return defaultValue; | |
| 596 } | |
| 597 throw new StateError("int value '$key' not found in $data."); | |
| 598 } | |
| 599 return value; | |
| 600 } | |
| 601 | |
| 602 List<int> getInts(data, key, {bool isOptional: false}) { | |
| 603 List list = _readEntry(data, key); | |
| 604 if (list == null) { | |
| 605 if (isOptional) { | |
| 606 return const []; | |
| 607 } | |
| 608 throw new StateError("Ints value '$key' not found in $data."); | |
| 609 } | |
| 610 return list; | |
| 611 } | |
| 612 | |
| 613 double getDouble(data, key, {bool isOptional: false, double defaultValue}) { | |
| 614 double value = _readEntry(data, key); | |
| 615 if (value == null) { | |
| 616 if (isOptional || defaultValue != null) { | |
| 617 return defaultValue; | |
| 618 } | |
| 619 throw new StateError("double value '$key' not found in $data."); | |
| 620 } | |
| 621 return value; | |
| 622 } | |
| 623 | |
| 624 String getString(data, key, {bool isOptional: false, String defaultValue}) { | |
| 625 String value = _readEntry(data, key); | |
| 626 if (value == null) { | |
| 627 if (isOptional || defaultValue != null) { | |
| 628 return defaultValue; | |
| 629 } | |
| 630 throw new StateError("String value '$key' not found in $data."); | |
| 631 } | |
| 632 return value; | |
| 633 } | |
| 634 | |
| 635 List<String> getStrings(data, key, {bool isOptional: false}) { | |
| 636 List list = _readEntry(data, key); | |
| 637 if (list == null) { | |
| 638 if (isOptional) { | |
| 639 return const []; | |
| 640 } | |
| 641 throw new StateError("Strings value '$key' not found in $data."); | |
| 642 } | |
| 643 return list; | |
| 644 } | |
| 645 | |
| 646 getEnum(data, key, List values, | |
| 647 {bool isOptional: false, defaultValue}) { | |
| 648 int value = _readEntry(data, key); | |
| 649 if (value == null) { | |
| 650 if (isOptional || defaultValue != null) { | |
| 651 return defaultValue; | |
| 652 } | |
| 653 throw new StateError("enum value '$key' not found in $data."); | |
| 654 } | |
| 655 return values[value]; | |
| 656 } | |
| 657 | |
| 658 ObjectDeserializer getObject(data, key, {bool isOptional: false}) { | |
| 659 Map map = _readEntry(data, key); | |
| 660 if (map == null) { | |
| 661 if (isOptional) { | |
| 662 return null; | |
| 663 } | |
| 664 throw new StateError("Object value '$key' not found in $data."); | |
| 665 } | |
| 666 return new JsonObjectDeserializer(this, map); | |
| 667 } | |
| 668 | |
| 669 MapDeserializer getMap(data, key, {bool isOptional: false}) { | |
| 670 Map map = _readEntry(data, key); | |
| 671 if (map == null) { | |
| 672 if (isOptional) { | |
| 673 return null; | |
| 674 } | |
| 675 throw new StateError("Map value '$key' not found in $data."); | |
| 676 } | |
| 677 return new JsonMapDeserializer(this, map); | |
| 678 } | |
| 679 | |
| 680 ListDeserializer getList(data, key, {bool isOptional: false}) { | |
| 681 List list = _readEntry(data, key); | |
| 682 if (list == null) { | |
| 683 if (isOptional) { | |
| 684 return null; | |
| 685 } | |
| 686 throw new StateError("List value '$key' not found in $data."); | |
| 687 } | |
| 688 return new JsonListDeserializer(this, list); | |
| 689 } | |
| 690 | |
| 691 Uri getUri(data, key, {bool isOptional: false, Uri defaultValue}) { | |
| 692 // TODO(johnniwinther): Support scheme specific encoding. | |
| 693 String value = _readEntry(data, key); | |
| 694 if (value == null) { | |
| 695 if (isOptional || defaultValue != null) { | |
| 696 return defaultValue; | |
| 697 } | |
| 698 throw new StateError("Uri value '$key' not found in $data."); | |
| 699 } | |
| 700 return Uri.parse(value); | |
| 701 } | |
| 702 } | |
| 703 | |
| 704 /// Strategy used by [Serializer] to define the memory and output encoding. | |
| 705 // TODO(johnniwinther): Split output encoding from memory object encoding. | |
|
floitsch
2015/06/26 20:54:05
Yes. But by removing the memory strategy. Just go
Johnni Winther
2015/07/03 12:13:45
Done.
| |
| 706 abstract class SerializationEncoder { | |
| 707 /// Encode [objectValue] into text. | |
| 708 String encode(ObjectValue objectValue); | |
| 709 | |
| 710 /// Create a [DataObject] for an entity with the given [id] and [kind]. | |
| 711 DataObject createDataObject(IntValue id, EnumValue kind); | |
| 712 | |
| 713 /// Create an [ObjectSerializer] for [dataObject]. | |
| 714 ObjectSerializer createObjectSerializer( | |
| 715 Serializer serializer, DataObject dataObject); | |
| 716 } | |
| 717 | |
| 718 /// Strategy used by [Deserializer] for decoding and reading data from a | |
| 719 /// serialized output. | |
| 720 // TODO(johnniwinther): Split input encoding from memory object encoding. | |
| 721 abstract class SerializationDecoder { | |
| 722 /// Decode [text] into an internal data model. | |
| 723 decode(String text); | |
| 724 | |
| 725 /// Read the main data entry for [key] from [mainData]. | |
| 726 List readMainData(mainData, Key key); | |
| 727 | |
| 728 /// Read the entry [key] from the [data] object. | |
| 729 readEntry(data, key); | |
| 730 } | |
| OLD | NEW |