Skip to content

Commit

Permalink
util: improve inspect edge cases
Browse files Browse the repository at this point in the history
This makes sure `compact` number mode causes small proxies and map
entries to be printed on a single line.

It also fixed the line break calculation for `compact` mode when not
set to `true`. It now also adds the additional whitespace, comma and
quotes to the formula to prevent exceeding the `breakLength`.

PR-URL: nodejs#27109
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Minwoo Jung <minwoo@nodesource.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
  • Loading branch information
BridgeAR committed Apr 10, 2019
1 parent bd9109c commit 892c51f
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 47 deletions.
92 changes: 46 additions & 46 deletions lib/internal/util/inspect.js
Original file line number Diff line number Diff line change
Expand Up @@ -424,7 +424,8 @@ function formatProxy(ctx, proxy, recurseTimes) {
formatValue(ctx, proxy[1], recurseTimes)
];
ctx.indentationLvl -= 2;
return reduceToSingleString(ctx, res, '', ['Proxy [', ']']);
return reduceToSingleString(
ctx, res, '', ['Proxy [', ']'], kArrayExtrasType, recurseTimes);
}

function findTypedConstructor(value) {
Expand Down Expand Up @@ -786,37 +787,8 @@ function formatRaw(ctx, value, recurseTimes, typedArray) {
}
}

let combine = false;
if (typeof ctx.compact === 'number') {
// Memorize the original output length. In case the the output is grouped,
// prevent lining up the entries on a single line.
const entries = output.length;
// Group array elements together if the array contains at least six separate
// entries.
if (extrasType === kArrayExtrasType && output.length > 6) {
output = groupArrayElements(ctx, output);
}
// `ctx.currentDepth` is set to the most inner depth of the currently
// inspected object part while `recurseTimes` is the actual current depth
// that is inspected.
//
// Example:
//
// const a = { first: [ 1, 2, 3 ], second: { inner: [ 1, 2, 3 ] } }
//
// The deepest depth of `a` is 2 (a.second.inner) and `a.first` has a max
// depth of 1.
//
// Consolidate all entries of the local most inner depth up to
// `ctx.compact`, as long as the properties are smaller than
// `ctx.breakLength`.
if (ctx.currentDepth - recurseTimes < ctx.compact &&
entries === output.length) {
combine = true;
}
}

const res = reduceToSingleString(ctx, output, base, braces, combine);
const res = reduceToSingleString(
ctx, output, base, braces, extrasType, recurseTimes);
const budget = ctx.budget[ctx.indentationLvl] || 0;
const newLength = budget + res.length;
ctx.budget[ctx.indentationLvl] = newLength;
Expand Down Expand Up @@ -984,9 +956,10 @@ function formatBigInt(fn, value) {
function formatPrimitive(fn, value, ctx) {
if (typeof value === 'string') {
if (ctx.compact !== true &&
ctx.indentationLvl + value.length > ctx.breakLength &&
value.length > kMinLineLength) {
const rawMaxLineLength = ctx.breakLength - ctx.indentationLvl;
ctx.indentationLvl + value.length + 4 > ctx.breakLength &&
value.length > kMinLineLength) {
// Subtract the potential quotes, the space and the plus as well (4).
const rawMaxLineLength = ctx.breakLength - ctx.indentationLvl - 4;
const maxLineLength = Math.max(rawMaxLineLength, kMinLineLength);
const lines = Math.ceil(value.length / maxLineLength);
const averageLineLength = Math.ceil(value.length / lines);
Expand Down Expand Up @@ -1231,7 +1204,8 @@ function formatMapIterInner(ctx, recurseTimes, entries, state) {
formatValue(ctx, entries[pos], recurseTimes),
formatValue(ctx, entries[pos + 1], recurseTimes)
];
output[i] = reduceToSingleString(ctx, res, '', ['[', ']']);
output[i] = reduceToSingleString(
ctx, res, '', ['[', ']'], kArrayExtrasType, recurseTimes);
}
}
ctx.indentationLvl -= 2;
Expand Down Expand Up @@ -1368,17 +1342,43 @@ function isBelowBreakLength(ctx, output, start, base) {
return base === '' || !base.includes('\n');
}

function reduceToSingleString(ctx, output, base, braces, combine = false) {
function reduceToSingleString(
ctx, output, base, braces, extrasType, recurseTimes) {
if (ctx.compact !== true) {
if (combine) {
// Line up all entries on a single line in case the entries do not exceed
// `breakLength`. Add 10 as constant to start next to all other factors
// that may reduce `breakLength`.
const start = output.length + ctx.indentationLvl +
braces[0].length + base.length + 10;
if (isBelowBreakLength(ctx, output, start, base)) {
return `${base ? `${base} ` : ''}${braces[0]} ${join(output, ', ')} ` +
braces[1];
if (typeof ctx.compact === 'number' && ctx.compact >= 1) {
// Memorize the original output length. In case the the output is grouped,
// prevent lining up the entries on a single line.
const entries = output.length;
// Group array elements together if the array contains at least six
// separate entries.
if (extrasType === kArrayExtrasType && entries > 6) {
output = groupArrayElements(ctx, output);
}
// `ctx.currentDepth` is set to the most inner depth of the currently
// inspected object part while `recurseTimes` is the actual current depth
// that is inspected.
//
// Example:
//
// const a = { first: [ 1, 2, 3 ], second: { inner: [ 1, 2, 3 ] } }
//
// The deepest depth of `a` is 2 (a.second.inner) and `a.first` has a max
// depth of 1.
//
// Consolidate all entries of the local most inner depth up to
// `ctx.compact`, as long as the properties are smaller than
// `ctx.breakLength`.
if (ctx.currentDepth - recurseTimes < ctx.compact &&
entries === output.length) {
// Line up all entries on a single line in case the entries do not
// exceed `breakLength`. Add 10 as constant to start next to all other
// factors that may reduce `breakLength`.
const start = output.length + ctx.indentationLvl +
braces[0].length + base.length + 10;
if (isBelowBreakLength(ctx, output, start, base)) {
return `${base ? `${base} ` : ''}${braces[0]} ${join(output, ', ')}` +
` ${braces[1]}`;
}
}
}
// Line up each entry on an individual line.
Expand Down
2 changes: 1 addition & 1 deletion test/parallel/test-util-inspect.js
Original file line number Diff line number Diff line change
Expand Up @@ -1674,7 +1674,7 @@ assert.strictEqual(util.inspect('"\'${a}'), "'\"\\'${a}'");
return 'BazError';
}
}, undefined]
].forEach(([Class, message, messages], i) => {
].forEach(([Class, message], i) => {
console.log('Test %i', i);
const foo = new Class(message);
const name = foo.name;
Expand Down

0 comments on commit 892c51f

Please sign in to comment.