Add CodeSpan to represent code sections in dump info
diff --git a/CHANGELOG.md b/CHANGELOG.md
index f9a4cf4..65d6f80 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,14 @@
properties were only used for serialization and deserialization. Those values
are now computed during the serialization process instead.
+* Added `CodeSpan` - a representation of code regions referring to output files.
+ This will be used to transition to a lighterweight dump-info that doesn't
+ embed code snippets (since they are duplicated with the output program).
+
+ Encoder produces a new format for code-spans, but for a transitional period
+ the decoder is still backwards compatible (filling in just the `text` in
+ `CodeSpan` where the json contained a String).
+
## 0.5.17
* Make `live_code_size_analysis` print library URIs and not library names.
diff --git a/lib/info.dart b/lib/info.dart
index a3cb639..62a2de9 100644
--- a/lib/info.dart
+++ b/lib/info.dart
@@ -120,14 +120,14 @@
/// Major version indicating breaking changes in the format. A new version
/// means that an old deserialization algorithm will not work with the new
/// format.
- final int version = 5;
+ final int version = 6;
/// Minor version indicating non-breaking changes in the format. A change in
/// this version number means that the json parsing in this library from a
/// previous will continue to work after the change. This is typically
/// increased when adding new entries to the file format.
// Note: the dump-info.viewer app was written using a json parser version 3.2.
- final int minorVersion = 1;
+ final int minorVersion = 0;
AllInfo();
@@ -249,11 +249,28 @@
T accept<T>(InfoVisitor<T> visitor) => visitor.visitClass(this);
}
+/// Details about generated code spans.
+class CodeSpan {
+ /// File where the code was generated.
+ OutputUnitInfo outputUnit;
+
+ /// Start offset in the generated file.
+ int start;
+
+ /// end offset in the generated file.
+ int end;
+
+ /// The actual code.
+ String text;
+
+ CodeSpan({this.outputUnit, this.start, this.end, this.text});
+}
+
/// Information about a constant value.
// TODO(sigmund): add dependency data for ConstantInfo
class ConstantInfo extends BasicInfo {
/// The actual generated code for the constant.
- String code;
+ List<CodeSpan> code;
// TODO(sigmund): Add coverage support to constants?
ConstantInfo({int size: 0, this.code, OutputUnitInfo outputUnit})
@@ -276,7 +293,7 @@
List<ClosureInfo> closures;
/// The actual generated code for the field.
- String code;
+ List<CodeSpan> code;
/// Whether this corresponds to a const field declaration.
bool isConst;
@@ -350,7 +367,7 @@
int inlinedCount;
/// The actual generated code.
- String code;
+ List<CodeSpan> code;
/// Measurements collected for this function.
Measurements measurements;
diff --git a/lib/json_info_codec.dart b/lib/json_info_codec.dart
index ec0e6c1..aad6b5a 100644
--- a/lib/json_info_codec.dart
+++ b/lib/json_info_codec.dart
@@ -144,7 +144,7 @@
..size = json['size']
..type = json['type']
..inferredType = json['inferredType']
- ..code = json['code']
+ ..code = parseCode(json['code'])
..isConst = json['const'] ?? false
..initializer = parseId(json['initializer'])
..closures = (json['children'] as List)
@@ -155,7 +155,7 @@
ConstantInfo parseConstant(Map json) {
ConstantInfo result = parseId(json['id']);
return result
- ..code = json['code']
+ ..code = parseCode(json['code'])
..size = json['size']
..outputUnit = parseId(json['outputUnit']);
}
@@ -243,7 +243,7 @@
..inferredReturnType = json['inferredReturnType']
..parameters =
(json['parameters'] as List).map((p) => parseParameter(p)).toList()
- ..code = json['code']
+ ..code = parseCode(json['code'])
..sideEffects = json['sideEffects']
..modifiers =
parseModifiers(new Map<String, bool>.from(json['modifiers']))
@@ -321,6 +321,26 @@
assert(false);
});
}
+
+ List<CodeSpan> parseCode(dynamic json) {
+ // backwards compatibility with format 5.1:
+ if (json is String) {
+ return [new CodeSpan(outputUnit: null, start: -1, end: -1, text: json)];
+ }
+
+ if (json is List) {
+ return json.map((dynamic value) {
+ Map<String, dynamic> jsonCode = value;
+ return new CodeSpan(
+ outputUnit: parseId(jsonCode['outputUnit']),
+ start: jsonCode['start'],
+ end: jsonCode['end'],
+ text: jsonCode['text']);
+ }).toList();
+ }
+
+ return [];
+ }
}
class AllInfoToJsonConverter extends Converter<AllInfo, Map>
@@ -344,7 +364,7 @@
assert(info.parent == null);
assert(info.code != null);
// Instead, use the content of the code.
- id = info.code.hashCode;
+ id = info.code.first.text.hashCode;
} else {
id = longName(info, useLibraryUri: true, forId: true).hashCode;
}
@@ -492,7 +512,7 @@
..addAll(<String, Object>{
'children': _toSortedSerializedIds(info.closures, ids),
'inferredType': info.inferredType,
- 'code': info.code,
+ 'code': _serializeCode(info.code),
'type': info.type,
});
if (info.isConst) {
@@ -504,8 +524,8 @@
return result;
}
- Map visitConstant(ConstantInfo info) =>
- _visitBasicInfo(info)..addAll(<String, Object>{'code': info.code});
+ Map visitConstant(ConstantInfo info) => _visitBasicInfo(info)
+ ..addAll(<String, Object>{'code': _serializeCode(info.code)});
// TODO(sigmund): exclude false values (requires bumping the format version):
// var res = <String, bool>{};
@@ -559,7 +579,7 @@
info.parameters.map((p) => _visitParameterInfo(p)).toList(),
'sideEffects': info.sideEffects,
'inlinedCount': info.inlinedCount,
- 'code': info.code,
+ 'code': _serializeCode(info.code),
'type': info.type,
'measurements': _visitMeasurements(info.measurements),
// Note: version 3.2 of dump-info serializes `uses` in a section called
@@ -576,6 +596,17 @@
visitOutput(OutputUnitInfo info) =>
_visitBasicInfo(info)..['imports'] = info.imports;
+
+ List<Object> _serializeCode(List<CodeSpan> code) {
+ return code
+ .map<Object>((c) => {
+ 'outputUnit': idFor(c.outputUnit),
+ 'start': c.start,
+ 'end': c.end,
+ 'text': c.text,
+ })
+ .toList();
+ }
}
class AllInfoJsonCodec extends Codec<AllInfo, Map> {
diff --git a/lib/proto_info_codec.dart b/lib/proto_info_codec.dart
index db9b6a0..f0a6b6a 100644
--- a/lib/proto_info_codec.dart
+++ b/lib/proto_info_codec.dart
@@ -44,7 +44,7 @@
assert(info.parent == null);
assert(info.code != null);
// Instead, use the content of the code.
- id = info.code.hashCode;
+ id = info.code.first.text.hashCode;
} else {
id = longName(info, useLibraryUri: true, forId: true).hashCode;
}
@@ -146,7 +146,7 @@
}
if (info.code != null) {
- proto.code = info.code;
+ proto.code = info.code.map((c) => c.text).join('\n');
}
if (info.sideEffects != null) {
@@ -171,7 +171,7 @@
..isConst = info.isConst;
if (info.code != null) {
- proto.code = info.code;
+ proto.code = info.code.map((c) => c.text).join('\n');
}
if (info.initializer != null) {
@@ -185,7 +185,7 @@
}
static ConstantInfoPB _convertToConstantInfoPB(ConstantInfo info) {
- return new ConstantInfoPB()..code = info.code;
+ return new ConstantInfoPB()..code = info.code.map((c) => c.text).join('\n');
}
static OutputUnitInfoPB _convertToOutputUnitInfoPB(OutputUnitInfo info) {