Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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 library instance_ref_element; | 5 import 'dart:html'; |
| 6 | |
| 7 import 'dart:async'; | 6 import 'dart:async'; |
| 8 import 'package:polymer/polymer.dart'; | 7 import 'package:observatory/models.dart' as M; |
| 9 import 'package:observatory/service.dart'; | 8 import 'package:observatory/src/elements/curly_block.dart'; |
| 10 import 'service_ref.dart'; | 9 import 'package:observatory/src/elements/field_ref.dart'; |
| 11 | 10 import 'package:observatory/src/elements/helpers/any_ref.dart'; |
| 12 @CustomTag('instance-ref') | 11 import 'package:observatory/src/elements/helpers/rendering_scheduler.dart'; |
| 13 class InstanceRefElement extends ServiceRefElement { | 12 import 'package:observatory/src/elements/helpers/tag.dart'; |
| 13 import 'package:observatory/src/elements/helpers/uris.dart'; | |
| 14 import 'package:observatory/src/elements/sentinel_value.dart'; | |
| 15 | |
| 16 class InstanceRefElement extends HtmlElement implements Renderable { | |
| 17 static const tag = const Tag<InstanceRefElement>('instance-ref-wrapped'); | |
| 18 | |
| 19 RenderingScheduler<InstanceRefElement> _r; | |
| 20 | |
| 21 Stream<RenderedEvent<InstanceRefElement>> get onRendered => _r.onRendered; | |
| 22 | |
| 23 M.IsolateRef _isolate; | |
| 24 M.InstanceRef _instance; | |
| 25 M.InstanceRepository _instances; | |
| 26 M.Instance _loadedInstance; | |
| 27 bool _expanded = false; | |
| 28 | |
| 29 M.IsolateRef get isolate => _isolate; | |
| 30 M.InstanceRef get instance => _instance; | |
| 31 | |
| 32 factory InstanceRefElement(M.IsolateRef isolate, M.InstanceRef instance, | |
| 33 M.InstanceRepository instances, {RenderingQueue queue}) { | |
| 34 assert(isolate != null); | |
| 35 assert(instance != null); | |
| 36 assert(instances != null); | |
| 37 InstanceRefElement e = document.createElement(tag.name); | |
| 38 e._r = new RenderingScheduler(e, queue: queue); | |
| 39 e._isolate = isolate; | |
| 40 e._instance = instance; | |
| 41 e._instances = instances; | |
| 42 return e; | |
| 43 } | |
| 44 | |
| 14 InstanceRefElement.created() : super.created(); | 45 InstanceRefElement.created() : super.created(); |
| 15 | 46 |
| 16 String get hoverText { | 47 @override |
| 17 if (ref != null) { | 48 void attached() { |
| 18 if (ref.type == 'Sentinel') { | 49 super.attached(); |
| 19 if (ref.id == 'objects/optimized-out') { | 50 _r.enable(); |
| 20 return 'This object is no longer needed and has been removed by the op timizing compiler.'; | 51 } |
|
Cutch
2016/08/15 23:27:07
long line?
cbernaschina
2016/08/16 00:01:43
The long line was in the previous version.
| |
| 21 } else if (ref.id == 'objects/collected') { | 52 |
| 22 return 'This object has been reclaimed by the garbage collector.'; | 53 @override |
| 23 } else if (ref.id == 'objects/expired') { | 54 void detached() { |
| 24 return 'The handle to this object has expired. Consider refreshing th e page.'; | 55 super.detached(); |
| 25 } else if (ref.id == 'objects/not-initialized') { | 56 children = []; |
| 26 return 'This object will be initialized once it is accessed by the pro gram.'; | 57 _r.disable(notify: true); |
| 27 } else if (ref.id == 'objects/being-initialized') { | 58 } |
| 28 return 'This object is currently being initialized.'; | 59 |
| 29 } | 60 void render() { |
| 30 } | 61 final content = _createLink(); |
| 31 } | 62 |
| 32 return super.hoverText; | 63 if (_hasValue()) { |
| 33 } | 64 content.addAll([ |
| 34 | 65 new SpanElement()..text = ' ', |
| 35 // TODO(turnidge): This is here to workaround vm/dart2js differences. | 66 new CurlyBlockElement(expanded: _expanded, queue: _r.queue) |
| 36 dynamic expander() { | 67 ..children = [ |
| 37 return expandEvent; | 68 new DivElement()..classes = ['indent'] |
| 38 } | 69 ..children = _createValue() |
| 39 | 70 ] |
| 71 ..onToggle.listen((e) async { | |
| 72 _expanded = e.control.expanded; | |
| 73 if (_expanded) { | |
| 74 e.control.disabled = true; | |
| 75 await _refresh(); | |
| 76 e.control.disabled = false; | |
| 77 } | |
| 78 }) | |
| 79 ]); | |
| 80 } | |
| 81 | |
| 82 children = content; | |
| 83 } | |
| 84 | |
| 85 Future _refresh() async { | |
| 86 _loadedInstance = await _instances.get(_instance.id); | |
| 87 _r.dirty(); | |
| 88 } | |
| 89 | |
| 90 List<Element> _createShowMoreButton() { | |
| 91 if (_loadedInstance.count == null) { | |
| 92 return []; | |
| 93 } | |
| 94 final count = _loadedInstance.count; | |
| 95 final button = new ButtonElement() | |
| 96 ..text = 'show next ${count}'; | |
| 97 button.onClick.listen((_) async { | |
| 98 button.disabled = true; | |
| 99 _loadedInstance = await _instances.get(_instance.id, count: count * 2); | |
| 100 _r.dirty(); | |
| 101 }); | |
| 102 return [button]; | |
| 103 } | |
| 104 | |
| 105 List<Element> _createLink() { | |
| 106 switch (_instance.kind) { | |
| 107 case M.InstanceKind.vNull: | |
| 108 case M.InstanceKind.bool: | |
| 109 case M.InstanceKind.int: | |
| 110 case M.InstanceKind.double: | |
| 111 case M.InstanceKind.float32x4: | |
| 112 case M.InstanceKind.float64x2: | |
| 113 case M.InstanceKind.int32x4: | |
| 114 return [ | |
| 115 new AnchorElement(href: Uris.inspect(_isolate, object: _instance)) | |
| 116 ..text = _instance.valueAsString | |
| 117 ]; | |
| 118 case M.InstanceKind.string: | |
| 119 return [ | |
| 120 new AnchorElement(href: Uris.inspect(_isolate, object: _instance)) | |
| 121 ..text = asStringLiteral(_instance.valueAsString, | |
| 122 _instance.valueAsStringIsTruncated) | |
| 123 ]; | |
| 124 case M.InstanceKind.type: | |
| 125 case M.InstanceKind.typeRef: | |
| 126 case M.InstanceKind.typeParameter: | |
| 127 case M.InstanceKind.boundedType: | |
| 128 return [ | |
| 129 new AnchorElement(href: Uris.inspect(_isolate, object: _instance)) | |
| 130 ..text = _instance.name | |
| 131 ]; | |
| 132 case M.InstanceKind.closure: | |
| 133 return [ | |
| 134 new AnchorElement(href: Uris.inspect(_isolate, object: _instance)) | |
| 135 ..children = [ | |
| 136 new SpanElement()..classes = ['empathize']..text = 'Closure', | |
| 137 new SpanElement()..text = _instance.closureFunction.name | |
| 138 ] | |
| 139 ]; | |
| 140 case M.InstanceKind.regExp: | |
| 141 return [ | |
| 142 new AnchorElement(href: Uris.inspect(_isolate, object: _instance)) | |
| 143 ..children = [ | |
| 144 new SpanElement()..classes = ['empathize'] | |
| 145 ..text = _instance.clazz.name, | |
| 146 new SpanElement()..text = _instance.pattern.name | |
| 147 ] | |
| 148 ]; | |
| 149 case M.InstanceKind.stackTrace: | |
| 150 return [ | |
| 151 new AnchorElement(href: Uris.inspect(_isolate, object: _instance)) | |
| 152 ..text = _instance.clazz.name, | |
| 153 new CurlyBlockElement(queue: _r.queue) | |
| 154 ..children = [ | |
| 155 new DivElement()..classes = ['stackTraceBox'] | |
| 156 ..text = _instance.valueAsString | |
| 157 ] | |
| 158 ]; | |
| 159 case M.InstanceKind.plainInstance: | |
| 160 return [ | |
| 161 new AnchorElement(href: Uris.inspect(_isolate, object: _instance)) | |
| 162 ..classes = ['empathize'] | |
| 163 ..text = _instance.clazz.name | |
| 164 ]; | |
| 165 case M.InstanceKind.list: | |
| 166 case M.InstanceKind.map: | |
| 167 case M.InstanceKind.uint8ClampedList: | |
| 168 case M.InstanceKind.uint8List: | |
| 169 case M.InstanceKind.uint16List: | |
| 170 case M.InstanceKind.uint32List: | |
| 171 case M.InstanceKind.uint64List: | |
| 172 case M.InstanceKind.int8List: | |
| 173 case M.InstanceKind.int16List: | |
| 174 case M.InstanceKind.int32List: | |
| 175 case M.InstanceKind.int64List: | |
| 176 case M.InstanceKind.float32List: | |
| 177 case M.InstanceKind.float64List: | |
| 178 case M.InstanceKind.int32x4List: | |
| 179 case M.InstanceKind.float32x4List: | |
| 180 case M.InstanceKind.float64x2List: | |
| 181 return [ | |
| 182 new AnchorElement(href: Uris.inspect(_isolate, object: _instance)) | |
| 183 ..children = [ | |
| 184 new SpanElement()..classes = ['empathize'] | |
| 185 ..text = _instance.clazz.name, | |
| 186 new SpanElement()..text = ' (${_instance.length})' | |
| 187 ] | |
| 188 ]; | |
| 189 case M.InstanceKind.mirrorReference: | |
| 190 return [ | |
| 191 new AnchorElement(href: Uris.inspect(_isolate, object: _instance)) | |
| 192 ..classes = ['empathize'] | |
| 193 ..text = _instance.clazz.name | |
| 194 ]; | |
| 195 case M.InstanceKind.weakProperty: | |
| 196 return [ | |
| 197 new AnchorElement(href: Uris.inspect(_isolate, object: _instance)) | |
| 198 ..classes = ['empathize'] | |
| 199 ..text = _instance.clazz.name | |
| 200 ]; | |
| 201 } | |
| 202 throw new Exception('Unkown InstanceKind: ${_instance.kind}'); | |
| 203 } | |
| 204 | |
| 205 bool _hasValue() { | |
| 206 switch (_instance.kind) { | |
| 207 case M.InstanceKind.plainInstance: | |
| 208 case M.InstanceKind.mirrorReference: | |
| 209 case M.InstanceKind.weakProperty: | |
| 210 return true; | |
| 211 case M.InstanceKind.list: | |
| 212 case M.InstanceKind.map: | |
| 213 case M.InstanceKind.uint8ClampedList: | |
| 214 case M.InstanceKind.uint8List: | |
| 215 case M.InstanceKind.uint16List: | |
| 216 case M.InstanceKind.uint32List: | |
| 217 case M.InstanceKind.uint64List: | |
| 218 case M.InstanceKind.int8List: | |
| 219 case M.InstanceKind.int16List: | |
| 220 case M.InstanceKind.int32List: | |
| 221 case M.InstanceKind.int64List: | |
| 222 case M.InstanceKind.float32List: | |
| 223 case M.InstanceKind.float64List: | |
| 224 case M.InstanceKind.int32x4List: | |
| 225 case M.InstanceKind.float32x4List: | |
| 226 case M.InstanceKind.float64x2List: | |
| 227 return _instance.length > 0; | |
| 228 default: | |
| 229 return false; | |
| 230 } | |
| 231 } | |
| 232 List<Element> _createValue() { | |
| 233 if (_loadedInstance == null) { | |
| 234 return [new SpanElement()..text = 'Loading...']; | |
| 235 } | |
| 236 print(_instance.kind); | |
| 237 switch (_instance.kind) { | |
| 238 case M.InstanceKind.plainInstance: | |
| 239 return _loadedInstance.fields.map((f) => | |
| 240 new DivElement() | |
| 241 ..children = [ | |
| 242 new FieldRefElement(_isolate, f.decl, _instances, | |
| 243 queue: _r.queue), | |
| 244 new SpanElement()..text = ' = ', | |
| 245 f.value.isSentinel | |
| 246 ? new SentinelValueElement(f.value.asSentinel, queue: _r.queue) | |
| 247 : new InstanceRefElement(_isolate, f.value.asValue, _instances, | |
| 248 queue: _r.queue) | |
| 249 ]).toList(); | |
| 250 case M.InstanceKind.list: | |
| 251 var index = 0; | |
| 252 return _loadedInstance.elements.map((e) => | |
| 253 new DivElement() | |
| 254 ..children = [ | |
| 255 new SpanElement()..text = '[ ${index++} ] : ', | |
| 256 e.isSentinel | |
| 257 ? new SentinelValueElement(e.asSentinel, queue: _r.queue) | |
| 258 : anyRef(_isolate, e.asValue, _instances, queue: _r.queue) | |
| 259 // should be: | |
| 260 // new InstanceRefElement(_isolate, e.asValue, _instances, queue: _r.queue) | |
|
Cutch
2016/08/15 23:27:07
weird indentation. Please fix the code or write a
cbernaschina
2016/08/16 00:01:43
Done.
| |
| 261 // in some situations we obtain values that are not InstanceRef. | |
| 262 ]).toList()..addAll(_createShowMoreButton()); | |
| 263 case M.InstanceKind.map: | |
| 264 return _loadedInstance.associations.map((a) => | |
| 265 new DivElement() | |
| 266 ..children = [ | |
| 267 new SpanElement()..text = '[ ', | |
| 268 a.key.isSentinel | |
| 269 ? new SentinelValueElement(a.key.asSentinel, queue: _r.queue) | |
| 270 : new InstanceRefElement(_isolate, a.key.asValue, _instances, | |
| 271 queue: _r.queue), | |
| 272 new SpanElement()..text = ' ] : ', | |
| 273 a.value.isSentinel | |
| 274 ? new SentinelValueElement(a.value.asSentinel, queue: _r.queue) | |
| 275 : new InstanceRefElement(_isolate, a.value.asValue, _instances, | |
| 276 queue: _r.queue) | |
| 277 ]).toList()..addAll(_createShowMoreButton()); | |
| 278 case M.InstanceKind.uint8ClampedList: | |
| 279 case M.InstanceKind.uint8List: | |
| 280 case M.InstanceKind.uint16List: | |
| 281 case M.InstanceKind.uint32List: | |
| 282 case M.InstanceKind.uint64List: | |
| 283 case M.InstanceKind.int8List: | |
| 284 case M.InstanceKind.int16List: | |
| 285 case M.InstanceKind.int32List: | |
| 286 case M.InstanceKind.int64List: | |
| 287 case M.InstanceKind.float32List: | |
| 288 case M.InstanceKind.float64List: | |
| 289 case M.InstanceKind.int32x4List: | |
| 290 case M.InstanceKind.float32x4List: | |
| 291 case M.InstanceKind.float64x2List: | |
| 292 var index = 0; | |
| 293 return _loadedInstance.typedElements | |
| 294 .map((e) => new DivElement()..text = '[ ${index++} ] : $e') | |
| 295 .toList()..addAll(_createShowMoreButton()); | |
| 296 break; | |
| 297 case M.InstanceKind.mirrorReference: | |
| 298 return [ | |
| 299 new SpanElement()..text = '<referent> : ', | |
| 300 new InstanceRefElement(_isolate, _loadedInstance.referent, _instances, | |
| 301 queue: _r.queue) | |
| 302 ]; | |
| 303 case M.InstanceKind.weakProperty: | |
| 304 return [ | |
| 305 new SpanElement()..text = '<key> : ', | |
| 306 new InstanceRefElement(_isolate, _loadedInstance.key, _instances, | |
| 307 queue: _r.queue), | |
| 308 new BRElement(), | |
| 309 new SpanElement()..text = '<value> : ', | |
| 310 new InstanceRefElement(_isolate, _loadedInstance.value, _instances, | |
| 311 queue: _r.queue), | |
| 312 ]; | |
| 313 default: | |
| 314 return []; | |
| 315 } | |
| 316 } | |
| 317 | |
| 318 static String asStringLiteral(String value, [bool wasTruncated=false]) { | |
| 319 var result = new List(); | |
| 320 result.add("'".codeUnitAt(0)); | |
| 321 for (int codeUnit in value.codeUnits) { | |
| 322 if (codeUnit == '\n'.codeUnitAt(0)) result.addAll('\\n'.codeUnits); | |
| 323 else if (codeUnit == '\r'.codeUnitAt(0)) result.addAll('\\r'.codeUnits); | |
| 324 else if (codeUnit == '\f'.codeUnitAt(0)) result.addAll('\\f'.codeUnits); | |
| 325 else if (codeUnit == '\b'.codeUnitAt(0)) result.addAll('\\b'.codeUnits); | |
| 326 else if (codeUnit == '\t'.codeUnitAt(0)) result.addAll('\\t'.codeUnits); | |
| 327 else if (codeUnit == '\v'.codeUnitAt(0)) result.addAll('\\v'.codeUnits); | |
| 328 else if (codeUnit == '\$'.codeUnitAt(0)) result.addAll('\\\$'.codeUnits); | |
| 329 else if (codeUnit == '\\'.codeUnitAt(0)) result.addAll('\\\\'.codeUnits); | |
| 330 else if (codeUnit == "'".codeUnitAt(0)) result.addAll("'".codeUnits); | |
| 331 else if (codeUnit < 32) { | |
| 332 var escapeSequence = "\\u" + codeUnit.toRadixString(16).padLeft(4, "0") ; | |
| 333 result.addAll(escapeSequence.codeUnits); | |
| 334 } else result.add(codeUnit); | |
| 335 } | |
| 336 if (wasTruncated) { | |
| 337 result.addAll("...".codeUnits); | |
| 338 } else { | |
| 339 result.add("'".codeUnitAt(0)); | |
| 340 } | |
| 341 return new String.fromCharCodes(result); | |
| 342 } | |
| 343 | |
| 344 /* | |
|
Cutch
2016/08/15 23:27:07
dead code?
cbernaschina
2016/08/16 00:01:43
Done.
| |
| 40 void expandEvent(bool expand, Function onDone) { | 345 void expandEvent(bool expand, Function onDone) { |
| 41 assert(ref is Instance); | 346 assert(ref is Instance); |
| 42 if (expand) { | 347 if (expand) { |
| 43 ref.reload().then((result) { | 348 ref.reload().then((result) { |
| 44 if (result.valueAsString != null) { | 349 if (result.valueAsString != null) { |
| 45 result.name = result.valueAsString; | 350 result.name = result.valueAsString; |
| 46 result.vmName = result.valueAsString; | 351 result.vmName = result.valueAsString; |
| 47 } | 352 } |
| 48 ref = result; | 353 ref = result; |
| 49 notifyPropertyChange(#ref, 0, 1); | 354 notifyPropertyChange(#ref, 0, 1); |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 63 Future showMore() async { | 368 Future showMore() async { |
| 64 Instance instance = ref; | 369 Instance instance = ref; |
| 65 if (instance.isList) { | 370 if (instance.isList) { |
| 66 await instance.reload(count: instance.elements.length * 2); | 371 await instance.reload(count: instance.elements.length * 2); |
| 67 } else if (instance.isMap) { | 372 } else if (instance.isMap) { |
| 68 await instance.reload(count: instance.associations.length * 2); | 373 await instance.reload(count: instance.associations.length * 2); |
| 69 } else if (instance.isTypedData) { | 374 } else if (instance.isTypedData) { |
| 70 await instance.reload(count: instance.typedElements.length * 2); | 375 await instance.reload(count: instance.typedElements.length * 2); |
| 71 } | 376 } |
| 72 } | 377 } |
| 378 */ | |
| 73 } | 379 } |
| OLD | NEW |