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

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

Issue 2205733002: Deprecation of ClassMetadata wrapper for Class formatters so a stand-alone class is recognizable. (Closed) Base URL: https://github.com/dart-lang/dev_compiler.git@master
Patch Set: Change to using config instead of Symbols to identify classes for metadata Created 4 years, 4 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';
(...skipping 10 matching lines...) Expand all
21 /// the Dart formatter. 21 /// the Dart formatter.
22 /// 22 ///
23 /// We'd like this to be an enum, but we can't because it's a dev_compiler bug. 23 /// We'd like this to be an enum, but we can't because it's a dev_compiler bug.
24 class JsonMLConfig { 24 class JsonMLConfig {
25 const JsonMLConfig(this.name); 25 const JsonMLConfig(this.name);
26 26
27 final String name; 27 final String name;
28 static const none = const JsonMLConfig("none"); 28 static const none = const JsonMLConfig("none");
29 static const skipDart = const JsonMLConfig("skipDart"); 29 static const skipDart = const JsonMLConfig("skipDart");
30 static const keyToString = const JsonMLConfig("keyToString"); 30 static const keyToString = const JsonMLConfig("keyToString");
31 static const renderAsClass = const JsonMLConfig("renderAsClass");
Jacob 2016/08/02 01:45:11 no need for the word render. These are all options
bmilligan 2016/08/02 16:28:39 Done.
31 } 32 }
32 33
33 int _maxSpanLength = 100; 34 int _maxSpanLength = 100;
34
35 var _devtoolsFormatter = new JsonMLFormatter(new DartFormatter()); 35 var _devtoolsFormatter = new JsonMLFormatter(new DartFormatter());
36 36
37 String _typeof(object) => JS('String', 'typeof #', object); 37 String _typeof(object) => JS('String', 'typeof #', object);
38 38
39 List<String> getOwnPropertyNames(object) => JS('List<String>', 39 List<String> getOwnPropertyNames(object) => JS('List<String>',
40 'dart.list(Object.getOwnPropertyNames(#), #)', object, String); 40 'dart.list(Object.getOwnPropertyNames(#), #)', object, String);
41 41
42 List getOwnPropertySymbols(object) => 42 List getOwnPropertySymbols(object) =>
43 JS('List', 'Object.getOwnPropertySymbols(#)', object); 43 JS('List', 'Object.getOwnPropertySymbols(#)', object);
44 44
45 // TODO(jacobr): move this to dart:js and fully implement. 45 // TODO(jacobr): move this to dart:js and fully implement.
46 class JSNative { 46 class JSNative {
47 // Name may be a String or a Symbol. 47 // Name may be a String or a Symbol.
48 static getProperty(object, name) => JS('', '#[#]', object, name); 48 static getProperty(object, name) => JS('', '#[#]', object, name);
49 // Name may be a String or a Symbol. 49 // Name may be a String or a Symbol.
50 static setProperty(object, name, value) => 50 static setProperty(object, name, value) =>
51 JS('', '#[#]=#', object, name, value); 51 JS('', '#[#]=#', object, name, value);
52 } 52 }
53 53
54 void addMetadataChildren(object, Set<NameValuePair> ret) {
55 ret.add(new NameValuePair(
56 name: getTypeName(_getType(object)),
57 value: object,
58 config: JsonMLConfig.renderAsClass));
59 }
60
54 String getObjectTypeName(object) { 61 String getObjectTypeName(object) {
55 var reifiedType = dart.getReifiedType(object); 62 var reifiedType = dart.getReifiedType(object);
56 if (reifiedType == null) { 63 if (reifiedType == null) {
57 if (_typeof(object) == 'function') { 64 if (_typeof(object) == 'function') {
58 return '[[Raw JavaScript Function]]'; 65 return '[[Raw JavaScript Function]]';
59 } 66 }
60 return '<Error getting type name>'; 67 return '<Error getting type name>';
61 } 68 }
62 return getTypeName(reifiedType); 69 return getTypeName(reifiedType);
63 } 70 }
64 71
65 String getTypeName(Type type) { 72 String getTypeName(Type type) {
66 var name = dart.typeName(type); 73 var name = dart.typeName(type);
67 // Hack to cleanup names for List<dynamic> 74 // Hack to cleanup names for List<dynamic>
68 // TODO(jacobr): it would be nice if there was a way we could distinguish 75 // TODO(jacobr): it would be nice if there was a way we could distinguish
69 // between a List<dynamic> created from Dart and an Array passed in from 76 // between a List<dynamic> created from Dart and an Array passed in from
70 // JavaScript. 77 // JavaScript.
71 if (name == 'JSArray<dynamic>' || name == 'JSObject<Array>') 78 if (name == 'JSArray<dynamic>' || name == 'JSObject<Array>')
72 return 'List<dynamic>'; 79 return 'List<dynamic>';
73 return name; 80 return name;
74 } 81 }
75 82
83 Object _getType(object) =>
84 object is Type ? object : dart.getReifiedType(object);
85
76 String safePreview(object) { 86 String safePreview(object) {
77 try { 87 try {
78 var preview = _devtoolsFormatter._simpleFormatter.preview(object); 88 var preview = _devtoolsFormatter._simpleFormatter.preview(object);
79 if (preview != null) return preview; 89 if (preview != null) return preview;
80 return object.toString(); 90 return object.toString();
81 } catch (e) { 91 } catch (e) {
82 return '<Exception thrown> $e'; 92 return '<Exception thrown> $e';
83 } 93 }
84 } 94 }
85 95
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
176 final String name; 186 final String name;
177 final Object object; 187 final Object object;
178 } 188 }
179 189
180 class NamedConstructor { 190 class NamedConstructor {
181 NamedConstructor(this.object); 191 NamedConstructor(this.object);
182 192
183 final Object object; 193 final Object object;
184 } 194 }
185 195
186 class ClassMetadata {
187 ClassMetadata(this.object, {this.name});
188
189 final Object object;
190 final String name;
191
192 String get typeName =>
193 name ??
194 getTypeName(object is Type ? object : dart.getReifiedType(object));
195 }
196
197 class HeritageClause { 196 class HeritageClause {
198 HeritageClause(this.name, this.types); 197 HeritageClause(this.name, this.types);
199 198
200 final String name; 199 final String name;
201 final List types; 200 final List types;
202 } 201 }
203 202
204 Object safeGetProperty(Object protoChain, String name) { 203 Object safeGetProperty(Object protoChain, Object name) {
205 try { 204 try {
206 return JSNative.getProperty(protoChain, name); 205 return JSNative.getProperty(protoChain, name);
207 } catch (e) { 206 } catch (e) {
208 return '<Exception thrown> $e'; 207 return '<Exception thrown> $e';
209 } 208 }
210 } 209 }
211 210
212 safeProperties(object) => new Map.fromIterable( 211 safeProperties(object) => new Map.fromIterable(
213 getOwnPropertyNames(object) 212 getOwnPropertyNames(object)
214 .where((each) => safeGetProperty(object, each) != null), 213 .where((each) => safeGetProperty(object, each) != null),
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
293 292
294 void setMaxSpanLengthForTestingOnly(int spanLength) { 293 void setMaxSpanLengthForTestingOnly(int spanLength) {
295 _maxSpanLength = spanLength; 294 _maxSpanLength = spanLength;
296 } 295 }
297 296
298 header(object, config) { 297 header(object, config) {
299 customFormattersOn = true; 298 customFormattersOn = true;
300 if (config == JsonMLConfig.skipDart || isNativeJavaScriptObject(object)) { 299 if (config == JsonMLConfig.skipDart || isNativeJavaScriptObject(object)) {
301 return null; 300 return null;
302 } 301 }
303 302 var c = _simpleFormatter.preview(object, config: config);
304 var c = _simpleFormatter.preview(object);
305 if (c == null) return null; 303 if (c == null) return null;
306 304
307 if (config == JsonMLConfig.keyToString) { 305 if (config == JsonMLConfig.keyToString) {
308 c = object.toString(); 306 c = object.toString();
309 } 307 }
310 308
311 // Indicate this is a Dart Object by using a Dart background color. 309 // Indicate this is a Dart Object by using a Dart background color.
312 // This is stylistically a bit ugly but it eases distinguishing Dart and 310 // This is stylistically a bit ugly but it eases distinguishing Dart and
313 // JS objects. 311 // JS objects.
314 var element = new JsonMLElement('span') 312 var element = new JsonMLElement('span')
315 ..setStyle('background-color: #d9edf7;') 313 ..setStyle('background-color: #d9edf7;')
316 ..createTextChild(c); 314 ..createTextChild(c);
317 return element.toJsonML(); 315 return element.toJsonML();
318 } 316 }
319 317
320 bool hasBody(object) => _simpleFormatter.hasChildren(object); 318 bool hasBody(object, config) =>
319 _simpleFormatter.hasChildren(object, config: config);
321 320
322 body(object) { 321 body(object, config) {
323 var body = new JsonMLElement('ol') 322 var body = new JsonMLElement('ol')
324 ..setStyle('list-style-type: none;' 323 ..setStyle('list-style-type: none;'
325 'padding-left: 0px;' 324 'padding-left: 0px;'
326 'margin-top: 0px;' 325 'margin-top: 0px;'
327 'margin-bottom: 0px;' 326 'margin-bottom: 0px;'
328 'margin-left: 12px;'); 327 'margin-left: 12px;');
329 if (object is StackTrace) { 328 if (object is StackTrace) {
330 body.addStyle('color: rgb(196, 26, 22);'); 329 body.addStyle('color: rgb(196, 26, 22);');
331 } 330 }
332 var children = _simpleFormatter.children(object); 331 var children = _simpleFormatter.children(object, config: config);
333 for (NameValuePair child in children) { 332 for (NameValuePair child in children) {
334 var li = body.createChild('li'); 333 var li = body.createChild('li');
335 var nameSpan = new JsonMLElement('span') 334 var nameSpan = new JsonMLElement('span')
336 ..createTextChild( 335 ..createTextChild(
337 child.displayName.isNotEmpty ? '${child.displayName}: ' : '') 336 child.displayName.isNotEmpty ? '${child.displayName}: ' : '')
338 ..setStyle('color: rgb(136, 19, 145);'); 337 ..setStyle('color: rgb(136, 19, 145);');
339 if (_typeof(child.value) == 'object' || 338 if (_typeof(child.value) == 'object' ||
340 _typeof(child.value) == 'function') { 339 _typeof(child.value) == 'function') {
341 nameSpan.addStyle("padding-left: 13px;"); 340 nameSpan.addStyle("padding-left: 13px;");
342 341
343 li.appendChild(nameSpan); 342 li.appendChild(nameSpan);
344 var objectTag = li.createObjectTag(child.value); 343 var objectTag = li.createObjectTag(child.value);
345 objectTag.addAttribute('config', child.config); 344 objectTag.addAttribute('config', child.config);
346 if (!_simpleFormatter.hasChildren(child.value)) { 345 if (!_simpleFormatter.hasChildren(child.value, config: child.config)) {
347 li.setStyle("padding-left: 13px;"); 346 li.setStyle("padding-left: 13px;");
348 } 347 }
349 } else { 348 } else {
350 li.setStyle("padding-left: 13px;"); 349 li.setStyle("padding-left: 13px;");
351 li.createChild('span') 350 li.createChild('span')
352 ..appendChild(nameSpan) 351 ..appendChild(nameSpan)
353 ..createTextChild(safePreview(child.value)); 352 ..createTextChild(safePreview(child.value));
354 } 353 }
355 } 354 }
356 return body.toJsonML(); 355 return body.toJsonML();
357 } 356 }
358 } 357 }
359 358
360 abstract class Formatter { 359 abstract class Formatter {
361 bool accept(object); 360 bool accept(object);
362 String preview(object); 361 String preview(object);
363 bool hasChildren(object); 362 bool hasChildren(object);
364 List<NameValuePair> children(object); 363 List<NameValuePair> children(object);
365 } 364 }
366 365
367 class DartFormatter { 366 class DartFormatter {
368 List<Formatter> _formatters; 367 List<Formatter> _formatters;
369 368
370 DartFormatter() { 369 DartFormatter() {
371 // The order of formatters matters as formatters earlier in the list take 370 // The order of formatters matters as formatters earlier in the list take
372 // precedence. 371 // precedence.
373 _formatters = [ 372 _formatters = [
373 new ClassFormatter(),
374 new NamedConstructorFormatter(), 374 new NamedConstructorFormatter(),
375 new FunctionFormatter(),
376 new MapFormatter(), 375 new MapFormatter(),
377 new IterableFormatter(), 376 new IterableFormatter(),
377 new IterableSpanFormatter(),
378 new MapEntryFormatter(), 378 new MapEntryFormatter(),
379 new IterableSpanFormatter(),
380 new StackTraceFormatter(), 379 new StackTraceFormatter(),
381 new ClassMetadataFormatter(), 380 new FunctionFormatter(),
382 new HeritageClauseFormatter(), 381 new HeritageClauseFormatter(),
383 new LibraryModuleFormatter(), 382 new LibraryModuleFormatter(),
384 new LibraryFormatter(), 383 new LibraryFormatter(),
385 new ObjectFormatter(), 384 new ObjectFormatter(),
386 ]; 385 ];
387 } 386 }
388 387
389 String preview(object) { 388 String preview(object, {config: JsonMLConfig.none}) {
390 try { 389 try {
391 if (object == null || 390 if (object == null ||
392 object is num || 391 object is num ||
393 object is String || 392 object is String ||
394 isNativeJavaScriptObject(object)) { 393 isNativeJavaScriptObject(object)) {
395 return object.toString(); 394 return object.toString();
396 } 395 }
397 396 if (config == JsonMLConfig.renderAsClass)
397 return new ClassFormatter().preview(object);
398 for (var formatter in _formatters) { 398 for (var formatter in _formatters) {
399 if (formatter.accept(object)) return formatter.preview(object); 399 if (formatter.accept(object)) return formatter.preview(object);
400 } 400 }
401 } catch (e, trace) { 401 } catch (e, trace) {
402 // Log formatter internal errors as unfortunately the devtools cannot 402 // Log formatter internal errors as unfortunately the devtools cannot
403 // be used to debug formatter errors. 403 // be used to debug formatter errors.
404 html.window.console.error("Caught exception $e\n trace:\n$trace"); 404 html.window.console.error("Caught exception $e\n trace:\n$trace");
405 } 405 }
406 406
407 return null; 407 return null;
408 } 408 }
409 409
410 bool hasChildren(object) { 410 bool hasChildren(object, {config: JsonMLConfig.none}) {
411 if (object == null) return false; 411 if (object == null) return false;
412 try { 412 try {
413 if (config == JsonMLConfig.renderAsClass)
Jacob 2016/08/02 01:45:12 instead of special casing ClassFormatter here, pas
bmilligan 2016/08/02 16:28:39 Done.
414 return new ClassFormatter().hasChildren(object);
413 for (var formatter in _formatters) { 415 for (var formatter in _formatters) {
414 if (formatter.accept(object)) return formatter.hasChildren(object); 416 if (formatter.accept(object)) return formatter.hasChildren(object);
415 } 417 }
416 } catch (e, trace) { 418 } catch (e, trace) {
417 // See comment for preview. 419 // See comment for preview.
418 html.window.console 420 html.window.console
419 .error("[hasChildren] Caught exception $e\n trace:\n$trace"); 421 .error("[hasChildren] Caught exception $e\n trace:\n$trace");
420 } 422 }
421 return false; 423 return false;
422 } 424 }
423 425
424 List<NameValuePair> children(object) { 426 List<NameValuePair> children(object, {config: JsonMLConfig.none}) {
425 try { 427 try {
426 if (object != null) { 428 if (object != null) {
429 if (config == JsonMLConfig.renderAsClass)
430 return new ClassFormatter().children(object);
427 for (var formatter in _formatters) { 431 for (var formatter in _formatters) {
428 if (formatter.accept(object)) return formatter.children(object); 432 if (formatter.accept(object)) return formatter.children(object);
429 } 433 }
430 } 434 }
431 } catch (e, trace) { 435 } catch (e, trace) {
432 // See comment for preview. 436 // See comment for preview.
433 html.window.console.error("Caught exception $e\n trace:\n$trace"); 437 html.window.console.error("Caught exception $e\n trace:\n$trace");
434 } 438 }
435 return <NameValuePair>[]; 439 return <NameValuePair>[];
436 } 440 }
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
497 if (hasMethod(object, name)) { 501 if (hasMethod(object, name)) {
498 continue; 502 continue;
499 } 503 }
500 var value = safeGetProperty(object, name); 504 var value = safeGetProperty(object, name);
501 properties.add(new NameValuePair(name: name, value: value)); 505 properties.add(new NameValuePair(name: name, value: value));
502 } 506 }
503 } 507 }
504 508
505 return properties.toList(); 509 return properties.toList();
506 } 510 }
507
508 addMetadataChildren(object, Set<NameValuePair> ret) {
509 var child = new ClassMetadata(object);
510 ret.add(new NameValuePair(name: child.typeName, value: child));
511 }
512 } 511 }
513 512
514 /// Formatter for module Dart Library objects. 513 /// Formatter for module Dart Library objects.
515 class LibraryModuleFormatter extends ObjectFormatter { 514 class LibraryModuleFormatter implements Formatter {
516 String libraryName; 515 String libraryName;
517 516
518 accept(object) { 517 accept(object) {
519 libraryName = dart.getDartLibraryName(object); 518 libraryName = dart.getDartLibraryName(object);
520 return libraryName != null; 519 return libraryName != null;
521 } 520 }
522 521
523 bool hasChildren(object) => true; 522 bool hasChildren(object) => true;
524 523
525 String preview(object) { 524 String preview(object) {
(...skipping 15 matching lines...) Expand all
541 // Replace __ with / to make file paths more readable. Then 540 // Replace __ with / to make file paths more readable. Then
542 // 'src__result__error' becomes 'src/result/error'. 541 // 'src__result__error' becomes 'src/result/error'.
543 name = '${name.replaceAll("__", "/")}.dart'; 542 name = '${name.replaceAll("__", "/")}.dart';
544 children.add(new NameValuePair( 543 children.add(new NameValuePair(
545 name: name, value: new Library(name, value), hideName: true)); 544 name: name, value: new Library(name, value), hideName: true));
546 } 545 }
547 return children.toList(); 546 return children.toList();
548 } 547 }
549 } 548 }
550 549
551 /// Formatter for Dart Library objects. 550 class LibraryFormatter implements Formatter {
552 class LibraryFormatter extends ObjectFormatter {
553 var genericParameters = new HashMap<String, String>(); 551 var genericParameters = new HashMap<String, String>();
554 552
555 accept(object) => object is Library; 553 accept(object) => object is Library;
556 554
557 bool hasChildren(object) => true; 555 bool hasChildren(object) => true;
558 556
559 String preview(object) => object.name; 557 String preview(object) => object.name;
560 558
561 List<NameValuePair> children(object) { 559 List<NameValuePair> children(object) {
562 var children = new LinkedHashSet<NameValuePair>(); 560 var children = new LinkedHashSet<NameValuePair>();
(...skipping 29 matching lines...) Expand all
592 .replaceAll(new RegExp(r'[(|)]'), ''); 590 .replaceAll(new RegExp(r'[(|)]'), '');
593 } 591 }
594 592
595 classChild(String name, Object child) { 593 classChild(String name, Object child) {
596 var typeName = getTypeName(child); 594 var typeName = getTypeName(child);
597 // Generic class names are generated with a $ at the end, so the 595 // Generic class names are generated with a $ at the end, so the
598 // corresponding non-generic class can be identified by adding $. 596 // corresponding non-generic class can be identified by adding $.
599 var parameterName = '$name\$'; 597 var parameterName = '$name\$';
600 if (genericParameters.keys.contains(parameterName)) { 598 if (genericParameters.keys.contains(parameterName)) {
601 typeName = '$typeName<${genericParameters[parameterName]}>'; 599 typeName = '$typeName<${genericParameters[parameterName]}>';
600 JSNative.setProperty(child, 'genericTypeName', typeName);
602 } 601 }
603 return new NameValuePair( 602 return new NameValuePair(name: typeName, value: child);
604 name: typeName, value: new ClassMetadata(child, name: typeName));
605 } 603 }
606 } 604 }
607 605
608 /// Formatter for Dart Function objects. 606 /// Formatter for Dart Function objects.
609 /// Dart functions happen to be regular JavaScript Function objects but 607 /// Dart functions happen to be regular JavaScript Function objects but
610 /// we can distinguish them based on whether they have been tagged with 608 /// we can distinguish them based on whether they have been tagged with
611 /// runtime type information. 609 /// runtime type information.
612 class FunctionFormatter extends Formatter { 610 class FunctionFormatter implements Formatter {
613 accept(object) { 611 accept(object) {
614 if (_typeof(object) != 'function') return false; 612 if (_typeof(object) != 'function') return false;
615 return dart.getReifiedType(object) != null; 613 return dart.getReifiedType(object) != null;
616 } 614 }
617 615
618 bool hasChildren(object) => true; 616 bool hasChildren(object) => true;
619 617
620 String preview(object) { 618 String preview(object) {
621 return dart.typeName(dart.getReifiedType(object)); 619 return dart.typeName(dart.getReifiedType(object));
622 } 620 }
623 621
624 List<NameValuePair> children(object) => <NameValuePair>[ 622 List<NameValuePair> children(object) => <NameValuePair>[
625 new NameValuePair(name: 'signature', value: preview(object)), 623 new NameValuePair(name: 'signature', value: preview(object)),
626 new NameValuePair( 624 new NameValuePair(
627 name: 'JavaScript Function', 625 name: 'JavaScript Function',
628 value: object, 626 value: object,
629 config: JsonMLConfig.skipDart) 627 config: JsonMLConfig.skipDart)
630 ]; 628 ];
631 } 629 }
632 630
633 /// Formatter for Dart Map objects. 631 /// Formatter for Dart Map objects.
634 class MapFormatter extends ObjectFormatter { 632 class MapFormatter implements Formatter {
635 accept(object) => object is Map; 633 accept(object) => object is Map;
636 634
637 bool hasChildren(object) => true; 635 bool hasChildren(object) => true;
638 636
639 String preview(object) { 637 String preview(object) {
640 Map map = object; 638 Map map = object;
641 return '${getObjectTypeName(map)} length ${map.length}'; 639 return '${getObjectTypeName(map)} length ${map.length}';
642 } 640 }
643 641
644 List<NameValuePair> children(object) { 642 List<NameValuePair> children(object) {
645 // TODO(jacobr): be lazier about enumerating contents of Maps that are not 643 // TODO(jacobr): be lazier about enumerating contents of Maps that are not
646 // the build in LinkedHashMap class. 644 // the build in LinkedHashMap class.
647 // TODO(jacobr): handle large Maps better. 645 // TODO(jacobr): handle large Maps better.
648 Map map = object; 646 Map map = object;
649 var entries = new LinkedHashSet<NameValuePair>(); 647 var entries = new LinkedHashSet<NameValuePair>();
650 map.forEach((key, value) { 648 map.forEach((key, value) {
651 var entryWrapper = new MapEntry(key: key, value: value); 649 var entryWrapper = new MapEntry(key: key, value: value);
652 entries.add(new NameValuePair( 650 entries.add(new NameValuePair(
653 name: entries.length.toString(), value: entryWrapper)); 651 name: entries.length.toString(), value: entryWrapper));
654 }); 652 });
655 addMetadataChildren(object, entries); 653 addMetadataChildren(object, entries);
656 return entries.toList(); 654 return entries.toList();
657 } 655 }
658 } 656 }
659 657
660 /// Formatter for Dart Iterable objects including List and Set. 658 /// Formatter for Dart Iterable objects including List and Set.
661 class IterableFormatter extends ObjectFormatter { 659 class IterableFormatter implements Formatter {
662 bool accept(object) => object is Iterable; 660 bool accept(object) => object is Iterable;
663 661
664 String preview(object) { 662 String preview(object) {
665 Iterable iterable = object; 663 Iterable iterable = object;
666 try { 664 try {
667 var length = iterable.length; 665 var length = iterable.length;
668 return '${getObjectTypeName(iterable)} length $length'; 666 return '${getObjectTypeName(iterable)} length $length';
669 } catch (_) { 667 } catch (_) {
670 return '${getObjectTypeName(iterable)}'; 668 return '${getObjectTypeName(iterable)}';
671 } 669 }
672 } 670 }
673 671
674 bool hasChildren(object) => true; 672 bool hasChildren(object) => true;
675 673
676 List<NameValuePair> children(object) { 674 List<NameValuePair> children(object) {
677 // TODO(jacobr): be lazier about enumerating contents of Iterables that 675 // TODO(jacobr): be lazier about enumerating contents of Iterables that
678 // are not the built in Set or List types. 676 // are not the built in Set or List types.
679 // TODO(jacobr): handle large Iterables better. 677 // TODO(jacobr): handle large Iterables better.
680 // TODO(jacobr): consider only using numeric indices 678 // TODO(jacobr): consider only using numeric indices
681 var children = new LinkedHashSet<NameValuePair>(); 679 var children = new LinkedHashSet<NameValuePair>();
682 children.addAll(new IterableSpan(0, object.length, object).children()); 680 children.addAll(new IterableSpan(0, object.length, object).children());
683 // TODO(jacobr): provide a link to show regular class properties here. 681 // TODO(jacobr): provide a link to show regular class properties here.
684 // required for subclasses of iterable, etc. 682 // required for subclasses of iterable, etc.
685 addMetadataChildren(object, children); 683 addMetadataChildren(object, children);
686 return children.toList(); 684 return children.toList();
687 } 685 }
688 } 686 }
689 687
690 // This class does double duting displaying metadata for
691 class ClassMetadataFormatter implements Formatter {
692 accept(object) => object is ClassMetadata;
693
694 Object _getType(object) {
695 if (object is Type) return object;
696 return dart.getReifiedType(object);
697 }
698
699 String preview(object) {
700 ClassMetadata entry = object;
701 var type =
702 entry.object is Type ? entry.object : dart.getReifiedType(entry.object);
703 var implements = dart.getImplements(type);
704 if (implements != null) {
705 var typeNames = implements().map(getTypeName);
706 return '${entry.typeName} implements ${typeNames.join(", ")}';
707 } else {
708 return entry.typeName;
709 }
710 }
711
712 bool hasChildren(object) => true;
713
714 List<NameValuePair> children(object) {
715 ClassMetadata entry = object;
716 var classObject = entry.object;
717 // TODO(jacobr): add other entries describing the class such as
718 // links to the superclass, mixins, implemented interfaces, and methods.
719 var type = _getType(classObject);
720 var children = <NameValuePair>[];
721
722 var mixins = dart.getMixins(type);
723 if (mixins != null && mixins.isNotEmpty) {
724 children.add(new NameValuePair(
725 name: '[[Mixins]]', value: new HeritageClause('mixins', mixins)));
726 }
727
728 var hiddenProperties = ['length', 'name', 'prototype'];
729 // Addition of NameValuePairs for static variables and named constructors.
730 for (var name in getOwnPropertyNames(classObject)) {
731 // TODO(bmilligan): Perform more principled checks to filter out spurious
732 // members.
733 if (hiddenProperties.contains(name)) continue;
734 var value = safeGetProperty(classObject, name);
735 if (value != null && dart.getIsNamedConstructor(value) != null) {
736 value = new NamedConstructor(value);
737 name = '${entry.typeName}.$name';
738 }
739 children.add(new NameValuePair(name: name, value: value));
740 }
741
742 // TODO(bmilligan): Replace the hard coding of $identityHash.
743 var hiddenPrototypeProperties = ['constructor', 'new', r'$identityHash'];
744 // Addition of class methods.
745 var prototype = JS('var', '#["prototype"]', classObject);
746 if (prototype != null) {
747 for (var name in getOwnPropertyNames(prototype)) {
748 if (hiddenPrototypeProperties.contains(name)) continue;
749 // Simulate dart.bind by using dart.tag and tear off the function
750 // so it will be recognized by the FunctionFormatter.
751 var function = safeGetProperty(prototype, name);
752 var constructor = safeGetProperty(prototype, 'constructor');
753 var sigObj = dart.getMethodSig(constructor);
754 if (sigObj != null) {
755 var value = safeGetProperty(sigObj, name);
756 if (getTypeName(dart.getReifiedType(value)) != 'Null') {
757 dart.tag(function, value);
758 children.add(new NameValuePair(name: name, value: function));
759 }
760 }
761 }
762 }
763 // TODO(jacobr): provide a link to the base class or perhaps the entire
764 // base class hierarchy as a flat list.
765 // TODO(jacobr): add constructors, methods, extended class, and static
766 return children;
767 }
768 }
769
770 class NamedConstructorFormatter implements Formatter { 688 class NamedConstructorFormatter implements Formatter {
771 accept(object) => object is NamedConstructor; 689 accept(object) => object is NamedConstructor;
772 690
773 // TODO(bmilligan): Display the signature of the named constructor as the 691 // TODO(bmilligan): Display the signature of the named constructor as the
774 // preview. 692 // preview.
775 String preview(object) => 'Named Constructor'; 693 String preview(object) => 'Named Constructor';
776 694
777 bool hasChildren(object) => true; 695 bool hasChildren(object) => true;
778 696
779 List<NameValuePair> children(object) => <NameValuePair>[ 697 List<NameValuePair> children(object) => <NameValuePair>[
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
812 var typeNames = clause.types.map(getTypeName); 730 var typeNames = clause.types.map(getTypeName);
813 return '${clause.name} ${typeNames.join(", ")}'; 731 return '${clause.name} ${typeNames.join(", ")}';
814 } 732 }
815 733
816 bool hasChildren(object) => true; 734 bool hasChildren(object) => true;
817 735
818 List<NameValuePair> children(object) { 736 List<NameValuePair> children(object) {
819 HeritageClause clause = object; 737 HeritageClause clause = object;
820 var children = <NameValuePair>[]; 738 var children = <NameValuePair>[];
821 for (var type in clause.types) { 739 for (var type in clause.types) {
822 children.add(new NameValuePair(value: new ClassMetadata(type))); 740 children.add(
741 new NameValuePair(value: type, config: JsonMLConfig.renderAsClass));
823 } 742 }
824 return children; 743 return children;
825 } 744 }
826 } 745 }
827 746
828 /// Formatter for synthetic IterableSpan objects used to display contents of 747 /// Formatter for synthetic IterableSpan objects used to display contents of
829 /// an Iterable cleanly. 748 /// an Iterable cleanly.
830 class IterableSpanFormatter implements Formatter { 749 class IterableSpanFormatter implements Formatter {
831 accept(object) => object is IterableSpan; 750 accept(object) => object is IterableSpan;
832 751
(...skipping 18 matching lines...) Expand all
851 // StackTrace will be added as its own child. 770 // StackTrace will be added as its own child.
852 List<NameValuePair> children(object) => object 771 List<NameValuePair> children(object) => object
853 .toString() 772 .toString()
854 .split('\n') 773 .split('\n')
855 .map((line) => new NameValuePair( 774 .map((line) => new NameValuePair(
856 value: line.replaceFirst(new RegExp(r'^\s+at\s'), ''), 775 value: line.replaceFirst(new RegExp(r'^\s+at\s'), ''),
857 hideName: true)) 776 hideName: true))
858 .toList(); 777 .toList();
859 } 778 }
860 779
780 class ClassFormatter implements Formatter {
781 accept(object) => object is Type;
Jacob 2016/08/02 01:45:11 change this accept method to take the JSONMLConfig
bmilligan 2016/08/02 16:28:39 Done.
782
783 String preview(object) {
784 // TODO(bmilligan): Tag classes with generic types with a Symbol at their
Jacob 2016/08/02 01:45:12 this comment is obsolete
bmilligan 2016/08/02 16:28:39 The emphasis on this comment is on the "generic ty
Jacob 2016/08/02 16:39:44 Acknowledged.
785 // creation so they can be recognized by the ClassFormatter.
786 var typeName = safeGetProperty(object, 'genericTypeName');
787 if (typeName != null) return typeName;
788 var type = _getType(object);
789 var implements = dart.getImplements(type);
790 typeName = getTypeName(type);
791 if (implements != null) {
792 var typeNames = implements().map(getTypeName);
793 return '${typeName} implements ${typeNames.join(", ")}';
794 } else {
795 return typeName;
796 }
797 }
798
799 bool hasChildren(object) => true;
800
801 List<NameValuePair> children(object) {
802 // TODO(jacobr): add other entries describing the class such as
803 // links to the superclass, mixins, implemented interfaces, and methods.
804 var type = _getType(object);
805 var children = <NameValuePair>[];
806 var typeName = getTypeName(_getType(object));
807 var mixins = dart.getMixins(type);
808 if (mixins != null && mixins.isNotEmpty) {
809 children.add(new NameValuePair(
810 name: '[[Mixins]]', value: new HeritageClause('mixins', mixins)));
811 }
812
813 var hiddenProperties = ['length', 'name', 'prototype', 'genericTypeName'];
814 // Addition of NameValuePairs for static variables and named constructors.
815 for (var name in getOwnPropertyNames(object)) {
816 // TODO(bmilligan): Perform more principled checks to filter out spurious
817 // members.
818 if (hiddenProperties.contains(name)) continue;
819 var value = safeGetProperty(object, name);
820 if (value != null && dart.getIsNamedConstructor(value) != null) {
821 value = new NamedConstructor(value);
822 name = '${typeName}.$name';
823 }
824 children.add(new NameValuePair(name: name, value: value));
825 }
826
827 // TODO(bmilligan): Replace the hard coding of $identityHash.
828 var hiddenPrototypeProperties = ['constructor', 'new', r'$identityHash'];
829 // Addition of class methods.
830 var prototype = JS('var', '#["prototype"]', object);
831 if (prototype != null) {
832 for (var name in getOwnPropertyNames(prototype)) {
833 if (hiddenPrototypeProperties.contains(name)) continue;
834 // Simulate dart.bind by using dart.tag and tear off the function
835 // so it will be recognized by the FunctionFormatter.
836 var function = safeGetProperty(prototype, name);
837 var constructor = safeGetProperty(prototype, 'constructor');
838 var sigObj = dart.getMethodSig(constructor);
839 if (sigObj != null) {
840 var value = safeGetProperty(sigObj, name);
841 if (getTypeName(dart.getReifiedType(value)) != 'Null') {
842 dart.tag(function, value);
843 children.add(new NameValuePair(name: name, value: function));
844 }
845 }
846 }
847 }
848 return children;
849 }
850 }
851
861 /// This entry point is automatically invoked by the code generated by 852 /// This entry point is automatically invoked by the code generated by
862 /// Dart Dev Compiler 853 /// Dart Dev Compiler
863 registerDevtoolsFormatter() { 854 registerDevtoolsFormatter() {
864 var formatters = [_devtoolsFormatter]; 855 var formatters = [_devtoolsFormatter];
865 JS('', 'dart.global.devtoolsFormatters = #', formatters); 856 JS('', 'dart.global.devtoolsFormatters = #', formatters);
866 } 857 }
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