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

Side by Side Diff: sdk/lib/_internal/lib/convert_patch.dart

Issue 367683002: Use JsonMap even for JSON.decode with custom reviver. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Fix long line in test. Created 6 years, 5 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 | « no previous file | tests/corelib/json_map_test.dart » ('j') | 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) 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 patch; 7 import 'dart:_js_helper' show 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; 10 import 'dart:_internal' show MappedIterable;
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
45 return _convertJsonToDart(parsed, reviver); 45 return _convertJsonToDart(parsed, reviver);
46 } 46 }
47 } 47 }
48 48
49 /** 49 /**
50 * Walks the raw JavaScript value [json], replacing JavaScript Objects with 50 * Walks the raw JavaScript value [json], replacing JavaScript Objects with
51 * Maps. [json] is expected to be freshly allocated so elements can be replaced 51 * Maps. [json] is expected to be freshly allocated so elements can be replaced
52 * in-place. 52 * in-place.
53 */ 53 */
54 _convertJsonToDart(json, reviver(key, value)) { 54 _convertJsonToDart(json, reviver(key, value)) {
55 var revive = reviver == null ? (key, value) => value : reviver; 55 assert(reviver != null);
56
57 walk(e) { 56 walk(e) {
58 // JavaScript null, string, number, bool are in the correct representation. 57 // JavaScript null, string, number, bool are in the correct representation.
59 if (JS('bool', '# == null', e) || JS('bool', 'typeof # != "object"', e)) { 58 if (JS('bool', '# == null', e) || JS('bool', 'typeof # != "object"', e)) {
60 return e; 59 return e;
61 } 60 }
62 61
63 // This test is needed to avoid identifing '{"__proto__":[]}' as an Array. 62 // This test is needed to avoid identifing '{"__proto__":[]}' as an Array.
64 // TODO(sra): Replace this test with cheaper '#.constructor === Array' when 63 // TODO(sra): Replace this test with cheaper '#.constructor === Array' when
65 // bug 621 below is fixed. 64 // bug 621 below is fixed.
66 if (JS('bool', 'Object.getPrototypeOf(#) === Array.prototype', e)) { 65 if (JS('bool', 'Object.getPrototypeOf(#) === Array.prototype', e)) {
67 // Teach compiler the type is known by passing it through a JS-expression.
68 var list = JS('JSExtendableArray', '#', e);
69 // In-place update of the elements since JS Array is a Dart List. 66 // In-place update of the elements since JS Array is a Dart List.
70 for (int i = 0; i < list.length; i++) { 67 for (int i = 0; i < JS('int', '#.length', e); i++) {
71 // Use JS indexing to avoid range checks. We know this is the only 68 // Use JS indexing to avoid range checks. We know this is the only
72 // reference to the list, but the compiler will likely never be able to 69 // reference to the list, but the compiler will likely never be able to
73 // tell that this instance of the list cannot have its length changed by 70 // tell that this instance of the list cannot have its length changed by
74 // the reviver even though it later will be passed to the reviver at the 71 // the reviver even though it later will be passed to the reviver at the
75 // outer level. 72 // outer level.
76 var item = JS('', '#[#]', list, i); 73 var item = JS('', '#[#]', e, i);
77 JS('', '#[#]=#', list, i, revive(i, walk(item))); 74 JS('', '#[#]=#', e, i, reviver(i, walk(item)));
78 } 75 }
79 return list; 76 return e;
80 } 77 }
81 78
82 // Otherwise it is a plain Object, so copy to a Map. 79 // Otherwise it is a plain object, so copy to a JSON map, so we process
83 var keys = JS('JSExtendableArray', 'Object.keys(#)', e); 80 // and revive all entries recursively.
84 Map map = {}; 81 _JsonMap map = new _JsonMap(e);
82 var processed = map._processed;
83 List<String> keys = map._computeKeys();
85 for (int i = 0; i < keys.length; i++) { 84 for (int i = 0; i < keys.length; i++) {
86 String key = keys[i]; 85 String key = keys[i];
87 map[key] = revive(key, walk(JS('', '#[#]', e, key))); 86 var revived = reviver(key, walk(JS('', '#[#]', e, key)));
87 JS('', '#[#]=#', processed, key, revived);
88 } 88 }
89 // V8 has a bug with properties named "__proto__" 89
90 // https://code.google.com/p/v8/issues/detail?id=621 90 // Update the JSON map structure so future access is cheaper.
91 var proto = JS('', '#.__proto__', e); 91 map._original = processed; // Don't keep two objects around.
92 // __proto__ can be undefined on IE9.
93 if (JS('bool',
94 'typeof # !== "undefined" && # !== Object.prototype',
95 proto, proto)) {
96 map['__proto__'] = revive('__proto__', walk(proto));
97 }
98 return map; 92 return map;
99 } 93 }
100 94
101 return revive(null, walk(json)); 95 return reviver(null, walk(json));
102 } 96 }
103 97
104 _convertJsonToDartLazy(object) { 98 _convertJsonToDartLazy(object) {
105 // JavaScript null and undefined are represented as null. 99 // JavaScript null and undefined are represented as null.
106 if (object == null) return null; 100 if (object == null) return null;
107 101
108 // JavaScript string, number, bool already has the correct representation. 102 // JavaScript string, number, bool already has the correct representation.
109 if (JS('bool', 'typeof # != "object"', object)) { 103 if (JS('bool', 'typeof # != "object"', object)) {
110 return object; 104 return object;
111 } 105 }
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
172 166
173 Iterable get values { 167 Iterable get values {
174 if (_isUpgraded) return _upgradedMap.values; 168 if (_isUpgraded) return _upgradedMap.values;
175 return new MappedIterable(_computeKeys(), (each) => this[each]); 169 return new MappedIterable(_computeKeys(), (each) => this[each]);
176 } 170 }
177 171
178 operator[]=(key, value) { 172 operator[]=(key, value) {
179 if (_isUpgraded) { 173 if (_isUpgraded) {
180 _upgradedMap[key] = value; 174 _upgradedMap[key] = value;
181 } else if (containsKey(key)) { 175 } else if (containsKey(key)) {
182 _setProperty(_processed, key, value); 176 var processed = _processed;
183 _setProperty(_original, key, null); // Reclaim memory. 177 _setProperty(processed, key, value);
178 var original = _original;
179 if (!identical(original, processed)) {
180 _setProperty(original, key, null); // Reclaim memory.
181 }
184 } else { 182 } else {
185 _upgrade()[key] = value; 183 _upgrade()[key] = value;
186 } 184 }
187 } 185 }
188 186
189 void addAll(Map other) { 187 void addAll(Map other) {
190 other.forEach((key, value) { 188 other.forEach((key, value) {
191 this[key] = value; 189 this[key] = value;
192 }); 190 });
193 } 191 }
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after
336 static _newJavaScriptObject() 334 static _newJavaScriptObject()
337 => JS('=Object', 'Object.create(null)'); 335 => JS('=Object', 'Object.create(null)');
338 } 336 }
339 337
340 @patch 338 @patch
341 class _Utf8Encoder { 339 class _Utf8Encoder {
342 // Use Uint8List when supported on all platforms. 340 // Use Uint8List when supported on all platforms.
343 @patch 341 @patch
344 static List<int> _createBuffer(int size) => new List<int>(size); 342 static List<int> _createBuffer(int size) => new List<int>(size);
345 } 343 }
OLDNEW
« no previous file with comments | « no previous file | tests/corelib/json_map_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698