From 95498df1cfc887e277c18cd1fce7de9c93a5569e Mon Sep 17 00:00:00 2001 From: Ruben Bridgewater Date: Wed, 1 May 2019 22:21:00 +0200 Subject: [PATCH] util: inspect constructor closer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This adds an extra check to `util.inspect` to closer inspect object constructors in case there's not much other information about the constructor. PR-URL: https://github.com/nodejs/node/pull/27522 Backport-PR-URL: https://github.com/nodejs/node/pull/27570 Reviewed-By: Anna Henningsen Reviewed-By: Michaƫl Zasso Reviewed-By: Rich Trott Reviewed-By: Yongsheng Zhang --- lib/internal/util/inspect.js | 4 +++- src/node_util.cc | 11 +++++++++++ test/parallel/test-util-inspect.js | 10 +++++----- 3 files changed, 19 insertions(+), 6 deletions(-) diff --git a/lib/internal/util/inspect.js b/lib/internal/util/inspect.js index 7f189b5b7466ef..90be07535730c4 100644 --- a/lib/internal/util/inspect.js +++ b/lib/internal/util/inspect.js @@ -28,6 +28,7 @@ const { kPending, kRejected, previewEntries, + getConstructorName: internalGetConstructorName, propertyFilter: { ALL_PROPERTIES, ONLY_ENUMERABLE @@ -349,6 +350,7 @@ function getEmptyFormatArray() { function getConstructorName(obj, ctx) { let firstProto; + const tmp = obj; while (obj) { const descriptor = Object.getOwnPropertyDescriptor(obj, 'constructor'); if (descriptor !== undefined && @@ -367,7 +369,7 @@ function getConstructorName(obj, ctx) { return null; } - return `<${inspect(firstProto, { + return `${internalGetConstructorName(tmp)} <${inspect(firstProto, { ...ctx, customInspect: false })}>`; diff --git a/src/node_util.cc b/src/node_util.cc index 180c58c4168e1d..0c498e2838c4fd 100644 --- a/src/node_util.cc +++ b/src/node_util.cc @@ -58,6 +58,16 @@ static void GetOwnNonIndexProperties( args.GetReturnValue().Set(properties); } +static void GetConstructorName( + const FunctionCallbackInfo& args) { + CHECK(args[0]->IsObject()); + + Local object = args[0].As(); + Local name = object->GetConstructorName(); + + args.GetReturnValue().Set(name); +} + static void GetPromiseDetails(const FunctionCallbackInfo& args) { // Return undefined if it's not a Promise. if (!args[0]->IsPromise()) @@ -262,6 +272,7 @@ void Initialize(Local target, env->SetMethodNoSideEffect(target, "previewEntries", PreviewEntries); env->SetMethodNoSideEffect(target, "getOwnNonIndexProperties", GetOwnNonIndexProperties); + env->SetMethodNoSideEffect(target, "getConstructorName", GetConstructorName); env->SetMethod(target, "arrayBufferViewHasBuffer", ArrayBufferViewHasBuffer); Local constants = Object::New(env->isolate()); diff --git a/test/parallel/test-util-inspect.js b/test/parallel/test-util-inspect.js index f1d5680d650ee4..4ecb69997863b0 100644 --- a/test/parallel/test-util-inspect.js +++ b/test/parallel/test-util-inspect.js @@ -2003,11 +2003,11 @@ assert.strictEqual( Object.setPrototypeOf(obj, value); assert.strictEqual( util.inspect(obj), - '<[Function (null prototype)]> { a: true }' + 'Object <[Function (null prototype)]> { a: true }' ); assert.strictEqual( util.inspect(obj, { colors: true }), - '<\u001b[36m[Function (null prototype)]\u001b[39m> ' + + 'Object <\u001b[36m[Function (null prototype)]\u001b[39m> ' + '{ a: \u001b[33mtrue\u001b[39m }' ); @@ -2017,14 +2017,14 @@ assert.strictEqual( Object.setPrototypeOf(obj, value); assert.strictEqual( util.inspect(obj), - '<[Array: null prototype] []> { a: true }' + 'Object <[Array: null prototype] []> { a: true }' ); function StorageObject() {} StorageObject.prototype = Object.create(null); assert.strictEqual( util.inspect(new StorageObject()), - '<[Object: null prototype] {}> {}' + 'StorageObject <[Object: null prototype] {}> {}' ); obj = [1, 2, 3]; @@ -2034,7 +2034,7 @@ assert.strictEqual( Object.setPrototypeOf(obj, Object.create(null)); assert.strictEqual( inspect(obj), - "<[Object: null prototype] {}> { '0': 1, '1': 2, '2': 3 }" + "Array <[Object: null prototype] {}> { '0': 1, '1': 2, '2': 3 }" ); }