diff options
author | Ruben Bridgewater <ruben@bridgewater.de> | 2018-08-21 17:39:01 +0200 |
---|---|---|
committer | Ruben Bridgewater <ruben@bridgewater.de> | 2018-08-24 15:21:54 +0200 |
commit | ea8b932f30665436796c7e5abd485f048a0f41c8 (patch) | |
tree | e3bcf358883b1cf6ddfec917a4fa056c97807f0e /lib/util.js | |
parent | 4dc8467dbb1f6a46c25931f92467a04bb384a830 (diff) | |
download | android-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.js | 83 |
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)}{`; + } } } |