Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 0911813

Browse filesBrowse files
himself65MylesBorins
authored andcommitted
n-api: add napi_get_all_property_names
Co-Authored-By: Gabriel Schulhof <gabriel.schulhof@intel.com> PR-URL: #30006 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Chengzhong Wu <legendecas@gmail.com> Reviewed-By: Gabriel Schulhof <gabriel.schulhof@intel.com> Reviewed-By: Michael Dawson <michael_dawson@ca.ibm.com> Reviewed-By: Rich Trott <rtrott@gmail.com>
1 parent 7a5d4fa commit 0911813
Copy full SHA for 0911813

File tree

Expand file treeCollapse file tree

7 files changed

+245
-12
lines changed
Open diff view settings
Filter options
Expand file treeCollapse file tree

7 files changed

+245
-12
lines changed
Open diff view settings
Collapse file

‎doc/api/n-api.md‎

Copy file name to clipboardExpand all lines: doc/api/n-api.md
+91Lines changed: 91 additions & 0 deletions
  • Display the source diff
  • Display the rich diff
Original file line numberDiff line numberDiff line change
@@ -1660,6 +1660,66 @@ However, for better performance, it's better for the caller to make sure that
16601660
the `napi_value` in question is of the JavaScript type expected by the API.
16611661

16621662
### Enum types
1663+
#### napi_key_collection_mode
1664+
<!-- YAML
1665+
added: REPLACEME
1666+
-->
1667+
1668+
> Stability: 1 - Experimental
1669+
1670+
```C
1671+
typedef enum {
1672+
napi_key_include_prototypes,
1673+
napi_key_own_only
1674+
} napi_key_collection_mode;
1675+
```
1676+
1677+
Describes the `Keys/Properties` filter enums:
1678+
1679+
`napi_key_collection_mode` limits the range of collected properties.
1680+
1681+
`napi_key_own_only` limits the collected properties to the given
1682+
object only. `napi_key_include_prototypes` will include all keys
1683+
of the objects's prototype chain as well.
1684+
1685+
#### napi_key_filter
1686+
<!-- YAML
1687+
added: REPLACEME
1688+
-->
1689+
1690+
> Stability: 1 - Experimental
1691+
1692+
```C
1693+
typedef enum {
1694+
napi_key_all_properties = 0,
1695+
napi_key_writable = 1,
1696+
napi_key_enumerable = 1 << 1,
1697+
napi_key_configurable = 1 << 2,
1698+
napi_key_skip_strings = 1 << 3,
1699+
napi_key_skip_symbols = 1 << 4
1700+
} napi_key_filter;
1701+
```
1702+
1703+
Property filter bits. They can be or'ed to build a composite filter.
1704+
1705+
#### napi_key_conversion
1706+
<!-- YAML
1707+
added: REPLACEME
1708+
-->
1709+
1710+
> Stability: 1 - Experimental
1711+
1712+
```C
1713+
typedef enum {
1714+
napi_key_keep_numbers,
1715+
napi_key_numbers_to_strings
1716+
} napi_key_conversion;
1717+
```
1718+
1719+
`napi_key_numbers_to_strings` will convert integer indices to
1720+
strings. `napi_key_keep_numbers` will return numbers for integer
1721+
indices.
1722+
16631723
#### napi_valuetype
16641724

16651725
```C
@@ -3532,6 +3592,37 @@ This API returns the names of the enumerable properties of `object` as an array
35323592
of strings. The properties of `object` whose key is a symbol will not be
35333593
included.
35343594

3595+
#### napi_get_all_property_names
3596+
<!-- YAML
3597+
added: REPLACEME
3598+
-->
3599+
3600+
> Stability: 1 - Experimental
3601+
3602+
```C
3603+
napi_get_all_property_names(napi_env env,
3604+
napi_value object,
3605+
napi_key_collection_mode key_mode,
3606+
napi_key_filter key_filter,
3607+
napi_key_conversion key_conversion,
3608+
napi_value* result);
3609+
```
3610+
3611+
* `[in] env`: The environment that the N-API call is invoked under.
3612+
* `[in] object`: The object from which to retrieve the properties.
3613+
* `[in] key_mode`: Whether to retrieve prototype properties as well.
3614+
* `[in] key_filter`: Which properties to retrieve
3615+
(enumerable/readable/writable).
3616+
* `[in] key_conversion`: Whether to convert numbered property keys to strings.
3617+
* `[out] result`: A `napi_value` representing an array of JavaScript values
3618+
that represent the property names of the object. [`napi_get_array_length`][] and
3619+
[`napi_get_element`][] can be used to iterate over `result`.
3620+
3621+
Returns `napi_ok` if the API succeeded.
3622+
3623+
This API returns an array containing the names of the available properties
3624+
of this object.
3625+
35353626
#### napi_set_property
35363627
<!-- YAML
35373628
added: v8.0.0
Collapse file

‎src/js_native_api.h‎

Copy file name to clipboardExpand all lines: src/js_native_api.h
+9Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -506,6 +506,15 @@ NAPI_EXTERN napi_status napi_get_value_bigint_words(napi_env env,
506506
size_t* word_count,
507507
uint64_t* words);
508508

509+
// Object
510+
NAPI_EXTERN napi_status
511+
napi_get_all_property_names(napi_env env,
512+
napi_value object,
513+
napi_key_collection_mode key_mode,
514+
napi_key_filter key_filter,
515+
napi_key_conversion key_conversion,
516+
napi_value* result);
517+
509518
// Instance data
510519
NAPI_EXTERN napi_status napi_set_instance_data(napi_env env,
511520
void* data,
Collapse file

‎src/js_native_api_types.h‎

Copy file name to clipboardExpand all lines: src/js_native_api_types.h
+21Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,4 +115,25 @@ typedef struct {
115115
napi_status error_code;
116116
} napi_extended_error_info;
117117

118+
#ifdef NAPI_EXPERIMENTAL
119+
typedef enum {
120+
napi_key_include_prototypes,
121+
napi_key_own_only
122+
} napi_key_collection_mode;
123+
124+
typedef enum {
125+
napi_key_all_properties = 0,
126+
napi_key_writable = 1,
127+
napi_key_enumerable = 1 << 1,
128+
napi_key_configurable = 1 << 2,
129+
napi_key_skip_strings = 1 << 3,
130+
napi_key_skip_symbols = 1 << 4
131+
} napi_key_filter;
132+
133+
typedef enum {
134+
napi_key_keep_numbers,
135+
napi_key_numbers_to_strings
136+
} napi_key_conversion;
137+
#endif
138+
118139
#endif // SRC_JS_NATIVE_API_TYPES_H_
Collapse file

‎src/js_native_api_v8.cc‎

Copy file name to clipboardExpand all lines: src/js_native_api_v8.cc
+77-11Lines changed: 77 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -898,26 +898,92 @@ napi_status napi_define_class(napi_env env,
898898
napi_status napi_get_property_names(napi_env env,
899899
napi_value object,
900900
napi_value* result) {
901+
return napi_get_all_property_names(
902+
env,
903+
object,
904+
napi_key_include_prototypes,
905+
static_cast<napi_key_filter>(napi_key_enumerable |
906+
napi_key_skip_symbols),
907+
napi_key_numbers_to_strings,
908+
result);
909+
}
910+
911+
napi_status napi_get_all_property_names(napi_env env,
912+
napi_value object,
913+
napi_key_collection_mode key_mode,
914+
napi_key_filter key_filter,
915+
napi_key_conversion key_conversion,
916+
napi_value* result) {
901917
NAPI_PREAMBLE(env);
902918
CHECK_ARG(env, result);
903919

904920
v8::Local<v8::Context> context = env->context();
905921
v8::Local<v8::Object> obj;
906922
CHECK_TO_OBJECT(env, context, obj, object);
907923

908-
v8::MaybeLocal<v8::Array> maybe_propertynames = obj->GetPropertyNames(
909-
context,
910-
v8::KeyCollectionMode::kIncludePrototypes,
911-
static_cast<v8::PropertyFilter>(
912-
v8::PropertyFilter::ONLY_ENUMERABLE |
913-
v8::PropertyFilter::SKIP_SYMBOLS),
914-
v8::IndexFilter::kIncludeIndices,
915-
v8::KeyConversionMode::kConvertToString);
924+
v8::PropertyFilter filter = v8::PropertyFilter::ALL_PROPERTIES;
925+
if (key_filter & napi_key_writable) {
926+
filter =
927+
static_cast<v8::PropertyFilter>(filter |
928+
v8::PropertyFilter::ONLY_WRITABLE);
929+
}
930+
if (key_filter & napi_key_enumerable) {
931+
filter =
932+
static_cast<v8::PropertyFilter>(filter |
933+
v8::PropertyFilter::ONLY_ENUMERABLE);
934+
}
935+
if (key_filter & napi_key_configurable) {
936+
filter =
937+
static_cast<v8::PropertyFilter>(filter |
938+
v8::PropertyFilter::ONLY_WRITABLE);
939+
}
940+
if (key_filter & napi_key_skip_strings) {
941+
filter =
942+
static_cast<v8::PropertyFilter>(filter |
943+
v8::PropertyFilter::SKIP_STRINGS);
944+
}
945+
if (key_filter & napi_key_skip_symbols) {
946+
filter =
947+
static_cast<v8::PropertyFilter>(filter |
948+
v8::PropertyFilter::SKIP_SYMBOLS);
949+
}
950+
v8::KeyCollectionMode collection_mode;
951+
v8::KeyConversionMode conversion_mode;
952+
953+
switch (key_mode) {
954+
case napi_key_include_prototypes:
955+
collection_mode = v8::KeyCollectionMode::kIncludePrototypes;
956+
break;
957+
case napi_key_own_only:
958+
collection_mode = v8::KeyCollectionMode::kOwnOnly;
959+
break;
960+
default:
961+
return napi_set_last_error(env, napi_invalid_arg);
962+
}
916963

917-
CHECK_MAYBE_EMPTY(env, maybe_propertynames, napi_generic_failure);
964+
switch (key_conversion) {
965+
case napi_key_keep_numbers:
966+
conversion_mode = v8::KeyConversionMode::kKeepNumbers;
967+
break;
968+
case napi_key_numbers_to_strings:
969+
conversion_mode = v8::KeyConversionMode::kConvertToString;
970+
break;
971+
default:
972+
return napi_set_last_error(env, napi_invalid_arg);
973+
}
918974

919-
*result = v8impl::JsValueFromV8LocalValue(
920-
maybe_propertynames.ToLocalChecked());
975+
v8::MaybeLocal<v8::Array> maybe_all_propertynames =
976+
obj->GetPropertyNames(context,
977+
collection_mode,
978+
filter,
979+
v8::IndexFilter::kIncludeIndices,
980+
conversion_mode);
981+
982+
CHECK_MAYBE_EMPTY_WITH_PREAMBLE(
983+
env, maybe_all_propertynames, napi_generic_failure);
984+
985+
*result =
986+
v8impl::JsValueFromV8LocalValue(maybe_all_propertynames.ToLocalChecked());
921987
return GET_RETURN_STATUS(env);
922988
}
923989

Collapse file

‎src/js_native_api_v8.h‎

Copy file name to clipboardExpand all lines: src/js_native_api_v8.h
+11Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,17 @@ napi_status napi_set_last_error(napi_env env, napi_status error_code,
165165
} \
166166
} while (0)
167167

168+
#define RETURN_STATUS_IF_FALSE_WITH_PREAMBLE(env, condition, status) \
169+
do { \
170+
if (!(condition)) { \
171+
return napi_set_last_error( \
172+
(env), try_catch.HasCaught() ? napi_pending_exception : (status)); \
173+
} \
174+
} while (0)
175+
176+
#define CHECK_MAYBE_EMPTY_WITH_PREAMBLE(env, maybe, status) \
177+
RETURN_STATUS_IF_FALSE_WITH_PREAMBLE((env), !((maybe).IsEmpty()), (status))
178+
168179
namespace v8impl {
169180

170181
//=== Conversion between V8 Handles and napi_value ========================
Collapse file

‎test/js-native-api/test_object/test.js‎

Copy file name to clipboardExpand all lines: test/js-native-api/test_object/test.js
+6-1Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -212,8 +212,10 @@ assert.strictEqual(newObject.test_string, 'test string');
212212
inherited: 1
213213
});
214214

215+
const fooSymbol = Symbol('foo');
216+
215217
object.normal = 2;
216-
object[Symbol('foo')] = 3;
218+
object[fooSymbol] = 3;
217219
Object.defineProperty(object, 'unenumerable', {
218220
value: 4,
219221
enumerable: false,
@@ -224,6 +226,9 @@ assert.strictEqual(newObject.test_string, 'test string');
224226

225227
assert.deepStrictEqual(test_object.GetPropertyNames(object),
226228
['5', 'normal', 'inherited']);
229+
230+
assert.deepStrictEqual(test_object.GetSymbolNames(object),
231+
[fooSymbol]);
227232
}
228233

229234
// Verify that passing NULL to napi_set_property() results in the correct
Collapse file

‎test/js-native-api/test_object/test_object.c‎

Copy file name to clipboardExpand all lines: test/js-native-api/test_object/test_object.c
+30Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
#define NAPI_EXPERIMENTAL
2+
13
#include <js_native_api.h>
24
#include "../common.h"
35
#include <string.h>
@@ -82,6 +84,33 @@ static napi_value GetPropertyNames(napi_env env, napi_callback_info info) {
8284
return output;
8385
}
8486

87+
static napi_value GetSymbolNames(napi_env env, napi_callback_info info) {
88+
size_t argc = 1;
89+
napi_value args[1];
90+
NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, NULL, NULL));
91+
92+
NAPI_ASSERT(env, argc >= 1, "Wrong number of arguments");
93+
94+
napi_valuetype value_type0;
95+
NAPI_CALL(env, napi_typeof(env, args[0], &value_type0));
96+
97+
NAPI_ASSERT(env,
98+
value_type0 == napi_object,
99+
"Wrong type of arguments. Expects an object as first argument.");
100+
101+
napi_value output;
102+
NAPI_CALL(env,
103+
napi_get_all_property_names(
104+
env,
105+
args[0],
106+
napi_key_include_prototypes,
107+
napi_key_skip_strings,
108+
napi_key_numbers_to_strings,
109+
&output));
110+
111+
return output;
112+
}
113+
85114
static napi_value Set(napi_env env, napi_callback_info info) {
86115
size_t argc = 3;
87116
napi_value args[3];
@@ -449,6 +478,7 @@ napi_value Init(napi_env env, napi_value exports) {
449478
DECLARE_NAPI_PROPERTY("Get", Get),
450479
DECLARE_NAPI_PROPERTY("GetNamed", GetNamed),
451480
DECLARE_NAPI_PROPERTY("GetPropertyNames", GetPropertyNames),
481+
DECLARE_NAPI_PROPERTY("GetSymbolNames", GetSymbolNames),
452482
DECLARE_NAPI_PROPERTY("Set", Set),
453483
DECLARE_NAPI_PROPERTY("SetNamed", SetNamed),
454484
DECLARE_NAPI_PROPERTY("Has", Has),

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.