Skip to content
Permalink
Browse files

util: add (typed) array length to the default output

Align the inspect output with the one used in the Chrome dev tools.
A recent survey outlined that most users prefer to see the number
of set and map entries. This should count as well for array sizes.
The size is only added to regular arrays in case the constructor is
not the default constructor.
Typed arrays always indicate their size.

PR-URL: #31027
Reviewed-By: Michaël Zasso <targos@protonmail.com>
Reviewed-By: Rich Trott <rtrott@gmail.com>
Reviewed-By: Anto Aravinth <anto.aravinth.cse@gmail.com>
  • Loading branch information
BridgeAR committed Dec 19, 2019
1 parent ffbf790 commit a6998085d27412b57c06a29142960bb0e4d35b92
@@ -117,6 +117,9 @@ const setSizeGetter = uncurryThis(
ObjectGetOwnPropertyDescriptor(SetPrototype, 'size').get);
const mapSizeGetter = uncurryThis(
ObjectGetOwnPropertyDescriptor(MapPrototype, 'size').get);
const typedArraySizeGetter = uncurryThis(
ObjectGetOwnPropertyDescriptor(
ObjectGetPrototypeOf(Uint8Array.prototype), 'length').get);

let hexSlice;

@@ -562,18 +565,18 @@ function addPrototypeProperties(ctx, main, obj, recurseTimes, isProto, output) {
} while (++depth !== 3);
}

function getPrefix(constructor, tag, fallback) {
function getPrefix(constructor, tag, fallback, size = '') {
if (constructor === null) {
if (tag !== '') {
return `[${fallback}: null prototype] [${tag}] `;
return `[${fallback}${size}: null prototype] [${tag}] `;
}
return `[${fallback}: null prototype] `;
return `[${fallback}${size}: null prototype] `;
}

if (tag !== '' && constructor !== tag) {
return `${constructor} [${tag}] `;
return `${constructor}${size} [${tag}] `;
}
return `${constructor} `;
return `${constructor}${size} `;
}

// Look up the keys of the object.
@@ -758,58 +761,48 @@ function formatRaw(ctx, value, recurseTimes, typedArray) {
if (value[SymbolIterator] || constructor === null) {
noIterator = false;
if (ArrayIsArray(value)) {
keys = getOwnNonIndexProperties(value, filter);
// Only set the constructor for non ordinary ("Array [...]") arrays.
const prefix = getPrefix(constructor, tag, 'Array');
braces = [`${prefix === 'Array ' ? '' : prefix}[`, ']'];
const prefix = (constructor !== 'Array' || tag !== '') ?
getPrefix(constructor, tag, 'Array', `(${value.length})`) :
'';
keys = getOwnNonIndexProperties(value, filter);
braces = [`${prefix}[`, ']'];
if (value.length === 0 && keys.length === 0 && protoProps === undefined)
return `${braces[0]}]`;
extrasType = kArrayExtrasType;
formatter = formatArray;
} else if (isSet(value)) {
const size = setSizeGetter(value);
const prefix = getPrefix(constructor, tag, 'Set', `(${size})`);
keys = getKeys(value, ctx.showHidden);
let prefix = '';
if (constructor !== null) {
if (constructor === tag)
tag = '';
prefix = getPrefix(`${constructor}(${size})`, tag, '');
formatter = formatSet.bind(null, value, size);
} else {
prefix = getPrefix(constructor, tag, `Set(${size})`);
formatter = formatSet.bind(null, SetPrototypeValues(value), size);
}
formatter = constructor !== null ?
formatSet.bind(null, value) :
formatSet.bind(null, SetPrototypeValues(value));
if (size === 0 && keys.length === 0 && protoProps === undefined)
return `${prefix}{}`;
braces = [`${prefix}{`, '}'];
} else if (isMap(value)) {
const size = mapSizeGetter(value);
const prefix = getPrefix(constructor, tag, 'Map', `(${size})`);
keys = getKeys(value, ctx.showHidden);
let prefix = '';
if (constructor !== null) {
if (constructor === tag)
tag = '';
prefix = getPrefix(`${constructor}(${size})`, tag, '');
formatter = formatMap.bind(null, value, size);
} else {
prefix = getPrefix(constructor, tag, `Map(${size})`);
formatter = formatMap.bind(null, MapPrototypeEntries(value), size);
}
formatter = constructor !== null ?
formatMap.bind(null, value) :
formatMap.bind(null, MapPrototypeEntries(value));
if (size === 0 && keys.length === 0 && protoProps === undefined)
return `${prefix}{}`;
braces = [`${prefix}{`, '}'];
} else if (isTypedArray(value)) {
keys = getOwnNonIndexProperties(value, filter);
let bound = value;
let prefix = '';
let fallback = '';
if (constructor === null) {
const constr = findTypedConstructor(value);
prefix = getPrefix(constructor, tag, constr.name);
fallback = constr.name;
// Reconstruct the array information.
bound = new constr(value);
} else {
prefix = getPrefix(constructor, tag);
}
const size = typedArraySizeGetter(value);
const prefix = getPrefix(constructor, tag, fallback, `(${size})`);
braces = [`${prefix}[`, ']'];
if (value.length === 0 && keys.length === 0 && !ctx.showHidden)
return `${braces[0]}]`;
@@ -1425,7 +1418,7 @@ function formatTypedArray(value, ctx, ignored, recurseTimes) {
return output;
}

function formatSet(value, size, ctx, ignored, recurseTimes) {
function formatSet(value, ctx, ignored, recurseTimes) {
const output = [];
ctx.indentationLvl += 2;
for (const v of value) {
@@ -1435,7 +1428,7 @@ function formatSet(value, size, ctx, ignored, recurseTimes) {
return output;
}

function formatMap(value, size, ctx, ignored, recurseTimes) {
function formatMap(value, ctx, ignored, recurseTimes) {
const output = [];
ctx.indentationLvl += 2;
for (const [k, v] of value) {
@@ -51,8 +51,8 @@ assert.throws(
{
code: 'ERR_ASSERTION',
message: `${defaultMsgStartFull} ... Lines skipped\n\n` +
'+ Uint8Array [\n' +
'- Buffer [Uint8Array] [\n 120,\n...\n 122,\n 10\n ]'
'+ Uint8Array(4) [\n' +
'- Buffer(4) [Uint8Array] [\n 120,\n...\n 122,\n 10\n ]'
}
);
assert.deepEqual(arr, buf);
@@ -66,7 +66,7 @@ assert.deepEqual(arr, buf);
{
code: 'ERR_ASSERTION',
message: `${defaultMsgStartFull}\n\n` +
' Buffer [Uint8Array] [\n' +
' Buffer(4) [Uint8Array] [\n' +
' 120,\n' +
' 121,\n' +
' 122,\n' +
@@ -86,7 +86,7 @@ assert.deepEqual(arr, buf);
{
code: 'ERR_ASSERTION',
message: `${defaultMsgStartFull}\n\n` +
' Uint8Array [\n' +
' Uint8Array(4) [\n' +
' 120,\n' +
' 121,\n' +
' 122,\n' +
@@ -58,7 +58,7 @@ b.inspect = undefined;
b.prop = new Uint8Array(0);
assert.strictEqual(
util.inspect(b),
'<Buffer 31 32, inspect: undefined, prop: Uint8Array []>'
'<Buffer 31 32, inspect: undefined, prop: Uint8Array(0) []>'
);

b = Buffer.alloc(0);
@@ -15,7 +15,7 @@ assert.throws(
{
code: 'ERR_INVALID_ARG_VALUE',
message: 'The argument \'buffer\' is empty and cannot be written. ' +
'Received Uint8Array []'
'Received Uint8Array(0) []'
}
);

@@ -24,7 +24,7 @@ assert.throws(
{
code: 'ERR_INVALID_ARG_VALUE',
message: 'The argument \'buffer\' is empty and cannot be written. ' +
'Received Uint8Array []'
'Received Uint8Array(0) []'
}
);

@@ -35,7 +35,7 @@ assert.throws(
{
code: 'ERR_INVALID_ARG_VALUE',
message: 'The argument \'buffer\' is empty and cannot be written. ' +
'Received Uint8Array []'
'Received Uint8Array(0) []'
}
);
})();
@@ -158,7 +158,7 @@ assert.strictEqual(util.format('%s', () => 5), '() => 5');
class Foobar extends Array { aaa = true; }
assert.strictEqual(
util.format('%s', new Foobar(5)),
'Foobar [ <5 empty items>, aaa: true ]'
'Foobar(5) [ <5 empty items>, aaa: true ]'
);

// Subclassing:

0 comments on commit a699808

Please sign in to comment.
You can’t perform that action at this time.