Index: sdk/lib/_internal/compiler/implementation/lib/json_patch.dart |
diff --git a/sdk/lib/_internal/compiler/implementation/lib/json_patch.dart b/sdk/lib/_internal/compiler/implementation/lib/json_patch.dart |
new file mode 100644 |
index 0000000000000000000000000000000000000000..14642bf4ccbb554ac0af78c1fbe8554bd9d83697 |
--- /dev/null |
+++ b/sdk/lib/_internal/compiler/implementation/lib/json_patch.dart |
@@ -0,0 +1,66 @@ |
+// Patch file for dart:json library. |
Lasse Reichstein Nielsen
2013/01/31 06:58:44
Needs copyright header.
sra1
2013/01/31 22:49:36
Done.
|
+ |
+import 'dart:_foreign_helper' show JS; |
+ |
+part of dart.json; |
Lasse Reichstein Nielsen
2013/01/31 06:58:44
Does this parse? You usually can't have "part of"
Johnni Winther
2013/01/31 08:32:59
Yes, it looks odd. It should be removed.
sra1
2013/01/31 22:49:36
Done.
|
+ |
+/** |
+ * Parses [json] and build the corresponding parsed JSON value. |
+ * |
+ * Parsed JSON values are of the types [num], [String], [bool], [Null], |
+ * [List]s of parsed JSON values or [Map]s from [String] to parsed |
+ * JSON values. |
+ * |
+ * The optional [revivier] function, if provided, is called once for each object |
Johnni Winther
2013/01/31 08:32:59
revivier -> reviver
sra1
2013/01/31 22:49:36
Done.
|
+ * or list property parsed. The arguments are the property name ([String]) or |
+ * list index ([int]), and the value is the parsed value. The return value of |
+ * the revivier will be used as the value of that property instead the parsed |
Johnni Winther
2013/01/31 08:32:59
ditto
sra1
2013/01/31 22:49:36
Done.
|
+ * value. The top level value is passed to the reviver with the empty string as |
+ * a key. |
+ * |
+ * Throws [FormatException] if the input is not valid JSON text. |
+ */ |
+patch parse(String json, [reviver(var key, var value)]) { |
Lasse Reichstein Nielsen
2013/01/31 06:58:44
You can't patch a function that isn't marked exter
Johnni Winther
2013/01/31 08:32:59
There is a pending CL that enforces this.
sra1
2013/01/31 22:49:36
Which CL is that?
Please don't commit until I have
Johnni Winther
2013/02/01 06:20:10
The CL is https://codereview.chromium.org/11864010
|
+ if (json is! String) throw new ArgumentError(json); |
+ |
+ var parsed; |
+ try { |
+ parsed = JS('=Object|=List|Null|bool|num|String', 'JSON.parse(#)', json); |
+ } catch (e) { |
+ throw new FormatException(JS('String', 'String(#)', e)); |
+ } |
+ |
+ return _convertJsonToDart(parsed, reviver); |
+} |
+ |
+/** |
+ * Walks the [json] value, replacing JavaScript Objects with Maps. |
+ */ |
+_convertJsonToDart(json, reviver(key, value)) { |
+ |
+ var revive = reviver == null ? (key, value) => value : reviver; |
+ |
+ walk(e) { |
Lasse Reichstein Nielsen
2013/01/31 06:58:44
Here "e" is really a JS object, not a Dart object,
sra1
2013/01/31 22:49:36
Done.
|
+ if (e is String) return e; |
+ if (e is num) return e; |
+ if (e is bool) return e; |
+ if (e == null) return e; |
+ if (e is List) { |
+ // In-place update of the elements since JS Array is a Dart List. |
+ for (int i = 0; i < e.length; i++) { |
+ e[i] = revive(i, walk(e[i])); |
+ } |
+ return e; |
+ } |
+ // Else it is a plain Object, copy to a Map. |
+ var keys = JS('=List', 'Object.keys(#)', e); |
Lasse Reichstein Nielsen
2013/01/31 06:58:44
Notice that V8 still has a bug handling keys named
sra1
2013/01/31 22:49:36
Interesting.
Object.keys(o) for this example retur
|
+ var map = {}; |
+ for (int i = 0; i < keys.length; i++) { |
+ String key = keys[i]; |
+ map[key] = revive(key, walk(JS('', '#[#]', e, key))); |
+ } |
+ return map; |
+ } |
+ |
+ return revive('', walk(json)); |
+} |