| // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| // for details. All rights reserved. Use of this source code is governed by a |
| // BSD-style license that can be found in the LICENSE file. |
| |
| library instance_view_element; |
| |
| import 'dart:async'; |
| import 'dart:html'; |
| import 'package:observatory/models.dart' as M; |
| import 'package:observatory/src/elements/class_ref.dart'; |
| import 'package:observatory/src/elements/context_ref.dart'; |
| import 'package:observatory/src/elements/curly_block.dart'; |
| import 'package:observatory/src/elements/eval_box.dart'; |
| import 'package:observatory/src/elements/field_ref.dart'; |
| import 'package:observatory/src/elements/function_ref.dart'; |
| import 'package:observatory/src/elements/helpers/any_ref.dart'; |
| import 'package:observatory/src/elements/helpers/nav_bar.dart'; |
| import 'package:observatory/src/elements/helpers/nav_menu.dart'; |
| import 'package:observatory/src/elements/helpers/rendering_scheduler.dart'; |
| import 'package:observatory/src/elements/helpers/tag.dart'; |
| import 'package:observatory/src/elements/instance_ref.dart'; |
| import 'package:observatory/src/elements/nav/class_menu.dart'; |
| import 'package:observatory/src/elements/nav/isolate_menu.dart'; |
| import 'package:observatory/src/elements/nav/library_menu.dart'; |
| import 'package:observatory/src/elements/nav/notify.dart'; |
| import 'package:observatory/src/elements/nav/refresh.dart'; |
| import 'package:observatory/src/elements/nav/top_menu.dart'; |
| import 'package:observatory/src/elements/nav/vm_menu.dart'; |
| import 'package:observatory/src/elements/object_common.dart'; |
| import 'package:observatory/src/elements/source_inset.dart'; |
| import 'package:observatory/src/elements/source_link.dart'; |
| import 'package:observatory/src/elements/view_footer.dart'; |
| import 'package:observatory/utils.dart'; |
| |
| class InstanceViewElement extends HtmlElement implements Renderable { |
| static const tag = |
| const Tag<InstanceViewElement>('instance-view', dependencies: const [ |
| ClassRefElement.tag, |
| ContextRefElement.tag, |
| CurlyBlockElement.tag, |
| FieldRefElement.tag, |
| FunctionRefElement.tag, |
| InstanceRefElement.tag, |
| NavClassMenuElement.tag, |
| NavLibraryMenuElement.tag, |
| NavTopMenuElement.tag, |
| NavVMMenuElement.tag, |
| NavIsolateMenuElement.tag, |
| NavRefreshElement.tag, |
| NavNotifyElement.tag, |
| ObjectCommonElement.tag, |
| SourceInsetElement.tag, |
| SourceLinkElement.tag, |
| ViewFooterElement.tag |
| ]); |
| |
| RenderingScheduler<InstanceViewElement> _r; |
| |
| Stream<RenderedEvent<InstanceViewElement>> get onRendered => _r.onRendered; |
| |
| M.VM _vm; |
| M.IsolateRef _isolate; |
| M.EventRepository _events; |
| M.NotificationRepository _notifications; |
| M.Instance _instance; |
| M.LibraryRef _library; |
| M.ObjectRepository _objects; |
| M.ClassRepository _classes; |
| M.RetainedSizeRepository _retainedSizes; |
| M.ReachableSizeRepository _reachableSizes; |
| M.InboundReferencesRepository _references; |
| M.RetainingPathRepository _retainingPaths; |
| M.ScriptRepository _scripts; |
| M.EvalRepository _eval; |
| M.TypeArguments _typeArguments; |
| M.TypeArgumentsRepository _arguments; |
| M.BreakpointRepository _breakpoints; |
| M.FunctionRepository _functions; |
| M.SourceLocation _location; |
| |
| M.VMRef get vm => _vm; |
| M.IsolateRef get isolate => _isolate; |
| M.NotificationRepository get notifications => _notifications; |
| M.Instance get instance => _instance; |
| |
| factory InstanceViewElement( |
| M.VM vm, |
| M.IsolateRef isolate, |
| M.Instance instance, |
| M.EventRepository events, |
| M.NotificationRepository notifications, |
| M.ObjectRepository objects, |
| M.ClassRepository classes, |
| M.RetainedSizeRepository retainedSizes, |
| M.ReachableSizeRepository reachableSizes, |
| M.InboundReferencesRepository references, |
| M.RetainingPathRepository retainingPaths, |
| M.ScriptRepository scripts, |
| M.EvalRepository eval, |
| M.TypeArgumentsRepository arguments, |
| M.BreakpointRepository breakpoints, |
| M.FunctionRepository functions, |
| {RenderingQueue queue}) { |
| assert(vm != null); |
| assert(isolate != null); |
| assert(events != null); |
| assert(notifications != null); |
| assert(instance != null); |
| assert(objects != null); |
| assert(classes != null); |
| assert(retainedSizes != null); |
| assert(reachableSizes != null); |
| assert(references != null); |
| assert(retainingPaths != null); |
| assert(scripts != null); |
| assert(eval != null); |
| assert(arguments != null); |
| assert(breakpoints != null); |
| assert(functions != null); |
| InstanceViewElement e = document.createElement(tag.name); |
| e._r = new RenderingScheduler<InstanceViewElement>(e, queue: queue); |
| e._vm = vm; |
| e._isolate = isolate; |
| e._events = events; |
| e._notifications = notifications; |
| e._instance = instance; |
| e._objects = objects; |
| e._classes = classes; |
| e._retainedSizes = retainedSizes; |
| e._reachableSizes = reachableSizes; |
| e._references = references; |
| e._retainingPaths = retainingPaths; |
| e._scripts = scripts; |
| e._eval = eval; |
| e._arguments = arguments; |
| e._breakpoints = breakpoints; |
| e._functions = functions; |
| return e; |
| } |
| |
| InstanceViewElement.created() : super.created(); |
| |
| @override |
| attached() { |
| super.attached(); |
| _r.enable(); |
| _loadExtraData(); |
| } |
| |
| @override |
| detached() { |
| super.detached(); |
| _r.disable(notify: true); |
| children = <Element>[]; |
| } |
| |
| void render() { |
| final content = <Element>[ |
| new HeadingElement.h2() |
| ..text = M.isAbstractType(_instance.kind) |
| ? 'type ${_instance.name}' |
| : 'instance of ${_instance.clazz.name}', |
| new HRElement(), |
| new ObjectCommonElement(_isolate, _instance, _retainedSizes, |
| _reachableSizes, _references, _retainingPaths, _objects, |
| queue: _r.queue), |
| new BRElement(), |
| new DivElement() |
| ..classes = ['memberList'] |
| ..children = _createMembers(), |
| new HRElement(), |
| new EvalBoxElement(_isolate, _instance, _objects, _eval, |
| quickExpressions: const ['toString()', 'runtimeType'], |
| queue: _r.queue) |
| ]; |
| if (_location != null) { |
| content.addAll([ |
| new HRElement(), |
| new SourceInsetElement(_isolate, _location, _scripts, _objects, _events, |
| queue: _r.queue) |
| ]); |
| } |
| content.addAll([new HRElement(), new ViewFooterElement(queue: _r.queue)]); |
| children = <Element>[ |
| navBar(_createMenu()), |
| new DivElement() |
| ..classes = ['content-centered-big'] |
| ..children = content |
| ]; |
| } |
| |
| List<Element> _createMenu() { |
| final menu = <Element>[ |
| new NavTopMenuElement(queue: _r.queue), |
| new NavVMMenuElement(_vm, _events, queue: _r.queue), |
| new NavIsolateMenuElement(_isolate, _events, queue: _r.queue) |
| ]; |
| if (_library != null) { |
| menu.add(new NavLibraryMenuElement(_isolate, _library, queue: _r.queue)); |
| } |
| menu.addAll(<Element>[ |
| new NavClassMenuElement(_isolate, _instance.clazz, queue: _r.queue), |
| navMenu('instance'), |
| new NavRefreshElement(queue: _r.queue) |
| ..onRefresh.listen((e) { |
| e.element.disabled = true; |
| _refresh(); |
| }), |
| new NavNotifyElement(_notifications, queue: _r.queue) |
| ]); |
| return menu; |
| } |
| |
| List<Element> _createMembers() { |
| final members = <Element>[]; |
| if (_instance.valueAsString != null) { |
| members.add(new DivElement() |
| ..classes = ['memberItem'] |
| ..children = <Element>[ |
| new DivElement() |
| ..classes = ['memberName'] |
| ..text = _instance.kind == M.InstanceKind.string |
| ? 'value as literal' |
| : 'value', |
| new DivElement() |
| ..classes = ['memberValue'] |
| ..text = _instance.kind == M.InstanceKind.string |
| ? Utils.formatStringAsLiteral( |
| _instance.valueAsString, _instance.valueAsStringIsTruncated) |
| : _instance.valueAsString |
| ]); |
| } |
| if (_instance.typeClass != null) { |
| members.add(new DivElement() |
| ..classes = ['memberItem'] |
| ..children = <Element>[ |
| new DivElement() |
| ..classes = ['memberName'] |
| ..text = 'type class', |
| new DivElement() |
| ..classes = ['memberValue'] |
| ..children = <Element>[ |
| new ClassRefElement(_isolate, _instance.typeClass, |
| queue: _r.queue) |
| ] |
| ]); |
| } |
| if (_typeArguments != null && _typeArguments.types.isNotEmpty) { |
| members.add(new DivElement() |
| ..classes = ['memberItem'] |
| ..children = <Element>[ |
| new DivElement() |
| ..classes = ['memberName'] |
| ..text = 'type arguments', |
| new DivElement() |
| ..classes = ['memberValue'] |
| ..children = ([new SpanElement()..text = '< '] |
| ..addAll(_typeArguments.types.expand((type) => [ |
| new InstanceRefElement(_isolate, type, _objects, |
| queue: _r.queue), |
| new SpanElement()..text = ', ' |
| ])) |
| ..removeLast() |
| ..add(new SpanElement()..text = ' >')) |
| ]); |
| } |
| if (_instance.parameterizedClass != null) { |
| members.add(new DivElement() |
| ..classes = ['memberItem'] |
| ..children = <Element>[ |
| new DivElement() |
| ..classes = ['memberName'] |
| ..text = 'parameterized class', |
| new DivElement() |
| ..classes = ['memberValue'] |
| ..children = <Element>[ |
| new ClassRefElement(_isolate, _instance.parameterizedClass, |
| queue: _r.queue) |
| ] |
| ]); |
| } |
| if (_instance.parameterIndex != null) { |
| members.add(new DivElement() |
| ..classes = ['memberItem'] |
| ..children = <Element>[ |
| new DivElement() |
| ..classes = ['memberName'] |
| ..text = 'parameter index', |
| new DivElement() |
| ..classes = ['memberValue'] |
| ..text = '${_instance.parameterIndex}' |
| ]); |
| } |
| if (_instance.targetType != null) { |
| members.add(new DivElement() |
| ..classes = ['memberItem'] |
| ..children = <Element>[ |
| new DivElement() |
| ..classes = ['memberName'] |
| ..text = 'target type', |
| new DivElement() |
| ..classes = ['memberValue'] |
| ..children = <Element>[ |
| new InstanceRefElement(_isolate, _instance.targetType, _objects, |
| queue: _r.queue) |
| ] |
| ]); |
| } |
| if (_instance.bound != null) { |
| members.add(new DivElement() |
| ..classes = ['memberItem'] |
| ..children = <Element>[ |
| new DivElement() |
| ..classes = ['memberName'] |
| ..text = 'bound', |
| new DivElement() |
| ..classes = ['memberValue'] |
| ..children = <Element>[ |
| new InstanceRefElement(_isolate, _instance.bound, _objects, |
| queue: _r.queue) |
| ] |
| ]); |
| } |
| if (_instance.closureFunction != null) { |
| members.add(new DivElement() |
| ..classes = ['memberItem'] |
| ..children = <Element>[ |
| new DivElement() |
| ..classes = ['memberName'] |
| ..text = 'closure function', |
| new DivElement() |
| ..classes = ['memberValue'] |
| ..children = <Element>[ |
| new FunctionRefElement(_isolate, _instance.closureFunction, |
| queue: _r.queue) |
| ] |
| ]); |
| } |
| if (_instance.closureContext != null) { |
| members.add(new DivElement() |
| ..classes = ['memberItem'] |
| ..children = <Element>[ |
| new DivElement() |
| ..classes = ['memberName'] |
| ..text = 'closure context', |
| new DivElement() |
| ..classes = ['memberValue'] |
| ..children = <Element>[ |
| new ContextRefElement( |
| _isolate, _instance.closureContext, _objects, |
| queue: _r.queue) |
| ] |
| ]); |
| } |
| if (_instance.kind == M.InstanceKind.closure) { |
| ButtonElement btn; |
| members.add(new DivElement() |
| ..classes = ['memberItem'] |
| ..children = <Element>[ |
| new DivElement() |
| ..classes = ['memberName'] |
| ..text = 'closure breakpoint', |
| new DivElement() |
| ..classes = ['memberValue'] |
| ..children = <Element>[ |
| btn = new ButtonElement() |
| ..text = _instance.activationBreakpoint == null |
| ? 'break on activation' |
| : 'remove' |
| ..onClick.listen((_) { |
| btn.disabled = true; |
| _toggleBreakpoint(); |
| }) |
| ] |
| ]); |
| } |
| |
| if (_instance.nativeFields != null && _instance.nativeFields.isNotEmpty) { |
| int i = 0; |
| members.add(new DivElement() |
| ..classes = ['memberItem'] |
| ..children = <Element>[ |
| new DivElement() |
| ..classes = ['memberName'] |
| ..text = 'native fields (${_instance.nativeFields.length})', |
| new DivElement() |
| ..classes = ['memberName'] |
| ..children = <Element>[ |
| new CurlyBlockElement( |
| expanded: _instance.nativeFields.length <= 100, |
| queue: _r.queue) |
| ..content = <Element>[ |
| new DivElement() |
| ..classes = ['memberList'] |
| ..children = _instance.nativeFields |
| .map<Element>((f) => new DivElement() |
| ..classes = ['memberItem'] |
| ..children = <Element>[ |
| new DivElement() |
| ..classes = ['memberName'] |
| ..text = '[ ${i++} ]', |
| new DivElement() |
| ..classes = ['memberValue'] |
| ..text = '[ ${f.value} ]' |
| ]) |
| .toList() |
| ] |
| ] |
| ]); |
| } |
| |
| if (_instance.fields != null && _instance.fields.isNotEmpty) { |
| final fields = _instance.fields.toList(); |
| members.add(new DivElement() |
| ..classes = ['memberItem'] |
| ..children = <Element>[ |
| new DivElement() |
| ..classes = ['memberName'] |
| ..text = 'fields (${fields.length})', |
| new DivElement() |
| ..classes = ['memberName'] |
| ..children = <Element>[ |
| new CurlyBlockElement( |
| expanded: fields.length <= 100, queue: _r.queue) |
| ..content = <Element>[ |
| new DivElement() |
| ..classes = ['memberList'] |
| ..children = fields |
| .map<Element>((f) => new DivElement() |
| ..classes = ['memberItem'] |
| ..children = <Element>[ |
| new DivElement() |
| ..classes = ['memberName'] |
| ..children = <Element>[ |
| new FieldRefElement(_isolate, f.decl, _objects, |
| queue: _r.queue) |
| ], |
| new DivElement() |
| ..classes = ['memberValue'] |
| ..children = <Element>[ |
| new SpanElement()..text = ' = ', |
| anyRef(_isolate, f.value, _objects, |
| queue: _r.queue) |
| ] |
| ]) |
| .toList() |
| ] |
| ] |
| ]); |
| } |
| |
| if (_instance.elements != null && _instance.elements.isNotEmpty) { |
| final elements = _instance.elements.toList(); |
| int i = 0; |
| members.add(new DivElement() |
| ..classes = ['memberItem'] |
| ..children = <Element>[ |
| new DivElement() |
| ..classes = ['memberName'] |
| ..text = 'elements (${_instance.length})', |
| new DivElement() |
| ..classes = ['memberValue'] |
| ..children = <Element>[ |
| new CurlyBlockElement( |
| expanded: elements.length <= 100, queue: _r.queue) |
| ..content = <Element>[ |
| new DivElement() |
| ..classes = ['memberList'] |
| ..children = elements |
| .map<Element>((element) => new DivElement() |
| ..classes = ['memberItem'] |
| ..children = <Element>[ |
| new DivElement() |
| ..classes = ['memberName'] |
| ..text = '[ ${i++} ]', |
| new DivElement() |
| ..classes = ['memberValue'] |
| ..children = <Element>[ |
| anyRef(_isolate, element, _objects, |
| queue: _r.queue) |
| ] |
| ]) |
| .toList() |
| ] |
| ] |
| ]); |
| if (_instance.length != elements.length) { |
| members.add(new DivElement() |
| ..classes = ['memberItem'] |
| ..children = <Element>[ |
| new DivElement() |
| ..classes = ['memberName'] |
| ..text = '...', |
| new DivElement() |
| ..classes = ['memberValue'] |
| ..text = '${_instance.length - elements.length} omitted elements' |
| ]); |
| } |
| } |
| |
| if (_instance.associations != null && _instance.associations.isNotEmpty) { |
| final associations = _instance.associations.toList(); |
| members.add(new DivElement() |
| ..classes = ['memberItem'] |
| ..children = <Element>[ |
| new DivElement() |
| ..classes = ['memberName'] |
| ..text = 'associations (${_instance.length})', |
| new DivElement() |
| ..classes = ['memberName'] |
| ..children = <Element>[ |
| new CurlyBlockElement( |
| expanded: associations.length <= 100, queue: _r.queue) |
| ..content = <Element>[ |
| new DivElement() |
| ..classes = ['memberList'] |
| ..children = associations |
| .map<Element>((a) => new DivElement() |
| ..classes = ['memberItem'] |
| ..children = <Element>[ |
| new DivElement() |
| ..classes = ['memberName'] |
| ..children = <Element>[ |
| new SpanElement()..text = '[ ', |
| anyRef(_isolate, a.key, _objects, |
| queue: _r.queue), |
| new SpanElement()..text = ' ]', |
| ], |
| new DivElement() |
| ..classes = ['memberValue'] |
| ..children = <Element>[ |
| anyRef(_isolate, a.value, _objects, |
| queue: _r.queue) |
| ] |
| ]) |
| .toList() |
| ] |
| ] |
| ]); |
| if (_instance.length != associations.length) { |
| members.add(new DivElement() |
| ..classes = ['memberItem'] |
| ..children = <Element>[ |
| new DivElement() |
| ..classes = ['memberName'] |
| ..text = '...', |
| new DivElement() |
| ..classes = ['memberValue'] |
| ..text = '${_instance.length - associations.length} ' |
| 'omitted elements' |
| ]); |
| } |
| } |
| |
| if (_instance.typedElements != null && _instance.typedElements.isNotEmpty) { |
| final typedElements = _instance.typedElements.toList(); |
| int i = 0; |
| members.add(new DivElement() |
| ..classes = ['memberItem'] |
| ..children = <Element>[ |
| new DivElement() |
| ..classes = ['memberName'] |
| ..text = 'elements (${_instance.length})', |
| new DivElement() |
| ..classes = ['memberValue'] |
| ..children = <Element>[ |
| new CurlyBlockElement( |
| expanded: typedElements.length <= 100, queue: _r.queue) |
| ..content = <Element>[ |
| new DivElement() |
| ..classes = ['memberList'] |
| ..children = typedElements |
| .map<Element>((e) => new DivElement() |
| ..classes = ['memberItem'] |
| ..children = <Element>[ |
| new DivElement() |
| ..classes = ['memberName'] |
| ..text = '[ ${i++} ]', |
| new DivElement() |
| ..classes = ['memberValue'] |
| ..text = '$e' |
| ]) |
| .toList() |
| ] |
| ] |
| ]); |
| if (_instance.length != typedElements.length) { |
| members.add(new DivElement() |
| ..classes = ['memberItem'] |
| ..children = <Element>[ |
| new DivElement() |
| ..classes = ['memberName'] |
| ..text = '...', |
| new DivElement() |
| ..classes = ['memberValue'] |
| ..text = '${_instance.length - typedElements.length} ' |
| 'omitted elements' |
| ]); |
| } |
| } |
| |
| if (_instance.kind == M.InstanceKind.regExp) { |
| members.addAll([ |
| new DivElement() |
| ..classes = ['memberItem'] |
| ..children = <Element>[ |
| new DivElement() |
| ..classes = ['memberName'] |
| ..text = 'pattern', |
| new DivElement() |
| ..classes = ['memberValue'] |
| ..children = <Element>[ |
| anyRef(_isolate, _instance.pattern, _objects, queue: _r.queue) |
| ] |
| ], |
| new DivElement() |
| ..classes = ['memberItem'] |
| ..children = <Element>[ |
| new DivElement() |
| ..classes = ['memberName'] |
| ..text = 'isCaseSensitive', |
| new DivElement() |
| ..classes = ['memberValue'] |
| ..text = _instance.isCaseSensitive ? 'yes' : 'no' |
| ], |
| new DivElement() |
| ..classes = ['memberItem'] |
| ..children = <Element>[ |
| new DivElement() |
| ..classes = ['memberName'] |
| ..text = 'isMultiLine', |
| new DivElement() |
| ..classes = ['memberValue'] |
| ..text = _instance.isMultiLine ? 'yes' : 'no' |
| ], |
| new DivElement() |
| ..classes = ['memberItem'] |
| ..children = <Element>[ |
| new DivElement() |
| ..classes = ['memberName'] |
| ..text = 'oneByteFunction', |
| new DivElement() |
| ..classes = ['memberValue'] |
| ..children = <Element>[ |
| new FunctionRefElement(_isolate, _instance.oneByteFunction, |
| queue: _r.queue) |
| ] |
| ], |
| new DivElement() |
| ..classes = ['memberItem'] |
| ..children = <Element>[ |
| new DivElement() |
| ..classes = ['memberName'] |
| ..text = 'twoByteFunction', |
| new DivElement() |
| ..classes = ['memberValue'] |
| ..children = <Element>[ |
| new FunctionRefElement(_isolate, _instance.twoByteFunction, |
| queue: _r.queue) |
| ] |
| ], |
| new DivElement() |
| ..classes = ['memberItem'] |
| ..children = <Element>[ |
| new DivElement() |
| ..classes = ['memberName'] |
| ..text = 'externalOneByteFunction', |
| new DivElement() |
| ..classes = ['memberValue'] |
| ..children = <Element>[ |
| new FunctionRefElement( |
| _isolate, _instance.externalOneByteFunction, |
| queue: _r.queue) |
| ] |
| ], |
| new DivElement() |
| ..classes = ['memberItem'] |
| ..children = <Element>[ |
| new DivElement() |
| ..classes = ['memberName'] |
| ..text = 'externalTwoByteFunction', |
| new DivElement() |
| ..classes = ['memberValue'] |
| ..children = <Element>[ |
| new FunctionRefElement( |
| _isolate, _instance.externalTwoByteFunction, |
| queue: _r.queue) |
| ] |
| ], |
| new DivElement() |
| ..classes = ['memberItem'] |
| ..children = <Element>[ |
| new DivElement() |
| ..classes = ['memberName'] |
| ..text = 'oneByteBytecode', |
| new DivElement() |
| ..classes = ['memberValue'] |
| ..children = <Element>[ |
| new InstanceRefElement( |
| _isolate, _instance.oneByteBytecode, _objects, |
| queue: _r.queue) |
| ] |
| ], |
| new DivElement() |
| ..classes = ['memberItem'] |
| ..children = <Element>[ |
| new DivElement() |
| ..classes = ['memberName'] |
| ..text = 'twoByteBytecode', |
| new DivElement() |
| ..classes = ['memberValue'] |
| ..children = <Element>[ |
| new InstanceRefElement( |
| _isolate, _instance.twoByteBytecode, _objects, |
| queue: _r.queue) |
| ] |
| ] |
| ]); |
| } |
| |
| if (_instance.kind == M.InstanceKind.mirrorReference) { |
| members.add(new DivElement() |
| ..classes = ['memberItem'] |
| ..children = <Element>[ |
| new DivElement() |
| ..classes = ['memberName'] |
| ..text = 'referent', |
| new DivElement() |
| ..classes = ['memberValue'] |
| ..children = <Element>[ |
| anyRef(_isolate, _instance.referent, _objects, queue: _r.queue) |
| ] |
| ]); |
| } |
| if (_instance.kind == M.InstanceKind.weakProperty) { |
| members.addAll([ |
| new DivElement() |
| ..classes = ['memberItem'] |
| ..children = <Element>[ |
| new DivElement() |
| ..classes = ['memberName'] |
| ..text = 'key', |
| new DivElement() |
| ..classes = ['memberValue'] |
| ..children = <Element>[ |
| new InstanceRefElement(_isolate, _instance.key, _objects, |
| queue: _r.queue), |
| ] |
| ], |
| new DivElement() |
| ..classes = ['memberItem'] |
| ..children = <Element>[ |
| new DivElement() |
| ..classes = ['memberName'] |
| ..text = 'value', |
| new DivElement() |
| ..classes = ['memberValue'] |
| ..children = <Element>[ |
| new InstanceRefElement(_isolate, _instance.value, _objects, |
| queue: _r.queue), |
| ] |
| ] |
| ]); |
| } |
| return members; |
| } |
| |
| Future _refresh() async { |
| _instance = await _objects.get(_isolate, _instance.id); |
| await _loadExtraData(); |
| _r.dirty(); |
| } |
| |
| Future _loadExtraData() async { |
| _library = (await _classes.get(_isolate, _instance.clazz.id)).library; |
| if (_instance.typeArguments != null) { |
| _typeArguments = |
| await _arguments.get(_isolate, _instance.typeArguments.id); |
| } else { |
| _typeArguments = null; |
| } |
| if (_instance.closureFunction != null) { |
| _location = (await _functions.get(_isolate, _instance.closureFunction.id)) |
| .location; |
| } else if (_instance.typeClass != null) { |
| _location = |
| (await _classes.get(_isolate, _instance.typeClass.id)).location; |
| } |
| _r.dirty(); |
| } |
| |
| Future _toggleBreakpoint() async { |
| if (_instance.activationBreakpoint == null) { |
| await _breakpoints.addOnActivation(_isolate, _instance); |
| } else { |
| await _breakpoints.remove(_isolate, _instance.activationBreakpoint); |
| } |
| await _refresh(); |
| } |
| } |