util: add prototype support for boxed primitives
This makes sure manipulated prototypes from boxed primitives will be highlighted. It also makes sure that a potential `Symbol.toStringTag` is taken into account. PR-URL: https://github.com/nodejs/node/pull/27351 Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: John-David Dalton <john.david.dalton@gmail.com> Reviewed-By: Anto Aravinth <anto.aravinth.cse@gmail.com>
This commit is contained in:
parent
d04b376717
commit
55147d7d99
@ -385,8 +385,6 @@ function getPrefix(constructor, tag, fallback) {
|
||||
return `${constructor} `;
|
||||
}
|
||||
|
||||
const getBoxedValue = formatPrimitive.bind(null, stylizeNoColor);
|
||||
|
||||
// Look up the keys of the object.
|
||||
function getKeys(value, showHidden) {
|
||||
let keys;
|
||||
@ -709,31 +707,9 @@ function formatRaw(ctx, value, recurseTimes, typedArray) {
|
||||
braces[0] = `[${tag}] {`;
|
||||
formatter = formatNamespaceObject;
|
||||
} else if (isBoxedPrimitive(value)) {
|
||||
let type;
|
||||
if (isNumberObject(value)) {
|
||||
base = `[Number: ${getBoxedValue(NumberPrototype.valueOf(value))}]`;
|
||||
type = 'number';
|
||||
} else if (isStringObject(value)) {
|
||||
base = `[String: ${
|
||||
getBoxedValue(StringPrototype.valueOf(value), ctx)
|
||||
}]`;
|
||||
type = 'string';
|
||||
// For boxed Strings, we have to remove the 0-n indexed entries,
|
||||
// since they just noisy up the output and are redundant
|
||||
// Make boxed primitive Strings look like such
|
||||
keys = keys.slice(value.length);
|
||||
} else if (isBooleanObject(value)) {
|
||||
base = `[Boolean: ${getBoxedValue(BooleanPrototype.valueOf(value))}]`;
|
||||
type = 'boolean';
|
||||
} else if (isBigIntObject(value)) {
|
||||
base = `[BigInt: ${getBoxedValue(BigIntPrototype.valueOf(value))}]`;
|
||||
type = 'bigint';
|
||||
} else {
|
||||
base = `[Symbol: ${getBoxedValue(SymbolPrototype.valueOf(value))}]`;
|
||||
type = 'symbol';
|
||||
}
|
||||
base = getBoxedBase(value, ctx, keys, constructor, tag);
|
||||
if (keys.length === 0) {
|
||||
return ctx.stylize(base, type);
|
||||
return base;
|
||||
}
|
||||
} else {
|
||||
// The input prototype got manipulated. Special handle these. We have to
|
||||
@ -818,6 +794,46 @@ function getIteratorBraces(type, tag) {
|
||||
return [`[${tag}] {`, '}'];
|
||||
}
|
||||
|
||||
function getBoxedBase(value, ctx, keys, constructor, tag) {
|
||||
let fn;
|
||||
let type;
|
||||
if (isNumberObject(value)) {
|
||||
fn = NumberPrototype;
|
||||
type = 'Number';
|
||||
} else if (isStringObject(value)) {
|
||||
fn = StringPrototype;
|
||||
type = 'String';
|
||||
// For boxed Strings, we have to remove the 0-n indexed entries,
|
||||
// since they just noisy up the output and are redundant
|
||||
// Make boxed primitive Strings look like such
|
||||
keys.splice(0, value.length);
|
||||
} else if (isBooleanObject(value)) {
|
||||
fn = BooleanPrototype;
|
||||
type = 'Boolean';
|
||||
} else if (isBigIntObject(value)) {
|
||||
fn = BigIntPrototype;
|
||||
type = 'BigInt';
|
||||
} else {
|
||||
fn = SymbolPrototype;
|
||||
type = 'Symbol';
|
||||
}
|
||||
let base = `[${type}`;
|
||||
if (type !== constructor) {
|
||||
if (constructor === null) {
|
||||
base += ' (null prototype)';
|
||||
} else {
|
||||
base += ` (${constructor})`;
|
||||
}
|
||||
}
|
||||
base += `: ${formatPrimitive(stylizeNoColor, fn.valueOf(value), ctx)}]`;
|
||||
if (tag !== '' && tag !== constructor) {
|
||||
base += ` [${tag}]`;
|
||||
}
|
||||
if (keys.length !== 0 || ctx.stylize === stylizeNoColor)
|
||||
return base;
|
||||
return ctx.stylize(base, type.toLowerCase());
|
||||
}
|
||||
|
||||
function formatError(err, constructor, tag, ctx) {
|
||||
// TODO(BridgeAR): Always show the error code if present.
|
||||
let stack = err.stack || ErrorPrototype.toString(err);
|
||||
|
@ -856,9 +856,21 @@ assert.strictEqual(
|
||||
'[Symbol: Symbol(test)]'
|
||||
);
|
||||
assert.strictEqual(util.inspect(new Boolean(false)), '[Boolean: false]');
|
||||
assert.strictEqual(util.inspect(new Boolean(true)), '[Boolean: true]');
|
||||
assert.strictEqual(
|
||||
util.inspect(Object.setPrototypeOf(new Boolean(true), null)),
|
||||
'[Boolean (null prototype): true]'
|
||||
);
|
||||
assert.strictEqual(util.inspect(new Number(0)), '[Number: 0]');
|
||||
assert.strictEqual(util.inspect(new Number(-0)), '[Number: -0]');
|
||||
assert.strictEqual(
|
||||
util.inspect(
|
||||
Object.defineProperty(
|
||||
Object.setPrototypeOf(new Number(-0), Array.prototype),
|
||||
Symbol.toStringTag,
|
||||
{ value: 'Foobar' }
|
||||
)
|
||||
),
|
||||
'[Number (Array): -0] [Foobar]'
|
||||
);
|
||||
assert.strictEqual(util.inspect(new Number(-1.1)), '[Number: -1.1]');
|
||||
assert.strictEqual(util.inspect(new Number(13.37)), '[Number: 13.37]');
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user