Skip to content

Commit 6c52ef9

Browse files
committed
util: mark iterator entries as such
It is possible to distinguish the entries iterator from others. Expose that information to the users as well and improve the Symbol.toStringTag handling by adding a special tag instead of replacing the existent information. PR-URL: #26222 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Gus Caplan <me@gus.host> Reviewed-By: Jeremiah Senkpiel <fishrock123@rocketmail.com>
1 parent 0373836 commit 6c52ef9

File tree

2 files changed

+30
-11
lines changed

2 files changed

+30
-11
lines changed

lib/internal/util/inspect.js

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -540,6 +540,15 @@ function formatValue(ctx, value, recurseTimes, typedArray) {
540540
return formatRaw(ctx, value, recurseTimes, typedArray);
541541
}
542542

543+
function setIteratorBraces(type, tag) {
544+
if (tag !== `${type} Iterator`) {
545+
if (tag !== '')
546+
tag += '] [';
547+
tag += `${type} Iterator`;
548+
}
549+
return [`[${tag}] {`, '}'];
550+
}
551+
543552
function formatRaw(ctx, value, recurseTimes, typedArray) {
544553
let keys;
545554

@@ -594,11 +603,11 @@ function formatRaw(ctx, value, recurseTimes, typedArray) {
594603
extrasType = kArrayExtrasType;
595604
} else if (isMapIterator(value)) {
596605
keys = getKeys(value, ctx.showHidden);
597-
braces = [`[${tag}] {`, '}'];
606+
braces = setIteratorBraces('Map', tag);
598607
formatter = formatIterator;
599608
} else if (isSetIterator(value)) {
600609
keys = getKeys(value, ctx.showHidden);
601-
braces = [`[${tag}] {`, '}'];
610+
braces = setIteratorBraces('Set', tag);
602611
formatter = formatIterator;
603612
} else {
604613
noIterator = true;
@@ -730,10 +739,10 @@ function formatRaw(ctx, value, recurseTimes, typedArray) {
730739
}
731740
}
732741
if (isMapIterator(value)) {
733-
braces = [`[${tag || 'Map Iterator'}] {`, '}'];
742+
braces = setIteratorBraces('Map', tag);
734743
formatter = formatIterator;
735744
} else if (isSetIterator(value)) {
736-
braces = [`[${tag || 'Set Iterator'}] {`, '}'];
745+
braces = setIteratorBraces('Set', tag);
737746
formatter = formatIterator;
738747
// Handle other regular objects again.
739748
} else if (keys.length === 0) {
@@ -755,7 +764,7 @@ function formatRaw(ctx, value, recurseTimes, typedArray) {
755764
let output;
756765
const indentationLvl = ctx.indentationLvl;
757766
try {
758-
output = formatter(ctx, value, recurseTimes, keys);
767+
output = formatter(ctx, value, recurseTimes, keys, braces);
759768
for (i = 0; i < keys.length; i++) {
760769
output.push(
761770
formatProperty(ctx, value, recurseTimes, keys[i], extrasType));
@@ -1091,9 +1100,11 @@ function formatWeakMap(ctx, value, recurseTimes) {
10911100
return formatMapIterInner(ctx, recurseTimes, entries, kWeak);
10921101
}
10931102

1094-
function formatIterator(ctx, value, recurseTimes) {
1103+
function formatIterator(ctx, value, recurseTimes, keys, braces) {
10951104
const [entries, isKeyValue] = previewEntries(value, true);
10961105
if (isKeyValue) {
1106+
// Mark entry iterators as such.
1107+
braces[0] = braces[0].replace(/ Iterator] {$/, ' Entries] {');
10971108
return formatMapIterInner(ctx, recurseTimes, entries, kMapEntries);
10981109
}
10991110

test/parallel/test-util-inspect.js

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -976,10 +976,15 @@ if (typeof Symbol !== 'undefined') {
976976
{
977977
const map = new Map([['foo', 'bar']]);
978978
assert.strictEqual(util.inspect(map.keys()), '[Map Iterator] { \'foo\' }');
979-
assert.strictEqual(util.inspect(map.values()), '[Map Iterator] { \'bar\' }');
979+
const mapValues = map.values();
980+
Object.defineProperty(mapValues, Symbol.toStringTag, { value: 'Foo' });
981+
assert.strictEqual(
982+
util.inspect(mapValues),
983+
'[Foo] [Map Iterator] { \'bar\' }'
984+
);
980985
map.set('A', 'B!');
981986
assert.strictEqual(util.inspect(map.entries(), { maxArrayLength: 1 }),
982-
"[Map Iterator] { [ 'foo', 'bar' ], ... 1 more item }");
987+
"[Map Entries] { [ 'foo', 'bar' ], ... 1 more item }");
983988
// Make sure the iterator doesn't get consumed.
984989
const keys = map.keys();
985990
assert.strictEqual(util.inspect(keys), "[Map Iterator] { 'foo', 'A' }");
@@ -995,10 +1000,13 @@ if (typeof Symbol !== 'undefined') {
9951000
const aSet = new Set([1, 3]);
9961001
assert.strictEqual(util.inspect(aSet.keys()), '[Set Iterator] { 1, 3 }');
9971002
assert.strictEqual(util.inspect(aSet.values()), '[Set Iterator] { 1, 3 }');
998-
assert.strictEqual(util.inspect(aSet.entries()),
999-
'[Set Iterator] { [ 1, 1 ], [ 3, 3 ] }');
1003+
const setEntries = aSet.entries();
1004+
Object.defineProperty(setEntries, Symbol.toStringTag, { value: 'Foo' });
1005+
assert.strictEqual(util.inspect(setEntries),
1006+
'[Foo] [Set Entries] { [ 1, 1 ], [ 3, 3 ] }');
10001007
// Make sure the iterator doesn't get consumed.
10011008
const keys = aSet.keys();
1009+
Object.defineProperty(keys, Symbol.toStringTag, { value: null });
10021010
assert.strictEqual(util.inspect(keys), '[Set Iterator] { 1, 3 }');
10031011
assert.strictEqual(util.inspect(keys), '[Set Iterator] { 1, 3 }');
10041012
keys.extra = true;
@@ -1610,7 +1618,7 @@ assert.strictEqual(util.inspect('"\'${a}'), "'\"\\'${a}'");
16101618
[{ a: 5 }, '{ a: 5 }'],
16111619
[new Set([1, 2]), 'Set { 1, 2 }'],
16121620
[new Map([[1, 2]]), 'Map { 1 => 2 }'],
1613-
[new Set([1, 2]).entries(), '[Set Iterator] { [ 1, 1 ], [ 2, 2 ] }'],
1621+
[new Set([1, 2]).entries(), '[Set Entries] { [ 1, 1 ], [ 2, 2 ] }'],
16141622
[new Map([[1, 2]]).keys(), '[Map Iterator] { 1 }'],
16151623
[new Date(2000), '1970-01-01T00:00:02.000Z'],
16161624
[new Uint8Array(2), 'Uint8Array [ 0, 0 ]'],

0 commit comments

Comments
 (0)