| Index: runtime/observatory/lib/src/elements/class_view.dart
|
| diff --git a/runtime/observatory/lib/src/elements/class_view.dart b/runtime/observatory/lib/src/elements/class_view.dart
|
| index c87bee17fbe0dbd4e63f58006427fe97a1ed9c14..f649a310d75c7624198fff82e801e32c68fe9b33 100644
|
| --- a/runtime/observatory/lib/src/elements/class_view.dart
|
| +++ b/runtime/observatory/lib/src/elements/class_view.dart
|
| @@ -33,28 +33,28 @@ import 'package:observatory/src/elements/source_link.dart';
|
| import 'package:observatory/src/elements/view_footer.dart';
|
|
|
| class ClassViewElement extends HtmlElement implements Renderable {
|
| - static const tag = const Tag<ClassViewElement>('class-view',
|
| - dependencies: const [
|
| - ClassInstancesElement.tag,
|
| - ClassRefElement.tag,
|
| - CurlyBlockElement.tag,
|
| - ErrorRefElement.tag,
|
| - EvalBoxElement.tag,
|
| - FieldRefElement.tag,
|
| - FunctionRefElement.tag,
|
| - InstanceRefElement.tag,
|
| - LibraryRefElement.tag,
|
| - NavClassMenuElement.tag,
|
| - NavTopMenuElement.tag,
|
| - NavVMMenuElement.tag,
|
| - NavIsolateMenuElement.tag,
|
| - NavRefreshElement.tag,
|
| - NavNotifyElement.tag,
|
| - ObjectCommonElement.tag,
|
| - SourceInsetElement.tag,
|
| - SourceLinkElement.tag,
|
| - ViewFooterElement.tag
|
| - ]);
|
| + static const tag =
|
| + const Tag<ClassViewElement>('class-view', dependencies: const [
|
| + ClassInstancesElement.tag,
|
| + ClassRefElement.tag,
|
| + CurlyBlockElement.tag,
|
| + ErrorRefElement.tag,
|
| + EvalBoxElement.tag,
|
| + FieldRefElement.tag,
|
| + FunctionRefElement.tag,
|
| + InstanceRefElement.tag,
|
| + LibraryRefElement.tag,
|
| + NavClassMenuElement.tag,
|
| + NavTopMenuElement.tag,
|
| + NavVMMenuElement.tag,
|
| + NavIsolateMenuElement.tag,
|
| + NavRefreshElement.tag,
|
| + NavNotifyElement.tag,
|
| + ObjectCommonElement.tag,
|
| + SourceInsetElement.tag,
|
| + SourceLinkElement.tag,
|
| + ViewFooterElement.tag
|
| + ]);
|
|
|
| RenderingScheduler<ClassViewElement> _r;
|
|
|
| @@ -79,28 +79,30 @@ class ClassViewElement extends HtmlElement implements Renderable {
|
| M.ClassSampleProfileRepository _profiles;
|
| Iterable<M.Field> _classFields;
|
|
|
| -
|
| M.VMRef get vm => _vm;
|
| M.IsolateRef get isolate => _isolate;
|
| M.NotificationRepository get notifications => _notifications;
|
| M.Class get cls => _cls;
|
|
|
| - factory ClassViewElement(M.VM vm, M.IsolateRef isolate, M.Class cls,
|
| - M.EventRepository events,
|
| - M.NotificationRepository notifications,
|
| - M.ClassRepository classes,
|
| - M.RetainedSizeRepository retainedSizes,
|
| - M.ReachableSizeRepository reachableSizes,
|
| - M.InboundReferencesRepository references,
|
| - M.RetainingPathRepository retainingPaths,
|
| - M.FieldRepository fields,
|
| - M.ScriptRepository scripts,
|
| - M.InstanceRepository instances,
|
| - M.EvalRepository eval,
|
| - M.StronglyReachableInstancesRepository stronglyReachable,
|
| - M.TopRetainingInstancesRepository topRetained,
|
| - M.ClassSampleProfileRepository profiles,
|
| - {RenderingQueue queue}) {
|
| + factory ClassViewElement(
|
| + M.VM vm,
|
| + M.IsolateRef isolate,
|
| + M.Class cls,
|
| + M.EventRepository events,
|
| + M.NotificationRepository notifications,
|
| + M.ClassRepository classes,
|
| + M.RetainedSizeRepository retainedSizes,
|
| + M.ReachableSizeRepository reachableSizes,
|
| + M.InboundReferencesRepository references,
|
| + M.RetainingPathRepository retainingPaths,
|
| + M.FieldRepository fields,
|
| + M.ScriptRepository scripts,
|
| + M.InstanceRepository instances,
|
| + M.EvalRepository eval,
|
| + M.StronglyReachableInstancesRepository stronglyReachable,
|
| + M.TopRetainingInstancesRepository topRetained,
|
| + M.ClassSampleProfileRepository profiles,
|
| + {RenderingQueue queue}) {
|
| assert(vm != null);
|
| assert(isolate != null);
|
| assert(events != null);
|
| @@ -161,12 +163,20 @@ class ClassViewElement extends HtmlElement implements Renderable {
|
| bool _loadProfile = false;
|
|
|
| void render() {
|
| - _common = _common ?? new ObjectCommonElement(_isolate, _cls, _retainedSizes,
|
| - _reachableSizes, _references, _retainingPaths, _instances,
|
| - queue: _r.queue);
|
| - _classInstances = _classInstances ?? new ClassInstancesElement(_isolate,
|
| - _cls, _retainedSizes, _reachableSizes, _stronglyReachableInstances,
|
| - _topRetainedInstances, _instances, queue: _r.queue);
|
| + _common = _common ??
|
| + new ObjectCommonElement(_isolate, _cls, _retainedSizes, _reachableSizes,
|
| + _references, _retainingPaths, _instances,
|
| + queue: _r.queue);
|
| + _classInstances = _classInstances ??
|
| + new ClassInstancesElement(
|
| + _isolate,
|
| + _cls,
|
| + _retainedSizes,
|
| + _reachableSizes,
|
| + _stronglyReachableInstances,
|
| + _topRetainedInstances,
|
| + _instances,
|
| + queue: _r.queue);
|
| var header = '';
|
| if (_cls.isAbstract) {
|
| header += 'abstract ';
|
| @@ -180,91 +190,102 @@ class ClassViewElement extends HtmlElement implements Renderable {
|
| new NavVMMenuElement(_vm, _events, queue: _r.queue),
|
| new NavIsolateMenuElement(_isolate, _events, queue: _r.queue),
|
| new NavClassMenuElement(_isolate, _cls, queue: _r.queue),
|
| - new NavRefreshElement(label: 'Refresh Allocation Profile',
|
| - queue: _r.queue)
|
| - ..onRefresh.listen((e) {
|
| - e.element.disabled = true;
|
| - _loadProfile = true;
|
| - _r.dirty();
|
| - }),
|
| + new NavRefreshElement(
|
| + label: 'Refresh Allocation Profile', queue: _r.queue)
|
| + ..onRefresh.listen((e) {
|
| + e.element.disabled = true;
|
| + _loadProfile = true;
|
| + _r.dirty();
|
| + }),
|
| new NavRefreshElement(queue: _r.queue)
|
| - ..onRefresh.listen((e) {
|
| - e.element.disabled = true;
|
| - _common = null;
|
| - _classInstances = null;
|
| - _fieldsExpanded = null;
|
| - _functionsExpanded = null;
|
| - _refresh();
|
| - }),
|
| + ..onRefresh.listen((e) {
|
| + e.element.disabled = true;
|
| + _common = null;
|
| + _classInstances = null;
|
| + _fieldsExpanded = null;
|
| + _functionsExpanded = null;
|
| + _refresh();
|
| + }),
|
| new NavNotifyElement(_notifications, queue: _r.queue)
|
| ]),
|
| - new DivElement()..classes = ['content-centered-big']
|
| + new DivElement()
|
| + ..classes = ['content-centered-big']
|
| ..children = [
|
| new HeadingElement.h2()..text = '$header class ${_cls.name}',
|
| new HRElement(),
|
| _common,
|
| new BRElement(),
|
| - new DivElement()..classes = ['memberList']
|
| + new DivElement()
|
| + ..classes = ['memberList']
|
| ..children = _createMembers(),
|
| new DivElement()
|
| ..children = _cls.error == null
|
| - ? const []
|
| - : [
|
| - new HRElement(),
|
| - new ErrorRefElement(_cls.error, queue: _r.queue)
|
| - ],
|
| + ? const []
|
| + : [
|
| + new HRElement(),
|
| + new ErrorRefElement(_cls.error, queue: _r.queue)
|
| + ],
|
| new HRElement(),
|
| new EvalBoxElement(_isolate, _cls, _instances, _eval,
|
| - queue: _r.queue),
|
| + queue: _r.queue),
|
| new HRElement(),
|
| new HeadingElement.h2()..text = 'Fields & Functions',
|
| - new DivElement()..classes = ['memberList']
|
| + new DivElement()
|
| + ..classes = ['memberList']
|
| ..children = _createElements(),
|
| new HRElement(),
|
| new HeadingElement.h2()..text = 'Instances',
|
| new DivElement()
|
| - ..children = _cls.hasAllocations
|
| - ? [_classInstances]
|
| - : const [],
|
| + ..children = _cls.hasAllocations ? [_classInstances] : const [],
|
| new HRElement(),
|
| new HeadingElement.h2()..text = 'Allocations',
|
| - new DivElement()..classes = ['memberList']
|
| + new DivElement()
|
| + ..classes = ['memberList']
|
| ..children = [
|
| - new DivElement()..classes = ['memberName']
|
| + new DivElement()
|
| + ..classes = ['memberName']
|
| ..text = 'Tracing allocations? ',
|
| - new DivElement()..classes = ['memberValue']
|
| + new DivElement()
|
| + ..classes = ['memberValue']
|
| ..children = _cls.traceAllocations
|
| - ? [
|
| - new SpanElement()..text = 'Yes ',
|
| - new ButtonElement()..text = 'disable'
|
| - ..onClick.listen((e) async {
|
| - e.target.disabled = true;
|
| - await _profiles.disable(_isolate, _cls);
|
| - _loadProfile = true;
|
| - _refresh();
|
| - })
|
| - ]
|
| - : [
|
| - new SpanElement()..text = 'No ',
|
| - new ButtonElement()..text = 'enable'
|
| - ..onClick.listen((e) async {
|
| - e.target.disabled = true;
|
| - await _profiles.enable(_isolate, _cls);
|
| - _refresh();
|
| - })
|
| - ]
|
| + ? [
|
| + new SpanElement()..text = 'Yes ',
|
| + new ButtonElement()
|
| + ..text = 'disable'
|
| + ..onClick.listen((e) async {
|
| + e.target.disabled = true;
|
| + await _profiles.disable(_isolate, _cls);
|
| + _loadProfile = true;
|
| + _refresh();
|
| + })
|
| + ]
|
| + : [
|
| + new SpanElement()..text = 'No ',
|
| + new ButtonElement()
|
| + ..text = 'enable'
|
| + ..onClick.listen((e) async {
|
| + e.target.disabled = true;
|
| + await _profiles.enable(_isolate, _cls);
|
| + _refresh();
|
| + })
|
| + ]
|
| ],
|
| new DivElement()
|
| ..children = _loadProfile
|
| - ? [new ClassAllocationProfileElement(_isolate, _cls, _profiles,
|
| - queue: _r.queue)]
|
| - : const [],
|
| + ? [
|
| + new ClassAllocationProfileElement(_isolate, _cls, _profiles,
|
| + queue: _r.queue)
|
| + ]
|
| + : const [],
|
| new DivElement()
|
| ..children = _cls.location != null
|
| - ? [new HRElement(),
|
| - new SourceInsetElement(_isolate, _cls.location, _scripts,
|
| - _instances, _events, queue: _r.queue)]
|
| - : const [],
|
| + ? [
|
| + new HRElement(),
|
| + new SourceInsetElement(
|
| + _isolate, _cls.location, _scripts, _instances, _events,
|
| + queue: _r.queue)
|
| + ]
|
| + : const [],
|
| new HRElement(),
|
| new ViewFooterElement(queue: _r.queue)
|
| ]
|
| @@ -277,115 +298,127 @@ class ClassViewElement extends HtmlElement implements Renderable {
|
| List<Element> _createMembers() {
|
| final members = <Element>[];
|
| if (_cls.library != null) {
|
| - members.add(
|
| - new DivElement()..classes = ['memberItem']
|
| - ..children = [
|
| - new DivElement()..classes = ['memberName']
|
| - ..text = 'library',
|
| - new DivElement()..classes = ['memberValue']
|
| - ..children = [
|
| - new LibraryRefElement(_isolate, _cls.library, queue: _r.queue)
|
| - ]
|
| - ]
|
| - );
|
| + members.add(new DivElement()
|
| + ..classes = ['memberItem']
|
| + ..children = [
|
| + new DivElement()
|
| + ..classes = ['memberName']
|
| + ..text = 'library',
|
| + new DivElement()
|
| + ..classes = ['memberValue']
|
| + ..children = [
|
| + new LibraryRefElement(_isolate, _cls.library, queue: _r.queue)
|
| + ]
|
| + ]);
|
| }
|
| if (_cls.location != null) {
|
| - members.add(
|
| - new DivElement()..classes = ['memberItem']
|
| - ..children = [
|
| - new DivElement()..classes = ['memberName']
|
| - ..text = 'script',
|
| - new DivElement()..classes = ['memberValue']
|
| - ..children = [
|
| - new SourceLinkElement(_isolate, _cls.location, _scripts,
|
| - queue: _r.queue)
|
| - ]
|
| - ]
|
| - );
|
| + members.add(new DivElement()
|
| + ..classes = ['memberItem']
|
| + ..children = [
|
| + new DivElement()
|
| + ..classes = ['memberName']
|
| + ..text = 'script',
|
| + new DivElement()
|
| + ..classes = ['memberValue']
|
| + ..children = [
|
| + new SourceLinkElement(_isolate, _cls.location, _scripts,
|
| + queue: _r.queue)
|
| + ]
|
| + ]);
|
| }
|
| if (_cls.superclass != null) {
|
| - members.add(
|
| - new DivElement()..classes = ['memberItem']
|
| - ..children = [
|
| - new DivElement()..classes = ['memberName']
|
| - ..text = 'superclass',
|
| - new DivElement()..classes = ['memberValue']
|
| - ..children = [
|
| - new ClassRefElement(_isolate, _cls.superclass, queue: _r.queue)
|
| - ]
|
| - ]
|
| - );
|
| + members.add(new DivElement()
|
| + ..classes = ['memberItem']
|
| + ..children = [
|
| + new DivElement()
|
| + ..classes = ['memberName']
|
| + ..text = 'superclass',
|
| + new DivElement()
|
| + ..classes = ['memberValue']
|
| + ..children = [
|
| + new ClassRefElement(_isolate, _cls.superclass, queue: _r.queue)
|
| + ]
|
| + ]);
|
| }
|
| if (_cls.superType != null) {
|
| - members.add(
|
| - new DivElement()..classes = ['memberItem']
|
| - ..children = [
|
| - new DivElement()..classes = ['memberName']
|
| - ..text = 'supertype',
|
| - new DivElement()..classes = ['memberValue']
|
| - ..children = [
|
| - new InstanceRefElement(_isolate, _cls.superType, _instances,
|
| - queue: _r.queue)
|
| - ]
|
| - ]
|
| - );
|
| + members.add(new DivElement()
|
| + ..classes = ['memberItem']
|
| + ..children = [
|
| + new DivElement()
|
| + ..classes = ['memberName']
|
| + ..text = 'supertype',
|
| + new DivElement()
|
| + ..classes = ['memberValue']
|
| + ..children = [
|
| + new InstanceRefElement(_isolate, _cls.superType, _instances,
|
| + queue: _r.queue)
|
| + ]
|
| + ]);
|
| }
|
| if (cls.mixin != null) {
|
| - members.add(
|
| - new DivElement()..classes = ['memberItem']
|
| - ..children = [
|
| - new DivElement()..classes = ['memberName']
|
| - ..text = 'mixin',
|
| - new DivElement()..classes = ['memberValue']
|
| - ..children = [
|
| - new InstanceRefElement(_isolate, _cls.mixin, _instances,
|
| - queue: _r.queue)
|
| - ]
|
| - ]
|
| - );
|
| + members.add(new DivElement()
|
| + ..classes = ['memberItem']
|
| + ..children = [
|
| + new DivElement()
|
| + ..classes = ['memberName']
|
| + ..text = 'mixin',
|
| + new DivElement()
|
| + ..classes = ['memberValue']
|
| + ..children = [
|
| + new InstanceRefElement(_isolate, _cls.mixin, _instances,
|
| + queue: _r.queue)
|
| + ]
|
| + ]);
|
| }
|
| if (_cls.subclasses.length > 0) {
|
| - members.add(
|
| - new DivElement()..classes = ['memberItem']
|
| - ..children = [
|
| - new DivElement()..classes = ['memberName']
|
| - ..text = 'extended by',
|
| - new DivElement()..classes = ['memberValue']
|
| - ..children = (_cls.subclasses.expand((subcls) => [
|
| - new ClassRefElement(_isolate, subcls, queue: _r.queue),
|
| - new SpanElement()..text = ', '
|
| - ]).toList()..removeLast())
|
| - ]
|
| - );
|
| + members.add(new DivElement()
|
| + ..classes = ['memberItem']
|
| + ..children = [
|
| + new DivElement()
|
| + ..classes = ['memberName']
|
| + ..text = 'extended by',
|
| + new DivElement()
|
| + ..classes = ['memberValue']
|
| + ..children = (_cls.subclasses
|
| + .expand((subcls) => [
|
| + new ClassRefElement(_isolate, subcls, queue: _r.queue),
|
| + new SpanElement()..text = ', '
|
| + ])
|
| + .toList()..removeLast())
|
| + ]);
|
| }
|
|
|
| members.add(new BRElement());
|
|
|
| if (_cls.interfaces.length > 0) {
|
| - members.add(
|
| - new DivElement()..classes = ['memberItem']
|
| - ..children = [
|
| - new DivElement()..classes = ['memberName']
|
| - ..text = 'implements',
|
| - new DivElement()..classes = ['memberValue']
|
| - ..children = (_cls.interfaces.expand((interf) => [
|
| - new InstanceRefElement(_isolate, interf, _instances,
|
| - queue: _r.queue),
|
| - new SpanElement()..text = ', '
|
| - ]).toList()..removeLast())
|
| - ]
|
| - );
|
| + members.add(new DivElement()
|
| + ..classes = ['memberItem']
|
| + ..children = [
|
| + new DivElement()
|
| + ..classes = ['memberName']
|
| + ..text = 'implements',
|
| + new DivElement()
|
| + ..classes = ['memberValue']
|
| + ..children = (_cls.interfaces
|
| + .expand((interf) => [
|
| + new InstanceRefElement(_isolate, interf, _instances,
|
| + queue: _r.queue),
|
| + new SpanElement()..text = ', '
|
| + ])
|
| + .toList()..removeLast())
|
| + ]);
|
| }
|
| if (_cls.name != _cls.vmName) {
|
| - members.add(
|
| - new DivElement()..classes = ['memberItem']
|
| - ..children = [
|
| - new DivElement()..classes = ['memberName']
|
| - ..text = 'vm name',
|
| - new DivElement()..classes = ['memberValue']
|
| - ..text = '${_cls.vmName}'
|
| - ]
|
| - );
|
| + members.add(new DivElement()
|
| + ..classes = ['memberItem']
|
| + ..children = [
|
| + new DivElement()
|
| + ..classes = ['memberName']
|
| + ..text = 'vm name',
|
| + new DivElement()
|
| + ..classes = ['memberValue']
|
| + ..text = '${_cls.vmName}'
|
| + ]);
|
| }
|
| return members;
|
| }
|
| @@ -395,62 +428,70 @@ class ClassViewElement extends HtmlElement implements Renderable {
|
| if (_classFields != null && _classFields.isNotEmpty) {
|
| final fields = _classFields.toList();
|
| _fieldsExpanded = _fieldsExpanded ?? (fields.length <= 8);
|
| - members.add(
|
| - new DivElement()..classes = ['memberItem']
|
| - ..children = [
|
| - new DivElement()..classes = ['memberName']
|
| - ..text = 'fields ${fields.length}',
|
| - new DivElement()..classes = ['memberValue']
|
| - ..children =[
|
| - new CurlyBlockElement(expanded: _fieldsExpanded)
|
| - ..onToggle.listen((e) => _fieldsExpanded = e.control.expanded)
|
| - ..content = [
|
| - new DivElement()..classes = ['memberList']
|
| - ..children = (fields.map((f) =>
|
| - new DivElement()..classes = ['memberItem']
|
| + members.add(new DivElement()
|
| + ..classes = ['memberItem']
|
| + ..children = [
|
| + new DivElement()
|
| + ..classes = ['memberName']
|
| + ..text = 'fields ${fields.length}',
|
| + new DivElement()
|
| + ..classes = ['memberValue']
|
| + ..children = [
|
| + new CurlyBlockElement(expanded: _fieldsExpanded)
|
| + ..onToggle.listen((e) => _fieldsExpanded = e.control.expanded)
|
| + ..content = [
|
| + new DivElement()
|
| + ..classes = ['memberList']
|
| + ..children = (fields
|
| + .map((f) => new DivElement()
|
| + ..classes = ['memberItem']
|
| ..children = [
|
| - new DivElement()..classes = ['memberName']
|
| - ..children =[
|
| + new DivElement()
|
| + ..classes = ['memberName']
|
| + ..children = [
|
| new FieldRefElement(_isolate, f, _instances,
|
| - queue: _r.queue)
|
| + queue: _r.queue)
|
| ],
|
| - new DivElement()..classes = ['memberValue']
|
| + new DivElement()
|
| + ..classes = ['memberValue']
|
| ..children = f.staticValue == null
|
| - ? const []
|
| - : [
|
| - anyRef(_isolate, f.staticValue, _instances,
|
| - queue: _r.queue)
|
| - ]
|
| - ]
|
| - ).toList())
|
| - ]
|
| - ]
|
| - ]
|
| - );
|
| + ? const []
|
| + : [
|
| + anyRef(
|
| + _isolate, f.staticValue, _instances,
|
| + queue: _r.queue)
|
| + ]
|
| + ])
|
| + .toList())
|
| + ]
|
| + ]
|
| + ]);
|
| }
|
|
|
| if (_cls.functions.isNotEmpty) {
|
| final functions = _cls.functions.toList();
|
| _functionsExpanded = _functionsExpanded ?? (functions.length <= 8);
|
| - members.add(
|
| - new DivElement()..classes = ['memberItem']
|
| - ..children = [
|
| - new DivElement()..classes = ['memberName']
|
| - ..text = 'functions (${functions.length})',
|
| - new DivElement()..classes = ['memberValue']
|
| - ..children =[
|
| - new CurlyBlockElement(expanded: _functionsExpanded)
|
| - ..onToggle.listen((e) =>
|
| - _functionsExpanded = e.control.expanded)
|
| - ..content = (functions.map((f) =>
|
| - new DivElement()..classes = ['indent']
|
| + members.add(new DivElement()
|
| + ..classes = ['memberItem']
|
| + ..children = [
|
| + new DivElement()
|
| + ..classes = ['memberName']
|
| + ..text = 'functions (${functions.length})',
|
| + new DivElement()
|
| + ..classes = ['memberValue']
|
| + ..children = [
|
| + new CurlyBlockElement(expanded: _functionsExpanded)
|
| + ..onToggle
|
| + .listen((e) => _functionsExpanded = e.control.expanded)
|
| + ..content = (functions
|
| + .map((f) => new DivElement()
|
| + ..classes = ['indent']
|
| ..children = [
|
| new FunctionRefElement(_isolate, f, queue: _r.queue)
|
| - ]
|
| - ).toList())
|
| - ]
|
| - ]
|
| - );
|
| + ])
|
| + .toList())
|
| + ]
|
| + ]);
|
| }
|
| return members;
|
| }
|
| @@ -462,8 +503,8 @@ class ClassViewElement extends HtmlElement implements Renderable {
|
| }
|
|
|
| Future _loadAdditionalData() async {
|
| - _classFields = await Future.wait(_cls.fields.map((f)
|
| - => _fields.get(_isolate, f.id)));
|
| + _classFields =
|
| + await Future.wait(_cls.fields.map((f) => _fields.get(_isolate, f.id)));
|
| _r.dirty();
|
| }
|
| }
|
|
|