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 /// Data collected by the dump-info task. | 5 /// Data collected by the dump-info task. |
6 library compiler.src.lib.info; | 6 library compiler.src.lib.info; |
7 | 7 |
8 // Note: this file intentionally doesn't import anything from the compiler. That | 8 // Note: this file intentionally doesn't import anything from the compiler. That |
9 // should make it easier for tools to depend on this library. The idea is that | 9 // should make it easier for tools to depend on this library. The idea is that |
10 // by using this library, tools can consume the information in the same way it | 10 // by using this library, tools can consume the information in the same way it |
11 // is produced by the compiler. | 11 // is produced by the compiler. |
12 // TODO(sigmund): make this a proper public API (export this explicitly at the | 12 // TODO(sigmund): make this a proper public API (export this explicitly at the |
13 // lib folder level.) | 13 // lib folder level.) |
14 | 14 |
15 /// Common interface to many pieces of information generated by the compiler. | 15 /// Common interface to many pieces of information generated by the compiler. |
16 abstract class Info { | 16 abstract class Info { |
17 /// An identifier for the kind of information. | 17 /// An identifier for the kind of information. |
18 InfoKind get kind; | 18 InfoKind get kind; |
19 | 19 |
20 /// Name of the element associated with this info. | 20 /// Name of the element associated with this info. |
21 String name; | 21 String name; |
22 | 22 |
23 /// An id to uniquely identify this info among infos of the same [kind]. | 23 /// An id to uniquely identify this info among infos of the same [kind]. |
24 int get id; | 24 int get id; |
25 | 25 |
26 /// A globally unique id combining [kind] and [id] together. | 26 /// A globally unique id combining [kind] and [id] together. |
27 String get serializedId; | 27 String get serializedId; |
28 | 28 |
29 /// Id used by the compiler when instrumenting code for code coverage. | |
30 // TODO(sigmund): unify all ids. | |
sra1
2015/08/13 22:27:26
What do you mean by unify?
Siggi Cherem (dart-lang)
2015/08/13 23:40:21
since we also have id and serializedId, it would b
| |
31 String coverageId; | |
32 | |
29 /// Bytes used in the generated code for the corresponding element. | 33 /// Bytes used in the generated code for the corresponding element. |
30 int size; | 34 int size; |
31 | 35 |
32 /// Info of the enclosing element. | 36 /// Info of the enclosing element. |
33 Info parent; | 37 Info parent; |
34 | 38 |
35 /// Serializes the information into a JSON format. | 39 /// Serializes the information into a JSON format. |
36 // TODO(sigmund): refactor and put toJson outside the class, so we can have 2 | 40 // TODO(sigmund): refactor and put toJson outside the class, so we can have 2 |
37 // different serializer/deserializers at once. | 41 // different serializer/deserializers at once. |
38 Map toJson(); | 42 Map toJson(); |
39 | 43 |
40 void accept(InfoVisitor visitor); | 44 void accept(InfoVisitor visitor); |
41 } | 45 } |
42 | 46 |
43 /// Common information used for most kind of elements. | 47 /// Common information used for most kind of elements. |
44 // TODO(sigmund): add more: | 48 // TODO(sigmund): add more: |
45 // - inputSize: bytes used in the Dart source program | 49 // - inputSize: bytes used in the Dart source program |
46 abstract class BasicInfo implements Info { | 50 abstract class BasicInfo implements Info { |
47 final InfoKind kind; | 51 final InfoKind kind; |
48 final int id; | 52 final int id; |
53 String coverageId; | |
49 int size; | 54 int size; |
50 Info parent; | 55 Info parent; |
51 | 56 |
52 String get serializedId => '${_kindToString(kind)}/$id'; | 57 String get serializedId => '${_kindToString(kind)}/$id'; |
53 | 58 |
54 String name; | 59 String name; |
55 | 60 |
56 /// If using deferred libraries, where the element associated with this info | 61 /// If using deferred libraries, where the element associated with this info |
57 /// is generated. | 62 /// is generated. |
58 OutputUnitInfo outputUnit; | 63 OutputUnitInfo outputUnit; |
59 | 64 |
60 BasicInfo(this.kind, this.id, this.name, this.outputUnit, this.size); | 65 BasicInfo(this.kind, this.id, this.name, this.outputUnit, this.size, |
66 this.coverageId); | |
61 | 67 |
62 BasicInfo._fromId(String serializedId) | 68 BasicInfo._fromId(String serializedId) |
63 : kind = _kindFromSerializedId(serializedId), | 69 : kind = _kindFromSerializedId(serializedId), |
64 id = _idFromSerializedId(serializedId); | 70 id = _idFromSerializedId(serializedId); |
65 | 71 |
66 Map toJson() { | 72 Map toJson() { |
67 var res = { | 73 var res = { |
68 'id': serializedId, | 74 'id': serializedId, |
69 'kind': _kindToString(kind), | 75 'kind': _kindToString(kind), |
70 'name': name, | 76 'name': name, |
71 'size': size, | 77 'size': size, |
72 }; | 78 }; |
73 // TODO(sigmund): omit this also when outputUnit.id == 0 | 79 // TODO(sigmund): omit this also when outputUnit.id == 0 |
sra1
2015/08/13 22:27:26
nit: TODOs should have sentences. Begin with 'O',
Siggi Cherem (dart-lang)
2015/08/13 23:40:21
Done.
| |
74 // (most code is by default in the main output unit) | 80 // (most code is by default in the main output unit) |
75 if (outputUnit != null) res['outputUnit'] = outputUnit.serializedId; | 81 if (outputUnit != null) res['outputUnit'] = outputUnit.serializedId; |
82 if (coverageId != null) res['coverageId'] = coverageId; | |
76 if (parent != null) res['parent'] = parent.serializedId; | 83 if (parent != null) res['parent'] = parent.serializedId; |
77 return res; | 84 return res; |
78 } | 85 } |
79 | 86 |
80 String toString() => '$serializedId $name [$size]'; | 87 String toString() => '$serializedId $name [$size]'; |
81 } | 88 } |
82 | 89 |
83 /// Info associated with elements containing executable code (like fields and | 90 /// Info associated with elements containing executable code (like fields and |
84 /// methods) | 91 /// methods) |
85 abstract class CodeInfo implements Info { | 92 abstract class CodeInfo implements Info { |
(...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
301 result.fields.add(child); | 308 result.fields.add(child); |
302 } | 309 } |
303 } | 310 } |
304 return result; | 311 return result; |
305 } | 312 } |
306 | 313 |
307 FieldInfo parseField(Map json) { | 314 FieldInfo parseField(Map json) { |
308 FieldInfo result = parseId(json['id']); | 315 FieldInfo result = parseId(json['id']); |
309 return result..name = json['name'] | 316 return result..name = json['name'] |
310 ..parent = parseId(json['parent']) | 317 ..parent = parseId(json['parent']) |
318 ..coverageId = json['coverageId'] | |
311 ..outputUnit = parseId(json['outputUnit']) | 319 ..outputUnit = parseId(json['outputUnit']) |
312 ..size = json['size'] | 320 ..size = json['size'] |
313 ..type = json['type'] | 321 ..type = json['type'] |
314 ..inferredType = json['inferredType'] | 322 ..inferredType = json['inferredType'] |
315 ..code = json['code'] | 323 ..code = json['code'] |
316 ..closures = json['children'].map(parseId).toList(); | 324 ..closures = json['children'].map(parseId).toList(); |
317 } | 325 } |
318 | 326 |
319 TypedefInfo parseTypedef(Map json) { | 327 TypedefInfo parseTypedef(Map json) { |
320 TypedefInfo result = parseId(json['id']); | 328 TypedefInfo result = parseId(json['id']); |
321 return result..name = json['name'] | 329 return result..name = json['name'] |
322 ..parent = parseId(json['parent']) | 330 ..parent = parseId(json['parent']) |
323 ..type = json['type'] | 331 ..type = json['type'] |
324 ..size = 0; | 332 ..size = 0; |
325 } | 333 } |
326 | 334 |
327 ProgramInfo parseProgram(Map json) => | 335 ProgramInfo parseProgram(Map json) => |
328 new ProgramInfo()..size = json['size']; | 336 new ProgramInfo()..size = json['size']; |
329 | 337 |
330 FunctionInfo parseFunction(Map json) { | 338 FunctionInfo parseFunction(Map json) { |
331 FunctionInfo result = parseId(json['id']); | 339 FunctionInfo result = parseId(json['id']); |
332 return result..name = json['name'] | 340 return result..name = json['name'] |
333 ..parent = parseId(json['parent']) | 341 ..parent = parseId(json['parent']) |
342 ..coverageId = json['coverageId'] | |
334 ..outputUnit = parseId(json['outputUnit']) | 343 ..outputUnit = parseId(json['outputUnit']) |
335 ..size = json['size'] | 344 ..size = json['size'] |
336 ..type = json['type'] | 345 ..type = json['type'] |
337 ..returnType = json['returnType'] | 346 ..returnType = json['returnType'] |
338 ..inferredReturnType = json['inferredReturnType'] | 347 ..inferredReturnType = json['inferredReturnType'] |
339 ..parameters = json['parameters'].map(parseParameter).toList() | 348 ..parameters = json['parameters'].map(parseParameter).toList() |
340 ..code = json['code'] | 349 ..code = json['code'] |
341 ..sideEffects = json['sideEffects'] | 350 ..sideEffects = json['sideEffects'] |
342 ..modifiers = parseModifiers(json['modifiers']) | 351 ..modifiers = parseModifiers(json['modifiers']) |
343 ..closures = json['children'].map(parseId).toList(); | 352 ..closures = json['children'].map(parseId).toList(); |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
391 /// Typedefs defined within the library. | 400 /// Typedefs defined within the library. |
392 final List<TypedefInfo> typedefs = <TypedefInfo>[]; | 401 final List<TypedefInfo> typedefs = <TypedefInfo>[]; |
393 | 402 |
394 static int _id = 0; | 403 static int _id = 0; |
395 | 404 |
396 /// Whether there is any information recorded for this library. | 405 /// Whether there is any information recorded for this library. |
397 bool get isEmpty => | 406 bool get isEmpty => |
398 topLevelFunctions.isEmpty && topLevelVariables.isEmpty && classes.isEmpty; | 407 topLevelFunctions.isEmpty && topLevelVariables.isEmpty && classes.isEmpty; |
399 | 408 |
400 LibraryInfo(String name, this.uri, OutputUnitInfo outputUnit, int size) | 409 LibraryInfo(String name, this.uri, OutputUnitInfo outputUnit, int size) |
401 : super(InfoKind.library, _id++, name, outputUnit, size); | 410 : super(InfoKind.library, _id++, name, outputUnit, size, null); |
402 | 411 |
403 LibraryInfo._(String serializedId) : super._fromId(serializedId); | 412 LibraryInfo._(String serializedId) : super._fromId(serializedId); |
404 | 413 |
405 Map toJson() => super.toJson() | 414 Map toJson() => super.toJson() |
406 ..addAll({ | 415 ..addAll({ |
407 'children': [] | 416 'children': [] |
408 ..addAll(topLevelFunctions.map((f) => f.serializedId)) | 417 ..addAll(topLevelFunctions.map((f) => f.serializedId)) |
409 ..addAll(topLevelVariables.map((v) => v.serializedId)) | 418 ..addAll(topLevelVariables.map((v) => v.serializedId)) |
410 ..addAll(classes.map((c) => c.serializedId)) | 419 ..addAll(classes.map((c) => c.serializedId)) |
411 ..addAll(typedefs.map((t) => t.serializedId)), | 420 ..addAll(typedefs.map((t) => t.serializedId)), |
412 'canonicalUri': '$uri', | 421 'canonicalUri': '$uri', |
413 }); | 422 }); |
414 | 423 |
415 void accept(InfoVisitor visitor) => visitor.visitLibrary(this); | 424 void accept(InfoVisitor visitor) => visitor.visitLibrary(this); |
416 } | 425 } |
417 | 426 |
418 /// Information about an output unit. Normally there is just one for the entire | 427 /// Information about an output unit. Normally there is just one for the entire |
419 /// program unless the application uses deferred imports, in which case there | 428 /// program unless the application uses deferred imports, in which case there |
420 /// would be an additional output unit per deferred chunk. | 429 /// would be an additional output unit per deferred chunk. |
421 class OutputUnitInfo extends BasicInfo { | 430 class OutputUnitInfo extends BasicInfo { |
422 static int _ids = 0; | 431 static int _ids = 0; |
423 OutputUnitInfo(String name, int size) | 432 OutputUnitInfo(String name, int size) |
424 : super(InfoKind.outputUnit, _ids++, name, null, size); | 433 : super(InfoKind.outputUnit, _ids++, name, null, size, null); |
425 | 434 |
426 OutputUnitInfo._(String serializedId) : super._fromId(serializedId); | 435 OutputUnitInfo._(String serializedId) : super._fromId(serializedId); |
427 | 436 |
428 void accept(InfoVisitor visitor) => visitor.visitOutput(this); | 437 void accept(InfoVisitor visitor) => visitor.visitOutput(this); |
429 } | 438 } |
430 | 439 |
431 /// Information about a class element. | 440 /// Information about a class element. |
432 class ClassInfo extends BasicInfo { | 441 class ClassInfo extends BasicInfo { |
433 /// Whether the class is abstract. | 442 /// Whether the class is abstract. |
434 bool isAbstract; | 443 bool isAbstract; |
435 | 444 |
436 // TODO(sigmund): split static vs instance vs closures | 445 // TODO(sigmund): split static vs instance vs closures |
437 /// Functions (static or instance) defined in the class. | 446 /// Functions (static or instance) defined in the class. |
438 final List<FunctionInfo> functions = <FunctionInfo>[]; | 447 final List<FunctionInfo> functions = <FunctionInfo>[]; |
439 | 448 |
440 /// Fields defined in the class. | 449 /// Fields defined in the class. |
441 // TODO(sigmund): currently appears to only be populated with instance fields, | 450 // TODO(sigmund): currently appears to only be populated with instance fields, |
442 // but this should be fixed. | 451 // but this should be fixed. |
443 final List<FieldInfo> fields = <FieldInfo>[]; | 452 final List<FieldInfo> fields = <FieldInfo>[]; |
444 static int _ids = 0; | 453 static int _ids = 0; |
445 | 454 |
446 ClassInfo( | 455 ClassInfo( |
447 {String name, this.isAbstract, OutputUnitInfo outputUnit, int size: 0}) | 456 {String name, this.isAbstract, OutputUnitInfo outputUnit, int size: 0}) |
448 : super(InfoKind.clazz, _ids++, name, outputUnit, size); | 457 : super(InfoKind.clazz, _ids++, name, outputUnit, size, null); |
449 | 458 |
450 ClassInfo._(String serializedId) : super._fromId(serializedId); | 459 ClassInfo._(String serializedId) : super._fromId(serializedId); |
451 | 460 |
452 Map toJson() => super.toJson() | 461 Map toJson() => super.toJson() |
453 ..addAll({ | 462 ..addAll({ |
454 // TODO(sigmund): change format, include only when abstract is true. | 463 // TODO(sigmund): change format, include only when abstract is true. |
455 'modifiers': {'abstract': isAbstract}, | 464 'modifiers': {'abstract': isAbstract}, |
456 'children': [] | 465 'children': [] |
457 ..addAll(fields.map((f) => f.serializedId)) | 466 ..addAll(fields.map((f) => f.serializedId)) |
458 ..addAll(functions.map((m) => m.serializedId)) | 467 ..addAll(functions.map((m) => m.serializedId)) |
(...skipping 12 matching lines...) Expand all Loading... | |
471 | 480 |
472 /// Nested closures seen in the field initializer. | 481 /// Nested closures seen in the field initializer. |
473 List<FunctionInfo> closures; | 482 List<FunctionInfo> closures; |
474 | 483 |
475 /// The actual generated code for the field. | 484 /// The actual generated code for the field. |
476 String code; | 485 String code; |
477 | 486 |
478 static int _ids = 0; | 487 static int _ids = 0; |
479 FieldInfo( | 488 FieldInfo( |
480 {String name, | 489 {String name, |
490 String coverageId, | |
481 int size: 0, | 491 int size: 0, |
482 this.type, | 492 this.type, |
483 this.inferredType, | 493 this.inferredType, |
484 this.closures, | 494 this.closures, |
485 this.code, | 495 this.code, |
486 OutputUnitInfo outputUnit}) | 496 OutputUnitInfo outputUnit}) |
487 : super(InfoKind.field, _ids++, name, outputUnit, size); | 497 : super(InfoKind.field, _ids++, name, outputUnit, size, coverageId); |
488 | 498 |
489 FieldInfo._(String serializedId) : super._fromId(serializedId); | 499 FieldInfo._(String serializedId) : super._fromId(serializedId); |
490 | 500 |
491 Map toJson() => super.toJson() | 501 Map toJson() => super.toJson() |
492 ..addAll({ | 502 ..addAll({ |
493 'children': closures.map((i) => i.serializedId).toList(), | 503 'children': closures.map((i) => i.serializedId).toList(), |
494 'inferredType': inferredType, | 504 'inferredType': inferredType, |
495 'code': code, | 505 'code': code, |
496 'type': type, | 506 'type': type, |
497 }); | 507 }); |
498 | 508 |
499 void accept(InfoVisitor visitor) => visitor.visitField(this); | 509 void accept(InfoVisitor visitor) => visitor.visitField(this); |
500 } | 510 } |
501 | 511 |
502 /// Information about a typedef declaration. | 512 /// Information about a typedef declaration. |
503 class TypedefInfo extends BasicInfo { | 513 class TypedefInfo extends BasicInfo { |
504 /// The declared type. | 514 /// The declared type. |
505 String type; | 515 String type; |
506 | 516 |
507 static int _ids = 0; | 517 static int _ids = 0; |
508 TypedefInfo(String name, this.type, OutputUnitInfo outputUnit) | 518 TypedefInfo(String name, this.type, OutputUnitInfo outputUnit) |
509 : super(InfoKind.typedef, _ids++, name, outputUnit, 0); | 519 : super(InfoKind.typedef, _ids++, name, outputUnit, 0, null); |
510 | 520 |
511 TypedefInfo._(String serializedId) : super._fromId(serializedId); | 521 TypedefInfo._(String serializedId) : super._fromId(serializedId); |
512 | 522 |
513 Map toJson() => super.toJson()..['type'] = '$type'; | 523 Map toJson() => super.toJson()..['type'] = '$type'; |
514 | 524 |
515 void accept(InfoVisitor visitor) => visitor.visitTypedef(this); | 525 void accept(InfoVisitor visitor) => visitor.visitTypedef(this); |
516 } | 526 } |
517 | 527 |
518 /// Information about a function or method. | 528 /// Information about a function or method. |
519 class FunctionInfo extends BasicInfo with CodeInfo { | 529 class FunctionInfo extends BasicInfo with CodeInfo { |
(...skipping 29 matching lines...) Expand all Loading... | |
549 String sideEffects; | 559 String sideEffects; |
550 | 560 |
551 /// How many function calls were inlined into this function. | 561 /// How many function calls were inlined into this function. |
552 int inlinedCount; | 562 int inlinedCount; |
553 | 563 |
554 /// The actual generated code. | 564 /// The actual generated code. |
555 String code; | 565 String code; |
556 | 566 |
557 FunctionInfo( | 567 FunctionInfo( |
558 {String name, | 568 {String name, |
569 String coverageId, | |
559 OutputUnitInfo outputUnit, | 570 OutputUnitInfo outputUnit, |
560 int size: 0, | 571 int size: 0, |
561 this.functionKind, | 572 this.functionKind, |
562 this.modifiers, | 573 this.modifiers, |
563 this.closures, | 574 this.closures, |
564 this.type, | 575 this.type, |
565 this.returnType, | 576 this.returnType, |
566 this.inferredReturnType, | 577 this.inferredReturnType, |
567 this.parameters, | 578 this.parameters, |
568 this.sideEffects, | 579 this.sideEffects, |
569 this.inlinedCount, | 580 this.inlinedCount, |
570 this.code}) | 581 this.code}) |
571 : super(InfoKind.function, _ids++, name, outputUnit, size); | 582 : super(InfoKind.function, _ids++, name, outputUnit, size, coverageId); |
572 | 583 |
573 FunctionInfo._(String serializedId) : super._fromId(serializedId); | 584 FunctionInfo._(String serializedId) : super._fromId(serializedId); |
574 | 585 |
575 Map toJson() => super.toJson() | 586 Map toJson() => super.toJson() |
576 ..addAll({ | 587 ..addAll({ |
577 'children': closures.map((i) => i.serializedId).toList(), | 588 'children': closures.map((i) => i.serializedId).toList(), |
578 'modifiers': modifiers.toJson(), | 589 'modifiers': modifiers.toJson(), |
579 'returnType': returnType, | 590 'returnType': returnType, |
580 'inferredReturnType': inferredReturnType, | 591 'inferredReturnType': inferredReturnType, |
581 'parameters': parameters.map((p) => p.toJson()).toList(), | 592 'parameters': parameters.map((p) => p.toJson()).toList(), |
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
724 } | 735 } |
725 | 736 |
726 visitField(FieldInfo info) { | 737 visitField(FieldInfo info) { |
727 info.closures.forEach(visitFunction); | 738 info.closures.forEach(visitFunction); |
728 } | 739 } |
729 | 740 |
730 visitFunction(FunctionInfo info) { | 741 visitFunction(FunctionInfo info) { |
731 info.closures.forEach(visitFunction); | 742 info.closures.forEach(visitFunction); |
732 } | 743 } |
733 } | 744 } |
OLD | NEW |