Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(345)

Side by Side Diff: tool/input_sdk/private/debugger.dart

Issue 2100803007: Array formatting customized to look like JS (Closed) Base URL: https://github.com/dart-lang/dev_compiler.git@master
Patch Set: Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « lib/runtime/dart_sdk.js ('k') | tool/sdk_expected_errors.txt » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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 }
OLDNEW
« no previous file with comments | « lib/runtime/dart_sdk.js ('k') | tool/sdk_expected_errors.txt » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698