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 | 12 |
| 13 /// Config object to pass to devtools to signal that an object should not be | 13 /// JsonMLConfig object to pass to devtools to specify how an Object should |
| 14 /// formatted by the Dart formatter. This is used to specify that an Object | 14 /// be displayed. skipDart signals that an object should not be formatted |
| 15 /// by the Dart formatter. This is used to specify that an Object | |
| 15 /// should just be displayed using the regular JavaScript view instead of a | 16 /// should just be displayed using the regular JavaScript view instead of a |
| 16 /// custom Dart view. For example, this is used to display the JavaScript view | 17 /// custom Dart view. For example, this is used to display the JavaScript view |
| 17 /// of a Dart Function as a child of the regular Function object. | 18 /// of a Dart Function as a child of the regular Function object. keyToString |
| 18 const skipDartConfig = const Object(); | 19 /// signals that a map key object should have its toString() displayed by |
| 20 /// the Dart formatter. | |
| 21 /// | |
| 22 /// We'd like this to be an enum, but we can't because it's a dev_compiler bug. | |
| 23 class JsonMLConfig { | |
| 24 const JsonMLConfig(this.name); | |
| 25 | |
| 26 final String name; | |
| 27 static const none = const JsonMLConfig("none"); | |
| 28 static const skipDart = const JsonMLConfig("skipDart"); | |
| 29 static const keyToString = const JsonMLConfig("keyToString"); | |
| 30 } | |
| 31 | |
| 19 final int maxIterableChildrenToDisplay = 50; | 32 final int maxIterableChildrenToDisplay = 50; |
| 20 | 33 |
| 21 var _devtoolsFormatter = new JsonMLFormatter(new DartFormatter()); | 34 var _devtoolsFormatter = new JsonMLFormatter(new DartFormatter()); |
| 22 | 35 |
| 23 String _typeof(object) => JS('String', 'typeof #', object); | 36 String _typeof(object) => JS('String', 'typeof #', object); |
| 24 | 37 |
| 25 List<String> getOwnPropertyNames(object) => JS('List<String>', | 38 List<String> getOwnPropertyNames(object) => JS('List<String>', |
| 26 'dart.list(Object.getOwnPropertyNames(#), #)', object, String); | 39 'dart.list(Object.getOwnPropertyNames(#), #)', object, String); |
| 27 | 40 |
| 28 List getOwnPropertySymbols(object) => | 41 List getOwnPropertySymbols(object) => |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 78 bool hasMethod(object, String name) { | 91 bool hasMethod(object, String name) { |
| 79 try { | 92 try { |
| 80 return dart.hasMethod(object, name); | 93 return dart.hasMethod(object, name); |
| 81 } catch (e) { | 94 } catch (e) { |
| 82 return false; | 95 return false; |
| 83 } | 96 } |
| 84 } | 97 } |
| 85 | 98 |
| 86 /// [JsonMLFormatter] consumes [NameValuePair] objects and | 99 /// [JsonMLFormatter] consumes [NameValuePair] objects and |
| 87 class NameValuePair { | 100 class NameValuePair { |
| 88 NameValuePair({this.name, this.value, bool skipDart}) | 101 NameValuePair({this.name, this.value, this.config: JsonMLConfig.none}); |
| 89 : skipDart = skipDart == true; | |
| 90 | 102 |
| 91 // Define equality and hashCode so that NameValuePair can be used | 103 // Define equality and hashCode so that NameValuePair can be used |
| 92 // in a Set to dedupe entries with duplicate names. | 104 // in a Set to dedupe entries with duplicate names. |
| 93 operator ==(other) => other is NameValuePair && other.name == name; | 105 operator ==(other) => other is NameValuePair && other.name == name; |
| 94 int get hashCode => name.hashCode; | 106 int get hashCode => name.hashCode; |
| 95 | 107 |
| 96 final String name; | 108 final String name; |
| 97 final Object value; | 109 final Object value; |
| 98 final bool skipDart; | 110 final JsonMLConfig config; |
| 99 } | 111 } |
| 100 | 112 |
| 101 class MapEntry { | 113 class MapEntry { |
| 102 MapEntry({this.key, this.value}); | 114 MapEntry({this.key, this.value}); |
| 103 | 115 |
| 104 final String key; | 116 final Object key; |
| 105 final Object value; | 117 final Object value; |
| 106 } | 118 } |
| 107 | 119 |
| 108 class ClassMetadata { | 120 class ClassMetadata { |
| 109 ClassMetadata(this.object); | 121 ClassMetadata(this.object); |
| 110 | 122 |
| 111 final Object object; | 123 final Object object; |
| 112 } | 124 } |
| 113 | 125 |
| 114 class HeritageClause { | 126 class HeritageClause { |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 186 // TODO(jacobr): define a SimpleFormatter base class that DartFormatter | 198 // TODO(jacobr): define a SimpleFormatter base class that DartFormatter |
| 187 // implements if we decide to use this class elsewhere. We specify that the | 199 // implements if we decide to use this class elsewhere. We specify that the |
| 188 // type is DartFormatter here purely to get type checking benefits not because | 200 // type is DartFormatter here purely to get type checking benefits not because |
| 189 // this class is really intended to only support instances of type | 201 // this class is really intended to only support instances of type |
| 190 // DartFormatter. | 202 // DartFormatter. |
| 191 DartFormatter _simpleFormatter; | 203 DartFormatter _simpleFormatter; |
| 192 | 204 |
| 193 JsonMLFormatter(this._simpleFormatter); | 205 JsonMLFormatter(this._simpleFormatter); |
| 194 | 206 |
| 195 header(object, config) { | 207 header(object, config) { |
| 196 if (identical(config, skipDartConfig) || isNativeJavaScriptObject(object)) { | 208 if (config == JsonMLConfig.skipDart || isNativeJavaScriptObject(object)) { |
| 197 return null; | 209 return null; |
| 198 } | 210 } |
| 199 | 211 |
| 200 var c = _simpleFormatter.preview(object); | 212 var c = _simpleFormatter.preview(object); |
| 201 if (c == null) return null; | 213 if (c == null) return null; |
| 202 | 214 |
| 215 if (config == JsonMLConfig.keyToString) { | |
| 216 c = object.toString(); | |
| 217 } | |
| 218 | |
| 203 // Indicate this is a Dart Object by using a Dart background color. | 219 // Indicate this is a Dart Object by using a Dart background color. |
| 204 // This is stylistically a bit ugly but it eases distinguishing Dart and | 220 // This is stylistically a bit ugly but it eases distinguishing Dart and |
| 205 // JS objects. | 221 // JS objects. |
| 206 var element = new JsonMLElement('span') | 222 var element = new JsonMLElement('span') |
| 207 ..setStyle('background-color: #d9edf7') | 223 ..setStyle('background-color: #d9edf7') |
| 208 ..createTextChild(c); | 224 ..createTextChild(c); |
| 209 return element.toJsonML(); | 225 return element.toJsonML(); |
| 210 } | 226 } |
| 211 | 227 |
| 212 bool hasBody(object) => _simpleFormatter.hasChildren(object); | 228 bool hasBody(object) => _simpleFormatter.hasChildren(object); |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 223 var li = body.createChild('li'); | 239 var li = body.createChild('li'); |
| 224 var nameSpan = new JsonMLElement('span') | 240 var nameSpan = new JsonMLElement('span') |
| 225 ..createTextChild(child.name != null ? child.name + ': ' : '') | 241 ..createTextChild(child.name != null ? child.name + ': ' : '') |
| 226 ..setStyle('color: rgb(136, 19, 145);'); | 242 ..setStyle('color: rgb(136, 19, 145);'); |
| 227 if (_typeof(child.value) == 'object' || | 243 if (_typeof(child.value) == 'object' || |
| 228 _typeof(child.value) == 'function') { | 244 _typeof(child.value) == 'function') { |
| 229 nameSpan.addStyle("padding-left: 13px;"); | 245 nameSpan.addStyle("padding-left: 13px;"); |
| 230 | 246 |
| 231 li.appendChild(nameSpan); | 247 li.appendChild(nameSpan); |
| 232 var objectTag = li.createObjectTag(child.value); | 248 var objectTag = li.createObjectTag(child.value); |
| 233 if (child.skipDart) { | 249 objectTag.addAttribute('config', child.config); |
| 234 objectTag.addAttribute('config', skipDartConfig); | |
| 235 } | |
| 236 if (!_simpleFormatter.hasChildren(child.value)) { | 250 if (!_simpleFormatter.hasChildren(child.value)) { |
| 237 li.setStyle("padding-left: 13px;"); | 251 li.setStyle("padding-left: 13px;"); |
| 238 } | 252 } |
| 239 } else { | 253 } else { |
| 240 li.setStyle("padding-left: 13px;"); | 254 li.setStyle("padding-left: 13px;"); |
| 241 li.createChild('span') | 255 li.createChild('span') |
| 242 ..appendChild(nameSpan) | 256 ..appendChild(nameSpan) |
| 243 ..createTextChild(safePreview(child.value)); | 257 ..createTextChild(safePreview(child.value)); |
| 244 } | 258 } |
| 245 } | 259 } |
| (...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 419 | 433 |
| 420 bool hasChildren(object) => true; | 434 bool hasChildren(object) => true; |
| 421 | 435 |
| 422 String preview(object) { | 436 String preview(object) { |
| 423 return dart.typeName(dart.getReifiedType(object)); | 437 return dart.typeName(dart.getReifiedType(object)); |
| 424 } | 438 } |
| 425 | 439 |
| 426 List<NameValuePair> children(object) => <NameValuePair>[ | 440 List<NameValuePair> children(object) => <NameValuePair>[ |
| 427 new NameValuePair(name: 'signature', value: preview(object)), | 441 new NameValuePair(name: 'signature', value: preview(object)), |
| 428 new NameValuePair( | 442 new NameValuePair( |
| 429 name: 'JavaScript Function', value: object, skipDart: true) | 443 name: 'JavaScript Function', value: object, config: JsonMLConfig.ski pDart) |
| 430 ]; | 444 ]; |
| 431 } | 445 } |
| 432 | 446 |
| 433 /// Formatter for Dart Map objects. | 447 /// Formatter for Dart Map objects. |
| 434 class MapFormatter extends ObjectFormatter { | 448 class MapFormatter extends ObjectFormatter { |
| 435 accept(object) => object is Map; | 449 accept(object) => object is Map; |
| 436 | 450 |
| 437 bool hasChildren(object) => true; | 451 bool hasChildren(object) => true; |
| 438 | 452 |
| 439 String preview(object) { | 453 String preview(object) { |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 525 ret.add(new NameValuePair( | 539 ret.add(new NameValuePair( |
| 526 name: '[[Implements]]', | 540 name: '[[Implements]]', |
| 527 value: new HeritageClause('implements', implements()))); | 541 value: new HeritageClause('implements', implements()))); |
| 528 } | 542 } |
| 529 var mixins = dart.getMixins(type); | 543 var mixins = dart.getMixins(type); |
| 530 if (mixins != null && mixins.isNotEmpty) { | 544 if (mixins != null && mixins.isNotEmpty) { |
| 531 ret.add(new NameValuePair( | 545 ret.add(new NameValuePair( |
| 532 name: '[[Mixins]]', value: new HeritageClause('mixins', mixins))); | 546 name: '[[Mixins]]', value: new HeritageClause('mixins', mixins))); |
| 533 } | 547 } |
| 534 ret.add(new NameValuePair( | 548 ret.add(new NameValuePair( |
| 535 name: '[[JavaScript View]]', value: entry.object, skipDart: true)); | 549 name: '[[JavaScript View]]', value: entry.object, config: JsonMLConfig.s kipDart)); |
| 536 | 550 |
| 537 // TODO(jacobr): provide a link to the base class or perhaps the entire | 551 // TODO(jacobr): provide a link to the base class or perhaps the entire |
| 538 // base class hierarchy as a flat list. | 552 // base class hierarchy as a flat list. |
| 539 | 553 |
| 540 if (entry.object is! Type) { | 554 if (entry.object is! Type) { |
| 541 ret.add(new NameValuePair( | 555 ret.add(new NameValuePair( |
| 542 name: '[[JavaScript Constructor]]', | 556 name: '[[JavaScript Constructor]]', |
| 543 value: JSNative.getProperty(entry.object, 'constructor'), | 557 value: JSNative.getProperty(entry.object, 'constructor'), |
| 544 skipDart: true)); | 558 config: JsonMLConfig.skipDart)); |
| 545 // TODO(jacobr): add constructors, methods, extended class, and static | 559 // TODO(jacobr): add constructors, methods, extended class, and static |
| 546 } | 560 } |
| 547 return ret; | 561 return ret; |
| 548 } | 562 } |
| 549 } | 563 } |
| 550 | 564 |
| 551 /// Formatter for synthetic MapEntry objects used to display contents of a Map | 565 /// Formatter for synthetic MapEntry objects used to display contents of a Map |
| 552 /// cleanly. | 566 /// cleanly. |
| 553 class MapEntryFormatter implements Formatter { | 567 class MapEntryFormatter implements Formatter { |
| 554 accept(object) => object is MapEntry; | 568 accept(object) => object is MapEntry; |
| 555 | 569 |
| 556 String preview(object) { | 570 String preview(object) { |
| 557 MapEntry entry = object; | 571 MapEntry entry = object; |
| 558 return '${safePreview(entry.key)} => ${safePreview(entry.value)}'; | 572 return '${safePreview(entry.key)} => ${safePreview(entry.value)}'; |
| 559 } | 573 } |
| 560 | 574 |
| 561 bool hasChildren(object) => true; | 575 bool hasChildren(object) => true; |
| 562 | 576 |
| 563 List<NameValuePair> children(object) => <NameValuePair>[ | 577 List<NameValuePair> children(object) => <NameValuePair>[ |
| 564 new NameValuePair(name: 'key', value: object.key), | 578 new NameValuePair(name: 'key', value: object.key, config: JsonMLConfig.k eyToString), |
|
Jacob
2016/06/07 23:17:41
> 80 chars. run dartfmt and then you are good to s
priscillalee
2016/06/07 23:31:45
Done.
| |
| 565 new NameValuePair(name: 'value', value: object.value) | 579 new NameValuePair(name: 'value', value: object.value) |
| 566 ]; | 580 ]; |
| 567 } | 581 } |
| 568 | 582 |
| 569 /// Formatter for Dart Iterable objects including List and Set. | 583 /// Formatter for Dart Iterable objects including List and Set. |
| 570 class HeritageClauseFormatter implements Formatter { | 584 class HeritageClauseFormatter implements Formatter { |
| 571 bool accept(object) => object is HeritageClause; | 585 bool accept(object) => object is HeritageClause; |
| 572 | 586 |
| 573 String preview(object) { | 587 String preview(object) { |
| 574 HeritageClause clause = object; | 588 HeritageClause clause = object; |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 587 return ret; | 601 return ret; |
| 588 } | 602 } |
| 589 } | 603 } |
| 590 | 604 |
| 591 /// This entry point is automatically invoked by the code generated by | 605 /// This entry point is automatically invoked by the code generated by |
| 592 /// Dart Dev Compiler | 606 /// Dart Dev Compiler |
| 593 registerDevtoolsFormatter() { | 607 registerDevtoolsFormatter() { |
| 594 var formatters = [_devtoolsFormatter]; | 608 var formatters = [_devtoolsFormatter]; |
| 595 JS('', 'dart.global.devtoolsFormatters = #', formatters); | 609 JS('', 'dart.global.devtoolsFormatters = #', formatters); |
| 596 } | 610 } |
| OLD | NEW |