blob: 399bdbfb7157eacc0765d29ccae38985b611c53c [file] [log] [blame]
// 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})');
}
}