OLD | NEW |
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 /** | 7 /** |
8 * This writes out the state of the objects to an external format. It holds | 8 * This writes out the state of the objects to an external format. It holds |
9 * all of the intermediate state needed. The primary API for it is the | 9 * all of the intermediate state needed. The primary API for it is the |
10 * [write] method. | 10 * [write] method. |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
116 * track of it. Generate a [Reference] for this object if required. | 116 * track of it. Generate a [Reference] for this object if required. |
117 * When it's required is up to the particular rule, but generally everything | 117 * When it's required is up to the particular rule, but generally everything |
118 * gets a reference except a primitive. | 118 * gets a reference except a primitive. |
119 * Note that at this point the states are just the same as the fields of the | 119 * Note that at this point the states are just the same as the fields of the |
120 * object, and haven't been flattened. | 120 * object, and haven't been flattened. |
121 */ | 121 */ |
122 void _record(object, SerializationRule rule) { | 122 void _record(object, SerializationRule rule) { |
123 if (rule.shouldUseReferenceFor(object, this)) { | 123 if (rule.shouldUseReferenceFor(object, this)) { |
124 references.putIfAbsent(object, () => | 124 references.putIfAbsent(object, () => |
125 new Reference(this, rule.number, _nextObjectNumberFor(rule))); | 125 new Reference(this, rule.number, _nextObjectNumberFor(rule))); |
126 var state = rule.extractState(object, trace.note); | 126 var state = rule.extractState(object, trace.note, this); |
127 _addStateForRule(rule, state); | 127 _addStateForRule(rule, state); |
128 } | 128 } |
129 } | 129 } |
130 | 130 |
131 /** | 131 /** |
132 * Should we store primitive objects directly or create references for them. | 132 * Should we store primitive objects directly or create references for them. |
133 * That depends on which format we're using, so a flat format will want | 133 * That depends on which format we're using, so a flat format will want |
134 * references, but the Map format can store them directly. | 134 * references, but the Map format can store them directly. |
135 */ | 135 */ |
136 bool get shouldUseReferencesForPrimitives | 136 bool get shouldUseReferencesForPrimitives |
137 => format.shouldUseReferencesForPrimitives; | 137 => format.shouldUseReferencesForPrimitives; |
138 | 138 |
139 /** | 139 /** |
140 * Returns a serialized version of the [SerializationRule]s used to write | 140 * Returns a serialized version of the [SerializationRule]s used to write |
141 * the data, if [selfDescribing] is true, otherwise returns null. | 141 * the data, if [selfDescribing] is true, otherwise returns null. |
142 */ | 142 */ |
143 serializedRules() { | 143 serializedRules() { |
144 if (!selfDescribing) return null; | 144 if (!selfDescribing) return null; |
145 var meta = serialization.ruleSerialization(); | 145 var meta = serialization.ruleSerialization(); |
146 var writer = new Writer(meta); | 146 var writer = new Writer(meta, format); |
147 writer.selfDescribing = false; | 147 writer.selfDescribing = false; |
148 return writer.write(serialization._rules); | 148 return writer.write(serialization._rules); |
149 } | 149 } |
150 | 150 |
151 /** Record a [state] entry for a particular rule. */ | 151 /** Record a [state] entry for a particular rule. */ |
152 void _addStateForRule(eachRule, state) { | 152 void _addStateForRule(eachRule, state) { |
153 _growStates(eachRule); | 153 _growStates(eachRule); |
154 states[eachRule.number].add(state); | 154 states[eachRule.number].add(state); |
155 } | 155 } |
156 | 156 |
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
302 * functions, mirrors, or other non-portable entities. The map in which we | 302 * functions, mirrors, or other non-portable entities. The map in which we |
303 * look things up can be provided as an argument to read, but we can also | 303 * look things up can be provided as an argument to read, but we can also |
304 * provide a map here, and objects will be looked up in both places. | 304 * provide a map here, and objects will be looked up in both places. |
305 */ | 305 */ |
306 Map namedObjects; | 306 Map namedObjects; |
307 | 307 |
308 /** | 308 /** |
309 * Look up the reference to an external object. This can be held either in | 309 * Look up the reference to an external object. This can be held either in |
310 * the reader-specific list of externals or in the serializer's | 310 * the reader-specific list of externals or in the serializer's |
311 */ | 311 */ |
312 objectNamed(key) { | 312 objectNamed(key, [Function ifAbsent]) { |
313 var map = (namedObjects.containsKey(key)) | 313 var map = (namedObjects.containsKey(key)) |
314 ? namedObjects : serialization.namedObjects; | 314 ? namedObjects : serialization.namedObjects; |
315 if (!map.containsKey(key)) { | 315 if (!map.containsKey(key)) { |
316 throw 'Cannot find named object to link to: $key'; | 316 (ifAbsent == null ? keyNotFound : ifAbsent)(key); |
317 } | 317 } |
318 return map[key]; | 318 return map[key]; |
319 } | 319 } |
320 | 320 |
| 321 void keyNotFound(key) { |
| 322 throw new SerializationException( |
| 323 'Cannot find named object to link to: $key'); |
| 324 } |
| 325 |
321 /** | 326 /** |
322 * Return the list of rules to be used when writing. These come from the | 327 * Return the list of rules to be used when writing. These come from the |
323 * [serialization]. | 328 * [serialization]. |
324 */ | 329 */ |
325 List<SerializationRule> get rules => serialization._rules; | 330 List<SerializationRule> get rules => serialization._rules; |
326 | 331 |
327 /** | 332 /** |
328 * Internal use only, for testing purposes. Set the data for this reader | 333 * Internal use only, for testing purposes. Set the data for this reader |
329 * to a List of Lists whose size must match the number of rules. | 334 * to a List of Lists whose size must match the number of rules. |
330 */ | 335 */ |
(...skipping 12 matching lines...) Expand all Loading... |
343 var input = format.read(rawInput, this); | 348 var input = format.read(rawInput, this); |
344 data = input["data"]; | 349 data = input["data"]; |
345 rules.forEach(inflateForRule); | 350 rules.forEach(inflateForRule); |
346 return inflateReference(input["roots"].first); | 351 return inflateReference(input["roots"].first); |
347 } | 352 } |
348 | 353 |
349 /** | 354 /** |
350 * If the data we are reading from has rules written to it, read them back | 355 * If the data we are reading from has rules written to it, read them back |
351 * and set them as the rules we will use. | 356 * and set them as the rules we will use. |
352 */ | 357 */ |
353 void readRules(String newRules) { | 358 void readRules(newRules) { |
354 // TODO(alanknight): Replacing the serialization is kind of confusing. | 359 // TODO(alanknight): Replacing the serialization is kind of confusing. |
355 List rulesWeRead = (newRules == null) ? | 360 if (newRules == null) return; |
356 null : serialization.ruleSerialization().read(newRules, namedObjects); | 361 var reader = serialization.ruleSerialization().newReader(format); |
| 362 List rulesWeRead = reader.read(newRules, namedObjects); |
357 if (rulesWeRead != null && !rulesWeRead.isEmpty) { | 363 if (rulesWeRead != null && !rulesWeRead.isEmpty) { |
358 serialization = new Serialization.blank(); | 364 serialization = new Serialization.blank(); |
359 rulesWeRead.forEach(serialization.addRule); | 365 rulesWeRead.forEach(serialization.addRule); |
360 } | 366 } |
361 } | 367 } |
362 | 368 |
363 /** | 369 /** |
364 * Inflate all of the objects for [rule]. Does the essential state for all | 370 * Inflate all of the objects for [rule]. Does the essential state for all |
365 * objects first, then the non-essential state. This avoids cycles in | 371 * objects first, then the non-essential state. This avoids cycles in |
366 * non-essential state, because all the objects will have already been | 372 * non-essential state, because all the objects will have already been |
(...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
600 * for an example. It knows how to return its object and how to filter. | 606 * for an example. It knows how to return its object and how to filter. |
601 */ | 607 */ |
602 class DesignatedRuleForObject { | 608 class DesignatedRuleForObject { |
603 Function rulePredicate; | 609 Function rulePredicate; |
604 final target; | 610 final target; |
605 | 611 |
606 DesignatedRuleForObject(this.target, this.rulePredicate); | 612 DesignatedRuleForObject(this.target, this.rulePredicate); |
607 | 613 |
608 possibleRules(List rules) => rules.where(rulePredicate).toList(); | 614 possibleRules(List rules) => rules.where(rulePredicate).toList(); |
609 } | 615 } |
OLD | NEW |