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 |