From d6ab1ae42b39d64f0bcd65b17145f04a6292dd22 Mon Sep 17 00:00:00 2001 From: nekosu Date: Fri, 25 Apr 2025 23:44:53 +0800 Subject: [PATCH 1/2] feat: add sugar method for PropertyLValue (#1651) --- napi-inl.h | 5 +++++ napi.h | 3 +++ 2 files changed, 8 insertions(+) diff --git a/napi-inl.h b/napi-inl.h index 8e354585c..88a6cd4a7 100644 --- a/napi-inl.h +++ b/napi-inl.h @@ -1577,6 +1577,11 @@ inline Object::PropertyLValue& Object::PropertyLValue::operator=( return *this; } +template +inline Value Object::PropertyLValue::AsValue() const { + return Value(*this); +} + template inline Object::PropertyLValue::PropertyLValue(Object object, Key key) : _env(object.Env()), _object(object), _key(key) {} diff --git a/napi.h b/napi.h index 4838be6cc..bd604c6fd 100644 --- a/napi.h +++ b/napi.h @@ -860,6 +860,9 @@ class Object : public TypeTaggable { template PropertyLValue& operator=(ValueType value); + /// Converts an L-value to a value. For convenience. + Value AsValue() const; + private: PropertyLValue() = delete; PropertyLValue(Object object, Key key); From 740d16c76012b2d1b2b2edf10596d8ba300bca1f Mon Sep 17 00:00:00 2001 From: nekosu Date: Tue, 6 May 2025 14:45:55 +0800 Subject: [PATCH 2/2] test: add test for #1651 --- test/basic_types/value.cc | 6 ++++++ test/basic_types/value.js | 17 +++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/test/basic_types/value.cc b/test/basic_types/value.cc index 0d19726bb..7ec3b7e04 100644 --- a/test/basic_types/value.cc +++ b/test/basic_types/value.cc @@ -128,6 +128,11 @@ static Value ToObject(const CallbackInfo& info) { return MaybeUnwrap(info[0].ToObject()); } +static Value AccessProp(const CallbackInfo& info) { + Object obj = MaybeUnwrap(info[0].ToObject()); + return obj[info[1]].AsValue(); +} + Object InitBasicTypesValue(Env env) { Object exports = Object::New(env); @@ -150,6 +155,7 @@ Object InitBasicTypesValue(Env env) { exports["toNumber"] = Function::New(env, ToNumber); exports["toString"] = Function::New(env, ToString); exports["toObject"] = Function::New(env, ToObject); + exports["accessProp"] = Function::New(env, AccessProp); exports["strictlyEquals"] = Function::New(env, StrictlyEquals); exports["strictlyEqualsOverload"] = Function::New(env, StrictEqualsOverload); diff --git a/test/basic_types/value.js b/test/basic_types/value.js index 173bcc40a..adf73d39d 100644 --- a/test/basic_types/value.js +++ b/test/basic_types/value.js @@ -117,6 +117,21 @@ function test (binding) { assert(value.assertNonEmptyReturnValOnCast()); } + function accessPropTest (value) { + const testObject = { key: '123' }; + const testSymbol = Symbol('123'); + const testNumber = 123; + const destObj = { + testObject, + testSymbol, + [testNumber]: testNumber + }; + assert.strictEqual(value.accessProp(destObj, 'testObject'), testObject); + assert.strictEqual(value.accessProp(destObj, 'testSymbol'), testSymbol); + assert.strictEqual(value.accessProp(destObj, testNumber), testNumber); + assert.strictEqual(value.accessProp(destObj, 'invalidKey'), undefined); + } + const value = binding.basic_types_value; assertValueStrictlyEqual(value); @@ -153,4 +168,6 @@ function test (binding) { assert.strictEqual(value.toString(null), 'null'); typeConverterTest(value.toObject, Object); + + accessPropTest(value); }