@@ -192,6 +192,17 @@ struct napi_env__ {
192192 (out) = v8::type::New ((buffer), (byte_offset), (length)); \
193193 } while (0 )
194194
195+ #define RETURN_STATUS_IF_FALSE_WITH_PREAMBLE (env, condition, status ) \
196+ do { \
197+ if (!(condition)) { \
198+ return napi_set_last_error ( \
199+ (env), try_catch.HasCaught () ? napi_pending_exception : (status)); \
200+ } \
201+ } while (0 )
202+
203+ #define CHECK_MAYBE_EMPTY_WITH_PREAMBLE (env, maybe, status ) \
204+ RETURN_STATUS_IF_FALSE_WITH_PREAMBLE ((env), !((maybe).IsEmpty()), (status))
205+
195206namespace {
196207namespace v8impl {
197208
@@ -1604,19 +1615,92 @@ napi_status napi_define_class(napi_env env,
16041615napi_status napi_get_property_names (napi_env env,
16051616 napi_value object,
16061617 napi_value* result) {
1618+ return napi_get_all_property_names (
1619+ env,
1620+ object,
1621+ napi_key_include_prototypes,
1622+ static_cast <napi_key_filter>(napi_key_enumerable |
1623+ napi_key_skip_symbols),
1624+ napi_key_numbers_to_strings,
1625+ result);
1626+ }
1627+
1628+ napi_status napi_get_all_property_names (napi_env env,
1629+ napi_value object,
1630+ napi_key_collection_mode key_mode,
1631+ napi_key_filter key_filter,
1632+ napi_key_conversion key_conversion,
1633+ napi_value* result) {
16071634 NAPI_PREAMBLE (env);
16081635 CHECK_ARG (env, result);
16091636
16101637 v8::Local<v8::Context> context = env->context ();
16111638 v8::Local<v8::Object> obj;
16121639 CHECK_TO_OBJECT (env, context, obj, object);
16131640
1614- auto maybe_propertynames = obj->GetPropertyNames (context);
1641+ v8::PropertyFilter filter = v8::PropertyFilter::ALL_PROPERTIES;
1642+ if (key_filter & napi_key_writable) {
1643+ filter =
1644+ static_cast <v8::PropertyFilter>(filter |
1645+ v8::PropertyFilter::ONLY_WRITABLE);
1646+ }
1647+ if (key_filter & napi_key_enumerable) {
1648+ filter =
1649+ static_cast <v8::PropertyFilter>(filter |
1650+ v8::PropertyFilter::ONLY_ENUMERABLE);
1651+ }
1652+ if (key_filter & napi_key_configurable) {
1653+ filter =
1654+ static_cast <v8::PropertyFilter>(filter |
1655+ v8::PropertyFilter::ONLY_WRITABLE);
1656+ }
1657+ if (key_filter & napi_key_skip_strings) {
1658+ filter =
1659+ static_cast <v8::PropertyFilter>(filter |
1660+ v8::PropertyFilter::SKIP_STRINGS);
1661+ }
1662+ if (key_filter & napi_key_skip_symbols) {
1663+ filter =
1664+ static_cast <v8::PropertyFilter>(filter |
1665+ v8::PropertyFilter::SKIP_SYMBOLS);
1666+ }
1667+ v8::KeyCollectionMode collection_mode;
1668+ v8::KeyConversionMode conversion_mode;
1669+
1670+ switch (key_mode) {
1671+ case napi_key_include_prototypes:
1672+ collection_mode = v8::KeyCollectionMode::kIncludePrototypes ;
1673+ break ;
1674+ case napi_key_own_only:
1675+ collection_mode = v8::KeyCollectionMode::kOwnOnly ;
1676+ break ;
1677+ default :
1678+ return napi_set_last_error (env, napi_invalid_arg);
1679+ }
16151680
1616- CHECK_MAYBE_EMPTY (env, maybe_propertynames, napi_generic_failure);
1681+ switch (key_conversion) {
1682+ case napi_key_keep_numbers:
1683+ conversion_mode = v8::KeyConversionMode::kKeepNumbers ;
1684+ break ;
1685+ case napi_key_numbers_to_strings:
1686+ conversion_mode = v8::KeyConversionMode::kConvertToString ;
1687+ break ;
1688+ default :
1689+ return napi_set_last_error (env, napi_invalid_arg);
1690+ }
16171691
1618- *result = v8impl::JsValueFromV8LocalValue (
1619- maybe_propertynames.ToLocalChecked ());
1692+ v8::MaybeLocal<v8::Array> maybe_all_propertynames =
1693+ obj->GetPropertyNames (context,
1694+ collection_mode,
1695+ filter,
1696+ v8::IndexFilter::kIncludeIndices ,
1697+ conversion_mode);
1698+
1699+ CHECK_MAYBE_EMPTY_WITH_PREAMBLE (
1700+ env, maybe_all_propertynames, napi_generic_failure);
1701+
1702+ *result =
1703+ v8impl::JsValueFromV8LocalValue (maybe_all_propertynames.ToLocalChecked ());
16201704 return GET_RETURN_STATUS (env);
16211705}
16221706
0 commit comments