aboutsummaryrefslogtreecommitdiff
path: root/lib/util.js
diff options
context:
space:
mode:
authorRuben Bridgewater <ruben@bridgewater.de>2018-08-21 17:39:01 +0200
committerRuben Bridgewater <ruben@bridgewater.de>2018-08-24 15:21:54 +0200
commitea8b932f30665436796c7e5abd485f048a0f41c8 (patch)
treee3bcf358883b1cf6ddfec917a4fa056c97807f0e /lib/util.js
parent4dc8467dbb1f6a46c25931f92467a04bb384a830 (diff)
downloadandroid-node-v8-ea8b932f30665436796c7e5abd485f048a0f41c8.tar.gz
android-node-v8-ea8b932f30665436796c7e5abd485f048a0f41c8.tar.bz2
android-node-v8-ea8b932f30665436796c7e5abd485f048a0f41c8.zip
util: restore all information in inspect
The former implementation lacked symbols on the iterator objects without prototype. This is now fixed. The special handling for overriding `Symbol.iterator` was removed as it's very difficult to deal with this properly. Manipulating the symbols is just not supported. PR-URL: https://github.com/nodejs/node/pull/22437 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Diffstat (limited to 'lib/util.js')
-rw-r--r--lib/util.js83
1 files changed, 42 insertions, 41 deletions
diff --git a/lib/util.js b/lib/util.js
index fa96ade26a..e8fb41a219 100644
--- a/lib/util.js
+++ b/lib/util.js
@@ -513,13 +513,6 @@ function getPrefix(constructor, tag, fallback) {
return '';
}
-function addExtraKeys(source, target, keys) {
- for (const key of keys) {
- target[key] = source[key];
- }
- return target;
-}
-
function findTypedConstructor(value) {
for (const [check, clazz] of [
[isUint8Array, Uint8Array],
@@ -535,14 +528,36 @@ function findTypedConstructor(value) {
[isBigUint64Array, BigUint64Array]
]) {
if (check(value)) {
- return new clazz(value);
+ return clazz;
}
}
- return value;
}
const getBoxedValue = formatPrimitive.bind(null, stylizeNoColor);
+function noPrototypeIterator(ctx, value, recurseTimes) {
+ let newVal;
+ // TODO: Create a Subclass in case there's no prototype and show
+ // `null-prototype`.
+ if (isSet(value)) {
+ const clazz = Object.getPrototypeOf(value) || Set;
+ newVal = new clazz(setValues(value));
+ } else if (isMap(value)) {
+ const clazz = Object.getPrototypeOf(value) || Map;
+ newVal = new clazz(mapEntries(value));
+ } else if (Array.isArray(value)) {
+ const clazz = Object.getPrototypeOf(value) || Array;
+ newVal = new clazz(value.length || 0);
+ } else if (isTypedArray(value)) {
+ const clazz = findTypedConstructor(value) || Uint8Array;
+ newVal = new clazz(value);
+ }
+ if (newVal) {
+ Object.defineProperties(newVal, Object.getOwnPropertyDescriptors(value));
+ return formatValue(ctx, newVal, recurseTimes);
+ }
+}
+
// Note: using `formatValue` directly requires the indentation level to be
// corrected by setting `ctx.indentationLvL += diff` and then to decrease the
// value afterwards again.
@@ -798,39 +813,25 @@ function formatValue(ctx, value, recurseTimes) {
braces = ['{', '}'];
// The input prototype got manipulated. Special handle these.
// We have to rebuild the information so we are able to display everything.
- } else if (isSet(value)) {
- const newVal = addExtraKeys(value, new Set(setValues(value)), keys);
- return formatValue(ctx, newVal, recurseTimes);
- } else if (isMap(value)) {
- const newVal = addExtraKeys(value, new Map(mapEntries(value)), keys);
- return formatValue(ctx, newVal, recurseTimes);
- } else if (Array.isArray(value)) {
- // The prefix is not always possible to fully reconstruct.
- const prefix = getPrefix(constructor, tag);
- braces = [`${prefix === 'Array ' ? '' : prefix}[`, ']'];
- formatter = formatArray;
- const newValue = [];
- newValue.length = value.length;
- value = addExtraKeys(value, newValue, keys);
- } else if (isTypedArray(value)) {
- const newValue = findTypedConstructor(value);
- value = addExtraKeys(value, newValue, keys.slice(newValue.length));
- // The prefix is not always possible to fully reconstruct.
- braces = [`${getPrefix(getConstructorName(value), tag)}[`, ']'];
- formatter = formatTypedArray;
- } else if (isMapIterator(value)) {
- braces = [`[${tag || 'Map Iterator'}] {`, '}'];
- formatter = formatMapIterator;
- } else if (isSetIterator(value)) {
- braces = [`[${tag || 'Set Iterator'}] {`, '}'];
- formatter = formatSetIterator;
- // Handle other regular objects again.
- } else if (keyLength === 0) {
- if (isExternal(value))
- return ctx.stylize('[External]', 'special');
- return `${getPrefix(constructor, tag)}{}`;
} else {
- braces[0] = `${getPrefix(constructor, tag)}{`;
+ const specialIterator = noPrototypeIterator(ctx, value, recurseTimes);
+ if (specialIterator) {
+ return specialIterator;
+ }
+ if (isMapIterator(value)) {
+ braces = [`[${tag || 'Map Iterator'}] {`, '}'];
+ formatter = formatMapIterator;
+ } else if (isSetIterator(value)) {
+ braces = [`[${tag || 'Set Iterator'}] {`, '}'];
+ formatter = formatSetIterator;
+ // Handle other regular objects again.
+ } else if (keyLength === 0) {
+ if (isExternal(value))
+ return ctx.stylize('[External]', 'special');
+ return `${getPrefix(constructor, tag)}{}`;
+ } else {
+ braces[0] = `${getPrefix(constructor, tag)}{`;
+ }
}
}