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

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: Set class property for heritage clause 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 13 matching lines...) Expand all
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 } 31 }
32 32
33 int _maxSpanLength = 100; 33 int _maxSpanLength = 100;
34 34 Symbol isClass = JS('Symbol', 'Symbol("isClass")');
bmilligan 2016/08/02 01:12:44 Using 'new Symbol('isClass') in Dart followed by J
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 JSNative.setProperty(object, isClass, true);
56 ret.add(
57 new NameValuePair(name: getTypeName(_getType(object)), value: object));
58 }
59
54 String getObjectTypeName(object) { 60 String getObjectTypeName(object) {
55 var reifiedType = dart.getReifiedType(object); 61 var reifiedType = dart.getReifiedType(object);
56 if (reifiedType == null) { 62 if (reifiedType == null) {
57 if (_typeof(object) == 'function') { 63 if (_typeof(object) == 'function') {
58 return '[[Raw JavaScript Function]]'; 64 return '[[Raw JavaScript Function]]';
59 } 65 }
60 return '<Error getting type name>'; 66 return '<Error getting type name>';
61 } 67 }
62 return getTypeName(reifiedType); 68 return getTypeName(reifiedType);
63 } 69 }
64 70
65 String getTypeName(Type type) { 71 String getTypeName(Type type) {
66 var name = dart.typeName(type); 72 var name = dart.typeName(type);
67 // Hack to cleanup names for List<dynamic> 73 // Hack to cleanup names for List<dynamic>
68 // TODO(jacobr): it would be nice if there was a way we could distinguish 74 // 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 75 // between a List<dynamic> created from Dart and an Array passed in from
70 // JavaScript. 76 // JavaScript.
71 if (name == 'JSArray<dynamic>' || name == 'JSObject<Array>') 77 if (name == 'JSArray<dynamic>' || name == 'JSObject<Array>')
72 return 'List<dynamic>'; 78 return 'List<dynamic>';
73 return name; 79 return name;
74 } 80 }
75 81
82 Object _getType(object) =>
83 object is Type ? object : dart.getReifiedType(object);
84
76 String safePreview(object) { 85 String safePreview(object) {
77 try { 86 try {
78 var preview = _devtoolsFormatter._simpleFormatter.preview(object); 87 var preview = _devtoolsFormatter._simpleFormatter.preview(object);
79 if (preview != null) return preview; 88 if (preview != null) return preview;
80 return object.toString(); 89 return object.toString();
81 } catch (e) { 90 } catch (e) {
82 return '<Exception thrown> $e'; 91 return '<Exception thrown> $e';
83 } 92 }
84 } 93 }
85 94
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
176 final String name; 185 final String name;
177 final Object object; 186 final Object object;
178 } 187 }
179 188
180 class NamedConstructor { 189 class NamedConstructor {
181 NamedConstructor(this.object); 190 NamedConstructor(this.object);
182 191
183 final Object object; 192 final Object object;
184 } 193 }
185 194
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 { 195 class HeritageClause {
198 HeritageClause(this.name, this.types); 196 HeritageClause(this.name, this.types);
199 197
200 final String name; 198 final String name;
201 final List types; 199 final List types;
202 } 200 }
203 201
204 Object safeGetProperty(Object protoChain, String name) { 202 Object safeGetProperty(Object protoChain, Object name) {
205 try { 203 try {
206 return JSNative.getProperty(protoChain, name); 204 return JSNative.getProperty(protoChain, name);
207 } catch (e) { 205 } catch (e) {
208 return '<Exception thrown> $e'; 206 return '<Exception thrown> $e';
209 } 207 }
210 } 208 }
211 209
212 safeProperties(object) => new Map.fromIterable( 210 safeProperties(object) => new Map.fromIterable(
213 getOwnPropertyNames(object) 211 getOwnPropertyNames(object)
214 .where((each) => safeGetProperty(object, each) != null), 212 .where((each) => safeGetProperty(object, each) != null),
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
364 List<NameValuePair> children(object); 362 List<NameValuePair> children(object);
365 } 363 }
366 364
367 class DartFormatter { 365 class DartFormatter {
368 List<Formatter> _formatters; 366 List<Formatter> _formatters;
369 367
370 DartFormatter() { 368 DartFormatter() {
371 // The order of formatters matters as formatters earlier in the list take 369 // The order of formatters matters as formatters earlier in the list take
372 // precedence. 370 // precedence.
373 _formatters = [ 371 _formatters = [
372 new ClassFormatter(),
374 new NamedConstructorFormatter(), 373 new NamedConstructorFormatter(),
375 new FunctionFormatter(),
376 new MapFormatter(), 374 new MapFormatter(),
377 new IterableFormatter(), 375 new IterableFormatter(),
376 new IterableSpanFormatter(),
378 new MapEntryFormatter(), 377 new MapEntryFormatter(),
379 new IterableSpanFormatter(),
380 new StackTraceFormatter(), 378 new StackTraceFormatter(),
381 new ClassMetadataFormatter(), 379 new FunctionFormatter(),
382 new HeritageClauseFormatter(), 380 new HeritageClauseFormatter(),
383 new LibraryModuleFormatter(), 381 new LibraryModuleFormatter(),
384 new LibraryFormatter(), 382 new LibraryFormatter(),
385 new ObjectFormatter(), 383 new ObjectFormatter(),
386 ]; 384 ];
387 } 385 }
388 386
389 String preview(object) { 387 String preview(object) {
390 try { 388 try {
391 if (object == null || 389 if (object == null ||
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
497 if (hasMethod(object, name)) { 495 if (hasMethod(object, name)) {
498 continue; 496 continue;
499 } 497 }
500 var value = safeGetProperty(object, name); 498 var value = safeGetProperty(object, name);
501 properties.add(new NameValuePair(name: name, value: value)); 499 properties.add(new NameValuePair(name: name, value: value));
502 } 500 }
503 } 501 }
504 502
505 return properties.toList(); 503 return properties.toList();
506 } 504 }
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 } 505 }
513 506
514 /// Formatter for module Dart Library objects. 507 /// Formatter for module Dart Library objects.
515 class LibraryModuleFormatter extends ObjectFormatter { 508 class LibraryModuleFormatter implements Formatter {
516 String libraryName; 509 String libraryName;
517 510
518 accept(object) { 511 accept(object) {
519 libraryName = dart.getDartLibraryName(object); 512 libraryName = dart.getDartLibraryName(object);
520 return libraryName != null; 513 return libraryName != null;
521 } 514 }
522 515
523 bool hasChildren(object) => true; 516 bool hasChildren(object) => true;
524 517
525 String preview(object) { 518 String preview(object) {
(...skipping 15 matching lines...) Expand all
541 // Replace __ with / to make file paths more readable. Then 534 // Replace __ with / to make file paths more readable. Then
542 // 'src__result__error' becomes 'src/result/error'. 535 // 'src__result__error' becomes 'src/result/error'.
543 name = '${name.replaceAll("__", "/")}.dart'; 536 name = '${name.replaceAll("__", "/")}.dart';
544 children.add(new NameValuePair( 537 children.add(new NameValuePair(
545 name: name, value: new Library(name, value), hideName: true)); 538 name: name, value: new Library(name, value), hideName: true));
546 } 539 }
547 return children.toList(); 540 return children.toList();
548 } 541 }
549 } 542 }
550 543
551 /// Formatter for Dart Library objects. 544 class LibraryFormatter implements Formatter {
552 class LibraryFormatter extends ObjectFormatter {
553 var genericParameters = new HashMap<String, String>(); 545 var genericParameters = new HashMap<String, String>();
554 546
555 accept(object) => object is Library; 547 accept(object) => object is Library;
556 548
557 bool hasChildren(object) => true; 549 bool hasChildren(object) => true;
558 550
559 String preview(object) => object.name; 551 String preview(object) => object.name;
560 552
561 List<NameValuePair> children(object) { 553 List<NameValuePair> children(object) {
562 var children = new LinkedHashSet<NameValuePair>(); 554 var children = new LinkedHashSet<NameValuePair>();
(...skipping 29 matching lines...) Expand all
592 .replaceAll(new RegExp(r'[(|)]'), ''); 584 .replaceAll(new RegExp(r'[(|)]'), '');
593 } 585 }
594 586
595 classChild(String name, Object child) { 587 classChild(String name, Object child) {
596 var typeName = getTypeName(child); 588 var typeName = getTypeName(child);
597 // Generic class names are generated with a $ at the end, so the 589 // Generic class names are generated with a $ at the end, so the
598 // corresponding non-generic class can be identified by adding $. 590 // corresponding non-generic class can be identified by adding $.
599 var parameterName = '$name\$'; 591 var parameterName = '$name\$';
600 if (genericParameters.keys.contains(parameterName)) { 592 if (genericParameters.keys.contains(parameterName)) {
601 typeName = '$typeName<${genericParameters[parameterName]}>'; 593 typeName = '$typeName<${genericParameters[parameterName]}>';
594 JSNative.setProperty(child, 'genericTypeName', typeName);
602 } 595 }
603 return new NameValuePair( 596 return new NameValuePair(name: typeName, value: child);
604 name: typeName, value: new ClassMetadata(child, name: typeName));
605 } 597 }
606 } 598 }
607 599
608 /// Formatter for Dart Function objects. 600 /// Formatter for Dart Function objects.
609 /// Dart functions happen to be regular JavaScript Function objects but 601 /// Dart functions happen to be regular JavaScript Function objects but
610 /// we can distinguish them based on whether they have been tagged with 602 /// we can distinguish them based on whether they have been tagged with
611 /// runtime type information. 603 /// runtime type information.
612 class FunctionFormatter extends Formatter { 604 class FunctionFormatter implements Formatter {
613 accept(object) { 605 accept(object) {
614 if (_typeof(object) != 'function') return false; 606 if (_typeof(object) != 'function') return false;
615 return dart.getReifiedType(object) != null; 607 return dart.getReifiedType(object) != null;
616 } 608 }
617 609
618 bool hasChildren(object) => true; 610 bool hasChildren(object) => true;
619 611
620 String preview(object) { 612 String preview(object) {
621 return dart.typeName(dart.getReifiedType(object)); 613 return dart.typeName(dart.getReifiedType(object));
622 } 614 }
623 615
624 List<NameValuePair> children(object) => <NameValuePair>[ 616 List<NameValuePair> children(object) => <NameValuePair>[
625 new NameValuePair(name: 'signature', value: preview(object)), 617 new NameValuePair(name: 'signature', value: preview(object)),
626 new NameValuePair( 618 new NameValuePair(
627 name: 'JavaScript Function', 619 name: 'JavaScript Function',
628 value: object, 620 value: object,
629 config: JsonMLConfig.skipDart) 621 config: JsonMLConfig.skipDart)
630 ]; 622 ];
631 } 623 }
632 624
633 /// Formatter for Dart Map objects. 625 /// Formatter for Dart Map objects.
634 class MapFormatter extends ObjectFormatter { 626 class MapFormatter implements Formatter {
635 accept(object) => object is Map; 627 accept(object) => object is Map;
636 628
637 bool hasChildren(object) => true; 629 bool hasChildren(object) => true;
638 630
639 String preview(object) { 631 String preview(object) {
640 Map map = object; 632 Map map = object;
641 return '${getObjectTypeName(map)} length ${map.length}'; 633 return '${getObjectTypeName(map)} length ${map.length}';
642 } 634 }
643 635
644 List<NameValuePair> children(object) { 636 List<NameValuePair> children(object) {
645 // TODO(jacobr): be lazier about enumerating contents of Maps that are not 637 // TODO(jacobr): be lazier about enumerating contents of Maps that are not
646 // the build in LinkedHashMap class. 638 // the build in LinkedHashMap class.
647 // TODO(jacobr): handle large Maps better. 639 // TODO(jacobr): handle large Maps better.
648 Map map = object; 640 Map map = object;
649 var entries = new LinkedHashSet<NameValuePair>(); 641 var entries = new LinkedHashSet<NameValuePair>();
650 map.forEach((key, value) { 642 map.forEach((key, value) {
651 var entryWrapper = new MapEntry(key: key, value: value); 643 var entryWrapper = new MapEntry(key: key, value: value);
652 entries.add(new NameValuePair( 644 entries.add(new NameValuePair(
653 name: entries.length.toString(), value: entryWrapper)); 645 name: entries.length.toString(), value: entryWrapper));
654 }); 646 });
655 addMetadataChildren(object, entries); 647 addMetadataChildren(object, entries);
656 return entries.toList(); 648 return entries.toList();
657 } 649 }
658 } 650 }
659 651
660 /// Formatter for Dart Iterable objects including List and Set. 652 /// Formatter for Dart Iterable objects including List and Set.
661 class IterableFormatter extends ObjectFormatter { 653 class IterableFormatter implements Formatter {
662 bool accept(object) => object is Iterable; 654 bool accept(object) => object is Iterable;
663 655
664 String preview(object) { 656 String preview(object) {
665 Iterable iterable = object; 657 Iterable iterable = object;
666 try { 658 try {
667 var length = iterable.length; 659 var length = iterable.length;
668 return '${getObjectTypeName(iterable)} length $length'; 660 return '${getObjectTypeName(iterable)} length $length';
669 } catch (_) { 661 } catch (_) {
670 return '${getObjectTypeName(iterable)}'; 662 return '${getObjectTypeName(iterable)}';
671 } 663 }
672 } 664 }
673 665
674 bool hasChildren(object) => true; 666 bool hasChildren(object) => true;
675 667
676 List<NameValuePair> children(object) { 668 List<NameValuePair> children(object) {
677 // TODO(jacobr): be lazier about enumerating contents of Iterables that 669 // TODO(jacobr): be lazier about enumerating contents of Iterables that
678 // are not the built in Set or List types. 670 // are not the built in Set or List types.
679 // TODO(jacobr): handle large Iterables better. 671 // TODO(jacobr): handle large Iterables better.
680 // TODO(jacobr): consider only using numeric indices 672 // TODO(jacobr): consider only using numeric indices
681 var children = new LinkedHashSet<NameValuePair>(); 673 var children = new LinkedHashSet<NameValuePair>();
682 children.addAll(new IterableSpan(0, object.length, object).children()); 674 children.addAll(new IterableSpan(0, object.length, object).children());
683 // TODO(jacobr): provide a link to show regular class properties here. 675 // TODO(jacobr): provide a link to show regular class properties here.
684 // required for subclasses of iterable, etc. 676 // required for subclasses of iterable, etc.
685 addMetadataChildren(object, children); 677 addMetadataChildren(object, children);
686 return children.toList(); 678 return children.toList();
687 } 679 }
688 } 680 }
689 681
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 { 682 class NamedConstructorFormatter implements Formatter {
771 accept(object) => object is NamedConstructor; 683 accept(object) => object is NamedConstructor;
772 684
773 // TODO(bmilligan): Display the signature of the named constructor as the 685 // TODO(bmilligan): Display the signature of the named constructor as the
774 // preview. 686 // preview.
775 String preview(object) => 'Named Constructor'; 687 String preview(object) => 'Named Constructor';
776 688
777 bool hasChildren(object) => true; 689 bool hasChildren(object) => true;
778 690
779 List<NameValuePair> children(object) => <NameValuePair>[ 691 List<NameValuePair> children(object) => <NameValuePair>[
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
812 var typeNames = clause.types.map(getTypeName); 724 var typeNames = clause.types.map(getTypeName);
813 return '${clause.name} ${typeNames.join(", ")}'; 725 return '${clause.name} ${typeNames.join(", ")}';
814 } 726 }
815 727
816 bool hasChildren(object) => true; 728 bool hasChildren(object) => true;
817 729
818 List<NameValuePair> children(object) { 730 List<NameValuePair> children(object) {
819 HeritageClause clause = object; 731 HeritageClause clause = object;
820 var children = <NameValuePair>[]; 732 var children = <NameValuePair>[];
821 for (var type in clause.types) { 733 for (var type in clause.types) {
822 children.add(new NameValuePair(value: new ClassMetadata(type))); 734 JSNative.setProperty(type, isClass, true);
735 children.add(new NameValuePair(value: type));
823 } 736 }
824 return children; 737 return children;
825 } 738 }
826 } 739 }
827 740
828 /// Formatter for synthetic IterableSpan objects used to display contents of 741 /// Formatter for synthetic IterableSpan objects used to display contents of
829 /// an Iterable cleanly. 742 /// an Iterable cleanly.
830 class IterableSpanFormatter implements Formatter { 743 class IterableSpanFormatter implements Formatter {
831 accept(object) => object is IterableSpan; 744 accept(object) => object is IterableSpan;
832 745
(...skipping 18 matching lines...) Expand all
851 // StackTrace will be added as its own child. 764 // StackTrace will be added as its own child.
852 List<NameValuePair> children(object) => object 765 List<NameValuePair> children(object) => object
853 .toString() 766 .toString()
854 .split('\n') 767 .split('\n')
855 .map((line) => new NameValuePair( 768 .map((line) => new NameValuePair(
856 value: line.replaceFirst(new RegExp(r'^\s+at\s'), ''), 769 value: line.replaceFirst(new RegExp(r'^\s+at\s'), ''),
857 hideName: true)) 770 hideName: true))
858 .toList(); 771 .toList();
859 } 772 }
860 773
774 class ClassFormatter implements Formatter {
775 accept(object) => object is Type || safeGetProperty(object, isClass) == true;
776
777 String preview(object) {
778 // TODO(bmilligan): Tag classes with generic types with a Symbol at their
779 // creation so they can be recognized by the ClassFormatter.
780 var typeName = safeGetProperty(object, 'genericTypeName');
781 if (typeName != null) return typeName;
782 var type = _getType(object);
783 var implements = dart.getImplements(type);
784 typeName = getTypeName(type);
785 if (implements != null) {
786 var typeNames = implements().map(getTypeName);
787 return '${typeName} implements ${typeNames.join(", ")}';
788 } else {
789 return typeName;
790 }
791 }
792
793 bool hasChildren(object) => true;
794
795 List<NameValuePair> children(object) {
796 // TODO(jacobr): add other entries describing the class such as
797 // links to the superclass, mixins, implemented interfaces, and methods.
798 var type = _getType(object);
799 var children = <NameValuePair>[];
800 var typeName = getTypeName(_getType(object));
801 var mixins = dart.getMixins(type);
802 if (mixins != null && mixins.isNotEmpty) {
803 children.add(new NameValuePair(
804 name: '[[Mixins]]', value: new HeritageClause('mixins', mixins)));
805 }
806
807 var hiddenProperties = ['length', 'name', 'prototype', 'genericTypeName'];
808 // Addition of NameValuePairs for static variables and named constructors.
809 for (var name in getOwnPropertyNames(object)) {
810 // TODO(bmilligan): Perform more principled checks to filter out spurious
811 // members.
812 if (hiddenProperties.contains(name)) continue;
813 var value = safeGetProperty(object, name);
814 if (value != null && dart.getIsNamedConstructor(value) != null) {
815 value = new NamedConstructor(value);
816 name = '${typeName}.$name';
817 }
818 children.add(new NameValuePair(name: name, value: value));
819 }
820
821 // TODO(bmilligan): Replace the hard coding of $identityHash.
822 var hiddenPrototypeProperties = ['constructor', 'new', r'$identityHash'];
823 // Addition of class methods.
824 var prototype = JS('var', '#["prototype"]', object);
825 if (prototype != null) {
826 for (var name in getOwnPropertyNames(prototype)) {
827 if (hiddenPrototypeProperties.contains(name)) continue;
828 // Simulate dart.bind by using dart.tag and tear off the function
829 // so it will be recognized by the FunctionFormatter.
830 var function = safeGetProperty(prototype, name);
831 var constructor = safeGetProperty(prototype, 'constructor');
832 var sigObj = dart.getMethodSig(constructor);
833 if (sigObj != null) {
834 var value = safeGetProperty(sigObj, name);
835 if (getTypeName(dart.getReifiedType(value)) != 'Null') {
836 dart.tag(function, value);
837 children.add(new NameValuePair(name: name, value: function));
838 }
839 }
840 }
841 }
842 return children;
843 }
844 }
845
861 /// This entry point is automatically invoked by the code generated by 846 /// This entry point is automatically invoked by the code generated by
862 /// Dart Dev Compiler 847 /// Dart Dev Compiler
863 registerDevtoolsFormatter() { 848 registerDevtoolsFormatter() {
864 var formatters = [_devtoolsFormatter]; 849 var formatters = [_devtoolsFormatter];
865 JS('', 'dart.global.devtoolsFormatters = #', formatters); 850 JS('', 'dart.global.devtoolsFormatters = #', formatters);
866 } 851 }
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