| // Copyright (c) 2015, 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. |
| |
| library dart2js.serialization.json; |
| |
| import 'dart:convert'; |
| import 'keys.dart'; |
| import 'serialization.dart'; |
| import 'values.dart'; |
| |
| /// Serialization encoder for JSON. |
| class JsonSerializationEncoder implements SerializationEncoder { |
| const JsonSerializationEncoder(); |
| |
| String encode(ObjectValue objectValue) { |
| return new JsonEncoder.withIndent(' ').convert( |
| const JsonValueEncoder().convert(objectValue)); |
| } |
| } |
| |
| /// Serialization decoder for JSON. |
| class JsonSerializationDecoder implements SerializationDecoder { |
| const JsonSerializationDecoder(); |
| |
| Map decode(String text) => JSON.decode(text); |
| |
| /// Returns the name of the [key] which used for to store a [Key] into a |
| /// [Map]; corresponding to the encoding of object properties in |
| /// [JsonValueEncoder.visitObject]. |
| getObjectPropertyValue(Key key) => key.name; |
| } |
| |
| /// A [ValueVisitor] that computes a JSON object value. |
| class JsonValueEncoder implements ValueVisitor { |
| const JsonValueEncoder(); |
| |
| convert(Value value) => visit(value, null); |
| |
| @override |
| visit(Value value, [arg]) => value.accept(this, arg); |
| |
| @override |
| bool visitBool(BoolValue value, arg) => value.value; |
| |
| @override |
| visitConstant(ConstantValue value, arg) => visit(value.id); |
| |
| @override |
| double visitDouble(DoubleValue value, arg) => value.value; |
| |
| @override |
| visitElement(ElementValue value, arg) => visit(value.id); |
| |
| @override |
| visitEnum(EnumValue value, arg) => value.value.index; |
| |
| @override |
| int visitInt(IntValue value, arg) => value.value; |
| |
| @override |
| List visitList(ListValue value, arg) => value.values.map(visit).toList(); |
| |
| @override |
| Map visitMap(MapValue value, arg) { |
| Map<String, dynamic> map = <String, dynamic>{}; |
| value.map.forEach((String key, Value value) { |
| map[key] = visit(value); |
| }); |
| return map; |
| } |
| |
| @override |
| Map visitObject(ObjectValue value, arg) { |
| Map<String, dynamic> map = <String, dynamic>{}; |
| value.map.forEach((Key key, Value value) { |
| map[key.name] = visit(value); |
| }); |
| return map; |
| } |
| |
| @override |
| String visitString(StringValue value, arg) => value.value; |
| |
| @override |
| visitType(TypeValue value, arg) => visit(value.id); |
| |
| @override |
| visitUri(UriValue value, arg) => '${value.value}'; |
| } |
| |
| /// [ValueVisitor] that generates a verbose JSON-like output. |
| class PrettyPrintEncoder implements ValueVisitor { |
| StringBuffer buffer; |
| |
| String toText(Value value) { |
| buffer = new StringBuffer(); |
| visit(value, ''); |
| String text = buffer.toString(); |
| buffer = null; |
| return text; |
| } |
| |
| @override |
| void visit(Value value, String indentation) { |
| value.accept(this, indentation); |
| } |
| |
| @override |
| void visitBool(BoolValue value, String indentation) { |
| buffer.write(value.value); |
| } |
| |
| @override |
| void visitConstant(ConstantValue value, String indentation) { |
| buffer.write('Constant(${value.id}):${value.constant.getText()}'); |
| } |
| |
| @override |
| void visitDouble(DoubleValue value, String indentation) { |
| buffer.write(value.value); |
| } |
| @override |
| void visitElement(ElementValue value, String indentation) { |
| buffer.write('Element(${value.id}):${value.element}'); |
| } |
| |
| @override |
| void visitEnum(EnumValue value, String indentation) { |
| buffer.write(value.value); |
| } |
| |
| @override |
| void visitInt(IntValue value, String indentation) { |
| buffer.write(value.value); |
| } |
| |
| @override |
| void visitList(ListValue value, String indentation) { |
| if (value.values.isEmpty) { |
| buffer.write('[]'); |
| } else { |
| buffer.write('['); |
| bool needsComma = false; |
| String nextIndentation = '${indentation} '; |
| for (Value element in value.values) { |
| if (needsComma) { |
| buffer.write(','); |
| } |
| buffer.write('\n$nextIndentation'); |
| visit(element, nextIndentation); |
| needsComma = true; |
| } |
| buffer.write('\n$indentation]'); |
| } |
| } |
| |
| @override |
| void visitMap(MapValue value, String indentation) { |
| if (value.map.isEmpty) { |
| buffer.write('{}'); |
| } else { |
| buffer.write('{'); |
| bool needsComma = false; |
| String nextIndentation = '${indentation} '; |
| value.map.forEach((String key, Value subvalue) { |
| if (needsComma) { |
| buffer.write(','); |
| } |
| buffer.write('\n$nextIndentation$key: '); |
| visit(subvalue, nextIndentation); |
| needsComma = true; |
| }); |
| buffer.write('\n$indentation}'); |
| } |
| } |
| |
| @override |
| void visitObject(ObjectValue value, String indentation) { |
| if (value.map.isEmpty) { |
| buffer.write('{}'); |
| } else { |
| buffer.write('{'); |
| bool needsComma = false; |
| String nextIndentation = '${indentation} '; |
| value.map.forEach((Key key, Value subvalue) { |
| if (needsComma) { |
| buffer.write(','); |
| } |
| buffer.write('\n$nextIndentation$key: '); |
| visit(subvalue, nextIndentation); |
| needsComma = true; |
| }); |
| buffer.write('\n$indentation}'); |
| } |
| } |
| |
| @override |
| void visitString(StringValue value, String indentation) { |
| buffer.write('"${value.value}"'); |
| } |
| |
| @override |
| void visitType(TypeValue value, String indentation) { |
| buffer.write('Type(${value.id}):${value.type}'); |
| } |
| |
| @override |
| void visitUri(UriValue value, String indentation) { |
| buffer.write('Uri(${value.value})'); |
| } |
| } |