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

Unified Diff: sdk/lib/json/json.dart

Issue 25548010: Make JSON encoder take extra function argument to use instead of toJson calls. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Rename convert function to "toEncodable". Created 7 years, 2 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « sdk/lib/convert/json.dart ('k') | tests/json/json_test.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: sdk/lib/json/json.dart
diff --git a/sdk/lib/json/json.dart b/sdk/lib/json/json.dart
index 114feea544c6ff11cfefac09ae8f5d2a5a6fb866..ba9b7ac89cfb2f4d5b92596c3c066641eb0c4e0f 100644
--- a/sdk/lib/json/json.dart
+++ b/sdk/lib/json/json.dart
@@ -11,6 +11,7 @@ library dart.json;
import "dart:convert";
import "dart:_collection-dev" show deprecated;
+import "dart:collection" show HashSet;
export "dart:convert" show JsonUnsupportedObjectError, JsonCyclicError;
// JSON parsing and serialization.
@@ -51,28 +52,31 @@ parse(String json, [reviver(var key, var value)]) {
* For [List], the elements must all be serializable.
* For [Map], the keys must be [String] and the values must be serializable.
*
- * If a value is any other type is attempted serialized, a "toJson()" method
- * is invoked on the object and the result, which must be a directly
- * serializable value, is serialized instead of the original value.
+ * If a value is any other type is attempted serialized, the [toEncodable]
+ * method is called with the object as argument, and the result, which must be a
+ * directly serializable value, is serialized instead of the original value.
+ * If [toEncodable] is omitted, the default is to call `object.toJson()` on the
+ * object.
*
- * If the object does not support this method, throws, or returns a
- * value that is not directly serializable, a [JsonUnsupportedObjectError]
- * exception is thrown. If the call throws (including the case where there
- * is no nullary "toJson" method, the error is caught and stored in the
+ * If the conversion throws, or returns a value that is not directly
+ * serializable, a [JsonUnsupportedObjectError] exception is thrown.
+ * If the call throws (including the case where there
+ * is no nullary "toJson" method), the error is caught and stored in the
* [JsonUnsupportedObjectError]'s [:cause:] field.
*
* If a [List] or [Map] contains a reference to itself, directly or through
* other lists or maps, it cannot be serialized and a [JsonCyclicError] is
* thrown.
*
- * Json Objects should not change during serialization.
+ * The objects being serialized should not change during serialization.
* If an object is serialized more than once, [stringify] is allowed to cache
* the JSON text for it. I.e., if an object changes after it is first
* serialized, the new values may or may not be reflected in the result.
*/
@deprecated
-String stringify(Object object) {
- return _JsonStringifier.stringify(object);
+String stringify(Object object, [toEncodable(object)]) {
+ if (toEncodable == null) toEncodable = _defaultToEncodable;
+ return _JsonStringifier.stringify(object, toEncodable);
}
/**
@@ -87,8 +91,9 @@ String stringify(Object object) {
* [output], but it won't contain valid JSON text.
*/
@deprecated
-void printOn(Object object, StringSink output) {
- return _JsonStringifier.printOn(object, output);
+void printOn(Object object, StringSink output, [ toEncodable(object) ]) {
+ if (toEncodable == null) toEncodable = _defaultToEncodable;
+ return _JsonStringifier.printOn(object, output, toEncodable);
}
//// Implementation ///////////////////////////////////////////////////////////
@@ -643,22 +648,25 @@ class JsonParser {
}
}
+Object _defaultToEncodable(object) => object.toJson();
class _JsonStringifier {
- StringSink sink;
- List<Object> seen; // TODO: that should be identity set.
+ final Function toEncodable;
+ final StringSink sink;
+ final Set<Object> seen;
- _JsonStringifier(this.sink) : seen = [];
+ _JsonStringifier(this.sink, this.toEncodable)
+ : this.seen = new HashSet.identity();
- static String stringify(final object) {
+ static String stringify(final object, toEncodable(object)) {
StringBuffer output = new StringBuffer();
- _JsonStringifier stringifier = new _JsonStringifier(output);
+ _JsonStringifier stringifier = new _JsonStringifier(output, toEncodable);
stringifier.stringifyValue(object);
return output.toString();
}
- static void printOn(final object, StringSink output) {
- _JsonStringifier stringifier = new _JsonStringifier(output);
+ static void printOn(final object, StringSink output, toEncodable(object)) {
+ _JsonStringifier stringifier = new _JsonStringifier(output, toEncodable);
stringifier.stringifyValue(object);
}
@@ -715,11 +723,8 @@ class _JsonStringifier {
}
void checkCycle(final object) {
- // TODO: use Iterables.
- for (int i = 0; i < seen.length; i++) {
- if (identical(seen[i], object)) {
- throw new JsonCyclicError(object);
- }
+ if (seen.contains(object)) {
+ throw new JsonCyclicError(object);
}
seen.add(object);
}
@@ -731,11 +736,11 @@ class _JsonStringifier {
if (!stringifyJsonValue(object)) {
checkCycle(object);
try {
- var customJson = object.toJson();
+ var customJson = toEncodable(object);
if (!stringifyJsonValue(customJson)) {
throw new JsonUnsupportedObjectError(object);
}
- seen.removeLast();
+ seen.remove(object);
} catch (e) {
throw new JsonUnsupportedObjectError(object, cause: e);
}
@@ -780,7 +785,7 @@ class _JsonStringifier {
}
}
sink.write(']');
- seen.removeLast();
+ seen.remove(object);
return true;
} else if (object is Map) {
checkCycle(object);
@@ -799,7 +804,7 @@ class _JsonStringifier {
first = false;
});
sink.write('}');
- seen.removeLast();
+ seen.remove(object);
return true;
} else {
return false;
« no previous file with comments | « sdk/lib/convert/json.dart ('k') | tests/json/json_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698