diff options
author | Ruben Bridgewater <ruben@bridgewater.de> | 2018-03-09 15:03:44 +0100 |
---|---|---|
committer | Ruben Bridgewater <ruben@bridgewater.de> | 2018-03-25 03:21:27 +0200 |
commit | 1029dd36861d7ab592d4e219362706d2c161839a (patch) | |
tree | e9dc8ed32ab7812c537712967b5c634d8f1bfc11 /lib/util.js | |
parent | 0fbd4b1d021ed5fcd95210047a9e1d2addefe51a (diff) | |
download | android-node-v8-1029dd36861d7ab592d4e219362706d2c161839a.tar.gz android-node-v8-1029dd36861d7ab592d4e219362706d2c161839a.tar.bz2 android-node-v8-1029dd36861d7ab592d4e219362706d2c161839a.zip |
util: show Weak(Set|Map) entries in inspect
This adds support for WeakMap and WeakSet entries in `util.inspect`.
The output is limited to a maximum entry length of `maxArrayLength`.
PR-URL: https://github.com/nodejs/node/pull/19259
Fixes: https://github.com/nodejs/node/issues/19001:
Reviewed-By: Yosuke Furukawa <yosuke.furukawa@gmail.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Tiancheng "Timothy" Gu <timothygu99@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Diffstat (limited to 'lib/util.js')
-rw-r--r-- | lib/util.js | 68 |
1 files changed, 67 insertions, 1 deletions
diff --git a/lib/util.js b/lib/util.js index 774b185095..a9be7cbda4 100644 --- a/lib/util.js +++ b/lib/util.js @@ -32,7 +32,9 @@ const { isBuffer } = require('buffer').Buffer; const { previewMapIterator, - previewSetIterator + previewSetIterator, + previewWeakMap, + previewWeakSet } = require('internal/v8'); const { @@ -54,6 +56,8 @@ const { isPromise, isSet, isSetIterator, + isWeakMap, + isWeakSet, isRegExp, isDate, isTypedArray @@ -291,6 +295,8 @@ function inspect(value, opts) { colors: inspectDefaultOptions.colors, customInspect: inspectDefaultOptions.customInspect, showProxy: inspectDefaultOptions.showProxy, + // TODO(BridgeAR): Deprecate `maxArrayLength` and replace it with + // `maxEntries`. maxArrayLength: inspectDefaultOptions.maxArrayLength, breakLength: inspectDefaultOptions.breakLength, indentationLvl: 0, @@ -328,6 +334,8 @@ Object.defineProperty(inspect, 'defaultOptions', { if (options === null || typeof options !== 'object') { throw new ERR_INVALID_ARG_TYPE('options', 'Object', options); } + // TODO(BridgeAR): Add input validation and make sure `defaultOptions` are + // not configurable. return _extend(inspectDefaultOptions, options); } }); @@ -465,6 +473,7 @@ function formatValue(ctx, value, recurseTimes, ln) { let braces; let noIterator = true; let raw; + let extra; // Iterators and the rest are split to reduce checks if (value[Symbol.iterator]) { @@ -562,6 +571,20 @@ function formatValue(ctx, value, recurseTimes, ln) { } else if (isPromise(value)) { braces[0] = `${prefix}{`; formatter = formatPromise; + } else if (isWeakSet(value)) { + braces[0] = `${prefix}{`; + if (ctx.showHidden) { + formatter = formatWeakSet; + } else { + extra = '[items unknown]'; + } + } else if (isWeakMap(value)) { + braces[0] = `${prefix}{`; + if (ctx.showHidden) { + formatter = formatWeakMap; + } else { + extra = '[items unknown]'; + } } else { // Check boxed primitives other than string with valueOf() // NOTE: `Date` has to be checked first! @@ -616,6 +639,9 @@ function formatValue(ctx, value, recurseTimes, ln) { ctx.seen.push(value); const output = formatter(ctx, value, recurseTimes, keys); + if (extra !== undefined) + output.unshift(extra); + for (var i = 0; i < symbols.length; i++) { output.push(formatProperty(ctx, value, recurseTimes, symbols[i], 0)); } @@ -839,6 +865,46 @@ function formatMap(ctx, value, recurseTimes, keys) { return output; } +function formatWeakSet(ctx, value, recurseTimes, keys) { + const maxArrayLength = Math.max(ctx.maxArrayLength, 0); + const entries = previewWeakSet(value, maxArrayLength + 1); + const maxLength = Math.min(maxArrayLength, entries.length); + let output = new Array(maxLength); + for (var i = 0; i < maxLength; ++i) + output[i] = formatValue(ctx, entries[i], recurseTimes); + // Sort all entries to have a halfway reliable output (if more entries than + // retrieved ones exist, we can not reliably return the same output). + output = output.sort(); + if (entries.length > maxArrayLength) + output.push('... more items'); + for (i = 0; i < keys.length; i++) + output.push(formatProperty(ctx, value, recurseTimes, keys[i], 0)); + return output; +} + +function formatWeakMap(ctx, value, recurseTimes, keys) { + const maxArrayLength = Math.max(ctx.maxArrayLength, 0); + const entries = previewWeakMap(value, maxArrayLength + 1); + // Entries exist as [key1, val1, key2, val2, ...] + const remainder = entries.length / 2 > maxArrayLength; + const len = entries.length / 2 - (remainder ? 1 : 0); + const maxLength = Math.min(maxArrayLength, len); + let output = new Array(maxLength); + for (var i = 0; i < len; i++) { + const pos = i * 2; + output[i] = `${formatValue(ctx, entries[pos], recurseTimes)} => ` + + formatValue(ctx, entries[pos + 1], recurseTimes); + } + // Sort all entries to have a halfway reliable output (if more entries than + // retrieved ones exist, we can not reliably return the same output). + output = output.sort(); + if (remainder > 0) + output.push('... more items'); + for (i = 0; i < keys.length; i++) + output.push(formatProperty(ctx, value, recurseTimes, keys[i], 0)); + return output; +} + function formatCollectionIterator(preview, ctx, value, recurseTimes, keys) { const output = []; for (const entry of preview(value)) { |