| Index: sdk/lib/_internal/dartdoc/lib/src/json_serializer.dart
|
| ===================================================================
|
| --- sdk/lib/_internal/dartdoc/lib/src/json_serializer.dart (revision 32349)
|
| +++ sdk/lib/_internal/dartdoc/lib/src/json_serializer.dart (working copy)
|
| @@ -1,257 +0,0 @@
|
| -// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
|
| -// for details. All rights reserved. Use of this source code is governed by a
|
| -// BSD-style license that can be found in the LICENSE file.
|
| -
|
| -/**
|
| - * Simple library to serialize acyclic Dart types to JSON.
|
| - * This library is not intended for broad consumption and should be replaced
|
| - * with a more generic Dart serialization library when one is available.
|
| - */
|
| -library json_serializer;
|
| -
|
| -import 'dart:async';
|
| -import 'dart:convert';
|
| -import 'dart:mirrors';
|
| -
|
| -String serialize(Object o) {
|
| - var printer = new JsonPrinter();
|
| - _serialize(null, o, printer);
|
| - return printer.toString();
|
| -}
|
| -
|
| -/// Serialize the object with pretty printing.
|
| -String prettySerialize(Object o) {
|
| - var printer = new JsonPrinter(prettyPrint: true);
|
| - _serialize(null, o, printer);
|
| - return printer.toString();
|
| -}
|
| -
|
| -
|
| -void _serialize(String name, Object o, JsonPrinter printer) {
|
| - if (o == null) return;
|
| -
|
| - if (o is List) {
|
| - _serializeList(name, o, printer);
|
| - } else if (o is Map) {
|
| - _serializeMap(name, o, printer);
|
| - } else if (o is String) {
|
| - printer.addString(name, o);
|
| - } else if (o is bool) {
|
| - printer.addBool(name, o);
|
| - } else {
|
| - _serializeObject(name, o, printer);
|
| - }
|
| -}
|
| -
|
| -void _serializeObject(String name, Object o, JsonPrinter printer) {
|
| - printer.startObject(name);
|
| -
|
| - var mirror = reflect(o);
|
| - var classMirror = mirror.type;
|
| - var members = <String>[];
|
| - determineAllMembers(classMirror, members);
|
| -
|
| - // TODO(jacobr): this code works only because futures for mirrors return
|
| - // immediately.
|
| - for(String memberName in members) {
|
| - var result = mirror.getField(new Symbol(memberName));
|
| - _serialize(memberName, result.reflectee, printer);
|
| - }
|
| - printer.endObject();
|
| -}
|
| -
|
| -void determineAllMembers(ClassMirror classMirror,
|
| - List<String> members) {
|
| - for (var mirror in classMirror.declarations.values) {
|
| - if (mirror is VariableMirror ||
|
| - (mirror is MethodMirror && mirror.isGetter)) {
|
| - if (!members.contains(MirrorSystem.getName(mirror.simpleName))) {
|
| - members.add(MirrorSystem.getName(mirror.simpleName));
|
| - }
|
| - }
|
| - }
|
| - if (classMirror.superclass != null &&
|
| -
|
| - // TODO(ahe): What is this test for? Consider removing it,
|
| - // dart2js will issue an error if there is a cycle in superclass
|
| - // hierarchy.
|
| - classMirror.superclass.qualifiedName != classMirror.qualifiedName &&
|
| -
|
| - MirrorSystem.getName(classMirror.superclass.qualifiedName) !=
|
| - 'dart.core.Object') {
|
| - determineAllMembers(classMirror.superclass, members);
|
| - }
|
| -}
|
| -
|
| -void _serializeList(String name, List l, JsonPrinter printer) {
|
| - printer.startList(name);
|
| - for(var o in l) {
|
| - _serialize(null, o, printer);
|
| - }
|
| - printer.endList();
|
| -}
|
| -
|
| -void _serializeMap(String name, Map m, JsonPrinter printer) {
|
| - printer.startObject(name);
|
| - m.forEach((key, value) =>
|
| - _serialize(key, value, printer));
|
| - printer.endObject();
|
| -}
|
| -
|
| -class JsonPrinter {
|
| - static const int BACKSPACE = 8;
|
| - static const int TAB = 9;
|
| - static const int NEW_LINE = 10;
|
| - static const int FORM_FEED = 12;
|
| - static const int CARRIAGE_RETURN = 13;
|
| - static const int QUOTE = 34;
|
| - static const int BACKSLASH = 92;
|
| - static const int CHAR_B = 98;
|
| - static const int CHAR_F = 102;
|
| - static const int CHAR_N = 110;
|
| - static const int CHAR_R = 114;
|
| - static const int CHAR_T = 116;
|
| - static const int CHAR_U = 117;
|
| -
|
| - StringBuffer _sb;
|
| - int _indent = 0;
|
| - bool _inSet = false;
|
| -
|
| - bool prettyPrint;
|
| - JsonPrinter({this.prettyPrint: false}) {
|
| - _sb = new StringBuffer();
|
| - }
|
| -
|
| - void startObject(String name) {
|
| - _start(name);
|
| - _sb.write('{');
|
| -
|
| - _indent += 1;
|
| - _inSet = false;
|
| - }
|
| -
|
| - void endObject() {
|
| - _indent -= 1;
|
| - if (_inSet) {
|
| - _newline();
|
| - }
|
| - _sb.write('}');
|
| - _inSet = true;
|
| - }
|
| -
|
| - void startList(String name) {
|
| - _start(name);
|
| - _inSet = false;
|
| -
|
| - _sb.write('[');
|
| - _indent += 1;
|
| - }
|
| -
|
| - void endList() {
|
| - _indent -= 1;
|
| - if (_inSet) {
|
| - _newline();
|
| - }
|
| - _sb.write(']');
|
| - _inSet = true;
|
| - }
|
| -
|
| - void addString(String name, String value) {
|
| - _start(name);
|
| - _sb.write('"');
|
| - _escape(_sb, value);
|
| - _sb.write('"');
|
| - _inSet = true;
|
| - }
|
| -
|
| - void addBool(String name, bool value) {
|
| - _start(name);
|
| - _sb.write(value.toString());
|
| - _inSet = true;
|
| - }
|
| -
|
| - void addNum(String name, num value) {
|
| - _start(name);
|
| - _sb.write(value.toString());
|
| - _inSet = true;
|
| - }
|
| -
|
| - void _start(String name) {
|
| - if (_inSet) {
|
| - _sb.write(',');
|
| - }
|
| - // Do not print a newline at the beginning of the file.
|
| - if (!_sb.isEmpty) {
|
| - _newline();
|
| - }
|
| - if (name != null) {
|
| - _sb.write('"$name": ');
|
| - }
|
| - }
|
| -
|
| - void _newline([int indent = 0]) {
|
| - _sb.write('\n');
|
| - _indent += indent;
|
| -
|
| - for (var i = 0; i < _indent; ++i) {
|
| - _sb.write(' ');
|
| - }
|
| - }
|
| -
|
| - String toString() {
|
| - if (prettyPrint) {
|
| - return _sb.toString();
|
| - } else {
|
| - // Convenient hack to remove the pretty printing this serializer adds by
|
| - // default.
|
| - return JSON.encode(JSON.decode(_sb.toString()));
|
| - }
|
| - }
|
| -
|
| - static int _hexDigit(int x) => x < 10 ? 48 + x : 87 + x;
|
| -
|
| - static void _escape(StringBuffer sb, String s) {
|
| - final int length = s.length;
|
| - bool needsEscape = false;
|
| - final codeUnits = new List<int>();
|
| - for (int i = 0; i < length; i++) {
|
| - int codeUnit = s.codeUnitAt(i);
|
| - if (codeUnit < 32) {
|
| - needsEscape = true;
|
| - codeUnits.add(JsonPrinter.BACKSLASH);
|
| - switch (codeUnit) {
|
| - case JsonPrinter.BACKSPACE:
|
| - codeUnits.add(JsonPrinter.CHAR_B);
|
| - break;
|
| - case JsonPrinter.TAB:
|
| - codeUnits.add(JsonPrinter.CHAR_T);
|
| - break;
|
| - case JsonPrinter.NEW_LINE:
|
| - codeUnits.add(JsonPrinter.CHAR_N);
|
| - break;
|
| - case JsonPrinter.FORM_FEED:
|
| - codeUnits.add(JsonPrinter.CHAR_F);
|
| - break;
|
| - case JsonPrinter.CARRIAGE_RETURN:
|
| - codeUnits.add(JsonPrinter.CHAR_R);
|
| - break;
|
| - default:
|
| - codeUnits.add(JsonPrinter.CHAR_U);
|
| - codeUnits.add(_hexDigit((codeUnit >> 12) & 0xf));
|
| - codeUnits.add(_hexDigit((codeUnit >> 8) & 0xf));
|
| - codeUnits.add(_hexDigit((codeUnit >> 4) & 0xf));
|
| - codeUnits.add(_hexDigit(codeUnit & 0xf));
|
| - break;
|
| - }
|
| - } else if (codeUnit == JsonPrinter.QUOTE ||
|
| - codeUnit == JsonPrinter.BACKSLASH) {
|
| - needsEscape = true;
|
| - codeUnits.add(JsonPrinter.BACKSLASH);
|
| - codeUnits.add(codeUnit);
|
| - } else {
|
| - codeUnits.add(codeUnit);
|
| - }
|
| - }
|
| - sb.write(needsEscape ? new String.fromCharCodes(codeUnits) : s);
|
| - }
|
| -}
|
|
|