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

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

Issue 22375012: pkg/serialization updates (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: a bit more Created 7 years, 4 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 | Annotate | Revision Log
« no previous file with comments | « pkg/serialization/lib/src/basic_rule.dart ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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 part of serialization; 5 part of serialization;
6 6
7 // TODO(alanknight): We should have an example and tests for subclassing 7 // TODO(alanknight): We should have an example and tests for subclassing
8 // serialization rule rather than using the hard-coded ClosureToMap rule. And 8 // serialization rule rather than using the hard-coded ClosureToMap rule. And
9 // possibly an abstract superclass that's designed to be subclassed that way. 9 // possibly an abstract superclass that's designed to be subclassed that way.
10 /** 10 /**
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
100 * object's constructor. It is up to the rule what state is considered 100 * object's constructor. It is up to the rule what state is considered
101 * essential. 101 * essential.
102 */ 102 */
103 inflateEssential(state, Reader reader); 103 inflateEssential(state, Reader reader);
104 104
105 /** 105 /**
106 * The [object] has already been created. Set any of its non-essential 106 * The [object] has already been created. Set any of its non-essential
107 * variables from the representation in [state]. Where there are references 107 * variables from the representation in [state]. Where there are references
108 * to other objects they are resolved in the context of [reader]. 108 * to other objects they are resolved in the context of [reader].
109 */ 109 */
110 inflateNonEssential(state, object, Reader reader); 110 void inflateNonEssential(state, object, Reader reader);
111 111
112 /** 112 /**
113 * If we have [object] as part of our state, should we represent that 113 * If we have [object] as part of our state, should we represent that
114 * directly, or should we make a reference for it. By default, true. 114 * directly, or should we make a reference for it. By default, true.
115 * This may also delegate to [writer]. 115 * This may also delegate to [writer].
116 */ 116 */
117 bool shouldUseReferenceFor(object, Writer writer) => true; 117 bool shouldUseReferenceFor(object, Writer writer) => true;
118 118
119 /** 119 /**
120 * Return true if the data this rule returns is variable length, so a 120 * Return true if the data this rule returns is variable length, so a
(...skipping 27 matching lines...) Expand all
148 result.add(each); 148 result.add(each);
149 f(each); 149 f(each);
150 } 150 }
151 return result; 151 return result;
152 } 152 }
153 153
154 inflateEssential(List state, Reader r) => new List(); 154 inflateEssential(List state, Reader r) => new List();
155 155
156 // For a list, we consider all of its state non-essential and add it 156 // For a list, we consider all of its state non-essential and add it
157 // after creation. 157 // after creation.
158 inflateNonEssential(List state, List newList, Reader r) { 158 void inflateNonEssential(List state, List newList, Reader r) {
159 populateContents(state, newList, r); 159 populateContents(state, newList, r);
160 } 160 }
161 161
162 void populateContents(List state, List newList, Reader r) { 162 void populateContents(List state, List newList, Reader r) {
163 for(var each in state) { 163 for(var each in state) {
164 newList.add(r.inflateReference(each)); 164 newList.add(r.inflateReference(each));
165 } 165 }
166 } 166 }
167 167
168 bool get hasVariableLengthEntries => true; 168 bool get hasVariableLengthEntries => true;
169 } 169 }
170 170
171 /** 171 /**
172 * This is a subclass of ListRule where all of the list's contents are 172 * This is a subclass of ListRule where all of the list's contents are
173 * considered essential state. This is needed if an object X contains a List L, 173 * considered essential state. This is needed if an object X contains a List L,
174 * but it expects L's contents to be fixed when X's constructor is called. 174 * but it expects L's contents to be fixed when X's constructor is called.
175 */ 175 */
176 class ListRuleEssential extends ListRule { 176 class ListRuleEssential extends ListRule {
177 177
178 /** Create the new List and also inflate all of its contents. */ 178 /** Create the new List and also inflate all of its contents. */
179 inflateEssential(List state, Reader r) { 179 inflateEssential(List state, Reader r) {
180 var object = super.inflateEssential(state, r); 180 var object = super.inflateEssential(state, r);
181 populateContents(state, object, r); 181 populateContents(state, object, r);
182 return object; 182 return object;
183 } 183 }
184 184
185 /** Does nothing, because all the work has been done in inflateEssential. */ 185 /** Does nothing, because all the work has been done in inflateEssential. */
186 inflateNonEssential(state, newList, reader) {} 186 void inflateNonEssential(state, newList, reader) {}
187 187
188 bool get mustBePrimary => true; 188 bool get mustBePrimary => true;
189 } 189 }
190 190
191 /** 191 /**
192 * This rule handles things that implement Map. It will recreate them as 192 * This rule handles things that implement Map. It will recreate them as
193 * whatever the default implemenation of Map is on the target platform. If a 193 * whatever the default implemenation of Map is on the target platform. If a
194 * map has string keys it will attempt to retain it as a map for JSON formats, 194 * map has string keys it will attempt to retain it as a map for JSON formats,
195 * otherwise it will store it as a list of references to keys and values. 195 * otherwise it will store it as a list of references to keys and values.
196 */ 196 */
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
230 newState.add(writer._referenceFor(value)); 230 newState.add(writer._referenceFor(value));
231 }); 231 });
232 return newState; 232 return newState;
233 } 233 }
234 } 234 }
235 235
236 inflateEssential(state, Reader r) => new Map(); 236 inflateEssential(state, Reader r) => new Map();
237 237
238 // For a map, we consider all of its state non-essential and add it 238 // For a map, we consider all of its state non-essential and add it
239 // after creation. 239 // after creation.
240 inflateNonEssential(state, Map newMap, Reader r) { 240 void inflateNonEssential(state, Map newMap, Reader r) {
241 if (state is List) { 241 if (state is List) {
242 inflateNonEssentialFromList(state, newMap, r); 242 inflateNonEssentialFromList(state, newMap, r);
243 } else { 243 } else {
244 inflateNonEssentialFromMap(state, newMap, r); 244 inflateNonEssentialFromMap(state, newMap, r);
245 } 245 }
246 } 246 }
247 247
248 void inflateNonEssentialFromList(List state, Map newMap, Reader r) { 248 void inflateNonEssentialFromList(List state, Map newMap, Reader r) {
249 var key; 249 var key;
250 for (var each in state) { 250 for (var each in state) {
(...skipping 18 matching lines...) Expand all
269 /** 269 /**
270 * This rule handles primitive types, defined as those that we can normally 270 * This rule handles primitive types, defined as those that we can normally
271 * represent directly in the output format. We hard-code that to mean 271 * represent directly in the output format. We hard-code that to mean
272 * num, String, and bool. 272 * num, String, and bool.
273 */ 273 */
274 class PrimitiveRule extends SerializationRule { 274 class PrimitiveRule extends SerializationRule {
275 bool appliesTo(object, Writer w) => isPrimitive(object); 275 bool appliesTo(object, Writer w) => isPrimitive(object);
276 extractState(object, Function f, Writer w) => object; 276 extractState(object, Function f, Writer w) => object;
277 flatten(object, Writer writer) {} 277 flatten(object, Writer writer) {}
278 inflateEssential(state, Reader r) => state; 278 inflateEssential(state, Reader r) => state;
279 inflateNonEssential(object, _, Reader r) {} 279 void inflateNonEssential(object, _, Reader r) {}
280 280
281 bool get storesStateAsPrimitives => true; 281 bool get storesStateAsPrimitives => true;
282 282
283 /** 283 /**
284 * Indicate whether we should save pointers to this object as references 284 * Indicate whether we should save pointers to this object as references
285 * or store the object directly. For primitives this depends on the format, 285 * or store the object directly. For primitives this depends on the format,
286 * so we delegate to the writer. 286 * so we delegate to the writer.
287 */ 287 */
288 bool shouldUseReferenceFor(object, Writer w) => 288 bool shouldUseReferenceFor(object, Writer w) =>
289 w.shouldUseReferencesForPrimitives; 289 w.shouldUseReferencesForPrimitives;
(...skipping 13 matching lines...) Expand all
303 /** 303 /**
304 * This is a rule where the extraction and creation are hard-coded as 304 * This is a rule where the extraction and creation are hard-coded as
305 * closures. The result is expected to be a map indexed by field name. 305 * closures. The result is expected to be a map indexed by field name.
306 */ 306 */
307 class ClosureRule extends CustomRule { 307 class ClosureRule extends CustomRule {
308 308
309 /** The runtimeType of objects that this rule applies to. Used in appliesTo.*/ 309 /** The runtimeType of objects that this rule applies to. Used in appliesTo.*/
310 final Type type; 310 final Type type;
311 311
312 /** The function for constructing new objects when reading. */ 312 /** The function for constructing new objects when reading. */
313 ConstructType construct; 313 final ConstructType construct;
314 314
315 /** The function for returning an object's state as a Map. */ 315 /** The function for returning an object's state as a Map. */
316 GetStateType getStateFunction; 316 final GetStateType getStateFunction;
317 317
318 /** The function for setting an object's state from a Map. */ 318 /** The function for setting an object's state from a Map. */
319 NonEssentialStateType setNonEssentialState; 319 final NonEssentialStateType setNonEssentialState;
320 320
321 /** 321 /**
322 * Create a ClosureToMapRule for the given [type] which gets an object's 322 * Create a ClosureToMapRule for the given [type] which gets an object's
323 * state by calling [getState], creates a new object by calling [construct] 323 * state by calling [getState], creates a new object by calling [construct]
324 * and sets the new object's state by calling [setNonEssentialState]. 324 * and sets the new object's state by calling [setNonEssentialState].
325 */ 325 */
326 ClosureRule(this.type, this.getStateFunction, this.construct, 326 ClosureRule(this.type, this.getStateFunction, this.construct,
327 this.setNonEssentialState); 327 this.setNonEssentialState);
328 328
329 bool appliesTo(object, Writer w) => object.runtimeType == type; 329 bool appliesTo(object, Writer w) => object.runtimeType == type;
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
367 // proven necessary. 367 // proven necessary.
368 flatten(state, Writer writer) { 368 flatten(state, Writer writer) {
369 state[0] = writer._referenceFor(state[0]); 369 state[0] = writer._referenceFor(state[0]);
370 } 370 }
371 371
372 /** Look up the named object and return it. */ 372 /** Look up the named object and return it. */
373 inflateEssential(state, Reader r) => 373 inflateEssential(state, Reader r) =>
374 r.objectNamed(r.resolveReference(state.first)); 374 r.objectNamed(r.resolveReference(state.first));
375 375
376 /** Set any non-essential state on the object. For this rule, a no-op. */ 376 /** Set any non-essential state on the object. For this rule, a no-op. */
377 inflateNonEssential(state, object, Reader r) {} 377 void inflateNonEssential(state, object, Reader r) {}
378 378
379 /** Return the name for this object in the Writer. */ 379 /** Return the name for this object in the Writer. */
380 String nameFor(object, Writer writer) => writer.nameFor(object); 380 String nameFor(object, Writer writer) => writer.nameFor(object);
381 } 381 }
382 382
383 /** 383 /**
384 * This rule handles the special case of Mirrors. It stores the mirror by its 384 * This rule handles the special case of Mirrors. It stores the mirror by its
385 * qualifiedName and attempts to look it up in both the namedObjects 385 * qualifiedName and attempts to look it up in both the namedObjects
386 * collection, or if it's not found there, by looking it up in the mirror 386 * collection, or if it's not found there, by looking it up in the mirror
387 * system. When reading, the user is responsible for supplying the appropriate 387 * system. When reading, the user is responsible for supplying the appropriate
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
489 create(state) => new Symbol(state[0]); 489 create(state) => new Symbol(state[0]);
490 void setState(symbol, state) {} 490 void setState(symbol, state) {}
491 int get dataLength => 1; 491 int get dataLength => 1;
492 bool get hasVariableLengthEntries => false; 492 bool get hasVariableLengthEntries => false;
493 } 493 }
494 494
495 /** A hard-coded rule for DateTime. */ 495 /** A hard-coded rule for DateTime. */
496 class DateTimeRule extends CustomRule { 496 class DateTimeRule extends CustomRule {
497 bool appliesTo(instance, _) => instance is DateTime; 497 bool appliesTo(instance, _) => instance is DateTime;
498 List getState(DateTime date) => [date.millisecondsSinceEpoch, date.isUtc]; 498 List getState(DateTime date) => [date.millisecondsSinceEpoch, date.isUtc];
499 create(List state) => 499 DateTime create(List state) =>
500 new DateTime.fromMillisecondsSinceEpoch(state[0], isUtc: state[1]); 500 new DateTime.fromMillisecondsSinceEpoch(state[0], isUtc: state[1]);
501 void setState(date, state) {} 501 void setState(date, state) {}
502 // Let the system know we don't have to store a length for these. 502 // Let the system know we don't have to store a length for these.
503 int get dataLength => 2; 503 int get dataLength => 2;
504 bool get hasVariableLengthEntries => false; 504 bool get hasVariableLengthEntries => false;
505 } 505 }
506 506
507 /** Create a lazy list/map that will inflate its items on demand in [r]. */ 507 /** Create a lazy list/map that will inflate its items on demand in [r]. */
508 _lazy(l, Reader r) { 508 _lazy(l, Reader r) {
509 if (l is List) return new _LazyList(l, r); 509 if (l is List) return new _LazyList(l, r);
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
551 void addAll(Map other) => _throw(); 551 void addAll(Map other) => _throw();
552 } 552 }
553 553
554 /** 554 /**
555 * This provides an implementation of List that wraps a list which may 555 * This provides an implementation of List that wraps a list which may
556 * contain references to (potentially) non-inflated objects. If these 556 * contain references to (potentially) non-inflated objects. If these
557 * are accessed it will inflate them. This allows us to pass something that 557 * are accessed it will inflate them. This allows us to pass something that
558 * looks like it's just a list of objects to a [CustomRule] without needing 558 * looks like it's just a list of objects to a [CustomRule] without needing
559 * to inflate all the references in advance. 559 * to inflate all the references in advance.
560 */ 560 */
561 class _LazyList extends IterableBase with ListMixin implements List { 561 class _LazyList extends ListBase {
562 _LazyList(this._raw, this._reader); 562 _LazyList(this._raw, this._reader);
563 563
564 final List _raw; 564 final List _raw;
565 final Reader _reader; 565 final Reader _reader;
566 566
567 operator [](int x) => _reader.inflateReference(_raw[x]); 567 operator [](int x) => _reader.inflateReference(_raw[x]);
568 int get length => _raw.length; 568 int get length => _raw.length;
569 569
570 void set length(int value) => _throw(); 570 void set length(int value) => _throw();
571 571
572 void operator []=(int index, value) => _throw(); 572 void operator []=(int index, value) => _throw();
573 573
574 void _throw() { 574 void _throw() {
575 throw new UnsupportedError("Not modifiable"); 575 throw new UnsupportedError("Not modifiable");
576 } 576 }
577 } 577 }
OLDNEW
« no previous file with comments | « pkg/serialization/lib/src/basic_rule.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698