From b75af1537dd30f81fd73ce7b1dda3d9f0129ab76 Mon Sep 17 00:00:00 2001 From: Joyee Cheung Date: Wed, 6 Mar 2019 12:33:09 +0100 Subject: [PATCH] lib: move format and formatWithOptions into internal/util/inspect.js So these can be required without requiring the whole `util.js`. PR-URL: https://github.com/nodejs/node/pull/26468 Reviewed-By: Anna Henningsen Reviewed-By: Ruben Bridgewater --- lib/internal/util/inspect.js | 133 +++++++++++++++++++++++++++++++++- lib/util.js | 135 ++--------------------------------- 2 files changed, 137 insertions(+), 131 deletions(-) diff --git a/lib/internal/util/inspect.js b/lib/internal/util/inspect.js index 2ab596f1f83167..cb4beb040d6f97 100644 --- a/lib/internal/util/inspect.js +++ b/lib/internal/util/inspect.js @@ -1354,8 +1354,139 @@ function reduceToSingleString(ctx, output, base, braces, combine = false) { return `${braces[0]}${ln}${join(output, `,\n${indentation} `)} ${braces[1]}`; } +const emptyOptions = {}; +function format(...args) { + return formatWithOptions(emptyOptions, ...args); +} + +let CIRCULAR_ERROR_MESSAGE; +function tryStringify(arg) { + try { + return JSON.stringify(arg); + } catch (err) { + // Populate the circular error message lazily + if (!CIRCULAR_ERROR_MESSAGE) { + try { + const a = {}; a.a = a; JSON.stringify(a); + } catch (err) { + CIRCULAR_ERROR_MESSAGE = err.message; + } + } + if (err.name === 'TypeError' && err.message === CIRCULAR_ERROR_MESSAGE) + return '[Circular]'; + throw err; + } +} + +function formatWithOptions(inspectOptions, f) { + let i, tempStr; + if (typeof f !== 'string') { + if (arguments.length === 1) return ''; + let res = ''; + for (i = 1; i < arguments.length - 1; i++) { + res += inspect(arguments[i], inspectOptions); + res += ' '; + } + res += inspect(arguments[i], inspectOptions); + return res; + } + + if (arguments.length === 2) return f; + + let str = ''; + let a = 2; + let lastPos = 0; + for (i = 0; i < f.length - 1; i++) { + if (f.charCodeAt(i) === 37) { // '%' + const nextChar = f.charCodeAt(++i); + if (a !== arguments.length) { + switch (nextChar) { + case 115: // 's' + tempStr = String(arguments[a++]); + break; + case 106: // 'j' + tempStr = tryStringify(arguments[a++]); + break; + case 100: // 'd' + const tempNum = arguments[a++]; + // eslint-disable-next-line valid-typeof + if (typeof tempNum === 'bigint') { + tempStr = `${tempNum}n`; + } else if (typeof tempNum === 'symbol') { + tempStr = 'NaN'; + } else { + tempStr = `${Number(tempNum)}`; + } + break; + case 79: // 'O' + tempStr = inspect(arguments[a++], inspectOptions); + break; + case 111: // 'o' + { + const opts = { + showHidden: true, + showProxy: true, + depth: 4, + ...inspectOptions + }; + tempStr = inspect(arguments[a++], opts); + break; + } + case 105: // 'i' + const tempInteger = arguments[a++]; + // eslint-disable-next-line valid-typeof + if (typeof tempInteger === 'bigint') { + tempStr = `${tempInteger}n`; + } else if (typeof tempInteger === 'symbol') { + tempStr = 'NaN'; + } else { + tempStr = `${parseInt(tempInteger)}`; + } + break; + case 102: // 'f' + const tempFloat = arguments[a++]; + if (typeof tempFloat === 'symbol') { + tempStr = 'NaN'; + } else { + tempStr = `${parseFloat(tempFloat)}`; + } + break; + case 37: // '%' + str += f.slice(lastPos, i); + lastPos = i + 1; + continue; + default: // Any other character is not a correct placeholder + continue; + } + if (lastPos !== i - 1) + str += f.slice(lastPos, i - 1); + str += tempStr; + lastPos = i + 1; + } else if (nextChar === 37) { + str += f.slice(lastPos, i); + lastPos = i + 1; + } + } + } + if (lastPos === 0) + str = f; + else if (lastPos < f.length) + str += f.slice(lastPos); + while (a < arguments.length) { + const x = arguments[a++]; + if ((typeof x !== 'object' && typeof x !== 'symbol') || x === null) { + str += ` ${x}`; + } else { + str += ` ${inspect(x, inspectOptions)}`; + } + } + return str; +} + module.exports = { inspect, formatProperty, - kObjectType + kObjectType, + format, + formatWithOptions }; diff --git a/lib/util.js b/lib/util.js index 6bc255d694d0de..4467499978f0d9 100644 --- a/lib/util.js +++ b/lib/util.js @@ -22,7 +22,11 @@ 'use strict'; const errors = require('internal/errors'); -const { inspect } = require('internal/util/inspect'); +const { + format, + formatWithOptions, + inspect +} = require('internal/util/inspect'); const { ERR_FALSY_VALUE_REJECTION, ERR_INVALID_ARG_TYPE, @@ -46,137 +50,8 @@ function uncurryThis(func) { } const objectToString = uncurryThis(Object.prototype.toString); -let CIRCULAR_ERROR_MESSAGE; let internalDeepEqual; -function tryStringify(arg) { - try { - return JSON.stringify(arg); - } catch (err) { - // Populate the circular error message lazily - if (!CIRCULAR_ERROR_MESSAGE) { - try { - const a = {}; a.a = a; JSON.stringify(a); - } catch (err) { - CIRCULAR_ERROR_MESSAGE = err.message; - } - } - if (err.name === 'TypeError' && err.message === CIRCULAR_ERROR_MESSAGE) - return '[Circular]'; - throw err; - } -} - -const emptyOptions = {}; -function format(...args) { - return formatWithOptions(emptyOptions, ...args); -} - -function formatWithOptions(inspectOptions, f) { - let i, tempStr; - if (typeof f !== 'string') { - if (arguments.length === 1) return ''; - let res = ''; - for (i = 1; i < arguments.length - 1; i++) { - res += inspect(arguments[i], inspectOptions); - res += ' '; - } - res += inspect(arguments[i], inspectOptions); - return res; - } - - if (arguments.length === 2) return f; - - let str = ''; - let a = 2; - let lastPos = 0; - for (i = 0; i < f.length - 1; i++) { - if (f.charCodeAt(i) === 37) { // '%' - const nextChar = f.charCodeAt(++i); - if (a !== arguments.length) { - switch (nextChar) { - case 115: // 's' - tempStr = String(arguments[a++]); - break; - case 106: // 'j' - tempStr = tryStringify(arguments[a++]); - break; - case 100: // 'd' - const tempNum = arguments[a++]; - // eslint-disable-next-line valid-typeof - if (typeof tempNum === 'bigint') { - tempStr = `${tempNum}n`; - } else if (typeof tempNum === 'symbol') { - tempStr = 'NaN'; - } else { - tempStr = `${Number(tempNum)}`; - } - break; - case 79: // 'O' - tempStr = inspect(arguments[a++], inspectOptions); - break; - case 111: // 'o' - { - const opts = { - showHidden: true, - showProxy: true, - depth: 4, - ...inspectOptions - }; - tempStr = inspect(arguments[a++], opts); - break; - } - case 105: // 'i' - const tempInteger = arguments[a++]; - // eslint-disable-next-line valid-typeof - if (typeof tempInteger === 'bigint') { - tempStr = `${tempInteger}n`; - } else if (typeof tempInteger === 'symbol') { - tempStr = 'NaN'; - } else { - tempStr = `${parseInt(tempInteger)}`; - } - break; - case 102: // 'f' - const tempFloat = arguments[a++]; - if (typeof tempFloat === 'symbol') { - tempStr = 'NaN'; - } else { - tempStr = `${parseFloat(tempFloat)}`; - } - break; - case 37: // '%' - str += f.slice(lastPos, i); - lastPos = i + 1; - continue; - default: // Any other character is not a correct placeholder - continue; - } - if (lastPos !== i - 1) - str += f.slice(lastPos, i - 1); - str += tempStr; - lastPos = i + 1; - } else if (nextChar === 37) { - str += f.slice(lastPos, i); - lastPos = i + 1; - } - } - } - if (lastPos === 0) - str = f; - else if (lastPos < f.length) - str += f.slice(lastPos); - while (a < arguments.length) { - const x = arguments[a++]; - if ((typeof x !== 'object' && typeof x !== 'symbol') || x === null) { - str += ` ${x}`; - } else { - str += ` ${inspect(x, inspectOptions)}`; - } - } - return str; -} - const debugs = {}; let debugEnvRegex = /^$/; if (process.env.NODE_DEBUG) {