Chromium Code Reviews| 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 library dart._debugger; | 5 library dart._debugger; |
| 6 | 6 |
| 7 import 'dart:_foreign_helper' show JS; | 7 import 'dart:_foreign_helper' show JS; |
| 8 import 'dart:_runtime' as dart; | 8 import 'dart:_runtime' as dart; |
| 9 import 'dart:core'; | 9 import 'dart:core'; |
| 10 import 'dart:collection'; | 10 import 'dart:collection'; |
| 11 import 'dart:html' as html; | 11 import 'dart:html' as html; |
| 12 import 'dart:math'; | |
| 12 | 13 |
| 13 /// JsonMLConfig object to pass to devtools to specify how an Object should | 14 /// JsonMLConfig object to pass to devtools to specify how an Object should |
| 14 /// be displayed. skipDart signals that an object should not be formatted | 15 /// be displayed. skipDart signals that an object should not be formatted |
| 15 /// by the Dart formatter. This is used to specify that an Object | 16 /// by the Dart formatter. This is used to specify that an Object |
| 16 /// should just be displayed using the regular JavaScript view instead of a | 17 /// should just be displayed using the regular JavaScript view instead of a |
| 17 /// custom Dart view. For example, this is used to display the JavaScript view | 18 /// custom Dart view. For example, this is used to display the JavaScript view |
| 18 /// of a Dart Function as a child of the regular Function object. keyToString | 19 /// of a Dart Function as a child of the regular Function object. keyToString |
| 19 /// signals that a map key object should have its toString() displayed by | 20 /// signals that a map key object should have its toString() displayed by |
| 20 /// the Dart formatter. | 21 /// the Dart formatter. |
| 21 /// | 22 /// |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 91 bool hasMethod(object, String name) { | 92 bool hasMethod(object, String name) { |
| 92 try { | 93 try { |
| 93 return dart.hasMethod(object, name); | 94 return dart.hasMethod(object, name); |
| 94 } catch (e) { | 95 } catch (e) { |
| 95 return false; | 96 return false; |
| 96 } | 97 } |
| 97 } | 98 } |
| 98 | 99 |
| 99 /// [JsonMLFormatter] consumes [NameValuePair] objects and | 100 /// [JsonMLFormatter] consumes [NameValuePair] objects and |
| 100 class NameValuePair { | 101 class NameValuePair { |
| 101 NameValuePair({this.name, this.value, this.config: JsonMLConfig.none}); | 102 NameValuePair({this.name, this.value, this.config: JsonMLConfig.none, this.hid eName: false}); |
|
Jacob
2016/06/27 23:12:04
run dartfmt
bmilligan
2016/06/28 01:16:35
Done.
| |
| 102 | 103 |
| 103 // Define equality and hashCode so that NameValuePair can be used | 104 // Define equality and hashCode so that NameValuePair can be used |
| 104 // in a Set to dedupe entries with duplicate names. | 105 // in a Set to dedupe entries with duplicate names. |
| 105 operator ==(other) => other is NameValuePair && other.name == name; | 106 operator ==(other) => other is NameValuePair && other.name == name; |
| 106 int get hashCode => name.hashCode; | 107 int get hashCode => name.hashCode; |
| 107 | 108 |
| 108 final String name; | 109 final String name; |
| 109 final Object value; | 110 final Object value; |
| 110 final JsonMLConfig config; | 111 final JsonMLConfig config; |
| 112 final bool hideName; | |
| 113 | |
| 114 String get displayName => hideName ? null : name; | |
|
Jacob
2016/06/27 23:12:04
would '' be cleaner than null? In general prefer t
bmilligan
2016/06/28 01:16:36
Done.
| |
| 111 } | 115 } |
| 112 | 116 |
| 113 class MapEntry { | 117 class MapEntry { |
| 114 MapEntry({this.key, this.value}); | 118 MapEntry({this.key, this.value}); |
| 115 | 119 |
| 116 final Object key; | 120 final Object key; |
| 117 final Object value; | 121 final Object value; |
| 118 } | 122 } |
| 119 | 123 |
| 124 class IterableSpan { | |
| 125 IterableSpan({this.low, this.high, this.object}); | |
| 126 | |
| 127 final int low; | |
|
Jacob
2016/06/27 23:12:04
instead of low and high
use
start, end
instead o
bmilligan
2016/06/28 01:16:35
Done.
| |
| 128 final int high; | |
| 129 final Iterable object; | |
| 130 } | |
| 131 | |
| 120 class ClassMetadata { | 132 class ClassMetadata { |
| 121 ClassMetadata(this.object); | 133 ClassMetadata(this.object); |
| 122 | 134 |
| 123 final Object object; | 135 final Object object; |
| 124 } | 136 } |
| 125 | 137 |
| 126 class HeritageClause { | 138 class HeritageClause { |
| 127 HeritageClause(this.name, this.types); | 139 HeritageClause(this.name, this.types); |
| 128 | 140 |
| 129 final String name; | 141 final String name; |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 231 var body = new JsonMLElement('ol') | 243 var body = new JsonMLElement('ol') |
| 232 ..setStyle('list-style-type: none;' | 244 ..setStyle('list-style-type: none;' |
| 233 'padding-left: 0px;' | 245 'padding-left: 0px;' |
| 234 'margin-top: 0px;' | 246 'margin-top: 0px;' |
| 235 'margin-bottom: 0px;' | 247 'margin-bottom: 0px;' |
| 236 'margin-left: 12px'); | 248 'margin-left: 12px'); |
| 237 var children = _simpleFormatter.children(object); | 249 var children = _simpleFormatter.children(object); |
| 238 for (NameValuePair child in children) { | 250 for (NameValuePair child in children) { |
| 239 var li = body.createChild('li'); | 251 var li = body.createChild('li'); |
| 240 var nameSpan = new JsonMLElement('span') | 252 var nameSpan = new JsonMLElement('span') |
| 241 ..createTextChild(child.name != null ? child.name + ': ' : '') | 253 ..createTextChild(child.displayName != null ? child.displayName + ': ' : '') |
|
Jacob
2016/06/27 23:12:04
not your fault but change from
child.displayName
Jacob
2016/06/27 23:12:04
change to
child.displayName.isEmpty ? '' : ...
bmilligan
2016/06/28 01:16:35
Done.
bmilligan
2016/06/28 01:16:36
Should it be isNotEmpty?
| |
| 242 ..setStyle('color: rgb(136, 19, 145);'); | 254 ..setStyle('color: rgb(136, 19, 145);'); |
| 243 if (_typeof(child.value) == 'object' || | 255 if (_typeof(child.value) == 'object' || |
| 244 _typeof(child.value) == 'function') { | 256 _typeof(child.value) == 'function') { |
| 245 nameSpan.addStyle("padding-left: 13px;"); | 257 nameSpan.addStyle("padding-left: 13px;"); |
| 246 | 258 |
| 247 li.appendChild(nameSpan); | 259 li.appendChild(nameSpan); |
| 248 var objectTag = li.createObjectTag(child.value); | 260 var objectTag = li.createObjectTag(child.value); |
| 249 objectTag.addAttribute('config', child.config); | 261 objectTag.addAttribute('config', child.config); |
| 250 if (!_simpleFormatter.hasChildren(child.value)) { | 262 if (!_simpleFormatter.hasChildren(child.value)) { |
| 251 li.setStyle("padding-left: 13px;"); | 263 li.setStyle("padding-left: 13px;"); |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 272 List<Formatter> _formatters; | 284 List<Formatter> _formatters; |
| 273 | 285 |
| 274 DartFormatter() { | 286 DartFormatter() { |
| 275 // The order of formatters matters as formatters later in the list take | 287 // The order of formatters matters as formatters later in the list take |
| 276 // precidence. | 288 // precidence. |
| 277 _formatters = [ | 289 _formatters = [ |
| 278 new FunctionFormatter(), | 290 new FunctionFormatter(), |
| 279 new MapFormatter(), | 291 new MapFormatter(), |
| 280 new IterableFormatter(), | 292 new IterableFormatter(), |
| 281 new MapEntryFormatter(), | 293 new MapEntryFormatter(), |
| 294 new IterableSpanFormatter(), | |
| 282 new ClassMetadataFormatter(), | 295 new ClassMetadataFormatter(), |
| 283 new HeritageClauseFormatter(), | 296 new HeritageClauseFormatter(), |
| 284 new ObjectFormatter() | 297 new ObjectFormatter(), |
| 285 ]; | 298 ]; |
| 286 } | 299 } |
| 287 | 300 |
| 288 String preview(object) { | 301 String preview(object) { |
| 289 try { | 302 try { |
| 290 if (object == null || | 303 if (object == null || |
| 291 object is num || | 304 object is num || |
| 292 object is String || | 305 object is String || |
| 293 isNativeJavaScriptObject(object)) { | 306 isNativeJavaScriptObject(object)) { |
| 294 return object.toString(); | 307 return object.toString(); |
| (...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 487 } | 500 } |
| 488 } | 501 } |
| 489 | 502 |
| 490 bool hasChildren(object) => true; | 503 bool hasChildren(object) => true; |
| 491 | 504 |
| 492 List<NameValuePair> children(object) { | 505 List<NameValuePair> children(object) { |
| 493 // TODO(jacobr): be lazier about enumerating contents of Iterables that | 506 // TODO(jacobr): be lazier about enumerating contents of Iterables that |
| 494 // are not the built in Set or List types. | 507 // are not the built in Set or List types. |
| 495 // TODO(jacobr): handle large Iterables better. | 508 // TODO(jacobr): handle large Iterables better. |
| 496 // TODO(jacobr): consider only using numeric indices | 509 // TODO(jacobr): consider only using numeric indices |
| 497 Iterable iterable = object; | |
| 498 var ret = new LinkedHashSet<NameValuePair>(); | 510 var ret = new LinkedHashSet<NameValuePair>(); |
| 499 var i = 0; | 511 ret.addAll(iterableChildren(new IterableSpan(low: 0, high: object.length-1, object: object))); |
|
Jacob
2016/06/27 23:12:04
no real need for method names to indicate the type
bmilligan
2016/06/28 01:16:35
Done.
| |
| 500 for (var entry in iterable) { | |
| 501 if (i > maxIterableChildrenToDisplay) { | |
| 502 ret.add(new NameValuePair( | |
| 503 name: 'Warning', value: 'Truncated Iterable display')); | |
| 504 // TODO(jacobr): provide an expandable entry to show more entries. | |
| 505 break; | |
| 506 } | |
| 507 ret.add(new NameValuePair(name: i.toString(), value: entry)); | |
| 508 i++; | |
| 509 } | |
| 510 // TODO(jacobr): provide a link to show regular class properties here. | 512 // TODO(jacobr): provide a link to show regular class properties here. |
| 511 // required for subclasses of iterable, etc. | 513 // required for subclasses of iterable, etc. |
| 512 addMetadataChildren(object, ret); | 514 addMetadataChildren(object, ret); |
| 513 return ret.toList(); | 515 return ret.toList(); |
| 514 } | 516 } |
| 515 } | 517 } |
| 516 | 518 |
| 517 // This class does double duting displaying metadata for | 519 // This class does double duting displaying metadata for |
| 518 class ClassMetadataFormatter implements Formatter { | 520 class ClassMetadataFormatter implements Formatter { |
| 519 accept(object) => object is ClassMetadata; | 521 accept(object) => object is ClassMetadata; |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 600 List<NameValuePair> children(object) { | 602 List<NameValuePair> children(object) { |
| 601 HeritageClause clause = object; | 603 HeritageClause clause = object; |
| 602 var ret = <NameValuePair>[]; | 604 var ret = <NameValuePair>[]; |
| 603 for (var type in clause.types) { | 605 for (var type in clause.types) { |
| 604 ret.add(new NameValuePair(value: new ClassMetadata(type))); | 606 ret.add(new NameValuePair(value: new ClassMetadata(type))); |
| 605 } | 607 } |
| 606 return ret; | 608 return ret; |
| 607 } | 609 } |
| 608 } | 610 } |
| 609 | 611 |
| 612 /// Formatter for synthetic MapEntry objects used to display contents of a Map | |
|
Jacob
2016/06/27 23:12:04
This comment is wrong. Update it to be about your
bmilligan
2016/06/28 01:16:36
Done.
| |
| 613 /// cleanly. | |
| 614 class IterableSpanFormatter implements Formatter { | |
| 615 accept(object) => object is IterableSpan; | |
| 616 | |
| 617 String preview(object) { | |
| 618 IterableSpan entry = object; | |
| 619 return '[${object.low}...${object.high}]'; | |
| 620 } | |
| 621 | |
| 622 bool hasChildren(object) => true; | |
| 623 | |
| 624 List<NameValuePair> children(object) => iterableChildren(object); | |
| 625 } | |
| 626 | |
| 627 List<NameValuePair> iterableChildren(IterableSpan span) { | |
| 628 int range = span.high - span.low + 1; | |
|
Jacob
2016/06/27 23:12:04
this should be called length not range.
Also, no n
bmilligan
2016/06/28 01:16:36
Done.
| |
| 629 List<NameValuePair> ret = new List<NameValuePair>(); | |
| 630 if (range <= 100) { | |
|
Jacob
2016/06/27 23:12:04
make 100 a constant
bmilligan
2016/06/28 01:16:35
Done.
| |
| 631 for(int i = span.low; i < span.high+1; i++) { | |
|
Jacob
2016/06/27 23:12:04
should be
i < span.end
bmilligan
2016/06/28 01:16:36
Done.
| |
| 632 ret.add(new NameValuePair(name: i.toString(), value: span.object.elementAt (i))); | |
| 633 } | |
| 634 } else { | |
| 635 int a = (log(range-1)/log(100)).truncate(); | |
|
Jacob
2016/06/27 23:12:04
what is a? can you write this code so it is cleare
bmilligan
2016/06/28 01:16:35
Done.
| |
| 636 for (int i = span.low; i < span.high; i += pow(100, a)) { | |
|
Jacob
2016/06/27 23:12:04
nit: assign pow(100, a) to a variable rather than
bmilligan
2016/06/28 01:16:35
Done.
| |
| 637 int endIndex = min(span.high - i + 1, pow(100, a)) + i - 1; | |
|
Jacob
2016/06/27 23:12:04
I expect by defining spans to be exclusive rather
bmilligan
2016/06/28 01:16:35
Done.
| |
| 638 var entryWrapper = new IterableSpan(low: i, high: endIndex, object: span.o bject); | |
| 639 ret.add(new NameValuePair( | |
| 640 name: '[${i}...${endIndex}]', value: entryWrapper, hideName: true)); | |
| 641 } | |
| 642 } | |
| 643 return ret; | |
| 644 } | |
| 645 | |
| 610 /// This entry point is automatically invoked by the code generated by | 646 /// This entry point is automatically invoked by the code generated by |
| 611 /// Dart Dev Compiler | 647 /// Dart Dev Compiler |
| 612 registerDevtoolsFormatter() { | 648 registerDevtoolsFormatter() { |
| 613 var formatters = [_devtoolsFormatter]; | 649 var formatters = [_devtoolsFormatter]; |
| 614 JS('', 'dart.global.devtoolsFormatters = #', formatters); | 650 JS('', 'dart.global.devtoolsFormatters = #', formatters); |
| 615 } | 651 } |
| OLD | NEW |