Skip to content

Commit 34905fc

Browse files
BridgeARaddaleax
authored andcommitted
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 fa8110a commit 34905fc

File tree

2 files changed

+30
-11
lines changed

2 files changed

+30
-11
lines changed

lib/internal/util/inspect.js

+17-6
Original file line numberDiff line numberDiff line change
@@ -539,6 +539,15 @@ function formatValue(ctx, value, recurseTimes, typedArray) {
539539
return formatRaw(ctx, value, recurseTimes, typedArray);
540540
}
541541

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

@@ -593,11 +602,11 @@ function formatRaw(ctx, value, recurseTimes, typedArray) {
593602
extrasType = kArrayExtrasType;
594603
} else if (isMapIterator(value)) {
595604
keys = getKeys(value, ctx.showHidden);
596-
braces = [`[${tag}] {`, '}'];
605+
braces = setIteratorBraces('Map', tag);
597606
formatter = formatIterator;
598607
} else if (isSetIterator(value)) {
599608
keys = getKeys(value, ctx.showHidden);
600-
braces = [`[${tag}] {`, '}'];
609+
braces = setIteratorBraces('Set', tag);
601610
formatter = formatIterator;
602611
} else {
603612
noIterator = true;
@@ -729,10 +738,10 @@ function formatRaw(ctx, value, recurseTimes, typedArray) {
729738
}
730739
}
731740
if (isMapIterator(value)) {
732-
braces = [`[${tag || 'Map Iterator'}] {`, '}'];
741+
braces = setIteratorBraces('Map', tag);
733742
formatter = formatIterator;
734743
} else if (isSetIterator(value)) {
735-
braces = [`[${tag || 'Set Iterator'}] {`, '}'];
744+
braces = setIteratorBraces('Set', tag);
736745
formatter = formatIterator;
737746
// Handle other regular objects again.
738747
} else if (keys.length === 0) {
@@ -754,7 +763,7 @@ function formatRaw(ctx, value, recurseTimes, typedArray) {
754763
let output;
755764
const indentationLvl = ctx.indentationLvl;
756765
try {
757-
output = formatter(ctx, value, recurseTimes, keys);
766+
output = formatter(ctx, value, recurseTimes, keys, braces);
758767
for (i = 0; i < keys.length; i++) {
759768
output.push(
760769
formatProperty(ctx, value, recurseTimes, keys[i], extrasType));
@@ -1090,9 +1099,11 @@ function formatWeakMap(ctx, value, recurseTimes) {
10901099
return formatMapIterInner(ctx, recurseTimes, entries, kWeak);
10911100
}
10921101

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

test/parallel/test-util-inspect.js

+13-5
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)