Add backwards-compatible json encoding (#66)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index e3f7302..cf4b084 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -20,6 +20,9 @@
serialization/deserialization implementation. This will eventually be used by
default by dart2js.
+* Added backwards compatibility to the JSON codec, to make transition to new
+ tools more gradual.
+
## 0.5.17
* Make `live_code_size_analysis` print library URIs and not library names.
diff --git a/lib/json_info_codec.dart b/lib/json_info_codec.dart
index 161e177..3a0f87f 100644
--- a/lib/json_info_codec.dart
+++ b/lib/json_info_codec.dart
@@ -329,8 +329,13 @@
class AllInfoToJsonConverter extends Converter<AllInfo, Map>
implements InfoVisitor<Map> {
+ /// Whether to generate json compatible with format 5.1
+ final bool isBackwardCompatible;
final Map<Info, Id> ids = new HashMap<Info, Id>();
final Set<String> usedIds = new Set<String>();
+ final Set<int> usedOldIds = new Set<int>();
+
+ AllInfoToJsonConverter({this.isBackwardCompatible: false});
Id idFor(Info info) {
var serializedId = ids[info];
@@ -344,25 +349,42 @@
"$info");
String id;
+ int oldId;
if (info is ConstantInfo) {
// No name and no parent, so `longName` isn't helpful
assert(info.name == null);
assert(info.parent == null);
assert(info.code != null);
// Instead, use the content of the code.
- id = info.code.first.text ?? "_";
+ if (isBackwardCompatible) {
+ oldId = info.code.first.text.hashCode;
+ } else {
+ id = info.code.first.text ?? "_";
+ }
} else {
id = longName(info, useLibraryUri: true, forId: true);
- if (info is FieldInfo || info is FunctionInfo || info is ClosureInfo) {
- id = "${id}_${info.size}";
+ if (isBackwardCompatible) {
+ oldId = id.hashCode;
+ } else {
+ if (info is FieldInfo || info is FunctionInfo || info is ClosureInfo) {
+ id = "${id}_${info.size}";
+ }
}
}
- int suffix = 0;
+
String candidateId;
- do {
- candidateId = id + (suffix == 0 ? '' : '.$suffix');
- suffix++;
- } while (!usedIds.add(candidateId));
+ if (isBackwardCompatible) {
+ while (!usedOldIds.add(oldId)) {
+ oldId++;
+ }
+ candidateId = '$oldId';
+ } else {
+ int suffix = 0;
+ do {
+ candidateId = id + (suffix == 0 ? '' : '.$suffix');
+ suffix++;
+ } while (!usedIds.add(candidateId));
+ }
serializedId = new Id(info.kind, candidateId);
return ids[info] = serializedId;
}
@@ -432,9 +454,9 @@
'holding': jsonHolding,
'dependencies': jsonDependencies,
'outputUnits': info.outputUnits.map((u) => u.accept(this)).toList(),
- 'dump_version': info.version,
+ 'dump_version': isBackwardCompatible ? 5 : info.version,
'deferredFiles': info.deferredFiles,
- 'dump_minor_version': info.minorVersion,
+ 'dump_minor_version': isBackwardCompatible ? 1 : info.minorVersion,
'program': info.program.accept(this)
};
}
@@ -564,7 +586,10 @@
visitOutput(OutputUnitInfo info) =>
_visitBasicInfo(info)..['imports'] = info.imports;
- List<Object> _serializeCode(List<CodeSpan> code) {
+ Object _serializeCode(List<CodeSpan> code) {
+ if (isBackwardCompatible) {
+ return code.map((c) => c.text).join('\n');
+ }
return code
.map<Object>((c) => {
'start': c.start,
@@ -576,8 +601,12 @@
}
class AllInfoJsonCodec extends Codec<AllInfo, Map> {
- final Converter<AllInfo, Map> encoder = new AllInfoToJsonConverter();
+ final Converter<AllInfo, Map> encoder;
final Converter<Map, AllInfo> decoder = new JsonToAllInfoConverter();
+
+ AllInfoJsonCodec({bool isBackwardCompatible: false})
+ : encoder = new AllInfoToJsonConverter(
+ isBackwardCompatible: isBackwardCompatible);
}
class Id {