зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1301794 - Allow sparse pseudo-arrays in console r=fitzgen
This commit is contained in:
Родитель
2c371e5b30
Коммит
388d2d0e89
|
@ -145,10 +145,11 @@ var inputTests = [
|
||||||
input: "new Object({1: 'this\\nis\\nsupposed\\nto\\nbe\\na\\nvery" +
|
input: "new Object({1: 'this\\nis\\nsupposed\\nto\\nbe\\na\\nvery" +
|
||||||
"\\nlong\\nstring\\n,shown\\non\\na\\nsingle\\nline', " +
|
"\\nlong\\nstring\\n,shown\\non\\na\\nsingle\\nline', " +
|
||||||
"2: 'a shorter string', 3: 100})",
|
"2: 'a shorter string', 3: 100})",
|
||||||
output: 'Object { 1: "this is supposed to be a very long ' + ELLIPSIS +
|
output: '[ <1 empty slot>, "this is supposed to be a very long ' + ELLIPSIS +
|
||||||
'", 2: "a shorter string", 3: 100 }',
|
'", "a shorter string", 100 ]',
|
||||||
printOutput: "[object Object]",
|
printOutput: "[object Object]",
|
||||||
inspectable: false,
|
inspectable: true,
|
||||||
|
variablesViewLabel: "Object[4]"
|
||||||
},
|
},
|
||||||
|
|
||||||
// 15
|
// 15
|
||||||
|
|
|
@ -131,10 +131,10 @@ var inputTests = [
|
||||||
// 14
|
// 14
|
||||||
{
|
{
|
||||||
input: '({0: "a", 42: "b"})',
|
input: '({0: "a", 42: "b"})',
|
||||||
output: 'Object { 0: "a", 42: "b" }',
|
output: '[ "a", <9 empty slots>, 33 more\u2026 ]',
|
||||||
printOutput: "[object Object]",
|
printOutput: "[object Object]",
|
||||||
inspectable: true,
|
inspectable: true,
|
||||||
variablesViewLabel: "Object",
|
variablesViewLabel: "Object[43]",
|
||||||
},
|
},
|
||||||
|
|
||||||
// 15
|
// 15
|
||||||
|
@ -189,10 +189,10 @@ var inputTests = [
|
||||||
// 20
|
// 20
|
||||||
{
|
{
|
||||||
input: '({length: 1})',
|
input: '({length: 1})',
|
||||||
output: 'Object { length: 1 }',
|
output: '[ <1 empty slot> ]',
|
||||||
printOutput: "[object Object]",
|
printOutput: "[object Object]",
|
||||||
inspectable: true,
|
inspectable: true,
|
||||||
variablesViewLabel: "Object",
|
variablesViewLabel: "Object[1]",
|
||||||
},
|
},
|
||||||
|
|
||||||
// 21
|
// 21
|
||||||
|
@ -216,10 +216,10 @@ var inputTests = [
|
||||||
// 23
|
// 23
|
||||||
{
|
{
|
||||||
input: '({0: "a", 1: "b", length: 3})',
|
input: '({0: "a", 1: "b", length: 3})',
|
||||||
output: 'Object { length: 3, 2 more\u2026 }',
|
output: '[ "a", "b", <1 empty slot> ]',
|
||||||
printOutput: "[object Object]",
|
printOutput: "[object Object]",
|
||||||
inspectable: true,
|
inspectable: true,
|
||||||
variablesViewLabel: "Object",
|
variablesViewLabel: "Object[3]",
|
||||||
},
|
},
|
||||||
|
|
||||||
// 24
|
// 24
|
||||||
|
@ -234,10 +234,10 @@ var inputTests = [
|
||||||
// 25
|
// 25
|
||||||
{
|
{
|
||||||
input: '({0: "a", 2: "b", length: 3})',
|
input: '({0: "a", 2: "b", length: 3})',
|
||||||
output: 'Object { length: 3, 2 more\u2026 }',
|
output: '[ "a", <1 empty slot>, "b" ]',
|
||||||
printOutput: "[object Object]",
|
printOutput: "[object Object]",
|
||||||
inspectable: true,
|
inspectable: true,
|
||||||
variablesViewLabel: "Object",
|
variablesViewLabel: "Object[3]",
|
||||||
},
|
},
|
||||||
|
|
||||||
// 26
|
// 26
|
||||||
|
@ -257,6 +257,15 @@ var inputTests = [
|
||||||
inspectable: true,
|
inspectable: true,
|
||||||
variablesViewLabel: "Object",
|
variablesViewLabel: "Object",
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// 28
|
||||||
|
{
|
||||||
|
input: '({42: "a"})',
|
||||||
|
output: 'Object { 42: "a" }',
|
||||||
|
printOutput: "[object Object]",
|
||||||
|
inspectable: true,
|
||||||
|
variablesViewLabel: "Object",
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
function test() {
|
function test() {
|
||||||
|
|
|
@ -1793,36 +1793,45 @@ DebuggerServer.ObjectActorPreviewers.Object = [
|
||||||
},
|
},
|
||||||
|
|
||||||
function PseudoArray({obj, hooks}, grip, rawObj) {
|
function PseudoArray({obj, hooks}, grip, rawObj) {
|
||||||
let length = 0;
|
let length;
|
||||||
|
|
||||||
let keys = obj.getOwnPropertyNames();
|
let keys = obj.getOwnPropertyNames();
|
||||||
if (keys.length == 0) {
|
if (keys.length == 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pseudo-arrays should only have array indices and, optionally, a "length" property.
|
// If no item is going to be displayed in preview, better display as sparse object.
|
||||||
// Since array indices are sorted first, check if the last property is "length".
|
// The first key should contain the smallest integer index (if any).
|
||||||
if(keys[keys.length-1] === "length") {
|
if(keys[0] >= OBJECT_PREVIEW_MAX_ITEMS) {
|
||||||
keys.pop();
|
|
||||||
// The value of "length" should equal the number of other properties. If eventually
|
|
||||||
// we allow sparse pseudo-arrays, we should check whether it's a Uint32 instead.
|
|
||||||
if(rawObj.length !== keys.length) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ensure that the keys are consecutive integers starting at "0". If eventually we
|
|
||||||
// allow sparse pseudo-arrays, we should check that they are array indices, that is:
|
|
||||||
// `(key >>> 0) + '' === key && key !== "4294967295"`.
|
|
||||||
// Checking the last property first allows us to avoid useless iterations when
|
|
||||||
// there is any property which is not an array index.
|
|
||||||
if(keys.length && keys[keys.length-1] !== keys.length - 1 + '') {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
for (let key of keys) {
|
|
||||||
if (key !== (length++) + '') {
|
// Pseudo-arrays should only have array indices and, optionally, a "length" property.
|
||||||
|
// Since integer indices are sorted first, check if the last property is "length".
|
||||||
|
if(keys[keys.length-1] === "length") {
|
||||||
|
keys.pop();
|
||||||
|
length = DevToolsUtils.getProperty(obj, "length");
|
||||||
|
} else {
|
||||||
|
// Otherwise, let length be the (presumably) greatest array index plus 1.
|
||||||
|
length = +keys[keys.length-1] + 1;
|
||||||
|
}
|
||||||
|
// Check if length is a valid array length, i.e. is a Uint32 number.
|
||||||
|
if(typeof length !== "number" || length >>> 0 !== length) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure all keys are increasing array indices smaller than length. The order is not
|
||||||
|
// guaranteed for exotic objects but, in most cases, big array indices and properties
|
||||||
|
// which are not integer indices should be at the end. Then, iterating backwards
|
||||||
|
// allows us to return earlier when the object is not completely a pseudo-array.
|
||||||
|
let prev = length;
|
||||||
|
for(let i = keys.length - 1; i >= 0; --i) {
|
||||||
|
let key = keys[i];
|
||||||
|
let numKey = key >>> 0; // ToUint32(key)
|
||||||
|
if (numKey + '' !== key || numKey >= prev) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
prev = numKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
grip.preview = {
|
grip.preview = {
|
||||||
|
@ -1836,12 +1845,14 @@ DebuggerServer.ObjectActorPreviewers.Object = [
|
||||||
}
|
}
|
||||||
|
|
||||||
let items = grip.preview.items = [];
|
let items = grip.preview.items = [];
|
||||||
|
let numItems = Math.min(OBJECT_PREVIEW_MAX_ITEMS, length);
|
||||||
|
|
||||||
let i = 0;
|
for (let i = 0; i < numItems; ++i) {
|
||||||
for (let key of keys) {
|
let desc = obj.getOwnPropertyDescriptor(i);
|
||||||
if (rawObj.hasOwnProperty(key) && i++ < OBJECT_PREVIEW_MAX_ITEMS) {
|
if (desc && 'value' in desc) {
|
||||||
let value = makeDebuggeeValueIfNeeded(obj, rawObj[key]);
|
items.push(hooks.createValueGrip(desc.value));
|
||||||
items.push(hooks.createValueGrip(value));
|
} else {
|
||||||
|
items.push(null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче