Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(63)

Side by Side Diff: pkg/compiler/lib/src/serialization/serialization.dart

Issue 1192103002: Support serialization of the compiler backbone. (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Created 5 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698