diff --git a/README.md b/README.md
index 4f5be7122..c27000a95 100644
--- a/README.md
+++ b/README.md
@@ -133,6 +133,12 @@ npm install
npm test
```
+To avoid testing the deprecated portions of the API run
+```
+npm install
+npm test --disable-deprecated
+```
+
Take a look and get inspired by our **[test suite](https://github.com/nodejs/node-addon-api/tree/master/test)**
diff --git a/doc/property_descriptor.md b/doc/property_descriptor.md
index 2c0fa6fac..82a87191f 100644
--- a/doc/property_descriptor.md
+++ b/doc/property_descriptor.md
@@ -22,19 +22,31 @@ Value TestFunction(const CallbackInfo& info) {
}
Void Init(Env env) {
- // Accessor
- PropertyDescriptor pd1 = PropertyDescriptor::Accessor("pd1", TestGetter);
- PropertyDescriptor pd2 = PropertyDescriptor::Accessor("pd2", TestGetter, TestSetter);
-
- // Function
- PropertyDescriptor pd3 = PropertyDescriptor::Function("function", TestFunction);
-
- // Value
- Boolean true_bool = Boolean::New(env, true);
- PropertyDescriptor pd4 = PropertyDescriptor::Value("boolean value", TestFunction, napi_writable);
-
- // Assign to an Object
+ // Create an object.
Object obj = Object::New(env);
+
+ // Accessor
+ PropertyDescriptor pd1 = PropertyDescriptor::Accessor(env,
+ obj,
+ "pd1",
+ TestGetter);
+ PropertyDescriptor pd2 = PropertyDescriptor::Accessor(env,
+ obj,
+ "pd2",
+ TestGetter,
+ TestSetter);
+ // Function
+ PropertyDescriptor pd3 = PropertyDescriptor::Function(env,
+ "function",
+ TestFunction);
+ // Value
+ Boolean true_bool = Boolean::New(env, true);
+ PropertyDescriptor pd4 =
+ PropertyDescriptor::Value("boolean value",
+ Napi::Boolean::New(env, true),
+ napi_writable);
+
+ // Assign properties to the object.
obj.DefineProperties({pd1, pd2, pd3, pd4});
}
```
@@ -71,6 +83,32 @@ The name of the property can be any of the following types:
- `napi_value value`
- `Napi::Name`
+**This signature is deprecated. It will result in a memory leak if used.**
+
+```cpp
+static Napi::PropertyDescriptor Napi::PropertyDescriptor::Accessor (
+ Napi::Env env,
+ Napi::Object object,
+ ___ name,
+ Getter getter,
+ napi_property_attributes attributes = napi_default,
+ void *data = nullptr);
+```
+
+* `[in] env`: The environemnt in which to create this accessor.
+* `[in] object`: The object on which the accessor will be defined.
+* `[in] name`: The name used for the getter function.
+* `[in] getter`: A getter function.
+* `[in] attributes`: Potential attributes for the getter function.
+* `[in] data`: A pointer to data of any type, default is a null pointer.
+
+Returns a `Napi::PropertyDescriptor` that contains a `Getter` accessor.
+
+The name of the property can be any of the following types:
+- `const char*`
+- `const std::string &`
+- `Napi::Name`
+
```cpp
static Napi::PropertyDescriptor Napi::PropertyDescriptor::Accessor (___ name,
Getter getter,
@@ -93,6 +131,34 @@ The name of the property can be any of the following types:
- `napi_value value`
- `Napi::Name`
+**This signature is deprecated. It will result in a memory leak if used.**
+
+```cpp
+static Napi::PropertyDescriptor Napi::PropertyDescriptor::Accessor (
+ Napi::Env env,
+ Napi::Object object,
+ ___ name,
+ Getter getter,
+ Setter setter,
+ napi_property_attributes attributes = napi_default,
+ void *data = nullptr);
+```
+
+* `[in] env`: The environemnt in which to create this accessor.
+* `[in] object`: The object on which the accessor will be defined.
+* `[in] name`: The name of the getter and setter function.
+* `[in] getter`: The getter function.
+* `[in] setter`: The setter function.
+* `[in] attributes`: Potential attributes for the getter function.
+* `[in] data`: A pointer to data of any type, default is a null pointer.
+
+Returns a `Napi::PropertyDescriptor` that contains a `Getter` and `Setter` function.
+
+The name of the property can be any of the following types:
+- `const char*`
+- `const std::string &`
+- `Napi::Name`
+
### Function
```cpp
@@ -115,6 +181,30 @@ The name of the property can be any of the following types:
- `napi_value value`
- `Napi::Name`
+**This signature is deprecated. It will result in a memory leak if used.**
+
+```cpp
+static Napi::PropertyDescriptor Napi::PropertyDescriptor::Function (
+ Napi::Env env,
+ ___ name,
+ Callable cb,
+ napi_property_attributes attributes = napi_default,
+ void *data = nullptr);
+```
+
+* `[in] env`: The environemnt in which to create this accessor.
+* `[in] name`: The name of the Callable function.
+* `[in] cb`: The function
+* `[in] attributes`: Potential attributes for the getter function.
+* `[in] data`: A pointer to data of any type, default is a null pointer.
+
+Returns a `Napi::PropertyDescriptor` that contains a callable `Napi::Function`.
+
+The name of the property can be any of the following types:
+- `const char*`
+- `const std::string &`
+- `Napi::Name`
+
### Value
```cpp
diff --git a/doc/setup.md b/doc/setup.md
index 542729a69..36e6fc956 100644
--- a/doc/setup.md
+++ b/doc/setup.md
@@ -66,3 +66,6 @@ To use **N-API** in a native module:
At build time, the N-API back-compat library code will be used only when the
targeted node version *does not* have N-API built-in.
+
+The preprocessor directive `NODE_ADDON_API_DISABLE_DEPRECATED` can be defined at
+compile time before including `napi.h` to skip the definition of deprecated APIs.
diff --git a/napi-inl.deprecated.h b/napi-inl.deprecated.h
new file mode 100644
index 000000000..d00174357
--- /dev/null
+++ b/napi-inl.deprecated.h
@@ -0,0 +1,192 @@
+#ifndef SRC_NAPI_INL_DEPRECATED_H_
+#define SRC_NAPI_INL_DEPRECATED_H_
+
+////////////////////////////////////////////////////////////////////////////////
+// PropertyDescriptor class
+////////////////////////////////////////////////////////////////////////////////
+
+template
+inline PropertyDescriptor
+PropertyDescriptor::Accessor(const char* utf8name,
+ Getter getter,
+ napi_property_attributes attributes,
+ void* /*data*/) {
+ typedef details::CallbackData CbData;
+ // TODO: Delete when the function is destroyed
+ auto callbackData = new CbData({ getter, nullptr });
+
+ return PropertyDescriptor({
+ utf8name,
+ nullptr,
+ nullptr,
+ CbData::Wrapper,
+ nullptr,
+ nullptr,
+ attributes,
+ callbackData
+ });
+}
+
+template
+inline PropertyDescriptor PropertyDescriptor::Accessor(const std::string& utf8name,
+ Getter getter,
+ napi_property_attributes attributes,
+ void* data) {
+ return Accessor(utf8name.c_str(), getter, attributes, data);
+}
+
+template
+inline PropertyDescriptor PropertyDescriptor::Accessor(napi_value name,
+ Getter getter,
+ napi_property_attributes attributes,
+ void* /*data*/) {
+ typedef details::CallbackData CbData;
+ // TODO: Delete when the function is destroyed
+ auto callbackData = new CbData({ getter, nullptr });
+
+ return PropertyDescriptor({
+ nullptr,
+ name,
+ nullptr,
+ CbData::Wrapper,
+ nullptr,
+ nullptr,
+ attributes,
+ callbackData
+ });
+}
+
+template
+inline PropertyDescriptor PropertyDescriptor::Accessor(Name name,
+ Getter getter,
+ napi_property_attributes attributes,
+ void* data) {
+ napi_value nameValue = name;
+ return PropertyDescriptor::Accessor(nameValue, getter, attributes, data);
+}
+
+template
+inline PropertyDescriptor PropertyDescriptor::Accessor(const char* utf8name,
+ Getter getter,
+ Setter setter,
+ napi_property_attributes attributes,
+ void* /*data*/) {
+ typedef details::AccessorCallbackData CbData;
+ // TODO: Delete when the function is destroyed
+ auto callbackData = new CbData({ getter, setter });
+
+ return PropertyDescriptor({
+ utf8name,
+ nullptr,
+ nullptr,
+ CbData::GetterWrapper,
+ CbData::SetterWrapper,
+ nullptr,
+ attributes,
+ callbackData
+ });
+}
+
+template
+inline PropertyDescriptor PropertyDescriptor::Accessor(const std::string& utf8name,
+ Getter getter,
+ Setter setter,
+ napi_property_attributes attributes,
+ void* data) {
+ return Accessor(utf8name.c_str(), getter, setter, attributes, data);
+}
+
+template
+inline PropertyDescriptor PropertyDescriptor::Accessor(napi_value name,
+ Getter getter,
+ Setter setter,
+ napi_property_attributes attributes,
+ void* /*data*/) {
+ typedef details::AccessorCallbackData CbData;
+ // TODO: Delete when the function is destroyed
+ auto callbackData = new CbData({ getter, setter });
+
+ return PropertyDescriptor({
+ nullptr,
+ name,
+ nullptr,
+ CbData::GetterWrapper,
+ CbData::SetterWrapper,
+ nullptr,
+ attributes,
+ callbackData
+ });
+}
+
+template
+inline PropertyDescriptor PropertyDescriptor::Accessor(Name name,
+ Getter getter,
+ Setter setter,
+ napi_property_attributes attributes,
+ void* data) {
+ napi_value nameValue = name;
+ return PropertyDescriptor::Accessor(nameValue, getter, setter, attributes, data);
+}
+
+template
+inline PropertyDescriptor PropertyDescriptor::Function(const char* utf8name,
+ Callable cb,
+ napi_property_attributes attributes,
+ void* /*data*/) {
+ typedef decltype(cb(CallbackInfo(nullptr, nullptr))) ReturnType;
+ typedef details::CallbackData CbData;
+ // TODO: Delete when the function is destroyed
+ auto callbackData = new CbData({ cb, nullptr });
+
+ return PropertyDescriptor({
+ utf8name,
+ nullptr,
+ CbData::Wrapper,
+ nullptr,
+ nullptr,
+ nullptr,
+ attributes,
+ callbackData
+ });
+}
+
+template
+inline PropertyDescriptor PropertyDescriptor::Function(const std::string& utf8name,
+ Callable cb,
+ napi_property_attributes attributes,
+ void* data) {
+ return Function(utf8name.c_str(), cb, attributes, data);
+}
+
+template
+inline PropertyDescriptor PropertyDescriptor::Function(napi_value name,
+ Callable cb,
+ napi_property_attributes attributes,
+ void* /*data*/) {
+ typedef decltype(cb(CallbackInfo(nullptr, nullptr))) ReturnType;
+ typedef details::CallbackData CbData;
+ // TODO: Delete when the function is destroyed
+ auto callbackData = new CbData({ cb, nullptr });
+
+ return PropertyDescriptor({
+ nullptr,
+ name,
+ CbData::Wrapper,
+ nullptr,
+ nullptr,
+ nullptr,
+ attributes,
+ callbackData
+ });
+}
+
+template
+inline PropertyDescriptor PropertyDescriptor::Function(Name name,
+ Callable cb,
+ napi_property_attributes attributes,
+ void* data) {
+ napi_value nameValue = name;
+ return PropertyDescriptor::Function(nameValue, cb, attributes, data);
+}
+
+#endif // !SRC_NAPI_INL_DEPRECATED_H_
diff --git a/napi-inl.h b/napi-inl.h
index aead8b9ce..6d8a021c1 100644
--- a/napi-inl.h
+++ b/napi-inl.h
@@ -60,6 +60,41 @@ namespace details {
} \
} while (0)
+// Attach a data item to an object and delete it when the object gets
+// garbage-collected.
+// TODO: Replace this code with `napi_add_finalizer()` whenever it becomes
+// available on all supported versions of Node.js.
+template
+static inline napi_status AttachData(napi_env env,
+ napi_value obj,
+ FreeType* data) {
+ napi_value symbol, external;
+ napi_status status = napi_create_symbol(env, nullptr, &symbol);
+ if (status == napi_ok) {
+ status = napi_create_external(env,
+ data,
+ [](napi_env /*env*/, void* data, void* /*hint*/) {
+ delete static_cast(data);
+ },
+ nullptr,
+ &external);
+ if (status == napi_ok) {
+ napi_property_descriptor desc = {
+ nullptr,
+ symbol,
+ nullptr,
+ nullptr,
+ nullptr,
+ external,
+ napi_default,
+ nullptr
+ };
+ status = napi_define_properties(env, obj, 1, &desc);
+ }
+ }
+ return status;
+}
+
// For use in JS to C++ callback wrappers to catch any Napi::Error exceptions
// and rethrow them as JavaScript exceptions before returning from the callback.
template
@@ -162,6 +197,10 @@ struct AccessorCallbackData {
} // namespace details
+#ifndef NODE_ADDON_API_DISABLE_DEPRECATED
+# include "napi-inl.deprecated.h"
+#endif // !NODE_ADDON_API_DISABLE_DEPRECATED
+
////////////////////////////////////////////////////////////////////////////////
// Module registration
////////////////////////////////////////////////////////////////////////////////
@@ -1587,6 +1626,22 @@ inline const T* TypedArrayOf::Data() const {
// Function class
////////////////////////////////////////////////////////////////////////////////
+template
+static inline napi_status
+CreateFunction(napi_env env,
+ const char* utf8name,
+ napi_callback cb,
+ CbData* data,
+ napi_value* result) {
+ napi_status status =
+ napi_create_function(env, utf8name, NAPI_AUTO_LENGTH, cb, data, result);
+ if (status == napi_ok) {
+ status = Napi::details::AttachData(env, *result, data);
+ }
+
+ return status;
+}
+
template
inline Function Function::New(napi_env env,
Callable cb,
@@ -1594,12 +1649,14 @@ inline Function Function::New(napi_env env,
void* data) {
typedef decltype(cb(CallbackInfo(nullptr, nullptr))) ReturnType;
typedef details::CallbackData CbData;
- // TODO: Delete when the function is destroyed
auto callbackData = new CbData({ cb, data });
napi_value value;
- napi_status status = napi_create_function(
- env, utf8name, NAPI_AUTO_LENGTH, CbData::Wrapper, callbackData, &value);
+ napi_status status = CreateFunction(env,
+ utf8name,
+ CbData::Wrapper,
+ callbackData,
+ &value);
NAPI_THROW_IF_FAILED(env, status, Function());
return Function(env, value);
}
@@ -2541,14 +2598,18 @@ inline void CallbackInfo::SetData(void* data) {
template
inline PropertyDescriptor
-PropertyDescriptor::Accessor(const char* utf8name,
+PropertyDescriptor::Accessor(Napi::Env env,
+ Napi::Object object,
+ const char* utf8name,
Getter getter,
napi_property_attributes attributes,
void* /*data*/) {
typedef details::CallbackData CbData;
- // TODO: Delete when the function is destroyed
auto callbackData = new CbData({ getter, nullptr });
+ napi_status status = AttachData(env, object, callbackData);
+ NAPI_THROW_IF_FAILED(env, status, napi_property_descriptor());
+
return PropertyDescriptor({
utf8name,
nullptr,
@@ -2562,22 +2623,28 @@ PropertyDescriptor::Accessor(const char* utf8name,
}
template
-inline PropertyDescriptor PropertyDescriptor::Accessor(const std::string& utf8name,
+inline PropertyDescriptor PropertyDescriptor::Accessor(Napi::Env env,
+ Napi::Object object,
+ const std::string& utf8name,
Getter getter,
napi_property_attributes attributes,
void* data) {
- return Accessor(utf8name.c_str(), getter, attributes, data);
+ return Accessor(env, object, utf8name.c_str(), getter, attributes, data);
}
template
-inline PropertyDescriptor PropertyDescriptor::Accessor(napi_value name,
+inline PropertyDescriptor PropertyDescriptor::Accessor(Napi::Env env,
+ Napi::Object object,
+ Name name,
Getter getter,
napi_property_attributes attributes,
void* /*data*/) {
typedef details::CallbackData CbData;
- // TODO: Delete when the function is destroyed
auto callbackData = new CbData({ getter, nullptr });
+ napi_status status = AttachData(env, object, callbackData);
+ NAPI_THROW_IF_FAILED(env, status, napi_property_descriptor());
+
return PropertyDescriptor({
nullptr,
name,
@@ -2590,25 +2657,20 @@ inline PropertyDescriptor PropertyDescriptor::Accessor(napi_value name,
});
}
-template
-inline PropertyDescriptor PropertyDescriptor::Accessor(Name name,
- Getter getter,
- napi_property_attributes attributes,
- void* data) {
- napi_value nameValue = name;
- return PropertyDescriptor::Accessor(nameValue, getter, attributes, data);
-}
-
template
-inline PropertyDescriptor PropertyDescriptor::Accessor(const char* utf8name,
+inline PropertyDescriptor PropertyDescriptor::Accessor(Napi::Env env,
+ Napi::Object object,
+ const char* utf8name,
Getter getter,
Setter setter,
napi_property_attributes attributes,
void* /*data*/) {
typedef details::AccessorCallbackData CbData;
- // TODO: Delete when the function is destroyed
auto callbackData = new CbData({ getter, setter });
+ napi_status status = AttachData(env, object, callbackData);
+ NAPI_THROW_IF_FAILED(env, status, napi_property_descriptor());
+
return PropertyDescriptor({
utf8name,
nullptr,
@@ -2622,24 +2684,30 @@ inline PropertyDescriptor PropertyDescriptor::Accessor(const char* utf8name,
}
template
-inline PropertyDescriptor PropertyDescriptor::Accessor(const std::string& utf8name,
+inline PropertyDescriptor PropertyDescriptor::Accessor(Napi::Env env,
+ Napi::Object object,
+ const std::string& utf8name,
Getter getter,
Setter setter,
napi_property_attributes attributes,
void* data) {
- return Accessor(utf8name.c_str(), getter, setter, attributes, data);
+ return Accessor(env, object, utf8name.c_str(), getter, setter, attributes, data);
}
template
-inline PropertyDescriptor PropertyDescriptor::Accessor(napi_value name,
+inline PropertyDescriptor PropertyDescriptor::Accessor(Napi::Env env,
+ Napi::Object object,
+ Name name,
Getter getter,
Setter setter,
napi_property_attributes attributes,
void* /*data*/) {
typedef details::AccessorCallbackData CbData;
- // TODO: Delete when the function is destroyed
auto callbackData = new CbData({ getter, setter });
+ napi_status status = AttachData(env, object, callbackData);
+ NAPI_THROW_IF_FAILED(env, status, napi_property_descriptor());
+
return PropertyDescriptor({
nullptr,
name,
@@ -2652,77 +2720,54 @@ inline PropertyDescriptor PropertyDescriptor::Accessor(napi_value name,
});
}
-template
-inline PropertyDescriptor PropertyDescriptor::Accessor(Name name,
- Getter getter,
- Setter setter,
- napi_property_attributes attributes,
- void* data) {
- napi_value nameValue = name;
- return PropertyDescriptor::Accessor(nameValue, getter, setter, attributes, data);
-}
-
template
-inline PropertyDescriptor PropertyDescriptor::Function(const char* utf8name,
+inline PropertyDescriptor PropertyDescriptor::Function(Napi::Env env,
+ Napi::Object /*object*/,
+ const char* utf8name,
Callable cb,
napi_property_attributes attributes,
- void* /*data*/) {
- typedef decltype(cb(CallbackInfo(nullptr, nullptr))) ReturnType;
- typedef details::CallbackData CbData;
- // TODO: Delete when the function is destroyed
- auto callbackData = new CbData({ cb, nullptr });
-
+ void* data) {
return PropertyDescriptor({
utf8name,
nullptr,
- CbData::Wrapper,
nullptr,
nullptr,
nullptr,
+ Napi::Function::New(env, cb, utf8name, data),
attributes,
- callbackData
+ nullptr
});
}
template
-inline PropertyDescriptor PropertyDescriptor::Function(const std::string& utf8name,
+inline PropertyDescriptor PropertyDescriptor::Function(Napi::Env env,
+ Napi::Object object,
+ const std::string& utf8name,
Callable cb,
napi_property_attributes attributes,
void* data) {
- return Function(utf8name.c_str(), cb, attributes, data);
+ return Function(env, object, utf8name.c_str(), cb, attributes, data);
}
template
-inline PropertyDescriptor PropertyDescriptor::Function(napi_value name,
+inline PropertyDescriptor PropertyDescriptor::Function(Napi::Env env,
+ Napi::Object /*object*/,
+ Name name,
Callable cb,
napi_property_attributes attributes,
- void* /*data*/) {
- typedef decltype(cb(CallbackInfo(nullptr, nullptr))) ReturnType;
- typedef details::CallbackData CbData;
- // TODO: Delete when the function is destroyed
- auto callbackData = new CbData({ cb, nullptr });
-
+ void* data) {
return PropertyDescriptor({
nullptr,
name,
- CbData::Wrapper,
nullptr,
nullptr,
nullptr,
+ Napi::Function::New(env, cb, nullptr, data),
attributes,
- callbackData
+ nullptr
});
}
-template
-inline PropertyDescriptor PropertyDescriptor::Function(Name name,
- Callable cb,
- napi_property_attributes attributes,
- void* data) {
- napi_value nameValue = name;
- return PropertyDescriptor::Function(nameValue, cb, attributes, data);
-}
-
inline PropertyDescriptor PropertyDescriptor::Value(const char* utf8name,
napi_value value,
napi_property_attributes attributes) {
@@ -2791,20 +2836,106 @@ inline T* ObjectWrap::Unwrap(Object wrapper) {
return unwrapped;
}
+template
+inline Function
+ObjectWrap::DefineClass(Napi::Env env,
+ const char* utf8name,
+ const size_t props_count,
+ const napi_property_descriptor* descriptors,
+ void* data) {
+ napi_status status;
+ std::vector props(props_count);
+
+ // We copy the descriptors to a local array because before defining the class
+ // we must replace static method property descriptors with value property
+ // descriptors such that the value is a function-valued `napi_value` created
+ // with `CreateFunction()`.
+ //
+ // This replacement could be made for instance methods as well, but V8 aborts
+ // if we do that, because it expects methods defined on the prototype template
+ // to have `FunctionTemplate`s.
+ for (size_t index = 0; index < props_count; index++) {
+ props[index] = descriptors[index];
+ napi_property_descriptor* prop = &props[index];
+ if (prop->method == T::StaticMethodCallbackWrapper) {
+ status = CreateFunction(env,
+ utf8name,
+ prop->method,
+ static_cast(prop->data),
+ &(prop->value));
+ NAPI_THROW_IF_FAILED(env, status, Function());
+ prop->method = nullptr;
+ prop->data = nullptr;
+ } else if (prop->method == T::StaticVoidMethodCallbackWrapper) {
+ status = CreateFunction(env,
+ utf8name,
+ prop->method,
+ static_cast(prop->data),
+ &(prop->value));
+ NAPI_THROW_IF_FAILED(env, status, Function());
+ prop->method = nullptr;
+ prop->data = nullptr;
+ }
+ }
+
+ napi_value value;
+ status = napi_define_class(env,
+ utf8name,
+ NAPI_AUTO_LENGTH,
+ T::ConstructorCallbackWrapper,
+ data,
+ props_count,
+ props.data(),
+ &value);
+ NAPI_THROW_IF_FAILED(env, status, Function());
+
+ // After defining the class we iterate once more over the property descriptors
+ // and attach the data associated with accessors and instance methods to the
+ // newly created JavaScript class.
+ for (size_t idx = 0; idx < props_count; idx++) {
+ const napi_property_descriptor* prop = &props[idx];
+
+ if (prop->getter == T::StaticGetterCallbackWrapper ||
+ prop->setter == T::StaticSetterCallbackWrapper) {
+ status = Napi::details::AttachData(env,
+ value,
+ static_cast(prop->data));
+ NAPI_THROW_IF_FAILED(env, status, Function());
+ } else if (prop->getter == T::InstanceGetterCallbackWrapper ||
+ prop->setter == T::InstanceSetterCallbackWrapper) {
+ status = Napi::details::AttachData(env,
+ value,
+ static_cast(prop->data));
+ NAPI_THROW_IF_FAILED(env, status, Function());
+ } else if (prop->method != nullptr && !(prop->attributes & napi_static)) {
+ if (prop->method == T::InstanceVoidMethodCallbackWrapper) {
+ status = Napi::details::AttachData(env,
+ value,
+ static_cast(prop->data));
+ NAPI_THROW_IF_FAILED(env, status, Function());
+ } else if (prop->method == T::InstanceMethodCallbackWrapper) {
+ status = Napi::details::AttachData(env,
+ value,
+ static_cast(prop->data));
+ NAPI_THROW_IF_FAILED(env, status, Function());
+ }
+ }
+ }
+
+ return Function(env, value);
+}
+
template
inline Function ObjectWrap::DefineClass(
Napi::Env env,
const char* utf8name,
const std::initializer_list>& properties,
void* data) {
- napi_value value;
- napi_status status = napi_define_class(
- env, utf8name, NAPI_AUTO_LENGTH,
- T::ConstructorCallbackWrapper, data, properties.size(),
- reinterpret_cast(properties.begin()), &value);
- NAPI_THROW_IF_FAILED(env, status, Function());
-
- return Function(env, value);
+ return DefineClass(env,
+ utf8name,
+ properties.size(),
+ reinterpret_cast(properties.begin()),
+ data);
}
template
@@ -2813,14 +2944,11 @@ inline Function ObjectWrap::DefineClass(
const char* utf8name,
const std::vector>& properties,
void* data) {
- napi_value value;
- napi_status status = napi_define_class(
- env, utf8name, NAPI_AUTO_LENGTH,
- T::ConstructorCallbackWrapper, data, properties.size(),
- reinterpret_cast(properties.data()), &value);
- NAPI_THROW_IF_FAILED(env, status, Function());
-
- return Function(env, value);
+ return DefineClass(env,
+ utf8name,
+ properties.size(),
+ reinterpret_cast(properties.data()),
+ data);
}
template
@@ -2829,7 +2957,6 @@ inline ClassPropertyDescriptor ObjectWrap::StaticMethod(
StaticVoidMethodCallback method,
napi_property_attributes attributes,
void* data) {
- // TODO: Delete when the class is destroyed
StaticVoidMethodCallbackData* callbackData = new StaticVoidMethodCallbackData({ method, data });
napi_property_descriptor desc = napi_property_descriptor();
@@ -2846,7 +2973,6 @@ inline ClassPropertyDescriptor ObjectWrap::StaticMethod(
StaticMethodCallback method,
napi_property_attributes attributes,
void* data) {
- // TODO: Delete when the class is destroyed
StaticMethodCallbackData* callbackData = new StaticMethodCallbackData({ method, data });
napi_property_descriptor desc = napi_property_descriptor();
@@ -2863,7 +2989,6 @@ inline ClassPropertyDescriptor ObjectWrap::StaticMethod(
StaticVoidMethodCallback method,
napi_property_attributes attributes,
void* data) {
- // TODO: Delete when the class is destroyed
StaticVoidMethodCallbackData* callbackData = new StaticVoidMethodCallbackData({ method, data });
napi_property_descriptor desc = napi_property_descriptor();
@@ -2880,7 +3005,6 @@ inline ClassPropertyDescriptor ObjectWrap::StaticMethod(
StaticMethodCallback method,
napi_property_attributes attributes,
void* data) {
- // TODO: Delete when the class is destroyed
StaticMethodCallbackData* callbackData = new StaticMethodCallbackData({ method, data });
napi_property_descriptor desc = napi_property_descriptor();
@@ -2898,7 +3022,6 @@ inline ClassPropertyDescriptor ObjectWrap::StaticAccessor(
StaticSetterCallback setter,
napi_property_attributes attributes,
void* data) {
- // TODO: Delete when the class is destroyed
StaticAccessorCallbackData* callbackData =
new StaticAccessorCallbackData({ getter, setter, data });
@@ -2918,7 +3041,6 @@ inline ClassPropertyDescriptor ObjectWrap::StaticAccessor(
StaticSetterCallback setter,
napi_property_attributes attributes,
void* data) {
- // TODO: Delete when the class is destroyed
StaticAccessorCallbackData* callbackData =
new StaticAccessorCallbackData({ getter, setter, data });
@@ -2937,7 +3059,6 @@ inline ClassPropertyDescriptor ObjectWrap::InstanceMethod(
InstanceVoidMethodCallback method,
napi_property_attributes attributes,
void* data) {
- // TODO: Delete when the class is destroyed
InstanceVoidMethodCallbackData* callbackData =
new InstanceVoidMethodCallbackData({ method, data});
@@ -2955,7 +3076,6 @@ inline ClassPropertyDescriptor ObjectWrap::InstanceMethod(
InstanceMethodCallback method,
napi_property_attributes attributes,
void* data) {
- // TODO: Delete when the class is destroyed
InstanceMethodCallbackData* callbackData = new InstanceMethodCallbackData({ method, data });
napi_property_descriptor desc = napi_property_descriptor();
@@ -2972,7 +3092,6 @@ inline ClassPropertyDescriptor ObjectWrap::InstanceMethod(
InstanceVoidMethodCallback method,
napi_property_attributes attributes,
void* data) {
- // TODO: Delete when the class is destroyed
InstanceVoidMethodCallbackData* callbackData =
new InstanceVoidMethodCallbackData({ method, data});
@@ -2990,7 +3109,6 @@ inline ClassPropertyDescriptor ObjectWrap::InstanceMethod(
InstanceMethodCallback method,
napi_property_attributes attributes,
void* data) {
- // TODO: Delete when the class is destroyed
InstanceMethodCallbackData* callbackData = new InstanceMethodCallbackData({ method, data });
napi_property_descriptor desc = napi_property_descriptor();
@@ -3008,7 +3126,6 @@ inline ClassPropertyDescriptor ObjectWrap::InstanceAccessor(
InstanceSetterCallback setter,
napi_property_attributes attributes,
void* data) {
- // TODO: Delete when the class is destroyed
InstanceAccessorCallbackData* callbackData =
new InstanceAccessorCallbackData({ getter, setter, data });
@@ -3028,7 +3145,6 @@ inline ClassPropertyDescriptor ObjectWrap::InstanceAccessor(
InstanceSetterCallback setter,
napi_property_attributes attributes,
void* data) {
- // TODO: Delete when the class is destroyed
InstanceAccessorCallbackData* callbackData =
new InstanceAccessorCallbackData({ getter, setter, data });
diff --git a/napi.h b/napi.h
index ed86272c3..61df5fe19 100644
--- a/napi.h
+++ b/napi.h
@@ -1312,6 +1312,7 @@ namespace Napi {
class PropertyDescriptor {
public:
+#ifndef NODE_ADDON_API_DISABLE_DEPRECATED
template
static PropertyDescriptor Accessor(const char* utf8name,
Getter getter,
@@ -1376,6 +1377,74 @@ namespace Napi {
Callable cb,
napi_property_attributes attributes = napi_default,
void* data = nullptr);
+#endif // !NODE_ADDON_API_DISABLE_DEPRECATED
+
+ template
+ static PropertyDescriptor Accessor(Napi::Env env,
+ Napi::Object object,
+ const char* utf8name,
+ Getter getter,
+ napi_property_attributes attributes = napi_default,
+ void* data = nullptr);
+ template
+ static PropertyDescriptor Accessor(Napi::Env env,
+ Napi::Object object,
+ const std::string& utf8name,
+ Getter getter,
+ napi_property_attributes attributes = napi_default,
+ void* data = nullptr);
+ template
+ static PropertyDescriptor Accessor(Napi::Env env,
+ Napi::Object object,
+ Name name,
+ Getter getter,
+ napi_property_attributes attributes = napi_default,
+ void* data = nullptr);
+ template
+ static PropertyDescriptor Accessor(Napi::Env env,
+ Napi::Object object,
+ const char* utf8name,
+ Getter getter,
+ Setter setter,
+ napi_property_attributes attributes = napi_default,
+ void* data = nullptr);
+ template
+ static PropertyDescriptor Accessor(Napi::Env env,
+ Napi::Object object,
+ const std::string& utf8name,
+ Getter getter,
+ Setter setter,
+ napi_property_attributes attributes = napi_default,
+ void* data = nullptr);
+ template
+ static PropertyDescriptor Accessor(Napi::Env env,
+ Napi::Object object,
+ Name name,
+ Getter getter,
+ Setter setter,
+ napi_property_attributes attributes = napi_default,
+ void* data = nullptr);
+ template
+ static PropertyDescriptor Function(Napi::Env env,
+ Napi::Object object,
+ const char* utf8name,
+ Callable cb,
+ napi_property_attributes attributes = napi_default,
+ void* data = nullptr);
+ template
+ static PropertyDescriptor Function(Napi::Env env,
+ Napi::Object object,
+ const std::string& utf8name,
+ Callable cb,
+ napi_property_attributes attributes = napi_default,
+ void* data = nullptr);
+ template
+ static PropertyDescriptor Function(Napi::Env env,
+ Napi::Object object,
+ Name name,
+ Callable cb,
+ napi_property_attributes attributes = napi_default,
+ void* data = nullptr);
static PropertyDescriptor Value(const char* utf8name,
napi_value value,
napi_property_attributes attributes = napi_default);
@@ -1543,6 +1612,11 @@ namespace Napi {
static napi_value InstanceGetterCallbackWrapper(napi_env env, napi_callback_info info);
static napi_value InstanceSetterCallbackWrapper(napi_env env, napi_callback_info info);
static void FinalizeCallback(napi_env env, void* data, void* hint);
+ static Function DefineClass(Napi::Env env,
+ const char* utf8name,
+ const size_t props_count,
+ const napi_property_descriptor* props,
+ void* data = nullptr);
template
struct MethodCallbackData {
diff --git a/test/binding.cc b/test/binding.cc
index ffa3ec7a0..101ac1f85 100644
--- a/test/binding.cc
+++ b/test/binding.cc
@@ -24,11 +24,15 @@ Object InitHandleScope(Env env);
Object InitMemoryManagement(Env env);
Object InitName(Env env);
Object InitObject(Env env);
+#ifndef NODE_ADDON_API_DISABLE_DEPRECATED
+Object InitObjectDeprecated(Env env);
+#endif // !NODE_ADDON_API_DISABLE_DEPRECATED
Object InitPromise(Env env);
Object InitTypedArray(Env env);
Object InitObjectWrap(Env env);
Object InitObjectReference(Env env);
Object InitVersionManagement(Env env);
+Object InitThunkingManual(Env env);
Object Init(Env env, Object exports) {
exports.Set("arraybuffer", InitArrayBuffer(env));
@@ -53,11 +57,15 @@ Object Init(Env env, Object exports) {
exports.Set("handlescope", InitHandleScope(env));
exports.Set("memory_management", InitMemoryManagement(env));
exports.Set("object", InitObject(env));
+#ifndef NODE_ADDON_API_DISABLE_DEPRECATED
+ exports.Set("object_deprecated", InitObjectDeprecated(env));
+#endif // !NODE_ADDON_API_DISABLE_DEPRECATED
exports.Set("promise", InitPromise(env));
exports.Set("typedarray", InitTypedArray(env));
exports.Set("objectwrap", InitObjectWrap(env));
exports.Set("objectreference", InitObjectReference(env));
exports.Set("version_management", InitVersionManagement(env));
+ exports.Set("thunking_manual", InitThunkingManual(env));
return exports;
}
diff --git a/test/binding.gyp b/test/binding.gyp
index 2eaccdb8b..417a2bb3b 100644
--- a/test/binding.gyp
+++ b/test/binding.gyp
@@ -1,6 +1,7 @@
{
'variables': {
- 'NAPI_VERSION%': ""
+ 'NAPI_VERSION%': "",
+ 'disable_deprecated': "();
String nameType = info[1].As();
+ Env env = info.Env();
- Boolean trueValue = Boolean::New(info.Env(), true);
+ Boolean trueValue = Boolean::New(env, true);
if (nameType.Utf8Value() == "literal") {
obj.DefineProperties({
- PropertyDescriptor::Accessor("readonlyAccessor", TestGetter),
- PropertyDescriptor::Accessor("readwriteAccessor", TestGetter, TestSetter),
+ PropertyDescriptor::Accessor(env, obj, "readonlyAccessor", TestGetter),
+ PropertyDescriptor::Accessor(env, obj, "readwriteAccessor", TestGetter, TestSetter),
PropertyDescriptor::Value("readonlyValue", trueValue),
PropertyDescriptor::Value("readwriteValue", trueValue, napi_writable),
PropertyDescriptor::Value("enumerableValue", trueValue, napi_enumerable),
PropertyDescriptor::Value("configurableValue", trueValue, napi_configurable),
- PropertyDescriptor::Function("function", TestFunction),
+ PropertyDescriptor::Function(env, obj, "function", TestFunction),
});
} else if (nameType.Utf8Value() == "string") {
// VS2013 has lifetime issues when passing temporary objects into the constructor of another
@@ -82,30 +83,30 @@ void DefineProperties(const CallbackInfo& info) {
std::string str7("function");
obj.DefineProperties({
- PropertyDescriptor::Accessor(str1, TestGetter),
- PropertyDescriptor::Accessor(str2, TestGetter, TestSetter),
+ PropertyDescriptor::Accessor(env, obj, str1, TestGetter),
+ PropertyDescriptor::Accessor(env, obj, str2, TestGetter, TestSetter),
PropertyDescriptor::Value(str3, trueValue),
PropertyDescriptor::Value(str4, trueValue, napi_writable),
PropertyDescriptor::Value(str5, trueValue, napi_enumerable),
PropertyDescriptor::Value(str6, trueValue, napi_configurable),
- PropertyDescriptor::Function(str7, TestFunction),
+ PropertyDescriptor::Function(env, obj, str7, TestFunction),
});
} else if (nameType.Utf8Value() == "value") {
obj.DefineProperties({
- PropertyDescriptor::Accessor(
- Napi::String::New(info.Env(), "readonlyAccessor"), TestGetter),
- PropertyDescriptor::Accessor(
- Napi::String::New(info.Env(), "readwriteAccessor"), TestGetter, TestSetter),
+ PropertyDescriptor::Accessor(env, obj,
+ Napi::String::New(env, "readonlyAccessor"), TestGetter),
+ PropertyDescriptor::Accessor(env, obj,
+ Napi::String::New(env, "readwriteAccessor"), TestGetter, TestSetter),
PropertyDescriptor::Value(
- Napi::String::New(info.Env(), "readonlyValue"), trueValue),
+ Napi::String::New(env, "readonlyValue"), trueValue),
PropertyDescriptor::Value(
- Napi::String::New(info.Env(), "readwriteValue"), trueValue, napi_writable),
+ Napi::String::New(env, "readwriteValue"), trueValue, napi_writable),
PropertyDescriptor::Value(
- Napi::String::New(info.Env(), "enumerableValue"), trueValue, napi_enumerable),
+ Napi::String::New(env, "enumerableValue"), trueValue, napi_enumerable),
PropertyDescriptor::Value(
- Napi::String::New(info.Env(), "configurableValue"), trueValue, napi_configurable),
- PropertyDescriptor::Function(
- Napi::String::New(info.Env(), "function"), TestFunction),
+ Napi::String::New(env, "configurableValue"), trueValue, napi_configurable),
+ PropertyDescriptor::Function(env, obj,
+ Napi::String::New(env, "function"), TestFunction),
});
}
}
diff --git a/test/object/object_deprecated.cc b/test/object/object_deprecated.cc
new file mode 100644
index 000000000..2ec16e579
--- /dev/null
+++ b/test/object/object_deprecated.cc
@@ -0,0 +1,66 @@
+#include "napi.h"
+
+using namespace Napi;
+
+static bool testValue = true;
+
+namespace {
+
+Value TestGetter(const CallbackInfo& info) {
+ return Boolean::New(info.Env(), testValue);
+}
+
+void TestSetter(const CallbackInfo& info) {
+ testValue = info[0].As();
+}
+
+Value TestFunction(const CallbackInfo& info) {
+ return Boolean::New(info.Env(), true);
+}
+
+void DefineProperties(const CallbackInfo& info) {
+ Object obj = info[0].As