| 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 |