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

Unified Diff: tool/input_sdk/private/debugger.dart

Issue 2164763005: Library custom formatters (Closed) Base URL: https://github.com/dart-lang/dev_compiler.git@master
Patch Set: Pub upgrade 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « tool/input_sdk/private/ddc_runtime/rtti.dart ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: tool/input_sdk/private/debugger.dart
diff --git a/tool/input_sdk/private/debugger.dart b/tool/input_sdk/private/debugger.dart
index ed6450550e965282b8e7d18041a041ba0c8738ae..4072a5a0268f3294ccf05e9f6893f99aa5b4e047 100644
--- a/tool/input_sdk/private/debugger.dart
+++ b/tool/input_sdk/private/debugger.dart
@@ -170,10 +170,25 @@ class IterableSpan {
}
}
+class Library {
+ Library(this.name, this.object);
+
+ final String name;
+ final Object object;
+}
+
+class NamedConstructor {
+ NamedConstructor(this.object);
+
+ final Object object;
+}
+
class ClassMetadata {
ClassMetadata(this.object);
final Object object;
+ String get name =>
+ getTypeName(object is Type ? object : dart.getReifiedType(object));
}
class HeritageClause {
@@ -333,9 +348,10 @@ class DartFormatter {
List<Formatter> _formatters;
DartFormatter() {
- // The order of formatters matters as formatters later in the list take
- // precidence.
+ // The order of formatters matters as formatters earlier in the list take
+ // precedence.
_formatters = [
+ new NamedConstructorFormatter(),
new FunctionFormatter(),
new MapFormatter(),
new IterableFormatter(),
@@ -343,6 +359,8 @@ class DartFormatter {
new IterableSpanFormatter(),
new ClassMetadataFormatter(),
new HeritageClauseFormatter(),
+ new ModuleLibraryFormatter(),
+ new LibraryFormatter(),
new ObjectFormatter(),
];
}
@@ -414,16 +432,8 @@ class ObjectFormatter extends Formatter {
// Set of property names used to avoid duplicates.
addMetadataChildren(object, properties);
- /// Helper to add members walking up the prototype chain being careful
- /// to avoid properties that are Dart methods.
- var protoChain = <Object>[];
var current = object;
- while (current != null &&
- !isNativeJavaScriptObject(current) &&
- JS("bool", "# !== Object.prototype", current)) {
- protoChain.add(current);
- current = JSNative.getProperty(current, '__proto__');
- }
+ var protoChain = getProtoChain(current);
// We walk the prototype chain for symbol properties because they take
// priority and are accessed instead of Dart properties according to Dart
@@ -445,12 +455,7 @@ class ObjectFormatter extends Formatter {
// start with an _
continue;
}
- var value;
- try {
- value = JSNative.getProperty(object, symbol);
- } catch (e) {
- value = '<Exception thrown> $e';
- }
+ var value = getPropertyValue(object, symbol);
properties.add(new NameValuePair(name: dartName, value: value));
}
}
@@ -464,12 +469,7 @@ class ObjectFormatter extends Formatter {
if (hasMethod(object, name)) {
continue;
}
- var value;
- try {
- value = JSNative.getProperty(object, name);
- } catch (e) {
- value = '<Exception thrown> $e';
- }
+ var value = getPropertyValue(object, name);
properties.add(new NameValuePair(name: name, value: value));
}
}
@@ -478,8 +478,100 @@ class ObjectFormatter extends Formatter {
}
addMetadataChildren(object, Set<NameValuePair> ret) {
- ret.add(
- new NameValuePair(name: '[[class]]', value: new ClassMetadata(object)));
+ var value = new ClassMetadata(object);
+ ret.add(new NameValuePair(name: value.name, value: value));
+ }
+
+ Object getPropertyValue(Object object, String name) {
Alan Knight 2016/07/21 17:44:48 It's better to avoid "get" as a prefix (even thoug
bmilligan 2016/07/22 18:25:19 Jacob suggested safeGetProperty. Are you referring
Alan Knight 2016/07/22 20:28:41 safeGetProperty seems reasonable. I was referring
bmilligan 2016/07/22 20:47:40 Done.
+ var value;
+ try {
+ value = JSNative.getProperty(object, name);
+ } catch (e) {
+ value = '<Exception thrown> $e';
+ }
+ return value;
+ }
+
+ /// Helper to add members walking up the prototype chain being careful
+ /// to avoid properties that are Dart methods.
Alan Knight 2016/07/21 17:44:49 What does the comment mean about being careful to
bmilligan 2016/07/22 18:25:18 This function existed previously, I just moved it
Alan Knight 2016/07/22 20:28:41 I'm suspicious it got moved to the wrong place som
bmilligan 2016/07/22 20:47:40 Done.
+ List<Object> getProtoChain(var current) {
Alan Knight 2016/07/21 17:44:49 Don't put "var" on a method parameter, either leav
bmilligan 2016/07/22 18:25:19 Done.
+ var protoChain = <Object>[];
+ while (current != null &&
+ !isNativeJavaScriptObject(current) &&
+ JS("bool", "# !== Object.prototype", current)) {
+ protoChain.add(current);
Alan Knight 2016/07/21 17:44:49 Naming an input parameter "current" feels odd. Al
bmilligan 2016/07/22 18:25:19 Done.
+ current = JSNative.getProperty(current, '__proto__');
+ }
+ return protoChain;
+ }
+}
+
+/// Formatter for module Dart Library objects.
Alan Knight 2016/07/21 17:44:49 What's the difference between a module dart librar
bmilligan 2016/07/22 18:25:18 The dart library module is an object that contains
Alan Knight 2016/07/22 20:28:41 Acknowledged.
+class ModuleLibraryFormatter extends ObjectFormatter {
+ String libraryName;
+
+ accept(object) {
+ var current = object;
+ var protoChain = getProtoChain(current);
+ for (current in protoChain) {
Alan Knight 2016/07/21 17:44:49 Using a for loop variable that's declared and init
bmilligan 2016/07/22 18:25:19 Yeah, I switched this part to be identifiable by s
+ for (var symbol in getOwnPropertySymbols(current)) {
+ if (symbolName(symbol) == 'dartLibraryName') {
+ libraryName = JSNative.getProperty(current, symbol);
Alan Knight 2016/07/21 17:44:49 We now have a function for this, so we should use
bmilligan 2016/07/22 18:25:19 Done.
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ bool hasChildren(object) => true;
+
+ String preview(object) {
+ var libraryNameArray = libraryName.split('/');
Alan Knight 2016/07/21 17:44:49 Better to just call this "libraryNames", makes the
bmilligan 2016/07/22 18:25:19 Done.
+ if (libraryNameArray.length > 1) {
+ libraryNameArray[libraryNameArray.length - 1] = '';
+ }
+ return 'Library Module: ${libraryNameArray.join('/')}';
+ }
+
+ List<NameValuePair> children(object) {
+ var properties = new LinkedHashSet<NameValuePair>();
Alan Knight 2016/07/21 17:44:49 These are linked because we want to preserve the J
bmilligan 2016/07/22 18:25:19 The JS order is already alphabetical. It's nice to
Alan Knight 2016/07/22 20:28:41 Acknowledged.
+ for (var name in getOwnPropertyNames(object)) {
+ var value = JSNative.getProperty(object, name);
Alan Knight 2016/07/21 17:44:49 Shouldn't this, and similarly below be calling our
bmilligan 2016/07/22 18:25:18 Done.
+ name = name.replaceAll('__', '/') + '.dart';
Alan Knight 2016/07/21 17:44:49 A comment for the replacement would be good.
bmilligan 2016/07/22 18:25:18 Done.
+ properties.add(new NameValuePair(
+ name: name, value: new Library(name, value), hideName: true));
+ }
+ return properties.toList();
+ }
+}
+
+/// Formatter for Dart Library objects.
+class LibraryFormatter extends ObjectFormatter {
+ accept(object) => object is Library;
+
+ bool hasChildren(object) => true;
+
+ String preview(object) => object.name;
+
+ List<NameValuePair> children(object) {
+ var properties = new LinkedHashSet<NameValuePair>();
Alan Knight 2016/07/21 17:44:49 Should this just be called "children"?
bmilligan 2016/07/22 18:25:18 Done.
+ var entry = object.object;
+ for (var name in getOwnPropertyNames(entry)) {
+ var value = getPropertyValue(entry, name);
+ // TODO(bmilligan): Make a note on the corresponding class object that it
+ // has a generic type.
+ if (JSNative.getProperty(value, 'name') == 'makeGenericType') {
+ continue;
+ } else if (value is Type) {
+ var classMetadata = new ClassMetadata(value);
+ properties.add(
+ new NameValuePair(name: classMetadata.name, value: classMetadata));
+ } else {
+ properties.add(new NameValuePair(name: name, value: value));
+ }
+ }
+ return properties.toList();
}
}
@@ -566,7 +658,7 @@ class IterableFormatter extends ObjectFormatter {
}
// This class does double duting displaying metadata for
-class ClassMetadataFormatter implements Formatter {
+class ClassMetadataFormatter extends ObjectFormatter {
accept(object) => object is ClassMetadata;
_getType(object) {
@@ -576,47 +668,96 @@ class ClassMetadataFormatter implements Formatter {
String preview(object) {
ClassMetadata entry = object;
- return getTypeName(_getType(entry.object));
+ var type =
+ entry.object is Type ? entry.object : dart.getReifiedType(entry.object);
+ var implements = dart.getImplements(type);
+ var ret = getTypeName(type);
Alan Knight 2016/07/21 17:44:48 var typeName?
bmilligan 2016/07/22 18:25:19 Done.
+ if (implements != null) {
+ var typeNames = implements().map((type) => getTypeName(type));
Alan Knight 2016/07/21 17:44:49 If you're just calling a one argument function/met
bmilligan 2016/07/22 18:25:18 Done.
+ return ret + ' implements ${typeNames.join(", ")}';
Alan Knight 2016/07/21 17:44:49 Really nitpicking it's slightly better to use an i
bmilligan 2016/07/22 18:25:19 Done.
+ } else {
+ return ret;
+ }
}
bool hasChildren(object) => true;
List<NameValuePair> children(object) {
ClassMetadata entry = object;
+ var classObject = entry.object;
// TODO(jacobr): add other entries describing the class such as
// links to the superclass, mixins, implemented interfaces, and methods.
- var type = _getType(entry.object);
+ var type = _getType(classObject);
var ret = <NameValuePair>[];
Alan Knight 2016/07/21 17:44:49 Also better as "children"
bmilligan 2016/07/22 18:25:19 Done.
- var implements = dart.getImplements(type);
- if (implements != null) {
- ret.add(new NameValuePair(
- name: '[[Implements]]',
- value: new HeritageClause('implements', implements())));
- }
+
var mixins = dart.getMixins(type);
if (mixins != null && mixins.isNotEmpty) {
ret.add(new NameValuePair(
name: '[[Mixins]]', value: new HeritageClause('mixins', mixins)));
}
- ret.add(new NameValuePair(
- name: '[[JavaScript View]]',
- value: entry.object,
- config: JsonMLConfig.skipDart));
- // TODO(jacobr): provide a link to the base class or perhaps the entire
- // base class hierarchy as a flat list.
+ // Addition of NameValuePairs for static variables and named constructors.
+ for (var name in getOwnPropertyNames(classObject)) {
+ if (name == 'length' || name == 'name' || name == 'prototype') continue;
Alan Knight 2016/07/21 17:44:49 This would be better in a separate list of propert
bmilligan 2016/07/22 18:25:18 Done.
+ var value = getPropertyValue(classObject, name);
+ for (var symbol in getOwnPropertySymbols(value)) {
+ if (symbolName(symbol) == 'isNamedConstructor') {
+ value = new NamedConstructor(value);
+ name = entry.name + '.' + name;
+ }
+ }
+ ret.add(new NameValuePair(name: name, value: value));
+ }
- if (entry.object is! Type) {
- ret.add(new NameValuePair(
- name: '[[JavaScript Constructor]]',
- value: JSNative.getProperty(entry.object, 'constructor'),
- config: JsonMLConfig.skipDart));
- // TODO(jacobr): add constructors, methods, extended class, and static
+ // Addition of class methods.
+ var prototype = JS('var', '#["prototype"]', classObject);
+ if (prototype != null) {
+ for (var name in getOwnPropertyNames(prototype)) {
+ if (name == 'constructor' ||
+ name == 'new' ||
Alan Knight 2016/07/21 17:44:49 Also better in a separate list.
bmilligan 2016/07/22 18:25:19 Done.
+ name == r'$identityHash') {
+ continue;
+ }
+ // Simulate dart.bind by using dart.tag and tear off the function
+ // so it will be recognized by the FunctionFormatter.
+ var function = getPropertyValue(prototype, name);
+ var constructor = getPropertyValue(prototype, 'constructor');
Alan Knight 2016/07/21 17:44:49 Also, I would think, call our wrapper for this. I
bmilligan 2016/07/22 18:25:18 Done.
+ for (var symbol in getOwnPropertySymbols(constructor)) {
+ if (symbolName(symbol) == 'sig') {
+ var sigObj = getPropertyValue(constructor, symbol);
+ var value = getPropertyValue(sigObj, name);
+ if (getTypeName(dart.getReifiedType(value)) != 'Null') {
+ dart.tag(function, value);
+ ret.add(new NameValuePair(name: name, value: function));
+ }
+ }
+ }
+ }
}
+ // TODO(jacobr): provide a link to the base class or perhaps the entire
+ // base class hierarchy as a flat list.
+ // TODO(jacobr): add constructors, methods, extended class, and static
return ret;
}
}
+class NamedConstructorFormatter implements Formatter {
+ accept(object) => object is NamedConstructor;
+
+ // TODO(bmilligan): Display the signature of the named constructor as the
+ // preview.
+ String preview(object) => 'Named Constructor';
+
+ bool hasChildren(object) => true;
+
+ List<NameValuePair> children(object) => <NameValuePair>[
+ new NameValuePair(
+ name: 'JavaScript Function',
+ value: object,
+ config: JsonMLConfig.skipDart)
+ ];
+}
+
/// Formatter for synthetic MapEntry objects used to display contents of a Map
/// cleanly.
class MapEntryFormatter implements Formatter {
« no previous file with comments | « tool/input_sdk/private/ddc_runtime/rtti.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698