Chromium Code Reviews| 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) { throw 'Cannot find named object to link to: $key';} | |
|
Jennifer Messerly
2013/02/08 04:04:38
Would be good to throw a more precise Exception he
Alan Knight
2013/02/11 23:38:42
Done.
| |
| 322 | |
| 321 /** | 323 /** |
| 322 * Return the list of rules to be used when writing. These come from the | 324 * Return the list of rules to be used when writing. These come from the |
| 323 * [serialization]. | 325 * [serialization]. |
| 324 */ | 326 */ |
| 325 List<SerializationRule> get rules => serialization._rules; | 327 List<SerializationRule> get rules => serialization._rules; |
| 326 | 328 |
| 327 /** | 329 /** |
| 328 * Internal use only, for testing purposes. Set the data for this reader | 330 * 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. | 331 * to a List of Lists whose size must match the number of rules. |
| 330 */ | 332 */ |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 343 var input = format.read(rawInput, this); | 345 var input = format.read(rawInput, this); |
| 344 data = input["data"]; | 346 data = input["data"]; |
| 345 rules.forEach(inflateForRule); | 347 rules.forEach(inflateForRule); |
| 346 return inflateReference(input["roots"].first); | 348 return inflateReference(input["roots"].first); |
| 347 } | 349 } |
| 348 | 350 |
| 349 /** | 351 /** |
| 350 * If the data we are reading from has rules written to it, read them back | 352 * 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. | 353 * and set them as the rules we will use. |
| 352 */ | 354 */ |
| 353 void readRules(String newRules) { | 355 void readRules(newRules) { |
| 354 // TODO(alanknight): Replacing the serialization is kind of confusing. | 356 // TODO(alanknight): Replacing the serialization is kind of confusing. |
| 355 List rulesWeRead = (newRules == null) ? | 357 if (newRules == null) return; |
| 356 null : serialization.ruleSerialization().read(newRules, namedObjects); | 358 var reader = serialization.ruleSerialization().newReader(format); |
| 359 List rulesWeRead = reader.read(newRules, namedObjects); | |
| 357 if (rulesWeRead != null && !rulesWeRead.isEmpty) { | 360 if (rulesWeRead != null && !rulesWeRead.isEmpty) { |
| 358 serialization = new Serialization.blank(); | 361 serialization = new Serialization.blank(); |
| 359 rulesWeRead.forEach(serialization.addRule); | 362 rulesWeRead.forEach(serialization.addRule); |
| 360 } | 363 } |
| 361 } | 364 } |
| 362 | 365 |
| 363 /** | 366 /** |
| 364 * Inflate all of the objects for [rule]. Does the essential state for all | 367 * 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 | 368 * objects first, then the non-essential state. This avoids cycles in |
| 366 * non-essential state, because all the objects will have already been | 369 * 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. | 603 * for an example. It knows how to return its object and how to filter. |
| 601 */ | 604 */ |
| 602 class DesignatedRuleForObject { | 605 class DesignatedRuleForObject { |
| 603 Function rulePredicate; | 606 Function rulePredicate; |
| 604 final target; | 607 final target; |
| 605 | 608 |
| 606 DesignatedRuleForObject(this.target, this.rulePredicate); | 609 DesignatedRuleForObject(this.target, this.rulePredicate); |
| 607 | 610 |
| 608 possibleRules(List rules) => rules.where(rulePredicate).toList(); | 611 possibleRules(List rules) => rules.where(rulePredicate).toList(); |
| 609 } | 612 } |
| OLD | NEW |