| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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 // Patch file for dart:convert library. | 5 // Patch file for dart:convert library. |
| 6 | 6 |
| 7 import 'dart:_js_helper' show argumentErrorValue, patch; | 7 import 'dart:_js_helper' show argumentErrorValue, patch; |
| 8 import 'dart:_foreign_helper' show JS; | 8 import 'dart:_foreign_helper' show JS; |
| 9 import 'dart:_interceptors' show JSExtendableArray; | 9 import 'dart:_interceptors' show JSExtendableArray; |
| 10 import 'dart:_internal' show MappedIterable, ListIterable; | 10 import 'dart:_internal' show MappedIterable, ListIterable; |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 116 // reference to the list, but the compiler will likely never be able to | 116 // reference to the list, but the compiler will likely never be able to |
| 117 // tell that this instance of the list cannot have its length changed by | 117 // tell that this instance of the list cannot have its length changed by |
| 118 // the reviver even though it later will be passed to the reviver at the | 118 // the reviver even though it later will be passed to the reviver at the |
| 119 // outer level. | 119 // outer level. |
| 120 var item = JS('', '#[#]', object, i); | 120 var item = JS('', '#[#]', object, i); |
| 121 JS('', '#[#]=#', object, i, _convertJsonToDartLazy(item)); | 121 JS('', '#[#]=#', object, i, _convertJsonToDartLazy(item)); |
| 122 } | 122 } |
| 123 return object; | 123 return object; |
| 124 } | 124 } |
| 125 | 125 |
| 126 class _JsonMap implements LinkedHashMap { | 126 class _JsonMap implements Map<String, dynamic> { |
| 127 // The original JavaScript object remains unchanged until | 127 // The original JavaScript object remains unchanged until |
| 128 // the map is eventually upgraded, in which case we null it | 128 // the map is eventually upgraded, in which case we null it |
| 129 // out to reclaim the memory used by it. | 129 // out to reclaim the memory used by it. |
| 130 var _original; | 130 var _original; |
| 131 | 131 |
| 132 // We keep track of the map entries that we have already | 132 // We keep track of the map entries that we have already |
| 133 // processed by adding them to a separate JavaScript object. | 133 // processed by adding them to a separate JavaScript object. |
| 134 var _processed = _newJavaScriptObject(); | 134 var _processed = _newJavaScriptObject(); |
| 135 | 135 |
| 136 // If the data slot isn't null, it represents either the list | 136 // If the data slot isn't null, it represents either the list |
| (...skipping 12 matching lines...) Expand all Loading... |
| 149 if (_isUnprocessed(result)) result = _process(key); | 149 if (_isUnprocessed(result)) result = _process(key); |
| 150 return result; | 150 return result; |
| 151 } | 151 } |
| 152 } | 152 } |
| 153 | 153 |
| 154 int get length => _isUpgraded ? _upgradedMap.length : _computeKeys().length; | 154 int get length => _isUpgraded ? _upgradedMap.length : _computeKeys().length; |
| 155 | 155 |
| 156 bool get isEmpty => length == 0; | 156 bool get isEmpty => length == 0; |
| 157 bool get isNotEmpty => length > 0; | 157 bool get isNotEmpty => length > 0; |
| 158 | 158 |
| 159 Iterable get keys { | 159 Iterable<String> get keys { |
| 160 if (_isUpgraded) return _upgradedMap.keys; | 160 if (_isUpgraded) return _upgradedMap.keys; |
| 161 return new _JsonMapKeyIterable(this); | 161 return new _JsonMapKeyIterable(this); |
| 162 } | 162 } |
| 163 | 163 |
| 164 Iterable get values { | 164 Iterable get values { |
| 165 if (_isUpgraded) return _upgradedMap.values; | 165 if (_isUpgraded) return _upgradedMap.values; |
| 166 return new MappedIterable(_computeKeys(), (each) => this[each]); | 166 return new MappedIterable(_computeKeys(), (each) => this[each]); |
| 167 } | 167 } |
| 168 | 168 |
| 169 operator []=(key, value) { | 169 operator []=(key, value) { |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 273 | 273 |
| 274 List<String> _computeKeys() { | 274 List<String> _computeKeys() { |
| 275 assert(!_isUpgraded); | 275 assert(!_isUpgraded); |
| 276 List keys = _data; | 276 List keys = _data; |
| 277 if (keys == null) { | 277 if (keys == null) { |
| 278 keys = _data = _getPropertyNames(_original); | 278 keys = _data = _getPropertyNames(_original); |
| 279 } | 279 } |
| 280 return JS('JSExtendableArray', '#', keys); | 280 return JS('JSExtendableArray', '#', keys); |
| 281 } | 281 } |
| 282 | 282 |
| 283 Map _upgrade() { | 283 Map<String, dynamic> _upgrade() { |
| 284 if (_isUpgraded) return _upgradedMap; | 284 if (_isUpgraded) return _upgradedMap; |
| 285 | 285 |
| 286 // Copy all the (key, value) pairs to a freshly allocated | 286 // Copy all the (key, value) pairs to a freshly allocated |
| 287 // linked hash map thus preserving the ordering. | 287 // linked hash map thus preserving the ordering. |
| 288 Map result = {}; | 288 Map result = <String, dynamic>{}; |
| 289 List<String> keys = _computeKeys(); | 289 List<String> keys = _computeKeys(); |
| 290 for (int i = 0; i < keys.length; i++) { | 290 for (int i = 0; i < keys.length; i++) { |
| 291 String key = keys[i]; | 291 String key = keys[i]; |
| 292 result[key] = this[key]; | 292 result[key] = this[key]; |
| 293 } | 293 } |
| 294 | 294 |
| 295 // We only upgrade when we need to extend the map, so we can | 295 // We only upgrade when we need to extend the map, so we can |
| 296 // safely force a concurrent modification error in case | 296 // safely force a concurrent modification error in case |
| 297 // someone is iterating over the map here. | 297 // someone is iterating over the map here. |
| 298 if (keys.isEmpty) { | 298 if (keys.isEmpty) { |
| (...skipping 25 matching lines...) Expand all Loading... |
| 324 static _getProperty(object, String key) => JS('', '#[#]', object, key); | 324 static _getProperty(object, String key) => JS('', '#[#]', object, key); |
| 325 static _setProperty(object, String key, value) => | 325 static _setProperty(object, String key, value) => |
| 326 JS('', '#[#]=#', object, key, value); | 326 JS('', '#[#]=#', object, key, value); |
| 327 static List _getPropertyNames(object) => | 327 static List _getPropertyNames(object) => |
| 328 JS('JSExtendableArray', 'Object.keys(#)', object); | 328 JS('JSExtendableArray', 'Object.keys(#)', object); |
| 329 static bool _isUnprocessed(object) => | 329 static bool _isUnprocessed(object) => |
| 330 JS('bool', 'typeof(#)=="undefined"', object); | 330 JS('bool', 'typeof(#)=="undefined"', object); |
| 331 static _newJavaScriptObject() => JS('=Object', 'Object.create(null)'); | 331 static _newJavaScriptObject() => JS('=Object', 'Object.create(null)'); |
| 332 } | 332 } |
| 333 | 333 |
| 334 class _JsonMapKeyIterable extends ListIterable { | 334 class _JsonMapKeyIterable extends ListIterable<String> { |
| 335 final _JsonMap _parent; | 335 final _JsonMap _parent; |
| 336 | 336 |
| 337 _JsonMapKeyIterable(this._parent); | 337 _JsonMapKeyIterable(this._parent); |
| 338 | 338 |
| 339 int get length => _parent.length; | 339 int get length => _parent.length; |
| 340 | 340 |
| 341 String elementAt(int index) { | 341 String elementAt(int index) { |
| 342 return _parent._isUpgraded | 342 return _parent._isUpgraded |
| 343 ? _parent.keys.elementAt(index) | 343 ? _parent.keys.elementAt(index) |
| 344 : _parent._computeKeys()[index]; | 344 : _parent._computeKeys()[index]; |
| 345 } | 345 } |
| 346 | 346 |
| 347 /// Although [ListIterable] defines its own iterator, we return the iterator | 347 /// Although [ListIterable] defines its own iterator, we return the iterator |
| 348 /// of the underlying list [_keys] in order to propagate | 348 /// of the underlying list [_keys] in order to propagate |
| 349 /// [ConcurrentModificationError]s. | 349 /// [ConcurrentModificationError]s. |
| 350 Iterator get iterator { | 350 Iterator<String> get iterator { |
| 351 return _parent._isUpgraded | 351 return _parent._isUpgraded |
| 352 ? _parent.keys.iterator | 352 ? _parent.keys.iterator |
| 353 : _parent._computeKeys().iterator; | 353 : _parent._computeKeys().iterator; |
| 354 } | 354 } |
| 355 | 355 |
| 356 /// Delegate to [parent.containsKey] to ensure the performance expected | 356 /// Delegate to [parent.containsKey] to ensure the performance expected |
| 357 /// from [Map.keys.containsKey]. | 357 /// from [Map.keys.containsKey]. |
| 358 bool contains(Object key) => _parent.containsKey(key); | 358 bool contains(Object key) => _parent.containsKey(key); |
| 359 } | 359 } |
| 360 | 360 |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 397 return super.fuse(next); | 397 return super.fuse(next); |
| 398 } | 398 } |
| 399 | 399 |
| 400 // Currently not intercepting UTF8 decoding. | 400 // Currently not intercepting UTF8 decoding. |
| 401 @patch | 401 @patch |
| 402 static String _convertIntercepted( | 402 static String _convertIntercepted( |
| 403 bool allowMalformed, List<int> codeUnits, int start, int end) { | 403 bool allowMalformed, List<int> codeUnits, int start, int end) { |
| 404 return null; // This call was not intercepted. | 404 return null; // This call was not intercepted. |
| 405 } | 405 } |
| 406 } | 406 } |
| OLD | NEW |