|
@ -1,6 +1,7 @@ |
|
|
'use strict'; |
|
|
'use strict'; |
|
|
|
|
|
|
|
|
const uv = process.binding('uv'); |
|
|
const uv = process.binding('uv'); |
|
|
|
|
|
const Debug = require('vm').runInDebugContext('Debug'); |
|
|
|
|
|
|
|
|
const formatRegExp = /%[sdj%]/g; |
|
|
const formatRegExp = /%[sdj%]/g; |
|
|
exports.format = function(f) { |
|
|
exports.format = function(f) { |
|
@ -192,6 +193,14 @@ function arrayToHash(array) { |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function inspectPromise(p) { |
|
|
|
|
|
var mirror = Debug.MakeMirror(p, true); |
|
|
|
|
|
if (!mirror.isPromise()) |
|
|
|
|
|
return null; |
|
|
|
|
|
return {status: mirror.status(), value: mirror.promiseValue().value_}; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function formatValue(ctx, value, recurseTimes) { |
|
|
function formatValue(ctx, value, recurseTimes) { |
|
|
// Provide a hook for user-specified inspect functions.
|
|
|
// Provide a hook for user-specified inspect functions.
|
|
|
// Check that value is an object with an inspect function on it
|
|
|
// Check that value is an object with an inspect function on it
|
|
@ -276,14 +285,43 @@ function formatValue(ctx, value, recurseTimes) { |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
var base = '', array = false, braces = ['{', '}']; |
|
|
var base = '', empty = false, braces, formatter; |
|
|
|
|
|
|
|
|
// Make Array say that they are Array
|
|
|
|
|
|
if (Array.isArray(value)) { |
|
|
if (Array.isArray(value)) { |
|
|
array = true; |
|
|
|
|
|
braces = ['[', ']']; |
|
|
braces = ['[', ']']; |
|
|
|
|
|
empty = value.length === 0; |
|
|
|
|
|
formatter = formatArray; |
|
|
|
|
|
} else if (value instanceof Set) { |
|
|
|
|
|
braces = ['Set {', '}']; |
|
|
|
|
|
// With `showHidden`, `length` will display as a hidden property for
|
|
|
|
|
|
// arrays. For consistency's sake, do the same for `size`, even though this
|
|
|
|
|
|
// property isn't selected by Object.getOwnPropertyNames().
|
|
|
|
|
|
if (ctx.showHidden) |
|
|
|
|
|
keys.unshift('size'); |
|
|
|
|
|
empty = value.size === 0; |
|
|
|
|
|
formatter = formatSet; |
|
|
|
|
|
} else if (value instanceof Map) { |
|
|
|
|
|
braces = ['Map {', '}']; |
|
|
|
|
|
// Ditto.
|
|
|
|
|
|
if (ctx.showHidden) |
|
|
|
|
|
keys.unshift('size'); |
|
|
|
|
|
empty = value.size === 0; |
|
|
|
|
|
formatter = formatMap; |
|
|
|
|
|
} else { |
|
|
|
|
|
// Only create a mirror if the object superficially looks like a Promise.
|
|
|
|
|
|
var promiseInternals = value instanceof Promise && inspectPromise(value); |
|
|
|
|
|
if (promiseInternals) { |
|
|
|
|
|
braces = ['Promise {', '}']; |
|
|
|
|
|
formatter = formatPromise; |
|
|
|
|
|
} else { |
|
|
|
|
|
braces = ['{', '}']; |
|
|
|
|
|
empty = true; // No other data than keys.
|
|
|
|
|
|
formatter = formatObject; |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
empty = empty === true && keys.length === 0; |
|
|
|
|
|
|
|
|
// Make functions say that they are functions
|
|
|
// Make functions say that they are functions
|
|
|
if (typeof value === 'function') { |
|
|
if (typeof value === 'function') { |
|
|
var n = value.name ? ': ' + value.name : ''; |
|
|
var n = value.name ? ': ' + value.name : ''; |
|
@ -323,7 +361,7 @@ function formatValue(ctx, value, recurseTimes) { |
|
|
base = ' ' + '[Boolean: ' + formatted + ']'; |
|
|
base = ' ' + '[Boolean: ' + formatted + ']'; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
if (keys.length === 0 && (!array || value.length === 0)) { |
|
|
if (empty === true) { |
|
|
return braces[0] + base + braces[1]; |
|
|
return braces[0] + base + braces[1]; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
@ -337,14 +375,7 @@ function formatValue(ctx, value, recurseTimes) { |
|
|
|
|
|
|
|
|
ctx.seen.push(value); |
|
|
ctx.seen.push(value); |
|
|
|
|
|
|
|
|
var output; |
|
|
var output = formatter(ctx, value, recurseTimes, visibleKeys, keys); |
|
|
if (array) { |
|
|
|
|
|
output = formatArray(ctx, value, recurseTimes, visibleKeys, keys); |
|
|
|
|
|
} else { |
|
|
|
|
|
output = keys.map(function(key) { |
|
|
|
|
|
return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array); |
|
|
|
|
|
}); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
ctx.seen.pop(); |
|
|
ctx.seen.pop(); |
|
|
|
|
|
|
|
@ -397,6 +428,13 @@ function formatError(value) { |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function formatObject(ctx, value, recurseTimes, visibleKeys, keys) { |
|
|
|
|
|
return keys.map(function(key) { |
|
|
|
|
|
return formatProperty(ctx, value, recurseTimes, visibleKeys, key, false); |
|
|
|
|
|
}); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function formatArray(ctx, value, recurseTimes, visibleKeys, keys) { |
|
|
function formatArray(ctx, value, recurseTimes, visibleKeys, keys) { |
|
|
var output = []; |
|
|
var output = []; |
|
|
for (var i = 0, l = value.length; i < l; ++i) { |
|
|
for (var i = 0, l = value.length; i < l; ++i) { |
|
@ -417,6 +455,59 @@ function formatArray(ctx, value, recurseTimes, visibleKeys, keys) { |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function formatSet(ctx, value, recurseTimes, visibleKeys, keys) { |
|
|
|
|
|
var output = []; |
|
|
|
|
|
value.forEach(function(v) { |
|
|
|
|
|
var nextRecurseTimes = recurseTimes === null ? null : recurseTimes - 1; |
|
|
|
|
|
var str = formatValue(ctx, v, nextRecurseTimes); |
|
|
|
|
|
output.push(str); |
|
|
|
|
|
}); |
|
|
|
|
|
keys.forEach(function(key) { |
|
|
|
|
|
output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, |
|
|
|
|
|
key, false)); |
|
|
|
|
|
}); |
|
|
|
|
|
return output; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function formatMap(ctx, value, recurseTimes, visibleKeys, keys) { |
|
|
|
|
|
var output = []; |
|
|
|
|
|
value.forEach(function(v, k) { |
|
|
|
|
|
var nextRecurseTimes = recurseTimes === null ? null : recurseTimes - 1; |
|
|
|
|
|
var str = formatValue(ctx, k, nextRecurseTimes); |
|
|
|
|
|
str += ' => '; |
|
|
|
|
|
str += formatValue(ctx, v, nextRecurseTimes); |
|
|
|
|
|
output.push(str); |
|
|
|
|
|
}); |
|
|
|
|
|
keys.forEach(function(key) { |
|
|
|
|
|
output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, |
|
|
|
|
|
key, false)); |
|
|
|
|
|
}); |
|
|
|
|
|
return output; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
function formatPromise(ctx, value, recurseTimes, visibleKeys, keys) { |
|
|
|
|
|
var output = []; |
|
|
|
|
|
var internals = inspectPromise(value); |
|
|
|
|
|
if (internals.status === 'pending') { |
|
|
|
|
|
output.push('<pending>'); |
|
|
|
|
|
} else { |
|
|
|
|
|
var nextRecurseTimes = recurseTimes === null ? null : recurseTimes - 1; |
|
|
|
|
|
var str = formatValue(ctx, internals.value, nextRecurseTimes); |
|
|
|
|
|
if (internals.status === 'rejected') { |
|
|
|
|
|
output.push('<rejected> ' + str); |
|
|
|
|
|
} else { |
|
|
|
|
|
output.push(str); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
keys.forEach(function(key) { |
|
|
|
|
|
output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, |
|
|
|
|
|
key, false)); |
|
|
|
|
|
}); |
|
|
|
|
|
return output; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) { |
|
|
function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) { |
|
|
var name, str, desc; |
|
|
var name, str, desc; |
|
|
desc = Object.getOwnPropertyDescriptor(value, key) || { value: value[key] }; |
|
|
desc = Object.getOwnPropertyDescriptor(value, key) || { value: value[key] }; |
|
@ -488,7 +579,10 @@ function reduceToSingleString(output, base, braces) { |
|
|
|
|
|
|
|
|
if (length > 60) { |
|
|
if (length > 60) { |
|
|
return braces[0] + |
|
|
return braces[0] + |
|
|
(base === '' ? '' : base + '\n ') + |
|
|
// If the opening "brace" is too large, like in the case of "Set {",
|
|
|
|
|
|
// we need to force the first item to be on the next line or the
|
|
|
|
|
|
// items will not line up correctly.
|
|
|
|
|
|
(base === '' && braces[0].length === 1 ? '' : base + '\n ') + |
|
|
' ' + |
|
|
' ' + |
|
|
output.join(',\n ') + |
|
|
output.join(',\n ') + |
|
|
' ' + |
|
|
' ' + |
|
|