@@ -192,6 +192,17 @@ struct napi_env__ {
192
192
(out) = v8::type::New ((buffer), (byte_offset), (length)); \
193
193
} while (0 )
194
194
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
+
195
206
namespace {
196
207
namespace v8impl {
197
208
@@ -1604,19 +1615,92 @@ napi_status napi_define_class(napi_env env,
1604
1615
napi_status napi_get_property_names (napi_env env,
1605
1616
napi_value object,
1606
1617
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) {
1607
1634
NAPI_PREAMBLE (env);
1608
1635
CHECK_ARG (env, result);
1609
1636
1610
1637
v8::Local<v8::Context> context = env->context ();
1611
1638
v8::Local<v8::Object> obj;
1612
1639
CHECK_TO_OBJECT (env, context, obj, object);
1613
1640
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
+ }
1615
1680
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
+ }
1617
1691
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 ());
1620
1704
return GET_RETURN_STATUS (env);
1621
1705
}
1622
1706
0 commit comments