OLD | NEW |
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 /// Converters and codecs for converting between JSON and [Info] classes. | 5 /// Converters and codecs for converting between JSON and [Info] classes. |
6 part of dart2js_info.info; | 6 part of dart2js_info.info; |
7 | 7 |
8 // TODO(sigmund): add unit tests. | 8 // TODO(sigmund): add unit tests. |
9 class JsonToAllInfoConverter extends Converter<Map, AllInfo> { | 9 class JsonToAllInfoConverter extends Converter<Map<String, dynamic>, AllInfo> { |
10 Map<String, Info> registry; | 10 Map<String, Info> registry; |
11 | 11 |
12 AllInfo convert(Map json) { | 12 AllInfo convert(Map<String, dynamic> json) { |
13 registry = <String, Info>{}; | 13 registry = <String, Info>{}; |
14 | 14 |
15 var result = new AllInfo(); | 15 var result = new AllInfo(); |
16 var elements = json['elements']; | 16 var elements = json['elements']; |
17 result.libraries.addAll(elements['library'].values.map(parseLibrary)); | 17 result.libraries |
18 result.classes.addAll(elements['class'].values.map(parseClass)); | 18 .addAll((elements['library'] as Map).values.map(parseLibrary)); |
19 result.functions.addAll(elements['function'].values.map(parseFunction)); | 19 result.classes.addAll((elements['class'] as Map).values.map(parseClass)); |
20 result.fields.addAll(elements['field'].values.map(parseField)); | 20 result.functions |
21 result.typedefs.addAll(elements['typedef'].values.map(parseTypedef)); | 21 .addAll((elements['function'] as Map).values.map(parseFunction)); |
| 22 result.fields.addAll((elements['field'] as Map).values.map(parseField)); |
| 23 result.typedefs |
| 24 .addAll((elements['typedef'] as Map).values.map(parseTypedef)); |
22 | 25 |
23 // TODO(sigmund): remove null check on next breaking version | 26 // TODO(sigmund): remove null check on next breaking version |
24 var constants = elements['constant']; | 27 var constants = elements['constant']; |
25 if (constants != null) { | 28 if (constants != null) { |
26 result.constants.addAll(constants.values.map(parseConstant)); | 29 result.constants.addAll((constants as Map).values.map(parseConstant)); |
27 } | 30 } |
28 | 31 |
29 var idMap = {}; | 32 var idMap = <String, Info>{}; |
30 for (var f in result.functions) { | 33 for (var f in result.functions) { |
31 idMap[f.serializedId] = f; | 34 idMap[f.serializedId] = f; |
32 } | 35 } |
33 for (var f in result.fields) { | 36 for (var f in result.fields) { |
34 idMap[f.serializedId] = f; | 37 idMap[f.serializedId] = f; |
35 } | 38 } |
36 | 39 |
37 json['holding'].forEach((k, deps) { | 40 json['holding'].forEach((k, deps) { |
38 var src = idMap[k]; | 41 var src = idMap[k]; |
39 assert(src != null); | 42 assert(src != null); |
40 for (var dep in deps) { | 43 for (var dep in deps) { |
41 var target = idMap[dep['id']]; | 44 var target = idMap[dep['id']]; |
42 assert(target != null); | 45 assert(target != null); |
43 src.uses.add(new DependencyInfo(target, dep['mask'])); | 46 (src as CodeInfo).uses.add(new DependencyInfo(target, dep['mask'])); |
44 } | 47 } |
45 }); | 48 }); |
46 | 49 |
47 json['dependencies']?.forEach((k, deps) { | 50 json['dependencies']?.forEach((String k, List<String> deps) { |
48 result.dependencies[idMap[k]] = deps.map((d) => idMap[d]).toList(); | 51 result.dependencies[idMap[k]] = deps.map((d) => idMap[d]).toList(); |
49 }); | 52 }); |
50 | 53 |
51 result.outputUnits.addAll(json['outputUnits'].map(parseOutputUnit)); | 54 result.outputUnits |
| 55 .addAll((json['outputUnits'] as List).map(parseOutputUnit)); |
52 | 56 |
53 result.program = parseProgram(json['program']); | 57 result.program = parseProgram(json['program']); |
54 // todo: version, etc | 58 // todo: version, etc |
55 return result; | 59 return result; |
56 } | 60 } |
57 | 61 |
58 OutputUnitInfo parseOutputUnit(Map json) { | 62 OutputUnitInfo parseOutputUnit(Map json) { |
59 OutputUnitInfo result = parseId(json['id']); | 63 OutputUnitInfo result = parseId(json['id']); |
60 result | 64 result |
61 ..name = json['name'] | 65 ..name = json['name'] |
62 ..size = json['size']; | 66 ..size = json['size']; |
63 result.imports.addAll(json['imports'] ?? const []); | 67 result.imports |
| 68 .addAll((json['imports'] as List).map((s) => s as String) ?? const []); |
64 return result; | 69 return result; |
65 } | 70 } |
66 | 71 |
67 LibraryInfo parseLibrary(Map json) { | 72 LibraryInfo parseLibrary(Map json) { |
68 LibraryInfo result = parseId(json['id']); | 73 LibraryInfo result = parseId(json['id']); |
69 result | 74 result |
70 ..name = json['name'] | 75 ..name = json['name'] |
71 ..uri = Uri.parse(json['canonicalUri']) | 76 ..uri = Uri.parse(json['canonicalUri']) |
72 ..outputUnit = parseId(json['outputUnit']) | 77 ..outputUnit = parseId(json['outputUnit']) |
73 ..size = json['size']; | 78 ..size = json['size']; |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
112 ..name = json['name'] | 117 ..name = json['name'] |
113 ..parent = parseId(json['parent']) | 118 ..parent = parseId(json['parent']) |
114 ..coverageId = json['coverageId'] | 119 ..coverageId = json['coverageId'] |
115 ..outputUnit = parseId(json['outputUnit']) | 120 ..outputUnit = parseId(json['outputUnit']) |
116 ..size = json['size'] | 121 ..size = json['size'] |
117 ..type = json['type'] | 122 ..type = json['type'] |
118 ..inferredType = json['inferredType'] | 123 ..inferredType = json['inferredType'] |
119 ..code = json['code'] | 124 ..code = json['code'] |
120 ..isConst = json['const'] ?? false | 125 ..isConst = json['const'] ?? false |
121 ..initializer = parseId(json['initializer']) | 126 ..initializer = parseId(json['initializer']) |
122 ..closures = json['children'].map(parseId).toList(); | 127 ..closures = (json['children'] as List).map(parseId).toList(); |
123 } | 128 } |
124 | 129 |
125 ConstantInfo parseConstant(Map json) { | 130 ConstantInfo parseConstant(Map json) { |
126 ConstantInfo result = parseId(json['id']); | 131 ConstantInfo result = parseId(json['id']); |
127 return result | 132 return result |
128 ..code = json['code'] | 133 ..code = json['code'] |
129 ..size = json['size']; | 134 ..size = json['size']; |
130 } | 135 } |
131 | 136 |
132 TypedefInfo parseTypedef(Map json) { | 137 TypedefInfo parseTypedef(Map json) { |
(...skipping 13 matching lines...) Expand all Loading... |
146 FunctionInfo result = parseId(json['id']); | 151 FunctionInfo result = parseId(json['id']); |
147 return result | 152 return result |
148 ..name = json['name'] | 153 ..name = json['name'] |
149 ..parent = parseId(json['parent']) | 154 ..parent = parseId(json['parent']) |
150 ..coverageId = json['coverageId'] | 155 ..coverageId = json['coverageId'] |
151 ..outputUnit = parseId(json['outputUnit']) | 156 ..outputUnit = parseId(json['outputUnit']) |
152 ..size = json['size'] | 157 ..size = json['size'] |
153 ..type = json['type'] | 158 ..type = json['type'] |
154 ..returnType = json['returnType'] | 159 ..returnType = json['returnType'] |
155 ..inferredReturnType = json['inferredReturnType'] | 160 ..inferredReturnType = json['inferredReturnType'] |
156 ..parameters = json['parameters'].map(parseParameter).toList() | 161 ..parameters = (json['parameters'] as List).map(parseParameter).toList() |
157 ..code = json['code'] | 162 ..code = json['code'] |
158 ..sideEffects = json['sideEffects'] | 163 ..sideEffects = json['sideEffects'] |
159 ..modifiers = parseModifiers(json['modifiers']) | 164 ..modifiers = |
160 ..closures = json['children'].map(parseId).toList() | 165 parseModifiers(new Map<String, bool>.from(json['modifiers'])) |
| 166 ..closures = (json['children'] as List).map(parseId).toList() |
161 ..measurements = parseMeasurements(json['measurements']); | 167 ..measurements = parseMeasurements(json['measurements']); |
162 } | 168 } |
163 | 169 |
164 ParameterInfo parseParameter(Map json) => | 170 ParameterInfo parseParameter(Map json) => |
165 new ParameterInfo(json['name'], json['type'], json['declaredType']); | 171 new ParameterInfo(json['name'], json['type'], json['declaredType']); |
166 | 172 |
167 Measurements parseMeasurements(Map json) { | 173 Measurements parseMeasurements(Map json) { |
168 if (json == null) return null; | 174 if (json == null) return null; |
169 var uri = json['sourceFile']; | 175 var uri = json['sourceFile']; |
170 var res = new Measurements(uri == null ? null : Uri.parse(uri)); | 176 var res = new Measurements(uri == null ? null : Uri.parse(uri)); |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
299 | 305 |
300 Map _visitBasicInfo(BasicInfo info) { | 306 Map _visitBasicInfo(BasicInfo info) { |
301 var res = { | 307 var res = { |
302 'id': info.serializedId, | 308 'id': info.serializedId, |
303 'kind': kindToString(info.kind), | 309 'kind': kindToString(info.kind), |
304 'name': info.name, | 310 'name': info.name, |
305 'size': info.size, | 311 'size': info.size, |
306 }; | 312 }; |
307 // TODO(sigmund): Omit this also when outputUnit.id == 0 (most code is in | 313 // TODO(sigmund): Omit this also when outputUnit.id == 0 (most code is in |
308 // the main output unit by default). | 314 // the main output unit by default). |
309 if (info.outputUnit != null) res['outputUnit'] = | 315 if (info.outputUnit != null) { |
310 info.outputUnit.serializedId; | 316 res['outputUnit'] = info.outputUnit.serializedId; |
| 317 } |
311 if (info.coverageId != null) res['coverageId'] = info.coverageId; | 318 if (info.coverageId != null) res['coverageId'] = info.coverageId; |
312 if (info.parent != null) res['parent'] = info.parent.serializedId; | 319 if (info.parent != null) res['parent'] = info.parent.serializedId; |
313 return res; | 320 return res; |
314 } | 321 } |
315 | 322 |
316 Map visitLibrary(LibraryInfo info) { | 323 Map visitLibrary(LibraryInfo info) { |
317 return _visitBasicInfo(info) | 324 return _visitBasicInfo(info) |
318 ..addAll({ | 325 ..addAll({ |
319 'children': [] | 326 'children': [] |
320 ..addAll(info.topLevelFunctions.map((f) => f.serializedId)) | 327 ..addAll(info.topLevelFunctions.map((f) => f.serializedId)) |
(...skipping 18 matching lines...) Expand all Loading... |
339 Map visitField(FieldInfo info) { | 346 Map visitField(FieldInfo info) { |
340 var result = _visitBasicInfo(info) | 347 var result = _visitBasicInfo(info) |
341 ..addAll({ | 348 ..addAll({ |
342 'children': info.closures.map((i) => i.serializedId).toList(), | 349 'children': info.closures.map((i) => i.serializedId).toList(), |
343 'inferredType': info.inferredType, | 350 'inferredType': info.inferredType, |
344 'code': info.code, | 351 'code': info.code, |
345 'type': info.type, | 352 'type': info.type, |
346 }); | 353 }); |
347 if (info.isConst) { | 354 if (info.isConst) { |
348 result['const'] = true; | 355 result['const'] = true; |
349 if (info.initializer != null) result['initializer'] = | 356 if (info.initializer != null) { |
350 info.initializer.serializedId; | 357 result['initializer'] = info.initializer.serializedId; |
| 358 } |
351 } | 359 } |
352 return result; | 360 return result; |
353 } | 361 } |
354 | 362 |
355 Map visitConstant(ConstantInfo info) => | 363 Map visitConstant(ConstantInfo info) => |
356 _visitBasicInfo(info)..addAll({'code': info.code}); | 364 _visitBasicInfo(info)..addAll({'code': info.code}); |
357 | 365 |
358 // TODO(sigmund): exclude false values (requires bumping the format version): | 366 // TODO(sigmund): exclude false values (requires bumping the format version): |
359 // var res = <String, bool>{}; | 367 // var res = <String, bool>{}; |
360 // if (isStatic) res['static'] = true; | 368 // if (isStatic) res['static'] = true; |
361 // if (isConst) res['const'] = true; | 369 // if (isConst) res['const'] = true; |
362 // if (isFactory) res['factory'] = true; | 370 // if (isFactory) res['factory'] = true; |
363 // if (isExternal) res['external'] = true; | 371 // if (isExternal) res['external'] = true; |
364 // return res; | 372 // return res; |
365 Map _visitFunctionModifiers(FunctionModifiers mods) => { | 373 Map _visitFunctionModifiers(FunctionModifiers mods) => { |
366 'static': mods.isStatic, | 374 'static': mods.isStatic, |
367 'const': mods.isConst, | 375 'const': mods.isConst, |
368 'factory': mods.isFactory, | 376 'factory': mods.isFactory, |
369 'external': mods.isExternal, | 377 'external': mods.isExternal, |
370 }; | 378 }; |
371 | 379 |
372 Map _visitParameterInfo(ParameterInfo info) => | 380 Map _visitParameterInfo(ParameterInfo info) => |
373 {'name': info.name, 'type': info.type, 'declaredType': info.declaredType}; | 381 {'name': info.name, 'type': info.type, 'declaredType': info.declaredType}; |
374 | 382 |
375 String _visitMetric(Metric metric) => metric.name; | 383 String _visitMetric(Metric metric) => metric.name; |
376 | 384 |
377 Map _visitMeasurements(Measurements measurements) { | 385 Map _visitMeasurements(Measurements measurements) { |
378 if (measurements == null) return null; | 386 if (measurements == null) return null; |
379 var jsonEntries = <String, List<Map>>{}; | 387 var jsonEntries = <String, List<int>>{}; |
380 measurements.entries.forEach((metric, values) { | 388 measurements.entries.forEach((metric, values) { |
381 jsonEntries[_visitMetric(metric)] = | 389 jsonEntries[_visitMetric(metric)] = |
382 values.expand((e) => [e.begin, e.end]).toList(); | 390 values.expand((e) => [e.begin, e.end]).toList(); |
383 }); | 391 }); |
384 var json = {'entries': jsonEntries}; | 392 var json = <String, dynamic>{'entries': jsonEntries}; |
385 // TODO(sigmund): encode uri as an offset of the URIs available in the parts | 393 // TODO(sigmund): encode uri as an offset of the URIs available in the parts |
386 // of the library info. | 394 // of the library info. |
387 if (measurements.uri != null) json['sourceFile'] = '${measurements.uri}'; | 395 if (measurements.uri != null) json['sourceFile'] = '${measurements.uri}'; |
388 if (measurements.counters[Metric.functions] != null) { | 396 if (measurements.counters[Metric.functions] != null) { |
389 json[_visitMetric(Metric.functions)] = | 397 json[_visitMetric(Metric.functions)] = |
390 measurements.counters[Metric.functions]; | 398 measurements.counters[Metric.functions]; |
391 } | 399 } |
392 if (measurements.counters[Metric.reachableFunctions] != null) { | 400 if (measurements.counters[Metric.reachableFunctions] != null) { |
393 json[_visitMetric(Metric.reachableFunctions)] = | 401 json[_visitMetric(Metric.reachableFunctions)] = |
394 measurements.counters[Metric.reachableFunctions]; | 402 measurements.counters[Metric.reachableFunctions]; |
(...skipping 23 matching lines...) Expand all Loading... |
418 visitTypedef(TypedefInfo info) => _visitBasicInfo(info)..['type'] = info.type; | 426 visitTypedef(TypedefInfo info) => _visitBasicInfo(info)..['type'] = info.type; |
419 | 427 |
420 visitOutput(OutputUnitInfo info) => | 428 visitOutput(OutputUnitInfo info) => |
421 _visitBasicInfo(info)..['imports'] = info.imports; | 429 _visitBasicInfo(info)..['imports'] = info.imports; |
422 } | 430 } |
423 | 431 |
424 class AllInfoJsonCodec extends Codec<AllInfo, Map> { | 432 class AllInfoJsonCodec extends Codec<AllInfo, Map> { |
425 final Converter<AllInfo, Map> encoder = new AllInfoToJsonConverter(); | 433 final Converter<AllInfo, Map> encoder = new AllInfoToJsonConverter(); |
426 final Converter<Map, AllInfo> decoder = new JsonToAllInfoConverter(); | 434 final Converter<Map, AllInfo> decoder = new JsonToAllInfoConverter(); |
427 } | 435 } |
OLD | NEW |