From 064057b7ad0ee6f76f43846b4f002072dafa1702 Mon Sep 17 00:00:00 2001 From: Gus Caplan Date: Wed, 16 May 2018 12:07:20 -0500 Subject: [PATCH] util: support inspecting namespaces of unevaluated modules PR-URL: https://github.com/nodejs/node/pull/20782 Reviewed-By: Ben Noordhuis Reviewed-By: Guy Bedford Reviewed-By: Ruben Bridgewater Reviewed-By: James M Snell --- lib/util.js | 53 ++++++++++++++++---- test/parallel/test-util-inspect-namespace.js | 22 ++++++++ 2 files changed, 64 insertions(+), 11 deletions(-) create mode 100644 test/parallel/test-util-inspect-namespace.js diff --git a/lib/util.js b/lib/util.js index f358adefdb25d6..2ef7e4e54c5c6d 100644 --- a/lib/util.js +++ b/lib/util.js @@ -629,6 +629,9 @@ function formatValue(ctx, value, recurseTimes, ln) { } else { extra = '[items unknown]'; } + } else if (types.isModuleNamespaceObject(value)) { + braces[0] = `[${tag}] {`; + formatter = formatNamespaceObject; } else { // Check boxed primitives other than string with valueOf() // NOTE: `Date` has to be checked first! @@ -757,6 +760,15 @@ function formatObject(ctx, value, recurseTimes, keys) { return output; } +function formatNamespaceObject(ctx, value, recurseTimes, keys) { + const len = keys.length; + const output = new Array(len); + for (var i = 0; i < len; i++) { + output[i] = formatNamespaceProperty(ctx, value, recurseTimes, keys[i]); + } + return output; +} + // The array is sparse and/or has extra keys function formatSpecialArray(ctx, value, recurseTimes, keys, maxLength, valLen) { const output = []; @@ -980,8 +992,36 @@ function formatPromise(ctx, value, recurseTimes, keys) { return output; } +function formatKey(ctx, key, enumerable) { + if (typeof key === 'symbol') { + return `[${ctx.stylize(key.toString(), 'symbol')}]`; + } + if (enumerable === false) { + return `[${key}]`; + } + if (keyStrRegExp.test(key)) { + return ctx.stylize(key, 'name'); + } + return ctx.stylize(strEscape(key), 'string'); +} + +function formatNamespaceProperty(ctx, ns, recurseTimes, key) { + let value; + try { + value = formatValue(ctx, ns[key], recurseTimes, true); + } catch (err) { + if (err instanceof ReferenceError) { + value = ctx.stylize('', 'special'); + } else { + throw err; + } + } + + return `${formatKey(ctx, key)}: ${value}`; +} + function formatProperty(ctx, value, recurseTimes, key, array) { - let name, str; + let str; const desc = Object.getOwnPropertyDescriptor(value, key) || { value: value[key], enumerable: true }; if (desc.value !== undefined) { @@ -1003,17 +1043,8 @@ function formatProperty(ctx, value, recurseTimes, key, array) { if (array === 1) { return str; } - if (typeof key === 'symbol') { - name = `[${ctx.stylize(key.toString(), 'symbol')}]`; - } else if (desc.enumerable === false) { - name = `[${key}]`; - } else if (keyStrRegExp.test(key)) { - name = ctx.stylize(key, 'name'); - } else { - name = ctx.stylize(strEscape(key), 'string'); - } - return `${name}: ${str}`; + return `${formatKey(ctx, key, desc.enumerable)}: ${str}`; } function reduceToSingleString(ctx, output, base, braces, addLn) { diff --git a/test/parallel/test-util-inspect-namespace.js b/test/parallel/test-util-inspect-namespace.js new file mode 100644 index 00000000000000..fddbcdb34697d9 --- /dev/null +++ b/test/parallel/test-util-inspect-namespace.js @@ -0,0 +1,22 @@ +'use strict'; + +// Flags: --experimental-vm-modules + +const common = require('../common'); +const assert = require('assert'); + +common.crashOnUnhandledRejection(); + +const { Module } = require('vm'); +const { inspect } = require('util'); + +(async () => { + const m = new Module('export const a = 1; export var b = 2'); + await m.link(() => 0); + m.instantiate(); + assert.strictEqual( + inspect(m.namespace), + '[Module] { a: , b: undefined }'); + await m.evaluate(); + assert.strictEqual(inspect(m.namespace), '[Module] { a: 1, b: 2 }'); +})();