Skip to content

Commit 97bc4c1

Browse files
authored
Add PropertyDescriptor creation methods (#29)
Add static methods on the PropertyDescriptor class that provide convenient ways to construct PropertyDescriptor instances for different kinds of property descriptors. These are equivalent to the similar static methods on the ObjectWrap class, except they are for use when defining properties outside of an object-wrapping scenario. Callbacks are templatized (like with Function::New()) so that they can work with lambdas or regular function pointers. New test cases cover the various overloads for constructing property descriptors and defining properties. And the Name class constructors needed to be made public, to allow code like value.As<Name>(), that is used by the test.
1 parent ce9f0d9 commit 97bc4c1

File tree

6 files changed

+495
-5
lines changed

6 files changed

+495
-5
lines changed

napi-inl.h

Lines changed: 259 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1125,6 +1125,35 @@ struct FinalizeData {
11251125
Hint* hint;
11261126
};
11271127

1128+
template <typename Getter, typename Setter>
1129+
struct AccessorCallbackData {
1130+
static inline
1131+
napi_value GetterWrapper(napi_env env, napi_callback_info info) {
1132+
try {
1133+
CallbackInfo callbackInfo(env, info);
1134+
AccessorCallbackData* callbackData =
1135+
static_cast<AccessorCallbackData*>(callbackInfo.Data());
1136+
return callbackData->getterCallback(callbackInfo);
1137+
}
1138+
NAPI_RETHROW_JS_ERROR(env)
1139+
}
1140+
1141+
static inline
1142+
napi_value SetterWrapper(napi_env env, napi_callback_info info) {
1143+
try {
1144+
CallbackInfo callbackInfo(env, info);
1145+
AccessorCallbackData* callbackData =
1146+
static_cast<AccessorCallbackData*>(callbackInfo.Data());
1147+
callbackData->setterCallback(callbackInfo);
1148+
return nullptr;
1149+
}
1150+
NAPI_RETHROW_JS_ERROR(env)
1151+
}
1152+
1153+
Getter getterCallback;
1154+
Setter setterCallback;
1155+
};
1156+
11281157
} // namespace details
11291158

11301159
template <typename Callable>
@@ -1908,6 +1937,236 @@ inline void CallbackInfo::SetData(void* data) {
19081937
_data = data;
19091938
}
19101939

1940+
////////////////////////////////////////////////////////////////////////////////
1941+
// PropertyDescriptor class
1942+
////////////////////////////////////////////////////////////////////////////////
1943+
1944+
template <typename Getter>
1945+
inline PropertyDescriptor
1946+
PropertyDescriptor::Accessor(const char* utf8name,
1947+
Getter getter,
1948+
napi_property_attributes attributes,
1949+
void* data) {
1950+
typedef details::CallbackData<Getter, Napi::Value> CbData;
1951+
// TODO: Delete when the function is destroyed
1952+
auto callbackData = new CbData({ getter });
1953+
1954+
return PropertyDescriptor({
1955+
utf8name,
1956+
nullptr,
1957+
nullptr,
1958+
CbData::Wrapper,
1959+
nullptr,
1960+
nullptr,
1961+
attributes,
1962+
callbackData
1963+
});
1964+
}
1965+
1966+
template <typename Getter>
1967+
inline PropertyDescriptor PropertyDescriptor::Accessor(const std::string& utf8name,
1968+
Getter getter,
1969+
napi_property_attributes attributes,
1970+
void* data) {
1971+
return Accessor(utf8name.c_str(), getter, attributes, data);
1972+
}
1973+
1974+
template <typename Getter>
1975+
inline PropertyDescriptor PropertyDescriptor::Accessor(napi_value name,
1976+
Getter getter,
1977+
napi_property_attributes attributes,
1978+
void* data) {
1979+
typedef details::CallbackData<Getter, Napi::Value> CbData;
1980+
// TODO: Delete when the function is destroyed
1981+
auto callbackData = new CbData({ getter });
1982+
1983+
return PropertyDescriptor({
1984+
nullptr,
1985+
name,
1986+
nullptr,
1987+
CbData::Wrapper,
1988+
nullptr,
1989+
nullptr,
1990+
attributes,
1991+
callbackData
1992+
});
1993+
}
1994+
1995+
template <typename Getter>
1996+
inline PropertyDescriptor PropertyDescriptor::Accessor(Name name,
1997+
Getter getter,
1998+
napi_property_attributes attributes,
1999+
void* data) {
2000+
napi_value nameValue = name;
2001+
return PropertyDescriptor::Accessor(nameValue, getter, attributes, data);
2002+
}
2003+
2004+
template <typename Getter, typename Setter>
2005+
inline PropertyDescriptor PropertyDescriptor::Accessor(const char* utf8name,
2006+
Getter getter,
2007+
Setter setter,
2008+
napi_property_attributes attributes,
2009+
void* data) {
2010+
typedef details::AccessorCallbackData<Getter, Setter> CbData;
2011+
// TODO: Delete when the function is destroyed
2012+
auto callbackData = new CbData({ getter, setter });
2013+
2014+
return PropertyDescriptor({
2015+
utf8name,
2016+
nullptr,
2017+
nullptr,
2018+
CbData::GetterWrapper,
2019+
CbData::SetterWrapper,
2020+
nullptr,
2021+
attributes,
2022+
callbackData
2023+
});
2024+
}
2025+
2026+
template <typename Getter, typename Setter>
2027+
inline PropertyDescriptor PropertyDescriptor::Accessor(const std::string& utf8name,
2028+
Getter getter,
2029+
Setter setter,
2030+
napi_property_attributes attributes,
2031+
void* data) {
2032+
return Accessor(utf8name.c_str(), getter, setter, attributes, data);
2033+
}
2034+
2035+
template <typename Getter, typename Setter>
2036+
inline PropertyDescriptor PropertyDescriptor::Accessor(napi_value name,
2037+
Getter getter,
2038+
Setter setter,
2039+
napi_property_attributes attributes,
2040+
void* data) {
2041+
typedef details::AccessorCallbackData<Getter, Setter> CbData;
2042+
// TODO: Delete when the function is destroyed
2043+
auto callbackData = new CbData({ getter, setter });
2044+
2045+
return PropertyDescriptor({
2046+
nullptr,
2047+
name,
2048+
nullptr,
2049+
CbData::GetterWrapper,
2050+
CbData::SetterWrapper,
2051+
nullptr,
2052+
attributes,
2053+
callbackData
2054+
});
2055+
}
2056+
2057+
template <typename Getter, typename Setter>
2058+
inline PropertyDescriptor PropertyDescriptor::Accessor(Name name,
2059+
Getter getter,
2060+
Setter setter,
2061+
napi_property_attributes attributes,
2062+
void* data) {
2063+
napi_value nameValue = name;
2064+
return PropertyDescriptor::Accessor(nameValue, getter, setter, attributes, data);
2065+
}
2066+
2067+
template <typename Callable>
2068+
inline PropertyDescriptor PropertyDescriptor::Function(const char* utf8name,
2069+
Callable cb,
2070+
napi_property_attributes attributes,
2071+
void* data) {
2072+
typedef decltype(cb(CallbackInfo(nullptr, nullptr))) ReturnType;
2073+
typedef details::CallbackData<Callable, ReturnType> CbData;
2074+
// TODO: Delete when the function is destroyed
2075+
auto callbackData = new CbData({ cb });
2076+
2077+
return PropertyDescriptor({
2078+
utf8name,
2079+
nullptr,
2080+
CbData::Wrapper,
2081+
nullptr,
2082+
nullptr,
2083+
nullptr,
2084+
attributes,
2085+
callbackData
2086+
});
2087+
}
2088+
2089+
template <typename Callable>
2090+
inline PropertyDescriptor PropertyDescriptor::Function(const std::string& utf8name,
2091+
Callable cb,
2092+
napi_property_attributes attributes,
2093+
void* data) {
2094+
return Function(utf8name.c_str(), cb, attributes, data);
2095+
}
2096+
2097+
template <typename Callable>
2098+
inline PropertyDescriptor PropertyDescriptor::Function(napi_value name,
2099+
Callable cb,
2100+
napi_property_attributes attributes,
2101+
void* data) {
2102+
typedef decltype(cb(CallbackInfo(nullptr, nullptr))) ReturnType;
2103+
typedef details::CallbackData<Callable, ReturnType> CbData;
2104+
// TODO: Delete when the function is destroyed
2105+
auto callbackData = new CbData({ cb });
2106+
2107+
return PropertyDescriptor({
2108+
nullptr,
2109+
name,
2110+
CbData::Wrapper,
2111+
nullptr,
2112+
nullptr,
2113+
nullptr,
2114+
attributes,
2115+
callbackData
2116+
});
2117+
}
2118+
2119+
template <typename Callable>
2120+
inline PropertyDescriptor PropertyDescriptor::Function(Name name,
2121+
Callable cb,
2122+
napi_property_attributes attributes,
2123+
void* data) {
2124+
napi_value nameValue = name;
2125+
return PropertyDescriptor::Function(nameValue, cb, attributes, data);
2126+
}
2127+
2128+
inline PropertyDescriptor PropertyDescriptor::Value(const char* utf8name,
2129+
napi_value value,
2130+
napi_property_attributes attributes) {
2131+
return PropertyDescriptor({
2132+
utf8name, nullptr, nullptr, nullptr, nullptr, value, attributes, nullptr
2133+
});
2134+
}
2135+
2136+
inline PropertyDescriptor PropertyDescriptor::Value(const std::string& utf8name,
2137+
napi_value value,
2138+
napi_property_attributes attributes) {
2139+
return Value(utf8name.c_str(), value, attributes);
2140+
}
2141+
2142+
inline PropertyDescriptor PropertyDescriptor::Value(napi_value name,
2143+
napi_value value,
2144+
napi_property_attributes attributes) {
2145+
return PropertyDescriptor({
2146+
nullptr, name, nullptr, nullptr, nullptr, value, attributes, nullptr
2147+
});
2148+
}
2149+
2150+
inline PropertyDescriptor PropertyDescriptor::Value(Name name,
2151+
Napi::Value value,
2152+
napi_property_attributes attributes) {
2153+
napi_value nameValue = name;
2154+
napi_value valueValue = value;
2155+
return PropertyDescriptor::Value(nameValue, valueValue, attributes);
2156+
}
2157+
2158+
inline PropertyDescriptor::PropertyDescriptor(napi_property_descriptor desc)
2159+
: _desc(desc) {
2160+
}
2161+
2162+
inline PropertyDescriptor::operator napi_property_descriptor&() {
2163+
return _desc;
2164+
}
2165+
2166+
inline PropertyDescriptor::operator const napi_property_descriptor&() const {
2167+
return _desc;
2168+
}
2169+
19112170
////////////////////////////////////////////////////////////////////////////////
19122171
// ObjectWrap<T> class
19132172
////////////////////////////////////////////////////////////////////////////////

napi.h

Lines changed: 82 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ namespace Napi {
152152
};
153153

154154
class Name : public Value {
155-
protected:
155+
public:
156156
Name();
157157
Name(napi_env env, napi_value value);
158158
};
@@ -685,10 +685,87 @@ namespace Napi {
685685

686686
class PropertyDescriptor {
687687
public:
688-
PropertyDescriptor(napi_property_descriptor desc) : _desc(desc) {}
689-
690-
operator napi_property_descriptor&() { return _desc; }
691-
operator const napi_property_descriptor&() const { return _desc; }
688+
template <typename Getter>
689+
static PropertyDescriptor Accessor(const char* utf8name,
690+
Getter getter,
691+
napi_property_attributes attributes = napi_default,
692+
void* data = nullptr);
693+
template <typename Getter>
694+
static PropertyDescriptor Accessor(const std::string& utf8name,
695+
Getter getter,
696+
napi_property_attributes attributes = napi_default,
697+
void* data = nullptr);
698+
template <typename Getter>
699+
static PropertyDescriptor Accessor(napi_value name,
700+
Getter getter,
701+
napi_property_attributes attributes = napi_default,
702+
void* data = nullptr);
703+
template <typename Getter>
704+
static PropertyDescriptor Accessor(Name name,
705+
Getter getter,
706+
napi_property_attributes attributes = napi_default,
707+
void* data = nullptr);
708+
template <typename Getter, typename Setter>
709+
static PropertyDescriptor Accessor(const char* utf8name,
710+
Getter getter,
711+
Setter setter,
712+
napi_property_attributes attributes = napi_default,
713+
void* data = nullptr);
714+
template <typename Getter, typename Setter>
715+
static PropertyDescriptor Accessor(const std::string& utf8name,
716+
Getter getter,
717+
Setter setter,
718+
napi_property_attributes attributes = napi_default,
719+
void* data = nullptr);
720+
template <typename Getter, typename Setter>
721+
static PropertyDescriptor Accessor(napi_value name,
722+
Getter getter,
723+
Setter setter,
724+
napi_property_attributes attributes = napi_default,
725+
void* data = nullptr);
726+
template <typename Getter, typename Setter>
727+
static PropertyDescriptor Accessor(Name name,
728+
Getter getter,
729+
Setter setter,
730+
napi_property_attributes attributes = napi_default,
731+
void* data = nullptr);
732+
template <typename Callable>
733+
static PropertyDescriptor Function(const char* utf8name,
734+
Callable cb,
735+
napi_property_attributes attributes = napi_default,
736+
void* data = nullptr);
737+
template <typename Callable>
738+
static PropertyDescriptor Function(const std::string& utf8name,
739+
Callable cb,
740+
napi_property_attributes attributes = napi_default,
741+
void* data = nullptr);
742+
template <typename Callable>
743+
static PropertyDescriptor Function(napi_value name,
744+
Callable cb,
745+
napi_property_attributes attributes = napi_default,
746+
void* data = nullptr);
747+
template <typename Callable>
748+
static PropertyDescriptor Function(Name name,
749+
Callable cb,
750+
napi_property_attributes attributes = napi_default,
751+
void* data = nullptr);
752+
static PropertyDescriptor Value(const char* utf8name,
753+
napi_value value,
754+
napi_property_attributes attributes = napi_default);
755+
static PropertyDescriptor Value(const std::string& utf8name,
756+
napi_value value,
757+
napi_property_attributes attributes = napi_default);
758+
static PropertyDescriptor Value(napi_value name,
759+
napi_value value,
760+
napi_property_attributes attributes = napi_default);
761+
static PropertyDescriptor Value(Name name,
762+
Napi::Value value,
763+
napi_property_attributes attributes = napi_default);
764+
765+
PropertyDescriptor(napi_property_descriptor desc);
766+
767+
operator napi_property_descriptor&();
768+
operator const napi_property_descriptor&() const;
692769

693770
private:
694771
napi_property_descriptor _desc;

test/binding.cc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ Object InitError(Env env);
88
Object InitExternal(Env env);
99
Object InitFunction(Env env);
1010
Object InitName(Env env);
11+
Object InitObject(Env env);
1112

1213
void Init(Env env, Object exports, Object module) {
1314
exports.Set("arraybuffer", InitArrayBuffer(env));
@@ -16,6 +17,7 @@ void Init(Env env, Object exports, Object module) {
1617
exports.Set("external", InitExternal(env));
1718
exports.Set("function", InitFunction(env));
1819
exports.Set("name", InitName(env));
20+
exports.Set("object", InitObject(env));
1921
}
2022

2123
NODE_API_MODULE(addon, Init)

test/binding.gyp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
'external.cc',
1111
'function.cc',
1212
'name.cc',
13+
'object.cc',
1314
],
1415
'include_dirs': ["<!(node -p \"require('../').include\")"],
1516
'dependencies': ["<!(node -p \"require('../').gyp\")"],

0 commit comments

Comments
 (0)