util: improve iterator inspect output

1) So far extra keys on an (Set|Map)Iterator were ignored. Those
   will now be visible.
2) Improve the performance of showing (Set|Map)Iterator by using
   the cloned iterator instead of copying all entries first.
3) So far the output was strictly limited to up to 100 entries.
   The limit will now depend on `maxArrayLength` instead (that
   default is set to 100 as well) and the output indicates that
   more entries exist than visible.

PR-URL: https://github.com/nodejs/node/pull/19259
Reviewed-By: Yosuke Furukawa <yosuke.furukawa@gmail.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Tiancheng "Timothy" Gu <timothygu99@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
This commit is contained in:
Ruben Bridgewater 2018-03-09 14:57:19 +01:00
parent a101631db0
commit 0fbd4b1d02
No known key found for this signature in database
GPG Key ID: F07496B3EB3C1762
4 changed files with 46 additions and 29 deletions

View File

@ -471,8 +471,8 @@
// functions lazily (unless --nolazy is set) so we need to do this // functions lazily (unless --nolazy is set) so we need to do this
// before we turn off --allow_natives_syntax again. // before we turn off --allow_natives_syntax again.
const v8 = NativeModule.require('internal/v8'); const v8 = NativeModule.require('internal/v8');
v8.previewMapIterator(new Map().entries(), 1); v8.previewMapIterator(new Map().entries());
v8.previewSetIterator(new Set().entries(), 1); v8.previewSetIterator(new Set().entries());
// Disable --allow_natives_syntax again unless it was explicitly // Disable --allow_natives_syntax again unless it was explicitly
// specified on the command line. // specified on the command line.
const re = /^--allow[-_]natives[-_]syntax$/; const re = /^--allow[-_]natives[-_]syntax$/;

View File

@ -1,21 +1,23 @@
'use strict'; 'use strict';
function take(it, n) { // This file provides access to some of V8's native runtime functions. See
const result = []; // https://github.com/v8/v8/wiki/Built-in-functions for further information
for (const e of it) { // about their implementation.
if (--n < 0) // They have to be loaded before anything else to make sure we deactivate them
break; // before executing any other code. Gaining access is achieved by using a
result.push(e); // specific flag that is used internally in the startup phase.
}
return result; // Clone the provided Map Iterator.
function previewMapIterator(it) {
return %MapIteratorClone(it);
} }
function previewMapIterator(it, n) { // Clone the provided Set Iterator.
return take(%MapIteratorClone(it), n); function previewSetIterator(it) {
return %SetIteratorClone(it);
} }
function previewSetIterator(it, n) { module.exports = {
return take(%SetIteratorClone(it), n); previewMapIterator,
} previewSetIterator
};
module.exports = { previewMapIterator, previewSetIterator };

View File

@ -30,7 +30,10 @@ const {
const { TextDecoder, TextEncoder } = require('internal/encoding'); const { TextDecoder, TextEncoder } = require('internal/encoding');
const { isBuffer } = require('buffer').Buffer; const { isBuffer } = require('buffer').Buffer;
const { previewMapIterator, previewSetIterator } = require('internal/v8'); const {
previewMapIterator,
previewSetIterator
} = require('internal/v8');
const { const {
getPromiseDetails, getPromiseDetails,
@ -836,25 +839,29 @@ function formatMap(ctx, value, recurseTimes, keys) {
return output; return output;
} }
function formatCollectionIterator(preview, ctx, value, recurseTimes, function formatCollectionIterator(preview, ctx, value, recurseTimes, keys) {
visibleKeys, keys) {
const nextRecurseTimes = recurseTimes === null ? null : recurseTimes - 1;
const vals = preview(value, 100);
const output = []; const output = [];
for (const o of vals) { for (const entry of preview(value)) {
output.push(formatValue(ctx, o, nextRecurseTimes)); if (ctx.maxArrayLength === output.length) {
output.push('... more items');
break;
}
output.push(formatValue(ctx, entry, recurseTimes));
}
for (var n = 0; n < keys.length; n++) {
output.push(formatProperty(ctx, value, recurseTimes, keys[n], 0));
} }
return output; return output;
} }
function formatMapIterator(ctx, value, recurseTimes, visibleKeys, keys) { function formatMapIterator(ctx, value, recurseTimes, keys) {
return formatCollectionIterator(previewMapIterator, ctx, value, recurseTimes, return formatCollectionIterator(previewMapIterator, ctx, value, recurseTimes,
visibleKeys, keys); keys);
} }
function formatSetIterator(ctx, value, recurseTimes, visibleKeys, keys) { function formatSetIterator(ctx, value, recurseTimes, keys) {
return formatCollectionIterator(previewSetIterator, ctx, value, recurseTimes, return formatCollectionIterator(previewSetIterator, ctx, value, recurseTimes,
visibleKeys, keys); keys);
} }
function formatPromise(ctx, value, recurseTimes, keys) { function formatPromise(ctx, value, recurseTimes, keys) {

View File

@ -448,7 +448,7 @@ assert.strictEqual(util.inspect(-5e-324), '-5e-324');
{ {
const map = new Map(); const map = new Map();
map.set(1, 2); map.set(1, 2);
const vals = previewMapIterator(map.entries(), 100); const vals = previewMapIterator(map.entries());
const valsOutput = []; const valsOutput = [];
for (const o of vals) { for (const o of vals) {
valsOutput.push(o); valsOutput.push(o);
@ -924,6 +924,10 @@ if (typeof Symbol !== 'undefined') {
const keys = map.keys(); const keys = map.keys();
assert.strictEqual(util.inspect(keys), '[Map Iterator] { \'foo\' }'); assert.strictEqual(util.inspect(keys), '[Map Iterator] { \'foo\' }');
assert.strictEqual(util.inspect(keys), '[Map Iterator] { \'foo\' }'); assert.strictEqual(util.inspect(keys), '[Map Iterator] { \'foo\' }');
keys.extra = true;
assert.strictEqual(
util.inspect(keys, { maxArrayLength: 0 }),
'[Map Iterator] { ... more items, extra: true }');
} }
// Test Set iterators. // Test Set iterators.
@ -937,6 +941,10 @@ if (typeof Symbol !== 'undefined') {
const keys = aSet.keys(); const keys = aSet.keys();
assert.strictEqual(util.inspect(keys), '[Set Iterator] { 1, 3 }'); assert.strictEqual(util.inspect(keys), '[Set Iterator] { 1, 3 }');
assert.strictEqual(util.inspect(keys), '[Set Iterator] { 1, 3 }'); assert.strictEqual(util.inspect(keys), '[Set Iterator] { 1, 3 }');
keys.extra = true;
assert.strictEqual(
util.inspect(keys, { maxArrayLength: 1 }),
'[Set Iterator] { 1, ... more items, extra: true }');
} }
// Test alignment of items in container. // Test alignment of items in container.