Skip to content

Commit 5931747

Browse files
BridgeARBethGriggs
authored andcommitted
util: inspect all prototypes
It is currently difficult to distinguish multiple objects from each other because the prototype is not properly inspected. From now on all prototypes will be inspected, even if we do not fully know how they will look like / what their shape really is. PR-URL: #24974 Fixes: #24917 Reviewed-By: Luigi Pinca <[email protected]> Reviewed-By: Anto Aravinth <[email protected]> Reviewed-By: James M Snell <[email protected]>
1 parent a9f239f commit 5931747

File tree

2 files changed

+25
-9
lines changed

2 files changed

+25
-9
lines changed

lib/internal/util/inspect.js

+7-6
Original file line numberDiff line numberDiff line change
@@ -322,7 +322,7 @@ function getEmptyFormatArray() {
322322
return [];
323323
}
324324

325-
function getConstructorName(obj) {
325+
function getConstructorName(obj, ctx) {
326326
let firstProto;
327327
while (obj) {
328328
const descriptor = Object.getOwnPropertyDescriptor(obj, 'constructor');
@@ -341,10 +341,11 @@ function getConstructorName(obj) {
341341
if (firstProto === null) {
342342
return null;
343343
}
344-
// TODO(BridgeAR): Improve prototype inspection.
345-
// We could use inspect on the prototype itself to improve the output.
346344

347-
return '';
345+
return `<${inspect(firstProto, {
346+
...ctx,
347+
customInspect: false
348+
})}>`;
348349
}
349350

350351
function getPrefix(constructor, tag, fallback) {
@@ -503,7 +504,7 @@ function formatValue(ctx, value, recurseTimes) {
503504
}
504505

505506
if (ctx.stop !== undefined) {
506-
const name = getConstructorName(value) || value[Symbol.toStringTag];
507+
const name = getConstructorName(value, ctx) || value[Symbol.toStringTag];
507508
return ctx.stylize(`[${name || 'Object'}]`, 'special');
508509
}
509510

@@ -547,7 +548,7 @@ function formatValue(ctx, value, recurseTimes) {
547548
function formatRaw(ctx, value, recurseTimes) {
548549
let keys;
549550

550-
const constructor = getConstructorName(value);
551+
const constructor = getConstructorName(value, ctx);
551552
let tag = value[Symbol.toStringTag];
552553
if (typeof tag !== 'string')
553554
tag = '';

test/parallel/test-util-inspect.js

+18-3
Original file line numberDiff line numberDiff line change
@@ -1738,19 +1738,34 @@ assert.strictEqual(
17381738
);
17391739
}
17401740

1741-
// Manipulate the prototype to one that we can not handle.
1741+
// Manipulate the prototype in weird ways.
17421742
{
17431743
let obj = { a: true };
17441744
let value = (function() { return function() {}; })();
17451745
Object.setPrototypeOf(value, null);
17461746
Object.setPrototypeOf(obj, value);
1747-
assert.strictEqual(util.inspect(obj), '{ a: true }');
1747+
assert.strictEqual(util.inspect(obj), '<[Function]> { a: true }');
1748+
assert.strictEqual(
1749+
util.inspect(obj, { colors: true }),
1750+
'<\u001b[36m[Function]\u001b[39m> { a: \u001b[33mtrue\u001b[39m }'
1751+
);
17481752

17491753
obj = { a: true };
17501754
value = [];
17511755
Object.setPrototypeOf(value, null);
17521756
Object.setPrototypeOf(obj, value);
1753-
assert.strictEqual(util.inspect(obj), '{ a: true }');
1757+
assert.strictEqual(
1758+
util.inspect(obj),
1759+
'<[Array: null prototype] []> { a: true }'
1760+
);
1761+
1762+
function StorageObject() {}
1763+
StorageObject.prototype = Object.create(null);
1764+
assert.strictEqual(
1765+
util.inspect(new StorageObject()),
1766+
'<[Object: null prototype] {}> {}'
1767+
);
1768+
17541769
}
17551770

17561771
// Check that the fallback always works.

0 commit comments

Comments
 (0)