Skip to content

Commit dc9516a

Browse files
authored
Add backwards-compatible json encoding (flutter#66)
1 parent 8439f0c commit dc9516a

File tree

2 files changed

+44
-12
lines changed

2 files changed

+44
-12
lines changed

CHANGELOG.md

+3
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@
2020
serialization/deserialization implementation. This will eventually be used by
2121
default by dart2js.
2222

23+
* Added backwards compatibility to the JSON codec, to make transition to new
24+
tools more gradual.
25+
2326
## 0.5.17
2427

2528
* Make `live_code_size_analysis` print library URIs and not library names.

lib/json_info_codec.dart

+41-12
Original file line numberDiff line numberDiff line change
@@ -329,8 +329,13 @@ class JsonToAllInfoConverter extends Converter<Map<String, dynamic>, AllInfo> {
329329

330330
class AllInfoToJsonConverter extends Converter<AllInfo, Map>
331331
implements InfoVisitor<Map> {
332+
/// Whether to generate json compatible with format 5.1
333+
final bool isBackwardCompatible;
332334
final Map<Info, Id> ids = new HashMap<Info, Id>();
333335
final Set<String> usedIds = new Set<String>();
336+
final Set<int> usedOldIds = new Set<int>();
337+
338+
AllInfoToJsonConverter({this.isBackwardCompatible: false});
334339

335340
Id idFor(Info info) {
336341
var serializedId = ids[info];
@@ -344,25 +349,42 @@ class AllInfoToJsonConverter extends Converter<AllInfo, Map>
344349
"$info");
345350

346351
String id;
352+
int oldId;
347353
if (info is ConstantInfo) {
348354
// No name and no parent, so `longName` isn't helpful
349355
assert(info.name == null);
350356
assert(info.parent == null);
351357
assert(info.code != null);
352358
// Instead, use the content of the code.
353-
id = info.code.first.text ?? "_";
359+
if (isBackwardCompatible) {
360+
oldId = info.code.first.text.hashCode;
361+
} else {
362+
id = info.code.first.text ?? "_";
363+
}
354364
} else {
355365
id = longName(info, useLibraryUri: true, forId: true);
356-
if (info is FieldInfo || info is FunctionInfo || info is ClosureInfo) {
357-
id = "${id}_${info.size}";
366+
if (isBackwardCompatible) {
367+
oldId = id.hashCode;
368+
} else {
369+
if (info is FieldInfo || info is FunctionInfo || info is ClosureInfo) {
370+
id = "${id}_${info.size}";
371+
}
358372
}
359373
}
360-
int suffix = 0;
374+
361375
String candidateId;
362-
do {
363-
candidateId = id + (suffix == 0 ? '' : '.$suffix');
364-
suffix++;
365-
} while (!usedIds.add(candidateId));
376+
if (isBackwardCompatible) {
377+
while (!usedOldIds.add(oldId)) {
378+
oldId++;
379+
}
380+
candidateId = '$oldId';
381+
} else {
382+
int suffix = 0;
383+
do {
384+
candidateId = id + (suffix == 0 ? '' : '.$suffix');
385+
suffix++;
386+
} while (!usedIds.add(candidateId));
387+
}
366388
serializedId = new Id(info.kind, candidateId);
367389
return ids[info] = serializedId;
368390
}
@@ -432,9 +454,9 @@ class AllInfoToJsonConverter extends Converter<AllInfo, Map>
432454
'holding': jsonHolding,
433455
'dependencies': jsonDependencies,
434456
'outputUnits': info.outputUnits.map((u) => u.accept(this)).toList(),
435-
'dump_version': info.version,
457+
'dump_version': isBackwardCompatible ? 5 : info.version,
436458
'deferredFiles': info.deferredFiles,
437-
'dump_minor_version': info.minorVersion,
459+
'dump_minor_version': isBackwardCompatible ? 1 : info.minorVersion,
438460
'program': info.program.accept(this)
439461
};
440462
}
@@ -564,7 +586,10 @@ class AllInfoToJsonConverter extends Converter<AllInfo, Map>
564586
visitOutput(OutputUnitInfo info) =>
565587
_visitBasicInfo(info)..['imports'] = info.imports;
566588

567-
List<Object> _serializeCode(List<CodeSpan> code) {
589+
Object _serializeCode(List<CodeSpan> code) {
590+
if (isBackwardCompatible) {
591+
return code.map((c) => c.text).join('\n');
592+
}
568593
return code
569594
.map<Object>((c) => {
570595
'start': c.start,
@@ -576,8 +601,12 @@ class AllInfoToJsonConverter extends Converter<AllInfo, Map>
576601
}
577602

578603
class AllInfoJsonCodec extends Codec<AllInfo, Map> {
579-
final Converter<AllInfo, Map> encoder = new AllInfoToJsonConverter();
604+
final Converter<AllInfo, Map> encoder;
580605
final Converter<Map, AllInfo> decoder = new JsonToAllInfoConverter();
606+
607+
AllInfoJsonCodec({bool isBackwardCompatible: false})
608+
: encoder = new AllInfoToJsonConverter(
609+
isBackwardCompatible: isBackwardCompatible);
581610
}
582611

583612
class Id {

0 commit comments

Comments
 (0)