Commit eccdf694 authored by Erik Luo's avatar Erik Luo Committed by Commit Bot

DevTools: show internal properties first in object preview

This CL prepares the DevTools frontend to specially format objects with
these internal properties:
- [[PrimitiveValue]] > shows this value in preview alone
- [[PromiseStatus]] + [[PromiseValue]] > shows '<resolved>: "foo"'
- [[GeneratorStatus]] > shows '<suspended>'

Screenshot: http://imgur.com/a/r3rXE

Bug: 567265
Change-Id: Ic14f361e6c2402340a4f3d30bcf255ed362663c6
Reviewed-on: https://chromium-review.googlesource.com/604938
Commit-Queue: Erik Luo <luoe@chromium.org>
Reviewed-by: default avatarDmitry Gozman <dgozman@chromium.org>
Reviewed-by: default avatarBlaise Bruer <allada@chromium.org>
Cr-Commit-Position: refs/heads/master@{#504220}
parent 8a7ab212
Tests that console properly displays information about ES6 features.
console-format-es6.js:15 Promise {[[PromiseStatus]]: "rejected", [[PromiseValue]]: -0}
console-format-es6.js:15 Promise {<rejected>: -0}
console-format-es6.js:16 [Promise]
globals[0]
Promise {[[PromiseStatus]]: "rejected", [[PromiseValue]]: -0}
Promise {<rejected>: -0}
console-format-es6.js:15 Promise {<resolved>: 1}
console-format-es6.js:16 [Promise]
globals[1]
Promise {<resolved>: 1}
console-format-es6.js:15 Promise {<pending>}
console-format-es6.js:16 [Promise]
globals[2]
Promise {<pending>}
console-format-es6.js:15 Symbol()
console-format-es6.js:16 [Symbol()]
globals[1]
globals[3]
Symbol()
console-format-es6.js:15 Symbol(a)
console-format-es6.js:16 [Symbol(a)]
globals[2]
globals[4]
Symbol(a)
console-format-es6.js:15 {a: Symbol(), Symbol(a): 2}
console-format-es6.js:16 [{…}]
globals[3]
globals[5]
{a: Symbol(), Symbol(a): 2}
console-format-es6.js:15 Map(1) {{…} => {…}}
console-format-es6.js:16 [Map(1)]
globals[4]
globals[6]
Map(1) {{…} => {…}}
console-format-es6.js:15 WeakMap {{…} => {…}}
console-format-es6.js:16 [WeakMap]
globals[5]
globals[7]
WeakMap {{…} => {…}}
console-format-es6.js:15 Set(1) {{…}}
console-format-es6.js:16 [Set(1)]
globals[6]
globals[8]
Set(1) {{…}}
console-format-es6.js:15 WeakSet {{…}}
console-format-es6.js:16 [WeakSet]
globals[7]
globals[9]
WeakSet {{…}}
console-format-es6.js:15 Map(1) {Map(0) => WeakMap}
console-format-es6.js:16 [Map(1)]
globals[8]
globals[10]
Map(1) {Map(0) => WeakMap}
console-format-es6.js:15 Map(1) {Map(1) => WeakMap}
console-format-es6.js:16 [Map(1)]
globals[9]
globals[11]
Map(1) {Map(1) => WeakMap}
console-format-es6.js:15 Set(1) {WeakSet}
console-format-es6.js:16 [Set(1)]
globals[10]
globals[12]
Set(1) {WeakSet}
console-format-es6.js:15 Set(1) {WeakSet}
console-format-es6.js:16 [Set(1)]
globals[11]
globals[13]
Set(1) {WeakSet}
console-format-es6.js:15 Map(6) {" from str " => " to str ", undefined => undefined, null => null, 42 => 42, {…} => {…}, …}
console-format-es6.js:16 [Map(6)]
globals[12]
globals[14]
Map(6) {" from str " => " to str ", undefined => undefined, null => null, 42 => 42, {…} => {…}, …}
console-format-es6.js:15 genFunction {[[GeneratorStatus]]: "suspended"}
console-format-es6.js:15 genFunction {<suspended>}
console-format-es6.js:16 [genFunction]
globals[13]
genFunction {[[GeneratorStatus]]: "suspended"}
globals[15]
genFunction {<suspended>}
Expanded all messages
console-format-es6.js:15 Promise {[[PromiseStatus]]: "rejected", [[PromiseValue]]: -0}
console-format-es6.js:15 Promise {<rejected>: -0}
__proto__: Promise
[[PromiseStatus]]: "rejected"
[[PromiseValue]]: -0
console-format-es6.js:16 [Promise]
0: Promise {[[PromiseStatus]]: "rejected", [[PromiseValue]]: -0}
0: Promise {<rejected>: -0}
length: 1
__proto__: Array(0)
globals[0]
Promise {[[PromiseStatus]]: "rejected", [[PromiseValue]]: -0}
Promise {<rejected>: -0}
__proto__: Promise
[[PromiseStatus]]: "rejected"
[[PromiseValue]]: -0
console-format-es6.js:15 Promise {<resolved>: 1}
__proto__: Promise
[[PromiseStatus]]: "resolved"
[[PromiseValue]]: 1
console-format-es6.js:16 [Promise]
0: Promise {<resolved>: 1}
length: 1
__proto__: Array(0)
globals[1]
Promise {<resolved>: 1}
__proto__: Promise
[[PromiseStatus]]: "resolved"
[[PromiseValue]]: 1
console-format-es6.js:15 Promise {<pending>}
__proto__: Promise
[[PromiseStatus]]: "pending"
[[PromiseValue]]: undefined
console-format-es6.js:16 [Promise]
0: Promise {<pending>}
length: 1
__proto__: Array(0)
globals[2]
Promise {<pending>}
__proto__: Promise
[[PromiseStatus]]: "pending"
[[PromiseValue]]: undefined
console-format-es6.js:15 Symbol()
console-format-es6.js:16 [Symbol()]
0: Symbol()
length: 1
__proto__: Array(0)
globals[1]
globals[3]
Symbol()
console-format-es6.js:15 Symbol(a)
console-format-es6.js:16 [Symbol(a)]
0: Symbol(a)
length: 1
__proto__: Array(0)
globals[2]
globals[4]
Symbol(a)
console-format-es6.js:15 {a: Symbol(), Symbol(a): 2}
a: Symbol()
......@@ -94,7 +128,7 @@ console-format-es6.js:16 [{…}]
0: {a: Symbol(), Symbol(a): 2}
length: 1
__proto__: Array(0)
globals[3]
globals[5]
{a: Symbol(), Symbol(a): 2}
a: Symbol()
getter: (...)
......@@ -111,7 +145,7 @@ console-format-es6.js:16 [Map(1)]
0: Map(1) {{…} => {…}}
length: 1
__proto__: Array(0)
globals[4]
globals[6]
Map(1) {{…} => {…}}
size: (...)
__proto__: Map
......@@ -127,7 +161,7 @@ console-format-es6.js:16 [WeakMap]
0: WeakMap {{…} => {…}}
length: 1
__proto__: Array(0)
globals[5]
globals[7]
WeakMap {{…} => {…}}
__proto__: WeakMap
[[Entries]]: Array(1)
......@@ -143,7 +177,7 @@ console-format-es6.js:16 [Set(1)]
0: Set(1) {{…}}
length: 1
__proto__: Array(0)
globals[6]
globals[8]
Set(1) {{…}}
size: (...)
__proto__: Set
......@@ -159,7 +193,7 @@ console-format-es6.js:16 [WeakSet]
0: WeakSet {{…}}
length: 1
__proto__: Array(0)
globals[7]
globals[9]
WeakSet {{…}}
__proto__: WeakSet
[[Entries]]: Array(1)
......@@ -175,7 +209,7 @@ console-format-es6.js:16 [Map(1)]
0: Map(1) {Map(0) => WeakMap}
length: 1
__proto__: Array(0)
globals[8]
globals[10]
Map(1) {Map(0) => WeakMap}
size: (...)
__proto__: Map
......@@ -192,7 +226,7 @@ console-format-es6.js:16 [Map(1)]
0: Map(1) {Map(1) => WeakMap}
length: 1
__proto__: Array(0)
globals[9]
globals[11]
Map(1) {Map(1) => WeakMap}
size: (...)
__proto__: Map
......@@ -209,7 +243,7 @@ console-format-es6.js:16 [Set(1)]
0: Set(1) {WeakSet}
length: 1
__proto__: Array(0)
globals[10]
globals[12]
Set(1) {WeakSet}
size: (...)
__proto__: Set
......@@ -226,7 +260,7 @@ console-format-es6.js:16 [Set(1)]
0: Set(1) {WeakSet}
length: 1
__proto__: Array(0)
globals[11]
globals[13]
Set(1) {WeakSet}
size: (...)
__proto__: Set
......@@ -248,7 +282,7 @@ console-format-es6.js:16 [Map(6)]
0: Map(6) {" from str " => " to str ", undefined => undefined, null => null, 42 => 42, {…} => {…}, …}
length: 1
__proto__: Array(0)
globals[12]
globals[14]
Map(6) {" from str " => " to str ", undefined => undefined, null => null, 42 => 42, {…} => {…}, …}
size: (...)
__proto__: Map
......@@ -260,23 +294,23 @@ Map(6) {" from str " => " to str ", undefined => undefined, null => null, 42 =>
4: {Object => Object}
5: {Array(1) => Array(1)}
length: 6
console-format-es6.js:15 genFunction {[[GeneratorStatus]]: "suspended"}
console-format-es6.js:15 genFunction {<suspended>}
__proto__: Generator
[[GeneratorStatus]]: "suspended"
[[GeneratorFunction]]: ƒ *()
[[GeneratorFunction]]: ƒ* ()
[[GeneratorReceiver]]: Window
[[GeneratorLocation]]: console-format-es6.js:59
[[GeneratorLocation]]: console-format-es6.js:62
[[Scopes]]: Scopes[2]
console-format-es6.js:16 [genFunction]
0: genFunction {[[GeneratorStatus]]: "suspended"}
0: genFunction {<suspended>}
length: 1
__proto__: Array(0)
globals[13]
genFunction {[[GeneratorStatus]]: "suspended"}
globals[15]
genFunction {<suspended>}
__proto__: Generator
[[GeneratorStatus]]: "suspended"
[[GeneratorFunction]]: ƒ *()
[[GeneratorFunction]]: ƒ* ()
[[GeneratorReceiver]]: Window
[[GeneratorLocation]]: console-format-es6.js:59
[[GeneratorLocation]]: console-format-es6.js:62
[[Scopes]]: Scopes[2]
......@@ -20,6 +20,9 @@
var p = Promise.reject(-0);
p.catch(function() {});
var p2 = Promise.resolve(1);
var p3 = new Promise(() => {});
var smb1 = Symbol();
var smb2 = Symbol("a");
var obj = {
......@@ -63,7 +66,7 @@
var generator = genFunction();
globals = [
p, smb1, smb2, obj, map, weakMap, set, weakSet,
p, p2, p3, smb1, smb2, obj, map, weakMap, set, weakSet,
mapMap0, mapMap, setSet0, setSet, bigmap, generator
];
......
......@@ -81,13 +81,22 @@ function onload()
var bigArray = [];
bigArray.length = 200;
bigArray.fill(1);
var boxedNumberWithProps = new Number(42);
boxedNumberWithProps[1] = "foo";
boxedNumberWithProps["a"] = "bar";
var boxedStringWithProps = new String("abc");
boxedStringWithProps["01"] = "foo";
boxedStringWithProps[3] = "foo";
boxedStringWithProps["a"] = "bar";
globals = [
regex1, regex2, str, str2, error, errorWithMessage, errorWithMultilineMessage, node, func, multilinefunc,
num, linkify, null, undefined, valuelessAttribute, valuedAttribute, existingAttribute, throwingLengthGetter,
NaN, Number.POSITIVE_INFINITY, Number.NEGATIVE_INFINITY, array, {}, [function() {}], bar, svg,
objectWithNonEnumerables, negZero, Object.create(null), Object, Object.prototype, arrayLikeFunction,
new Number(42), new String("abc"), new Uint16Array([1, 2, 3]), textNode, domException(),
tinyTypedArray, smallTypedArray, bigTypedArray, instanceWithLongClassName, bigArray, singleArray
tinyTypedArray, smallTypedArray, bigTypedArray, instanceWithLongClassName, bigArray, singleArray,
boxedNumberWithProps, boxedStringWithProps
];
runTest();
......
......@@ -102,6 +102,10 @@ CONSOLE MESSAGE: line 12: 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
CONSOLE MESSAGE: line 13: 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
CONSOLE MESSAGE: line 12: test
CONSOLE MESSAGE: line 13: test
CONSOLE MESSAGE: line 12: 42.0000
CONSOLE MESSAGE: line 13: 42.0000
CONSOLE MESSAGE: line 12: abc
CONSOLE MESSAGE: line 13: abc
Tests that console logging dumps proper messages.
console-format.html:22 Array(10)
......@@ -259,14 +263,14 @@ console-format.html:8 [ƒ]
globals[31]
ƒ ( /**/ foo/**/, /*/**/bar,
/**/baz) {}
console-format.html:7 Number {[[PrimitiveValue]]: 42}
console-format.html:7 Number {42}
console-format.html:8 [Number]
globals[32]
Number {[[PrimitiveValue]]: 42}
console-format.html:7 String {[[PrimitiveValue]]: "abc"}
Number {42}
console-format.html:7 String {"abc"}
console-format.html:8 [String]
globals[33]
String {[[PrimitiveValue]]: "abc"}
String {"abc"}
console-format.html:7 Uint16Array(3) [1, 2, 3]
console-format.html:8 [Uint16Array(3)]
globals[34]
......@@ -303,6 +307,14 @@ console-format.html:7 ["test"]
console-format.html:8 [Array(1)]
globals[42]
["test"]
console-format.html:7 Number {42, 1: "foo", a: "bar"}
console-format.html:8 [Number]
globals[43]
Number {42, 1: "foo", a: "bar"}
console-format.html:7 String {"abc", 3: "foo", 01: "foo", a: "bar"}
console-format.html:8 [String]
globals[44]
String {"abc", 3: "foo", 01: "foo", a: "bar"}
Expanded all messages
console-format.html:22 Array(10)
0: "test"
......@@ -650,18 +662,18 @@ console-format.html:8 [ƒ]
globals[31]
ƒ ( /**/ foo/**/, /*/**/bar,
/**/baz) {}
console-format.html:7 Number {[[PrimitiveValue]]: 42}
console-format.html:7 Number {42}
__proto__: Number
[[PrimitiveValue]]: 42
console-format.html:8 [Number]
0: Number {[[PrimitiveValue]]: 42}
0: Number {42}
length: 1
__proto__: Array(0)
globals[32]
Number {[[PrimitiveValue]]: 42}
Number {42}
__proto__: Number
[[PrimitiveValue]]: 42
console-format.html:7 String {[[PrimitiveValue]]: "abc"}
console-format.html:7 String {"abc"}
0: "a"
1: "b"
2: "c"
......@@ -669,11 +681,11 @@ console-format.html:7 String {[[PrimitiveValue]]: "abc"}
__proto__: String
[[PrimitiveValue]]: "abc"
console-format.html:8 [String]
0: String {[[PrimitiveValue]]: "abc"}
0: String {"abc"}
length: 1
__proto__: Array(0)
globals[33]
String {[[PrimitiveValue]]: "abc"}
String {"abc"}
0: "a"
1: "b"
2: "c"
......@@ -813,4 +825,44 @@ globals[42]
0: "test"
length: 1
__proto__: Array(0)
console-format.html:7 Number {42, 1: "foo", a: "bar"}
1: "foo"
a: "bar"
__proto__: Number
[[PrimitiveValue]]: 42
console-format.html:8 [Number]
0: Number {42, 1: "foo", a: "bar"}
length: 1
__proto__: Array(0)
globals[43]
Number {42, 1: "foo", a: "bar"}
1: "foo"
a: "bar"
__proto__: Number
[[PrimitiveValue]]: 42
console-format.html:7 String {"abc", 3: "foo", 01: "foo", a: "bar"}
0: "a"
01: "foo"
1: "b"
2: "c"
3: "foo"
a: "bar"
length: 3
__proto__: String
[[PrimitiveValue]]: "abc"
console-format.html:8 [String]
0: String {"abc", 3: "foo", 01: "foo", a: "bar"}
length: 1
__proto__: Array(0)
globals[44]
String {"abc", 3: "foo", 01: "foo", a: "bar"}
0: "a"
01: "foo"
1: "b"
2: "c"
3: "foo"
a: "bar"
length: 3
__proto__: String
[[PrimitiveValue]]: "abc"
......@@ -11,11 +11,24 @@ ObjectUI.RemoteObjectPreviewFormatter = class {
* @return {number}
*/
static _objectPropertyComparator(a, b) {
if (a.type !== 'function' && b.type === 'function')
return -1;
if (a.type === 'function' && b.type !== 'function')
return 1;
return 0;
return sortValue(a) - sortValue(b);
/**
* @param {!Protocol.Runtime.PropertyPreview} property
* @return {number}
*/
function sortValue(property) {
var internalName = ObjectUI.RemoteObjectPreviewFormatter._internalName;
if (property.name === internalName.PromiseStatus)
return 1;
else if (property.name === internalName.PromiseValue)
return 2;
else if (property.name === internalName.GeneratorStatus || internalName.PrimitiveValue)
return 3;
else if (property.type !== 'function')
return 4;
return 5;
}
}
/**
......@@ -79,6 +92,7 @@ ObjectUI.RemoteObjectPreviewFormatter = class {
* @param {!Protocol.Runtime.ObjectPreview} preview
*/
_appendObjectPropertiesPreview(parentElement, preview) {
var internalName = ObjectUI.RemoteObjectPreviewFormatter._internalName;
var properties = preview.properties.filter(p => p.type !== 'accessor')
.stableSort(ObjectUI.RemoteObjectPreviewFormatter._objectPropertyComparator);
for (var i = 0; i < properties.length; ++i) {
......@@ -86,9 +100,27 @@ ObjectUI.RemoteObjectPreviewFormatter = class {
parentElement.createTextChild(', ');
var property = properties[i];
parentElement.appendChild(this._renderDisplayName(property.name));
parentElement.createTextChild(': ');
parentElement.appendChild(this._renderPropertyPreviewOrAccessor([property]));
var name = property.name;
// Internal properties are given special formatting, e.g. Promises `<rejected>: 123`.
if (preview.subtype === 'promise' && name === internalName.PromiseStatus) {
parentElement.appendChild(this._renderDisplayName('<' + property.value + '>'));
var nextProperty = i + 1 < properties.length ? properties[i + 1] : null;
if (nextProperty && nextProperty.name === internalName.PromiseValue) {
if (property.value !== 'pending') {
parentElement.createTextChild(': ');
parentElement.appendChild(this._renderPropertyPreviewOrAccessor([nextProperty]));
}
i++;
}
} else if (preview.subtype === 'generator' && name === internalName.GeneratorStatus) {
parentElement.appendChild(this._renderDisplayName('<' + property.value + '>'));
} else if (name === internalName.PrimitiveValue) {
parentElement.appendChild(this._renderPropertyPreviewOrAccessor([property]));
} else {
parentElement.appendChild(this._renderDisplayName(name));
parentElement.createTextChild(': ');
parentElement.appendChild(this._renderPropertyPreviewOrAccessor([property]));
}
}
}
......@@ -255,3 +287,11 @@ ObjectUI.RemoteObjectPreviewFormatter = class {
return span;
}
};
/** @enum {string} */
ObjectUI.RemoteObjectPreviewFormatter._internalName = {
GeneratorStatus: '[[GeneratorStatus]]',
PrimitiveValue: '[[PrimitiveValue]]',
PromiseStatus: '[[PromiseStatus]]',
PromiseValue: '[[PromiseValue]]'
};
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment