summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/api/util.md8
-rw-r--r--lib/internal/util/inspect.js32
-rw-r--r--test/parallel/test-util-inspect.js33
3 files changed, 68 insertions, 5 deletions
diff --git a/doc/api/util.md b/doc/api/util.md
index 8c21bef9ae..0b9e477394 100644
--- a/doc/api/util.md
+++ b/doc/api/util.md
@@ -389,6 +389,9 @@ stream.write('With ES6');
<!-- YAML
added: v0.3.0
changes:
+ - version: REPLACEME
+ pr-url: https://github.com/nodejs/node/pull/24852
+ description: The `getters` option is supported now.
- version: v11.4.0
pr-url: https://github.com/nodejs/node/pull/24326
description: The `depth` default changed back to `2`.
@@ -468,6 +471,11 @@ changes:
of an object and Set and Map entries will be sorted in the returned string.
If set to `true` the [default sort][] is going to be used. If set to a
function, it is used as a [compare function][].
+ * `getters` {boolean|string} If set to `true`, getters are going to be
+ inspected as well. If set to `'get'` only getters without setter are going
+ to be inspected. If set to `'set'` only getters having a corresponding
+ setter are going to be inspected. This might cause side effects depending on
+ the getter function. **Default:** `false`.
* Returns: {string} The representation of passed object
The `util.inspect()` method returns a string representation of `object` that is
diff --git a/lib/internal/util/inspect.js b/lib/internal/util/inspect.js
index 6ec27b9d1d..f7e5507882 100644
--- a/lib/internal/util/inspect.js
+++ b/lib/internal/util/inspect.js
@@ -99,7 +99,8 @@ const inspectDefaultOptions = Object.seal({
maxArrayLength: 100,
breakLength: 60,
compact: true,
- sorted: false
+ sorted: false,
+ getters: false
});
const kObjectType = 0;
@@ -167,7 +168,8 @@ function inspect(value, opts) {
maxArrayLength: inspectDefaultOptions.maxArrayLength,
breakLength: inspectDefaultOptions.breakLength,
compact: inspectDefaultOptions.compact,
- sorted: inspectDefaultOptions.sorted
+ sorted: inspectDefaultOptions.sorted,
+ getters: inspectDefaultOptions.getters
};
if (arguments.length > 1) {
// Legacy...
@@ -1131,10 +1133,30 @@ function formatProperty(ctx, value, recurseTimes, key, type) {
}
ctx.indentationLvl -= diff;
} else if (desc.get !== undefined) {
- if (desc.set !== undefined) {
- str = ctx.stylize('[Getter/Setter]', 'special');
+ const label = desc.set !== undefined ? 'Getter/Setter' : 'Getter';
+ const s = ctx.stylize;
+ const sp = 'special';
+ if (ctx.getters && (ctx.getters === true ||
+ ctx.getters === 'get' && desc.set === undefined ||
+ ctx.getters === 'set' && desc.set !== undefined)) {
+ try {
+ const tmp = value[key];
+ ctx.indentationLvl += 2;
+ if (tmp === null) {
+ str = `${s(`[${label}:`, sp)} ${s('null', 'null')}${s(']', sp)}`;
+ } else if (typeof tmp === 'object') {
+ str = `${s(`[${label}]`, sp)} ${formatValue(ctx, tmp, recurseTimes)}`;
+ } else {
+ const primitive = formatPrimitive(s, tmp, ctx);
+ str = `${s(`[${label}:`, sp)} ${primitive}${s(']', sp)}`;
+ }
+ ctx.indentationLvl -= 2;
+ } catch (err) {
+ const message = `<Inspection threw (${err.message})>`;
+ str = `${s(`[${label}:`, sp)} ${message}${s(']', sp)}`;
+ }
} else {
- str = ctx.stylize('[Getter]', 'special');
+ str = ctx.stylize(`[${label}]`, sp);
}
} else if (desc.set !== undefined) {
str = ctx.stylize('[Setter]', 'special');
diff --git a/test/parallel/test-util-inspect.js b/test/parallel/test-util-inspect.js
index c0fc3219ce..20b03d2dd0 100644
--- a/test/parallel/test-util-inspect.js
+++ b/test/parallel/test-util-inspect.js
@@ -1764,3 +1764,36 @@ assert.strictEqual(
});
assert.strictEqual(util.inspect(obj), '[Set: null prototype] { 1, 2 }');
}
+
+// Check the getter option.
+{
+ let foo = 1;
+ const get = { get foo() { return foo; } };
+ const getset = {
+ get foo() { return foo; },
+ set foo(val) { foo = val; },
+ get inc() { return ++foo; }
+ };
+ const thrower = { get foo() { throw new Error('Oops'); } };
+ assert.strictEqual(
+ inspect(get, { getters: true, colors: true }),
+ '{ foo: \u001b[36m[Getter:\u001b[39m ' +
+ '\u001b[33m1\u001b[39m\u001b[36m]\u001b[39m }');
+ assert.strictEqual(
+ inspect(thrower, { getters: true }),
+ '{ foo: [Getter: <Inspection threw (Oops)>] }');
+ assert.strictEqual(
+ inspect(getset, { getters: true }),
+ '{ foo: [Getter/Setter: 1], inc: [Getter: 2] }');
+ assert.strictEqual(
+ inspect(getset, { getters: 'get' }),
+ '{ foo: [Getter/Setter], inc: [Getter: 3] }');
+ assert.strictEqual(
+ inspect(getset, { getters: 'set' }),
+ '{ foo: [Getter/Setter: 3], inc: [Getter] }');
+ getset.foo = new Set([[{ a: true }, 2, {}], 'foobar', { x: 1 }]);
+ assert.strictEqual(
+ inspect(getset, { getters: true }),
+ '{ foo: [Getter/Setter] Set { [ [Object], 2, {} ], ' +
+ "'foobar', { x: 1 } },\n inc: [Getter: NaN] }");
+}