From 1c2a8d59b55eda6b1f2f5e52f9c686f2a125d83d Mon Sep 17 00:00:00 2001 From: pacop <1923775+pacop@users.noreply.github.com> Date: Mon, 24 Aug 2020 20:27:19 +0200 Subject: [PATCH 01/16] doc: Added required return to example (#793) PR-URL: https://github.com/nodejs/node-addon-api/pull/793 Reviewed-By: Gabriel Schulhof Reviewed-By: Michael Dawson --- doc/function.md | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/function.md b/doc/function.md index c1b0fc9fb..610d1005c 100644 --- a/doc/function.md +++ b/doc/function.md @@ -30,6 +30,7 @@ Value Fn(const CallbackInfo& info) { Object Init(Env env, Object exports) { exports.Set(String::New(env, "fn"), Function::New(env)); + return exports; } NODE_API_MODULE(NODE_GYP_MODULE_NAME, Init) From c2cbbd9191e3b39c993b5417d9776d13a3045e75 Mon Sep 17 00:00:00 2001 From: Jim Schlight Date: Mon, 24 Aug 2020 11:28:07 -0700 Subject: [PATCH 02/16] doc: add link to n-api tutorial website (#794) PR-URL: https://github.com/nodejs/node-addon-api/pull/794 Reviewed-By: Gabriel Schulhof Reviewed-By: Michael Dawson --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 1f6e34e75..aa06eea67 100644 --- a/README.md +++ b/README.md @@ -37,6 +37,10 @@ APIs exposed by node-addon-api are generally used to create and manipulate JavaScript values. Concepts and operations generally map to ideas specified in the **ECMA262 Language Specification**. +The [N-API Resource](http://nodejs.github.io/node-addon-examples/) offers an +excellent orientation and tips for developers just getting started with N-API +and node-addon-api. + - **[Setup](#setup)** - **[API Documentation](#api)** - **[Examples](#examples)** From 518cfdcdc10301723b9d48848e8297f43dc54209 Mon Sep 17 00:00:00 2001 From: David Halls Date: Wed, 13 May 2020 23:03:15 +0100 Subject: [PATCH 03/16] test: test ObjectWrap destructor - no HandleScope Add test for ObjectWrap destructor (no HandleScope exception) REFS: https://github.com/nodejs/node-addon-api/issues/722 PR-URL: https://github.com/nodejs/node-addon-api/pull/729 Reviewed-By: Michael Dawson --- test/index.js | 5 +++++ test/objectwrap.cc | 10 ++++++++++ test/objectwrap_worker_thread.js | 14 ++++++++++++++ 3 files changed, 29 insertions(+) create mode 100644 test/objectwrap_worker_thread.js diff --git a/test/index.js b/test/index.js index 86939af84..33b128da0 100644 --- a/test/index.js +++ b/test/index.js @@ -55,6 +55,7 @@ let testModules = [ 'objectwrap_constructor_exception', 'objectwrap-removewrap', 'objectwrap_multiple_inheritance', + 'objectwrap_worker_thread', 'objectreference', 'reference', 'version_management' @@ -90,6 +91,10 @@ if (napiVersion < 6) { testModules.splice(testModules.indexOf('typedarray-bigint'), 1); } +if (majorNodeVersion < 12) { + testModules.splice(testModules.indexOf('objectwrap_worker_thread'), 1); +} + if (typeof global.gc === 'function') { (async function() { console.log(`Testing with N-API Version '${napiVersion}'.`); diff --git a/test/objectwrap.cc b/test/objectwrap.cc index 92a29ce74..2ffc85a25 100644 --- a/test/objectwrap.cc +++ b/test/objectwrap.cc @@ -40,6 +40,14 @@ class Test : public Napi::ObjectWrap { info.This().As().DefineProperty( Napi::PropertyDescriptor::Accessor("ownPropertyT", napi_enumerable, this)); + + bufref_ = Napi::Persistent(Napi::Buffer::New( + Env(), + static_cast(malloc(1)), + 1, + [](Napi::Env, uint8_t* bufaddr) { + free(bufaddr); + })); } static Napi::Value OwnPropertyGetter(const Napi::CallbackInfo& info) { @@ -183,6 +191,8 @@ class Test : public Napi::ObjectWrap { Napi::FunctionReference finalizeCb_; static std::string s_staticMethodText; + + Napi::Reference> bufref_; }; std::string Test::s_staticMethodText; diff --git a/test/objectwrap_worker_thread.js b/test/objectwrap_worker_thread.js new file mode 100644 index 000000000..348309976 --- /dev/null +++ b/test/objectwrap_worker_thread.js @@ -0,0 +1,14 @@ +'use strict'; +const buildType = process.config.target_defaults.default_configuration; +const { Worker, isMainThread } = require('worker_threads'); + +if (isMainThread) { + new Worker(__filename); +} else { + const test = binding => { + new binding.objectwrap.Test(); + }; + + test(require(`./build/${buildType}/binding.node`)); + test(require(`./build/${buildType}/binding_noexcept.node`)); +} From 2bc45bbffd0ffde6ba31f63eb1866ccf536f5050 Mon Sep 17 00:00:00 2001 From: Velmisov Date: Fri, 7 Aug 2020 18:46:20 +0300 Subject: [PATCH 04/16] test: refactor test to use async/await Refactor threadsafe_function test with async/await PR-URL: https://github.com/nodejs/node-addon-api/pull/787 Reviewed-By: Kevin Eady Reviewed-By: Michael Dawson --- .../threadsafe_function.js | 176 ++++++++++-------- 1 file changed, 100 insertions(+), 76 deletions(-) diff --git a/test/threadsafe_function/threadsafe_function.js b/test/threadsafe_function/threadsafe_function.js index a3690fcf3..4c4bbf8a3 100644 --- a/test/threadsafe_function/threadsafe_function.js +++ b/test/threadsafe_function/threadsafe_function.js @@ -4,10 +4,12 @@ const buildType = process.config.target_defaults.default_configuration; const assert = require('assert'); const common = require('../common'); -module.exports = test(require(`../build/${buildType}/binding.node`)) - .then(() => test(require(`../build/${buildType}/binding_noexcept.node`))); +module.exports = async function() { + await test(require(`../build/${buildType}/binding.node`)); + await test(require(`../build/${buildType}/binding_noexcept.node`)); +}; -function test(binding) { +async function test(binding) { const expectedArray = (function(arrayLength) { const result = []; for (let index = 0; index < arrayLength; index++) { @@ -43,7 +45,7 @@ function test(binding) { }); } - return new Promise(function testWithoutJSMarshaller(resolve) { + await new Promise(function testWithoutJSMarshaller(resolve) { let callCount = 0; binding.threadsafe_function.startThreadNoNative(function testCallback() { callCount++; @@ -59,112 +61,134 @@ function test(binding) { } }, false /* abort */, false /* launchSecondary */, binding.threadsafe_function.MAX_QUEUE_SIZE); - }) + }); // Start the thread in blocking mode, and assert that all values are passed. // Quit after it's done. - .then(() => testWithJSMarshaller({ - threadStarter: 'startThread', - maxQueueSize: binding.threadsafe_function.MAX_QUEUE_SIZE, - quitAfter: binding.threadsafe_function.ARRAY_LENGTH - })) - .then((result) => assert.deepStrictEqual(result, expectedArray)) + assert.deepStrictEqual( + await testWithJSMarshaller({ + threadStarter: 'startThread', + maxQueueSize: binding.threadsafe_function.MAX_QUEUE_SIZE, + quitAfter: binding.threadsafe_function.ARRAY_LENGTH + }), + expectedArray, + ); // Start the thread in blocking mode with an infinite queue, and assert that // all values are passed. Quit after it's done. - .then(() => testWithJSMarshaller({ - threadStarter: 'startThread', - maxQueueSize: 0, - quitAfter: binding.threadsafe_function.ARRAY_LENGTH - })) - .then((result) => assert.deepStrictEqual(result, expectedArray)) + assert.deepStrictEqual( + await testWithJSMarshaller({ + threadStarter: 'startThread', + maxQueueSize: 0, + quitAfter: binding.threadsafe_function.ARRAY_LENGTH + }), + expectedArray, + ); // Start the thread in non-blocking mode, and assert that all values are // passed. Quit after it's done. - .then(() => testWithJSMarshaller({ - threadStarter: 'startThreadNonblocking', - maxQueueSize: binding.threadsafe_function.MAX_QUEUE_SIZE, - quitAfter: binding.threadsafe_function.ARRAY_LENGTH - })) - .then((result) => assert.deepStrictEqual(result, expectedArray)) + assert.deepStrictEqual( + await testWithJSMarshaller({ + threadStarter: 'startThreadNonblocking', + maxQueueSize: binding.threadsafe_function.MAX_QUEUE_SIZE, + quitAfter: binding.threadsafe_function.ARRAY_LENGTH + }), + expectedArray, + ); // Start the thread in blocking mode, and assert that all values are passed. // Quit early, but let the thread finish. - .then(() => testWithJSMarshaller({ - threadStarter: 'startThread', - maxQueueSize: binding.threadsafe_function.MAX_QUEUE_SIZE, - quitAfter: 1 - })) - .then((result) => assert.deepStrictEqual(result, expectedArray)) + assert.deepStrictEqual( + await testWithJSMarshaller({ + threadStarter: 'startThread', + maxQueueSize: binding.threadsafe_function.MAX_QUEUE_SIZE, + quitAfter: 1 + }), + expectedArray, + ); // Start the thread in blocking mode with an infinite queue, and assert that // all values are passed. Quit early, but let the thread finish. - .then(() => testWithJSMarshaller({ - threadStarter: 'startThread', - maxQueueSize: 0, - quitAfter: 1 - })) - .then((result) => assert.deepStrictEqual(result, expectedArray)) + assert.deepStrictEqual( + await testWithJSMarshaller({ + threadStarter: 'startThread', + maxQueueSize: 0, + quitAfter: 1 + }), + expectedArray, + ); // Start the thread in non-blocking mode, and assert that all values are // passed. Quit early, but let the thread finish. - .then(() => testWithJSMarshaller({ - threadStarter: 'startThreadNonblocking', - maxQueueSize: binding.threadsafe_function.MAX_QUEUE_SIZE, - quitAfter: 1 - })) - .then((result) => assert.deepStrictEqual(result, expectedArray)) + assert.deepStrictEqual( + await testWithJSMarshaller({ + threadStarter: 'startThreadNonblocking', + maxQueueSize: binding.threadsafe_function.MAX_QUEUE_SIZE, + quitAfter: 1 + }), + expectedArray, + ); // Start the thread in blocking mode, and assert that all values are passed. // Quit early, but let the thread finish. Launch a secondary thread to test // the reference counter incrementing functionality. - .then(() => testWithJSMarshaller({ - threadStarter: 'startThread', - quitAfter: 1, - maxQueueSize: binding.threadsafe_function.MAX_QUEUE_SIZE, - launchSecondary: true - })) - .then((result) => assert.deepStrictEqual(result, expectedArray)) + assert.deepStrictEqual( + await testWithJSMarshaller({ + threadStarter: 'startThread', + quitAfter: 1, + maxQueueSize: binding.threadsafe_function.MAX_QUEUE_SIZE, + launchSecondary: true + }), + expectedArray, + ); // Start the thread in non-blocking mode, and assert that all values are // passed. Quit early, but let the thread finish. Launch a secondary thread // to test the reference counter incrementing functionality. - .then(() => testWithJSMarshaller({ - threadStarter: 'startThreadNonblocking', - quitAfter: 1, - maxQueueSize: binding.threadsafe_function.MAX_QUEUE_SIZE, - launchSecondary: true - })) - .then((result) => assert.deepStrictEqual(result, expectedArray)) + assert.deepStrictEqual( + await testWithJSMarshaller({ + threadStarter: 'startThreadNonblocking', + quitAfter: 1, + maxQueueSize: binding.threadsafe_function.MAX_QUEUE_SIZE, + launchSecondary: true + }), + expectedArray, + ); // Start the thread in blocking mode, and assert that it could not finish. // Quit early by aborting. - .then(() => testWithJSMarshaller({ - threadStarter: 'startThread', - quitAfter: 1, - maxQueueSize: binding.threadsafe_function.MAX_QUEUE_SIZE, - abort: true - })) - .then((result) => assert.strictEqual(result.indexOf(0), -1)) + assert.strictEqual( + (await testWithJSMarshaller({ + threadStarter: 'startThread', + quitAfter: 1, + maxQueueSize: binding.threadsafe_function.MAX_QUEUE_SIZE, + abort: true + })).indexOf(0), + -1, + ); // Start the thread in blocking mode with an infinite queue, and assert that // it could not finish. Quit early by aborting. - .then(() => testWithJSMarshaller({ - threadStarter: 'startThread', - quitAfter: 1, - maxQueueSize: 0, - abort: true - })) - .then((result) => assert.strictEqual(result.indexOf(0), -1)) + assert.strictEqual( + (await testWithJSMarshaller({ + threadStarter: 'startThread', + quitAfter: 1, + maxQueueSize: 0, + abort: true + })).indexOf(0), + -1, + ); // Start the thread in non-blocking mode, and assert that it could not finish. // Quit early and aborting. - .then(() => testWithJSMarshaller({ - threadStarter: 'startThreadNonblocking', - quitAfter: 1, - maxQueueSize: binding.threadsafe_function.MAX_QUEUE_SIZE, - abort: true - })) - .then((result) => assert.strictEqual(result.indexOf(0), -1)) + assert.strictEqual( + (await testWithJSMarshaller({ + threadStarter: 'startThreadNonblocking', + quitAfter: 1, + maxQueueSize: binding.threadsafe_function.MAX_QUEUE_SIZE, + abort: true + })).indexOf(0), + -1, + ); } From 9aceea71fc14b92a2dcec66141eb339c04c41be9 Mon Sep 17 00:00:00 2001 From: Gabriel Schulhof Date: Thu, 6 Aug 2020 11:24:17 -0700 Subject: [PATCH 05/16] src: concentrate callbacks provided to core N-API This change reduces the places where we declare private functions with the `napi_callback` signature for the purpose of using them with C++ callbacks passed as template arguments. We basically have 4 types: 1. static with `void` return 2. static with `napi_value` return 3. instance with `void` return 4. instance with `napi_value` return We can use one of these four calling patterns in the following places where we accept callbacks as template arguments: * `Napi::Function` (1. and 2.) * `Napi::PropertyDescriptor` (1. for the setter, 2. for the getter) * `Napi::InstanceWrap` (3., 4. for instance methods, 4. for instance getters) * `Napi::ObjectWrap` (1., 2. for static methods, 2. for static getters) In the case of `InstanceWrap` and `ObjectWrap` instance resp. static property descriptors we can also remove the infrastructure designed to allow for optional getters (`GetterTag` resp. `StaticGetterTag`) because the API for specifying instance resp. class property descriptors does not allow one to omit the getter. Signed-off-by: Gabriel Schulhof PR-URL: https://github.com/nodejs/node-addon-api/pull/786 Reviewed-By: Anna Henningsen Reviewed-By: Michael Dawson --- napi-inl.h | 162 ++++++++++++++++++++++++----------------------------- napi.h | 23 -------- 2 files changed, 72 insertions(+), 113 deletions(-) diff --git a/napi-inl.h b/napi-inl.h index 4f0636a08..3b2c558d5 100644 --- a/napi-inl.h +++ b/napi-inl.h @@ -135,6 +135,48 @@ struct CallbackData { void* data; }; +template +static napi_value +TemplatedVoidCallback(napi_env env, napi_callback_info info) NAPI_NOEXCEPT { + return details::WrapCallback([&] { + CallbackInfo cbInfo(env, info); + Callback(cbInfo); + return nullptr; + }); +} + +template +static napi_value +TemplatedCallback(napi_env env, napi_callback_info info) NAPI_NOEXCEPT { + return details::WrapCallback([&] { + CallbackInfo cbInfo(env, info); + return Callback(cbInfo); + }); +} + +template +static napi_value +TemplatedInstanceCallback(napi_env env, napi_callback_info info) NAPI_NOEXCEPT { + return details::WrapCallback([&] { + CallbackInfo cbInfo(env, info); + T* instance = T::Unwrap(cbInfo.This().As()); + return (instance->*UnwrapCallback)(cbInfo); + }); +} + +template +static napi_value +TemplatedInstanceVoidCallback(napi_env env, + napi_callback_info info) NAPI_NOEXCEPT { + return details::WrapCallback([&] { + CallbackInfo cbInfo(env, info); + T* instance = T::Unwrap(cbInfo.This().As()); + (instance->*UnwrapCallback)(cbInfo); + return nullptr; + }); +} + template struct FinalizeData { static inline @@ -1845,15 +1887,12 @@ CreateFunction(napi_env env, template inline Function Function::New(napi_env env, const char* utf8name, void* data) { napi_value result = nullptr; - napi_status status = napi_create_function( - env, utf8name, NAPI_AUTO_LENGTH, - [](napi_env env, napi_callback_info info) { - CallbackInfo callbackInfo(env, info); - return details::WrapCallback([&] { - cb(callbackInfo); - return nullptr; - }); - }, data, &result); + napi_status status = napi_create_function(env, + utf8name, + NAPI_AUTO_LENGTH, + details::TemplatedVoidCallback, + data, + &result); NAPI_THROW_IF_FAILED(env, status, Function()); return Function(env, result); } @@ -1861,14 +1900,12 @@ inline Function Function::New(napi_env env, const char* utf8name, void* data) { template inline Function Function::New(napi_env env, const char* utf8name, void* data) { napi_value result = nullptr; - napi_status status = napi_create_function( - env, utf8name, NAPI_AUTO_LENGTH, - [](napi_env env, napi_callback_info info) { - CallbackInfo callbackInfo(env, info); - return details::WrapCallback([&] { - return cb(callbackInfo); - }); - }, data, &result); + napi_status status = napi_create_function(env, + utf8name, + NAPI_AUTO_LENGTH, + details::TemplatedCallback, + data, + &result); NAPI_THROW_IF_FAILED(env, status, Function()); return Function(env, result); } @@ -2859,7 +2896,7 @@ PropertyDescriptor::Accessor(const char* utf8name, napi_property_descriptor desc = napi_property_descriptor(); desc.utf8name = utf8name; - desc.getter = &GetterCallbackWrapper; + desc.getter = details::TemplatedCallback; desc.attributes = attributes; desc.data = data; @@ -2882,7 +2919,7 @@ PropertyDescriptor::Accessor(Name name, napi_property_descriptor desc = napi_property_descriptor(); desc.name = name; - desc.getter = &GetterCallbackWrapper; + desc.getter = details::TemplatedCallback; desc.attributes = attributes; desc.data = data; @@ -2900,8 +2937,8 @@ PropertyDescriptor::Accessor(const char* utf8name, napi_property_descriptor desc = napi_property_descriptor(); desc.utf8name = utf8name; - desc.getter = &GetterCallbackWrapper; - desc.setter = &SetterCallbackWrapper; + desc.getter = details::TemplatedCallback; + desc.setter = details::TemplatedVoidCallback; desc.attributes = attributes; desc.data = data; @@ -2928,31 +2965,14 @@ PropertyDescriptor::Accessor(Name name, napi_property_descriptor desc = napi_property_descriptor(); desc.name = name; - desc.getter = &GetterCallbackWrapper; - desc.setter = &SetterCallbackWrapper; + desc.getter = details::TemplatedCallback; + desc.setter = details::TemplatedVoidCallback; desc.attributes = attributes; desc.data = data; return desc; } -template -napi_value -PropertyDescriptor::GetterCallbackWrapper(napi_env env, - napi_callback_info info) { - CallbackInfo cbInfo(env, info); - return Getter(cbInfo); -} - -template -napi_value -PropertyDescriptor::SetterCallbackWrapper(napi_env env, - napi_callback_info info) { - CallbackInfo cbInfo(env, info); - Setter(cbInfo); - return nullptr; -} - template inline PropertyDescriptor PropertyDescriptor::Accessor(Napi::Env env, @@ -3283,7 +3303,7 @@ inline ClassPropertyDescriptor InstanceWrap::InstanceMethod( void* data) { napi_property_descriptor desc = napi_property_descriptor(); desc.utf8name = utf8name; - desc.method = &InstanceWrap::WrappedMethod; + desc.method = details::TemplatedInstanceVoidCallback; desc.data = data; desc.attributes = attributes; return desc; @@ -3297,7 +3317,7 @@ inline ClassPropertyDescriptor InstanceWrap::InstanceMethod( void* data) { napi_property_descriptor desc = napi_property_descriptor(); desc.utf8name = utf8name; - desc.method = &InstanceWrap::WrappedMethod; + desc.method = details::TemplatedInstanceCallback; desc.data = data; desc.attributes = attributes; return desc; @@ -3311,7 +3331,7 @@ inline ClassPropertyDescriptor InstanceWrap::InstanceMethod( void* data) { napi_property_descriptor desc = napi_property_descriptor(); desc.name = name; - desc.method = &InstanceWrap::WrappedMethod; + desc.method = details::TemplatedInstanceVoidCallback; desc.data = data; desc.attributes = attributes; return desc; @@ -3325,7 +3345,7 @@ inline ClassPropertyDescriptor InstanceWrap::InstanceMethod( void* data) { napi_property_descriptor desc = napi_property_descriptor(); desc.name = name; - desc.method = &InstanceWrap::WrappedMethod; + desc.method = details::TemplatedInstanceCallback; desc.data = data; desc.attributes = attributes; return desc; @@ -3378,7 +3398,7 @@ inline ClassPropertyDescriptor InstanceWrap::InstanceAccessor( void* data) { napi_property_descriptor desc = napi_property_descriptor(); desc.utf8name = utf8name; - desc.getter = This::WrapGetter(This::GetterTag()); + desc.getter = details::TemplatedInstanceCallback; desc.setter = This::WrapSetter(This::SetterTag()); desc.data = data; desc.attributes = attributes; @@ -3394,7 +3414,7 @@ inline ClassPropertyDescriptor InstanceWrap::InstanceAccessor( void* data) { napi_property_descriptor desc = napi_property_descriptor(); desc.name = name; - desc.getter = This::WrapGetter(This::GetterTag()); + desc.getter = details::TemplatedInstanceCallback; desc.setter = This::WrapSetter(This::SetterTag()); desc.data = data; desc.attributes = attributes; @@ -3487,27 +3507,6 @@ inline napi_value InstanceWrap::InstanceSetterCallbackWrapper( }); } -template -template ::InstanceVoidMethodCallback method> -inline napi_value InstanceWrap::WrappedMethod(napi_env env, napi_callback_info info) noexcept { - return details::WrapCallback([&] { - const CallbackInfo cbInfo(env, info); - T* instance = T::Unwrap(cbInfo.This().As()); - (instance->*method)(cbInfo); - return nullptr; - }); -} - -template -template ::InstanceMethodCallback method> -inline napi_value InstanceWrap::WrappedMethod(napi_env env, napi_callback_info info) noexcept { - return details::WrapCallback([&] { - const CallbackInfo cbInfo(env, info); - T* instance = T::Unwrap(cbInfo.This().As()); - return (instance->*method)(cbInfo); - }); -} - template template ::InstanceSetterCallback method> inline napi_value InstanceWrap::WrappedMethod(napi_env env, napi_callback_info info) noexcept { @@ -3732,7 +3731,7 @@ inline ClassPropertyDescriptor ObjectWrap::StaticMethod( void* data) { napi_property_descriptor desc = napi_property_descriptor(); desc.utf8name = utf8name; - desc.method = &ObjectWrap::WrappedMethod; + desc.method = details::TemplatedVoidCallback; desc.data = data; desc.attributes = static_cast(attributes | napi_static); return desc; @@ -3746,7 +3745,7 @@ inline ClassPropertyDescriptor ObjectWrap::StaticMethod( void* data) { napi_property_descriptor desc = napi_property_descriptor(); desc.name = name; - desc.method = &ObjectWrap::WrappedMethod; + desc.method = details::TemplatedVoidCallback; desc.data = data; desc.attributes = static_cast(attributes | napi_static); return desc; @@ -3760,7 +3759,7 @@ inline ClassPropertyDescriptor ObjectWrap::StaticMethod( void* data) { napi_property_descriptor desc = napi_property_descriptor(); desc.utf8name = utf8name; - desc.method = &ObjectWrap::WrappedMethod; + desc.method = details::TemplatedCallback; desc.data = data; desc.attributes = static_cast(attributes | napi_static); return desc; @@ -3774,7 +3773,7 @@ inline ClassPropertyDescriptor ObjectWrap::StaticMethod( void* data) { napi_property_descriptor desc = napi_property_descriptor(); desc.name = name; - desc.method = &ObjectWrap::WrappedMethod; + desc.method = details::TemplatedCallback; desc.data = data; desc.attributes = static_cast(attributes | napi_static); return desc; @@ -3827,7 +3826,7 @@ inline ClassPropertyDescriptor ObjectWrap::StaticAccessor( void* data) { napi_property_descriptor desc = napi_property_descriptor(); desc.utf8name = utf8name; - desc.getter = This::WrapStaticGetter(This::StaticGetterTag()); + desc.getter = details::TemplatedCallback; desc.setter = This::WrapStaticSetter(This::StaticSetterTag()); desc.data = data; desc.attributes = static_cast(attributes | napi_static); @@ -3843,7 +3842,7 @@ inline ClassPropertyDescriptor ObjectWrap::StaticAccessor( void* data) { napi_property_descriptor desc = napi_property_descriptor(); desc.name = name; - desc.getter = This::WrapStaticGetter(This::StaticGetterTag()); + desc.getter = details::TemplatedCallback; desc.setter = This::WrapStaticSetter(This::StaticSetterTag()); desc.data = data; desc.attributes = static_cast(attributes | napi_static); @@ -3969,23 +3968,6 @@ inline void ObjectWrap::FinalizeCallback(napi_env env, void* data, void* /*hi delete instance; } -template -template ::StaticVoidMethodCallback method> -inline napi_value ObjectWrap::WrappedMethod(napi_env env, napi_callback_info info) noexcept { - return details::WrapCallback([&] { - method(CallbackInfo(env, info)); - return nullptr; - }); -} - -template -template ::StaticMethodCallback method> -inline napi_value ObjectWrap::WrappedMethod(napi_env env, napi_callback_info info) noexcept { - return details::WrapCallback([&] { - return method(CallbackInfo(env, info)); - }); -} - template template ::StaticSetterCallback method> inline napi_value ObjectWrap::WrappedMethod(napi_env env, napi_callback_info info) noexcept { diff --git a/napi.h b/napi.h index cf0ce51e7..76a62f659 100644 --- a/napi.h +++ b/napi.h @@ -1623,10 +1623,6 @@ namespace Napi { operator const napi_property_descriptor&() const; private: - template - static napi_value GetterCallbackWrapper(napi_env env, napi_callback_info info); - template - static napi_value SetterCallbackWrapper(napi_env env, napi_callback_info info); napi_property_descriptor _desc; }; @@ -1748,16 +1744,8 @@ namespace Napi { template static napi_value WrappedMethod(napi_env env, napi_callback_info info) noexcept; - template struct GetterTag {}; template struct SetterTag {}; - template - static napi_value WrappedMethod(napi_env env, napi_callback_info info) noexcept; - template - static napi_value WrappedMethod(napi_env env, napi_callback_info info) noexcept; - template - static napi_callback WrapGetter(GetterTag) noexcept { return &This::WrappedMethod; } - static napi_callback WrapGetter(GetterTag) noexcept { return nullptr; } template static napi_callback WrapSetter(SetterTag) noexcept { return &This::WrappedMethod; } static napi_callback WrapSetter(SetterTag) noexcept { return nullptr; } @@ -1892,22 +1880,11 @@ namespace Napi { StaticGetterCallback, StaticSetterCallback> StaticAccessorCallbackData; - template - static napi_value WrappedMethod(napi_env env, napi_callback_info info) noexcept; - - template - static napi_value WrappedMethod(napi_env env, napi_callback_info info) noexcept; - template static napi_value WrappedMethod(napi_env env, napi_callback_info info) noexcept; - template struct StaticGetterTag {}; template struct StaticSetterTag {}; - template - static napi_callback WrapStaticGetter(StaticGetterTag) noexcept { return &This::WrappedMethod; } - static napi_callback WrapStaticGetter(StaticGetterTag) noexcept { return nullptr; } - template static napi_callback WrapStaticSetter(StaticSetterTag) noexcept { return &This::WrappedMethod; } static napi_callback WrapStaticSetter(StaticSetterTag) noexcept { return nullptr; } From f27623ff611645cd7d927f0de81158a93e960542 Mon Sep 17 00:00:00 2001 From: Lovell Fuller Date: Tue, 14 Jul 2020 13:34:32 +0100 Subject: [PATCH 06/16] build: introduce include_dir Introduce `include_dir` for use with gyp in a scalar context Deprecate use of `include` in an gyp array context, which happens to work when paths are absolute, but can fail on Windows when paths are relative and a gyp file contains multiple entries in its `include_dirs` directive. This change corrects documentation and tooling, adds support for relative paths (e.g. those containing whitespace) in a backwards compatible manner and makes the approach holistically consistent with that used by nan. PR-URL: https://github.com/nodejs/node-addon-api/pull/766 Reviewed-By: Michael Dawson --- common.gypi | 2 +- doc/setup.md | 2 +- index.js | 7 ++++--- tools/conversion.js | 8 ++++---- 4 files changed, 10 insertions(+), 9 deletions(-) diff --git a/common.gypi b/common.gypi index 088f961ea..9be254f0b 100644 --- a/common.gypi +++ b/common.gypi @@ -15,7 +15,7 @@ } }] ], - 'include_dirs': [" Date: Fri, 4 Sep 2020 01:21:35 +0200 Subject: [PATCH 07/16] test: fix the threasfafe function test test: fixed the execution for the threasfafe function test PR-URL: https://github.com/nodejs/node-addon-api/pull/807 Fixes: https://github.com/nodejs/node-addon-api/issues/806 Reviewed-By: Michael Dawson -sh-4.2$ --- test/threadsafe_function/threadsafe_function.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/threadsafe_function/threadsafe_function.js b/test/threadsafe_function/threadsafe_function.js index 4c4bbf8a3..419c214f8 100644 --- a/test/threadsafe_function/threadsafe_function.js +++ b/test/threadsafe_function/threadsafe_function.js @@ -4,10 +4,10 @@ const buildType = process.config.target_defaults.default_configuration; const assert = require('assert'); const common = require('../common'); -module.exports = async function() { +module.exports = (async function() { await test(require(`../build/${buildType}/binding.node`)); await test(require(`../build/${buildType}/binding_noexcept.node`)); -}; +})(); async function test(binding) { const expectedArray = (function(arrayLength) { From 6562e6b0ab604fd55b9c2d0cf954c9ce93e4bdee Mon Sep 17 00:00:00 2001 From: NickNaso Date: Fri, 4 Sep 2020 02:41:14 +0200 Subject: [PATCH 08/16] test: added tests to check the build process Refs: https://github.com/nodejs/node-addon-api/pull/766 PR-URL: https://github.com/nodejs/node-addon-api/pull/808 Reviewed-By: Michael Dawson --- .gitignore | 1 + package.json | 1 + test/addon_build/index.js | 50 +++++++++++++++++++++++++ test/addon_build/tpl/.npmrc | 1 + test/addon_build/tpl/addon.cc | 17 +++++++++ test/addon_build/tpl/binding.gyp | 62 +++++++++++++++++++++++++++++++ test/addon_build/tpl/index.js | 9 +++++ test/addon_build/tpl/package.json | 11 ++++++ test/index.js | 1 + 9 files changed, 153 insertions(+) create mode 100644 test/addon_build/index.js create mode 100644 test/addon_build/tpl/.npmrc create mode 100644 test/addon_build/tpl/addon.cc create mode 100644 test/addon_build/tpl/binding.gyp create mode 100644 test/addon_build/tpl/index.js create mode 100644 test/addon_build/tpl/package.json diff --git a/.gitignore b/.gitignore index c10f4dffc..c5b8bc871 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ /build /benchmark/build /benchmark/src +/test/addon_build/addons diff --git a/package.json b/package.json index 64a44f32a..0ec1d6ed6 100644 --- a/package.json +++ b/package.json @@ -252,6 +252,7 @@ "description": "Node.js API (N-API)", "devDependencies": { "benchmark": "^2.1.4", + "fs-extra": "^9.0.1", "bindings": "^1.5.0", "safe-buffer": "^5.1.1" }, diff --git a/test/addon_build/index.js b/test/addon_build/index.js new file mode 100644 index 000000000..0d0c6ea2f --- /dev/null +++ b/test/addon_build/index.js @@ -0,0 +1,50 @@ +'use strict'; + +const { promisify } = require('util'); +const exec = promisify(require('child_process').exec); +const { copy, remove } = require('fs-extra'); +const path = require('path'); +const assert = require('assert') + +const ADDONS_FOLDER = path.join(__dirname, 'addons'); + +const addons = [ + 'echo addon', + 'echo-addon' +] + +async function beforeAll(addons) { + console.log(' >Preparing native addons to build') + for (const addon of addons) { + await remove(path.join(ADDONS_FOLDER, addon)); + await copy(path.join(__dirname, 'tpl'), path.join(ADDONS_FOLDER, addon)); + } +} + +async function test(addon) { + console.log(` >Building addon: '${addon}'`); + const { stderr, stdout } = await exec('npm install', { + cwd: path.join(ADDONS_FOLDER, addon) + }) + console.log(` >Runting test for: '${addon}'`); + // Disabled the checks on stderr and stdout because of this issuue on npm: + // Stop using process.umask(): https://github.com/npm/cli/issues/1103 + // We should enable the following checks again after the resolution of + // the reported issue. + // assert.strictEqual(stderr, ''); + // assert.ok(stderr.length === 0); + // assert.ok(stdout.length > 0); + const binding = require(`${ADDONS_FOLDER}/${addon}`); + assert.strictEqual(binding.except.echo('except'), 'except'); + assert.strictEqual(binding.except.echo(101), 101); + assert.strictEqual(binding.noexcept.echo('noexcept'), 'noexcept'); + assert.strictEqual(binding.noexcept.echo(103), 103); +} + + +module.exports = (async function() { + await beforeAll(addons); + for (const addon of addons) { + await test(addon); + } +})() diff --git a/test/addon_build/tpl/.npmrc b/test/addon_build/tpl/.npmrc new file mode 100644 index 000000000..9cf949503 --- /dev/null +++ b/test/addon_build/tpl/.npmrc @@ -0,0 +1 @@ +package-lock=false \ No newline at end of file diff --git a/test/addon_build/tpl/addon.cc b/test/addon_build/tpl/addon.cc new file mode 100644 index 000000000..1a86799c4 --- /dev/null +++ b/test/addon_build/tpl/addon.cc @@ -0,0 +1,17 @@ +#include + +Napi::Value Echo(const Napi::CallbackInfo& info) { + Napi::Env env = info.Env(); + if (info.Length() != 1) { + Napi::TypeError::New(env, "Wrong number of arguments. One argument expected.") + .ThrowAsJavaScriptException(); + } + return info[0].As(); +} + +Napi::Object Init(Napi::Env env, Napi::Object exports) { + exports.Set(Napi::String::New(env, "echo"), Napi::Function::New(env, Echo)); + return exports; +} + +NODE_API_MODULE(NODE_GYP_MODULE_NAME, Init) diff --git a/test/addon_build/tpl/binding.gyp b/test/addon_build/tpl/binding.gyp new file mode 100644 index 000000000..aa26f1acb --- /dev/null +++ b/test/addon_build/tpl/binding.gyp @@ -0,0 +1,62 @@ +{ + 'target_defaults': { + 'include_dirs': [ + " Date: Wed, 26 Aug 2020 10:22:31 -0700 Subject: [PATCH 09/16] doc: add inheritance links and other changes * README.md: * Change indentation to reflect class hierarchy. * Link to new doc/hierarchy.md which shows full class hierarchy. * Add single sentence with link to parent class at the top of class doc. * doc/addon.md: * Replace `Addon` with `Addon`. * Show templating in prototypes. * Move `InstanceWrap` method documentation to its own file, because it is shared with `ObjectWRap`, and link to said new file. * doc/array.md: Create the file from the `Array`-related contents of doc/basic_types.md. * Remove doc/basic_types.md, splitting its contents per-class into individual files. * Add doc/hierarchy.md, with full class hierarchy. * Add doc/instance_wrap.md for documenting `InstanceMethod`, `InstanceAccessor`, and `InstanceValue`. * Create doc/name.md from doc/basic_types.md, documenting `Napi::Name`. * doc/object_wrap.md: * Add templating notation `Napi::ObjectWrap`. * Show templating in prototypes. * Wrap file to 80 columns. * Remove methods provided by `InstanceWrap` and link to doc/instance_wrap.md. * doc/value.md: * Merge documentation from doc/basic_types.md. * Add namespacing. * Sort methods alphabetically. Signed-off-by: Gabriel Schulhof Fixes: https://github.com/nodejs/node-addon-api/issues/796 PR-URL: https://github.com/nodejs/node-addon-api/pull/798 Reviewed-By: Michael Dawson Reviewed-By: Nicola Del Gobbo --- README.md | 33 +- doc/addon.md | 397 +------------------ doc/array.md | 81 ++++ doc/array_buffer.md | 4 + doc/basic_types.md | 423 -------------------- doc/bigint.md | 4 + doc/boolean.md | 4 + doc/buffer.md | 4 + doc/dataview.md | 4 + doc/date.md | 4 +- doc/error.md | 5 + doc/external.md | 4 + doc/hierarchy.md | 91 +++++ doc/instance_wrap.md | 408 ++++++++++++++++++++ doc/name.md | 29 ++ doc/object.md | 8 +- doc/object_wrap.md | 530 ++++++-------------------- doc/promises.md | 5 + doc/string.md | 4 + doc/symbol.md | 4 + doc/typed_array.md | 4 + doc/typed_array_of.md | 4 + doc/value.md | 270 ++++++++----- doc/working_with_javascript_values.md | 2 +- 24 files changed, 989 insertions(+), 1337 deletions(-) create mode 100644 doc/array.md delete mode 100644 doc/basic_types.md create mode 100644 doc/hierarchy.md create mode 100644 doc/instance_wrap.md create mode 100644 doc/name.md diff --git a/README.md b/README.md index aa06eea67..dc316c1b0 100644 --- a/README.md +++ b/README.md @@ -81,28 +81,29 @@ The oldest Node.js version supported by the current version of node-addon-api is The following is the documentation for node-addon-api. + - [Full Class Hierarchy](doc/hierarchy.md) - [Addon Structure](doc/addon.md) - - [Basic Types](doc/basic_types.md) - - [Array](doc/basic_types.md#array) - - [Symbol](doc/symbol.md) - - [String](doc/string.md) - - [Name](doc/basic_types.md#name) - - [Number](doc/number.md) - - [Date](doc/date.md) - - [BigInt](doc/bigint.md) - - [Boolean](doc/boolean.md) + - Basic Types: - [Env](doc/env.md) - - [Value](doc/value.md) - [CallbackInfo](doc/callbackinfo.md) - [Reference](doc/reference.md) - - [External](doc/external.md) - - [Object](doc/object.md) - - [ObjectReference](doc/object_reference.md) - - [PropertyDescriptor](doc/property_descriptor.md) + - [Value](doc/value.md) + - [Name](doc/name.md) + - [Symbol](doc/symbol.md) + - [String](doc/string.md) + - [Number](doc/number.md) + - [Date](doc/date.md) + - [BigInt](doc/bigint.md) + - [Boolean](doc/boolean.md) + - [External](doc/external.md) + - [Object](doc/object.md) + - [Array](doc/array.md) + - [ObjectReference](doc/object_reference.md) + - [PropertyDescriptor](doc/property_descriptor.md) - [Error Handling](doc/error_handling.md) - [Error](doc/error.md) - - [TypeError](doc/type_error.md) - - [RangeError](doc/range_error.md) + - [TypeError](doc/type_error.md) + - [RangeError](doc/range_error.md) - [Object Lifetime Management](doc/object_lifetime_management.md) - [HandleScope](doc/handle_scope.md) - [EscapableHandleScope](doc/escapable_handle_scope.md) diff --git a/doc/addon.md b/doc/addon.md index b4c9c9d6b..ee85e7d5e 100644 --- a/doc/addon.md +++ b/doc/addon.md @@ -1,5 +1,7 @@ # Add-on Structure +Class `Napi::Addon` inherits from class [`Napi::InstanceWrap`][]. + Creating add-ons that work correctly when loaded multiple times from the same source package into multiple Node.js threads and/or multiple times into the same Node.js thread requires that all global data they hold be associated with the @@ -8,20 +10,20 @@ variables because doing so does not take into account the fact that an add-on may be loaded into multiple threads nor that an add-on may be loaded multiple times into a single thread. -The `Napi::Addon` class can be used to define an entire add-on. Instances of -`Napi::Addon` subclasses become instances of the add-on, stored safely by +The `Napi::Addon` class can be used to define an entire add-on. Instances of +`Napi::Addon` subclasses become instances of the add-on, stored safely by Node.js on its various threads and into its various contexts. Thus, any data -stored in the instance variables of a `Napi::Addon` subclass instance are stored -safely by Node.js. Functions exposed to JavaScript using -`Napi::Addon::InstanceMethod` and/or `Napi::Addon::DefineAddon` are instance -methods of the `Napi::Addon` subclass and thus have access to data stored inside -the instance. +stored in the instance variables of a `Napi::Addon` subclass instance are +stored safely by Node.js. Functions exposed to JavaScript using +`Napi::Addon::InstanceMethod` and/or `Napi::Addon::DefineAddon` are +instance methods of the `Napi::Addon` subclass and thus have access to data +stored inside the instance. -`Napi::Addon::DefineProperties` may be used to attach `Napi::Addon` subclass -instance methods to objects other than the one that will be returned to Node.js -as the add-on instance. +`Napi::Addon::DefineProperties` may be used to attach `Napi::Addon` +subclass instance methods to objects other than the one that will be returned to +Node.js as the add-on instance. -The `Napi::Addon` class can be used together with the `NODE_API_ADDON()` and +The `Napi::Addon` class can be used together with the `NODE_API_ADDON()` and `NODE_API_NAMED_ADDON()` macros to define add-ons. ## Example @@ -122,7 +124,8 @@ pass it to `DefineAddon()` as its first parameter if it wishes to replace the Defines an add-on instance with functions, accessors, and/or values. ```cpp -void Napi::Addon::DefineAddon(Napi::Object exports, +template +void Napi::Addon::DefineAddon(Napi::Object exports, const std::initializer_list& properties); ``` @@ -138,8 +141,9 @@ Defines function, accessor, and/or value properties on an object using add-on instance methods. ```cpp +template Napi::Object -Napi::Addon::DefineProperties(Napi::Object object, +Napi::Addon::DefineProperties(Napi::Object object, const std::initializer_list& properties); ``` @@ -150,369 +154,4 @@ See: [`Class property and descriptor`](class_property_descriptor.md). Returns `object`. -### InstanceMethod - -Creates a property descriptor that represents a method provided by the add-on. - -```cpp -static Napi::PropertyDescriptor -Napi::Addon::InstanceMethod(const char* utf8name, - InstanceVoidMethodCallback method, - napi_property_attributes attributes = napi_default, - void* data = nullptr); -``` - -- `[in] utf8name`: Null-terminated string that represents the name of the method -provided by the add-on. -- `[in] method`: The native function that represents a method provided by the -add-on. -- `[in] attributes`: The attributes associated with the property. One or more of -`napi_property_attributes`. -- `[in] data`: User-provided data passed into the method when it is invoked. - -Returns a `Napi::PropertyDescriptor` object that represents a method provided -by the add-on. The method must be of the form - -```cpp -void MethodName(const Napi::CallbackInfo& info); -``` - -### InstanceMethod - -Creates a property descriptor that represents a method provided by the add-on. - -```cpp -static Napi::PropertyDescriptor -Napi::Addon::InstanceMethod(const char* utf8name, - InstanceMethodCallback method, - napi_property_attributes attributes = napi_default, - void* data = nullptr); -``` - -- `[in] utf8name`: Null-terminated string that represents the name of the method -provided by the add-on. -- `[in] method`: The native function that represents a method provided by the -add-on. -- `[in] attributes`: The attributes associated with the property. One or more of -`napi_property_attributes`. -- `[in] data`: User-provided data passed into the method when it is invoked. - -Returns a `Napi::PropertyDescriptor` object that represents a method provided -by the add-on. The method must be of the form - -```cpp -Napi::Value MethodName(const Napi::CallbackInfo& info); -``` - -### InstanceMethod - -Creates a property descriptor that represents a method provided by the add-on. - -```cpp -static Napi::PropertyDescriptor -Napi::Addon::InstanceMethod(Napi::Symbol name, - InstanceVoidMethodCallback method, - napi_property_attributes attributes = napi_default, - void* data = nullptr); -``` - -- `[in] name`: JavaScript symbol that represents the name of the method provided -by the add-on. -- `[in] method`: The native function that represents a method provided by the -add-on. -- `[in] attributes`: The attributes associated with the property. One or more of -`napi_property_attributes`. -- `[in] data`: User-provided data passed into the method when it is invoked. - -Returns a `Napi::PropertyDescriptor` object that represents a method provided -by the add-on. The method must be of the form - -```cpp -void MethodName(const Napi::CallbackInfo& info); -``` - -### InstanceMethod - -Creates a property descriptor that represents a method provided by the add-on. - -```cpp -static Napi::PropertyDescriptor -Napi::Addon::InstanceMethod(Napi::Symbol name, - InstanceMethodCallback method, - napi_property_attributes attributes = napi_default, - void* data = nullptr); -``` - -- `[in] name`: JavaScript symbol that represents the name of the method provided -by the add-on. -- `[in] method`: The native function that represents a method provided by the -add-on. -- `[in] attributes`: The attributes associated with the property. One or more of -`napi_property_attributes`. -- `[in] data`: User-provided data passed into the method when it is invoked. - -Returns a `Napi::PropertyDescriptor` object that represents a method provided -by the add-on. The method must be of the form - -```cpp -Napi::Value MethodName(const Napi::CallbackInfo& info); -``` - -### InstanceMethod - -Creates a property descriptor that represents a method provided by the add-on. - -```cpp -template -static Napi::PropertyDescriptor -Napi::Addon::InstanceMethod(const char* utf8name, - napi_property_attributes attributes = napi_default, - void* data = nullptr); -``` - -- `[in] method`: The native function that represents a method provided by the -add-on. -- `[in] utf8name`: Null-terminated string that represents the name of the method -provided by the add-on. -- `[in] attributes`: The attributes associated with the property. One or more of -`napi_property_attributes`. -- `[in] data`: User-provided data passed into the method when it is invoked. - -Returns a `Napi::PropertyDescriptor` object that represents a method provided -by the add-on. The method must be of the form - -```cpp -void MethodName(const Napi::CallbackInfo& info); -``` - -### InstanceMethod - -Creates a property descriptor that represents a method provided by the add-on. - -```cpp -template -static Napi::PropertyDescriptor -Napi::Addon::InstanceMethod(const char* utf8name, - napi_property_attributes attributes = napi_default, - void* data = nullptr); -``` - -- `[in] method`: The native function that represents a method provided by the -add-on. -- `[in] utf8name`: Null-terminated string that represents the name of the method -provided by the add-on. -- `[in] attributes`: The attributes associated with the property. One or more of -`napi_property_attributes`. -- `[in] data`: User-provided data passed into the method when it is invoked. - -Returns a `Napi::PropertyDescriptor` object that represents a method provided -by the add-on. The method must be of the form - -```cpp -Napi::Value MethodName(const Napi::CallbackInfo& info); -``` - -### InstanceMethod - -Creates a property descriptor that represents a method provided by the add-on. - -```cpp -template -static Napi::PropertyDescriptor -Napi::Addon::InstanceMethod(Napi::Symbol name, - napi_property_attributes attributes = napi_default, - void* data = nullptr); -``` - -- `[in] method`: The native function that represents a method provided by the -add-on. -- `[in] name`: The `Napi::Symbol` object whose value is used to identify the -instance method for the class. -- `[in] attributes`: The attributes associated with the property. One or more of -`napi_property_attributes`. -- `[in] data`: User-provided data passed into the method when it is invoked. - -Returns a `Napi::PropertyDescriptor` object that represents a method provided -by the add-on. The method must be of the form - -```cpp -void MethodName(const Napi::CallbackInfo& info); -``` - -### InstanceMethod - -Creates a property descriptor that represents a method provided by the add-on. - -```cpp -template -static Napi::PropertyDescriptor -Napi::Addon::InstanceMethod(Napi::Symbol name, - napi_property_attributes attributes = napi_default, - void* data = nullptr); -``` - -- `[in] method`: The native function that represents a method provided by the -add-on. -- `[in] name`: The `Napi::Symbol` object whose value is used to identify the -instance method for the class. -- `[in] attributes`: The attributes associated with the property. One or more of -`napi_property_attributes`. -- `[in] data`: User-provided data passed into the method when it is invoked. - -Returns a `Napi::PropertyDescriptor` object that represents a method provided -by the add-on. The method must be of the form - -```cpp -Napi::Value MethodName(const Napi::CallbackInfo& info); -``` - -### InstanceAccessor - -Creates a property descriptor that represents an instance accessor property -provided by the add-on. - -```cpp -static Napi::PropertyDescriptor -Napi::Addon::InstanceAccessor(const char* utf8name, - InstanceGetterCallback getter, - InstanceSetterCallback setter, - napi_property_attributes attributes = napi_default, - void* data = nullptr); -``` - -- `[in] utf8name`: Null-terminated string that represents the name of the method -provided by the add-on. -- `[in] getter`: The native function to call when a get access to the property -is performed. -- `[in] setter`: The native function to call when a set access to the property -is performed. -- `[in] attributes`: The attributes associated with the property. One or more of -`napi_property_attributes`. -- `[in] data`: User-provided data passed into the getter or the setter when it -is invoked. - -Returns a `Napi::PropertyDescriptor` object that represents an instance accessor -property provided by the add-on. - -### InstanceAccessor - -Creates a property descriptor that represents an instance accessor property -provided by the add-on. - -```cpp -static Napi::PropertyDescriptor -Napi::Addon::InstanceAccessor(Symbol name, - InstanceGetterCallback getter, - InstanceSetterCallback setter, - napi_property_attributes attributes = napi_default, - void* data = nullptr); -``` - -- `[in] name`: The `Napi::Symbol` object whose value is used to identify the -instance accessor. -- `[in] getter`: The native function to call when a get access to the property of -a JavaScript class is performed. -- `[in] setter`: The native function to call when a set access to the property of -a JavaScript class is performed. -- `[in] attributes`: The attributes associated with the property. One or more of -`napi_property_attributes`. -- `[in] data`: User-provided data passed into the getter or the setter when it -is invoked. - -Returns a `Napi::PropertyDescriptor` object that represents an instance accessor -property provided by the add-on. - -### InstanceAccessor - -Creates a property descriptor that represents an instance accessor property -provided by the add-on. - -```cpp -template -static Napi::PropertyDescriptor -Napi::Addon::InstanceAccessor(const char* utf8name, - napi_property_attributes attributes = napi_default, - void* data = nullptr); -``` - -- `[in] getter`: The native function to call when a get access to the property of -a JavaScript class is performed. -- `[in] setter`: The native function to call when a set access to the property of -a JavaScript class is performed. -- `[in] utf8name`: Null-terminated string that represents the name of the method -provided by the add-on. -- `[in] attributes`: The attributes associated with the property. One or more of -`napi_property_attributes`. -- `[in] data`: User-provided data passed into the getter or the setter when it -is invoked. - -Returns a `Napi::PropertyDescriptor` object that represents an instance accessor -property provided by the add-on. - -### InstanceAccessor - -Creates a property descriptor that represents an instance accessor property -provided by the add-on. - -```cpp -template -static Napi::PropertyDescriptor -Napi::Addon::InstanceAccessor(Symbol name, - napi_property_attributes attributes = napi_default, - void* data = nullptr); -``` - -- `[in] getter`: The native function to call when a get access to the property of -a JavaScript class is performed. -- `[in] setter`: The native function to call when a set access to the property of -a JavaScript class is performed. -- `[in] name`: The `Napi::Symbol` object whose value is used to identify the -instance accessor. -- `[in] attributes`: The attributes associated with the property. One or more of -`napi_property_attributes`. -- `[in] data`: User-provided data passed into the getter or the setter when it -is invoked. - -Returns a `Napi::PropertyDescriptor` object that represents an instance accessor -property provided by the add-on. - -### InstanceValue - -Creates property descriptor that represents an instance value property provided -by the add-on. - -```cpp -static Napi::PropertyDescriptor -Napi::Addon::InstanceValue(const char* utf8name, - Napi::Value value, - napi_property_attributes attributes = napi_default); -``` - -- `[in] utf8name`: Null-terminated string that represents the name of the property. -- `[in] value`: The value that's retrieved by a get access of the property. -- `[in] attributes`: The attributes associated with the property. One or more of -`napi_property_attributes`. - -Returns a `Napi::PropertyDescriptor` object that represents an instance value -property of an add-on. - -### InstanceValue - -Creates property descriptor that represents an instance value property provided -by the add-on. - -```cpp -static Napi::PropertyDescriptor -Napi::Addon::InstanceValue(Symbol name, - Napi::Value value, - napi_property_attributes attributes = napi_default); -``` - -- `[in] name`: The `Napi::Symbol` object whose value is used to identify the -name of the property. -- `[in] value`: The value that's retrieved by a get access of the property. -- `[in] attributes`: The attributes associated with the property. One or more of -`napi_property_attributes`. - -Returns a `Napi::PropertyDescriptor` object that represents an instance value -property of an add-on. +[`Napi::InstanceWrap`]: ./instance_wrap.md diff --git a/doc/array.md b/doc/array.md new file mode 100644 index 000000000..a12e92daf --- /dev/null +++ b/doc/array.md @@ -0,0 +1,81 @@ +# Array + +Class [`Napi::Array`][] inherits from class [`Napi::Object`][]. + +Arrays are native representations of JavaScript Arrays. `Napi::Array` is a wrapper +around `napi_value` representing a JavaScript Array. + +[`Napi::TypedArray`][] and [`Napi::ArrayBuffer`][] correspond to JavaScript data +types such as [`Napi::Int32Array`][] and [`Napi::ArrayBuffer`][], respectively, +that can be used for transferring large amounts of data from JavaScript to the +native side. An example illustrating the use of a JavaScript-provided +`ArrayBuffer` in native code is available [here](https://github.com/nodejs/node-addon-examples/tree/master/array_buffer_to_native/node-addon-api). + +## Constructor +```cpp +Napi::Array::Array(); +``` + +Returns an empty array. + +If an error occurs, a `Napi::Error` will be thrown. If C++ exceptions are not +being used, callers should check the result of `Env::IsExceptionPending` before +attempting to use the returned value. + +```cpp +Napi::Array::Array(napi_env env, napi_value value); +``` +- `[in] env` - The environment in which to create the array. +- `[in] value` - The primitive to wrap. + +Returns a `Napi::Array` wrapping a `napi_value`. + +If an error occurs, a `Napi::Error` will get thrown. If C++ exceptions are not +being used, callers should check the result of `Env::IsExceptionPending` before +attempting to use the returned value. + +## Methods + +### New +```cpp +static Napi::Array Napi::Array::New(napi_env env); +``` +- `[in] env` - The environment in which to create the array. + +Returns a new `Napi::Array`. + +If an error occurs, a `Napi::Error` will get thrown. If C++ exceptions are not +being used, callers should check the result of `Env::IsExceptionPending` before +attempting to use the returned value. + +### New + +```cpp +static Napi::Array Napi::Array::New(napi_env env, size_t length); +``` +- `[in] env` - The environment in which to create the array. +- `[in] length` - The length of the array. + +Returns a new `Napi::Array` with the given length. + +If an error occurs, a `Napi::Error` will get thrown. If C++ exceptions are not +being used, callers should check the result of `Env::IsExceptionPending` before +attempting to use the returned value. + +### Length +```cpp +uint32_t Napi::Array::Length() const; +``` + +Returns the length of the array. + +Note: +This can execute JavaScript code implicitly according to JavaScript semantics. +If an error occurs, a `Napi::Error` will get thrown. If C++ exceptions are not +being used, callers should check the result of `Env::IsExceptionPending` before +attempting to use the returned value. + +[`Napi::ArrayBuffer`]: ./array_buffer.md +[`Napi::Int32Array`]: ./typed_array_of.md +[`Napi::Object`]: ./object.md +[`Napi::TypedArray`]: ./typed_array.md diff --git a/doc/array_buffer.md b/doc/array_buffer.md index ca9d45c00..988a839a4 100644 --- a/doc/array_buffer.md +++ b/doc/array_buffer.md @@ -1,5 +1,7 @@ # ArrayBuffer +Class `Napi::ArrayBuffer` inherits from class [`Napi::Object`][]. + The `Napi::ArrayBuffer` class corresponds to the [JavaScript `ArrayBuffer`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer) class. @@ -127,3 +129,5 @@ void* Napi::ArrayBuffer::Data() const; ``` Returns a pointer the wrapped data. + +[`Napi::Object`]: ./object.md diff --git a/doc/basic_types.md b/doc/basic_types.md deleted file mode 100644 index 03ec14b4b..000000000 --- a/doc/basic_types.md +++ /dev/null @@ -1,423 +0,0 @@ -# Basic Types - -Node Addon API consists of a few fundamental data types. These allow a user of -the API to create, convert and introspect fundamental JavaScript types, and -interoperate with their C++ counterparts. - -## Value - -`Napi::Value` is the base class of Node Addon API's fundamental object type hierarchy. -It represents a JavaScript value of an unknown type. It is a thin wrapper around -the N-API datatype `napi_value`. Methods on this class can be used to check -the JavaScript type of the underlying N-API `napi_value` and also to convert to -C++ types. - -### Constructor - -```cpp -Napi::Value::Value(); -``` - -Used to create a Node Addon API `Napi::Value` that represents an **empty** value. - -```cpp -Napi::Value::Value(napi_env env, napi_value value); -``` - -- `[in] env` - The `napi_env` environment in which to construct the `Napi::Value` -object. -- `[in] value` - The underlying JavaScript value that the `Napi::Value` instance -represents. - -Returns a Node.js Addon API `Napi::Value` that represents the `napi_value` passed -in. - -### Operators - -#### operator napi_value - -```cpp -Napi::Value::operator napi_value() const; -``` - -Returns the underlying N-API `napi_value`. If the instance is _empty_, this -returns `nullptr`. - -#### operator == - -```cpp -bool Napi::Value::operator ==(const Value& other) const; -``` - -Returns `true` if this value strictly equals another value, or `false` otherwise. - -#### operator != - -```cpp -bool Napi::Value::operator !=(const Value& other) const; -``` - -Returns `false` if this value strictly equals another value, or `true` otherwise. - -### Methods - -#### From -```cpp -template -static Napi::Value Napi::Value::From(napi_env env, const T& value); -``` - -- `[in] env` - The `napi_env` environment in which to construct the `Napi::Value` object. -- `[in] value` - The C++ type to represent in JavaScript. - -Returns a `Napi::Value` representing the input C++ type in JavaScript. - -This method is used to convert from a C++ type to a JavaScript value. -Here, `value` may be any of: -- `bool` - returns a `Napi::Boolean`. -- Any integer type - returns a `Napi::Number`. -- Any floating point type - returns a `Napi::Number`. -- `const char*` (encoded using UTF-8, null-terminated) - returns a `Napi::String`. -- `const char16_t*` (encoded using UTF-16-LE, null-terminated) - returns a `Napi::String`. -- `std::string` (encoded using UTF-8) - returns a `Napi::String`. -- `std::u16string` - returns a `Napi::String`. -- `napi::Value` - returns a `Napi::Value`. -- `napi_value` - returns a `Napi::Value`. - -#### As -```cpp -template T Napi::Value::As() const; -``` - -Returns the `Napi::Value` cast to a desired C++ type. - -Use this when the actual type is known or assumed. - -Note: -This conversion does NOT coerce the type. Calling any methods inappropriate for -the actual value type will throw `Napi::Error`. - -#### StrictEquals -```cpp -bool Napi::Value::StrictEquals(const Value& other) const; -``` - -- `[in] other` - The value to compare against. - -Returns true if the other `Napi::Value` is strictly equal to this one. - -#### Env -```cpp -Napi::Env Napi::Value::Env() const; -``` - -Returns the environment that the value is associated with. See -[`Napi::Env`](env.md) for more details about environments. - -#### IsEmpty -```cpp -bool Napi::Value::IsEmpty() const; -``` - -Returns `true` if the value is uninitialized. - -An empty value is invalid, and most attempts to perform an operation on an -empty value will result in an exception. An empty value is distinct from -JavaScript `null` or `undefined`, which are valid values. - -When C++ exceptions are disabled at compile time, a method with a `Napi::Value` -return type may return an empty value to indicate a pending exception. If C++ -exceptions are not being used, callers should check the result of -`Env::IsExceptionPending` before attempting to use the value. - -#### Type -```cpp -napi_valuetype Napi::Value::Type() const; -``` - -Returns the underlying N-API `napi_valuetype` of the value. - -#### IsUndefined -```cpp -bool Napi::Value::IsUndefined() const; -``` - -Returns `true` if the underlying value is a JavaScript `undefined` or `false` -otherwise. - -#### IsNull -```cpp -bool Napi::Value::IsNull() const; -``` - -Returns `true` if the underlying value is a JavaScript `null` or `false` -otherwise. - -#### IsBoolean -```cpp -bool Napi::Value::IsBoolean() const; -``` - -Returns `true` if the underlying value is a JavaScript `true` or JavaScript -`false`, or `false` if the value is not a `Napi::Boolean` value in JavaScript. - -#### IsNumber -```cpp -bool Napi::Value::IsNumber() const; -``` - -Returns `true` if the underlying value is a JavaScript `Napi::Number` or `false` -otherwise. - -#### IsString -```cpp -bool Napi::Value::IsString() const; -``` - -Returns `true` if the underlying value is a JavaScript `Napi::String` or `false` -otherwise. - -#### IsSymbol -```cpp -bool Napi::Value::IsSymbol() const; -``` - -Returns `true` if the underlying value is a JavaScript `Napi::Symbol` or `false` -otherwise. - -#### IsArray -```cpp -bool Napi::Value::IsArray() const; -``` - -Returns `true` if the underlying value is a JavaScript `Napi::Array` or `false` -otherwise. - -#### IsArrayBuffer -```cpp -bool Napi::Value::IsArrayBuffer() const; -``` - -Returns `true` if the underlying value is a JavaScript `Napi::ArrayBuffer` or `false` -otherwise. - -#### IsTypedArray -```cpp -bool Napi::Value::IsTypedArray() const; -``` - -Returns `true` if the underlying value is a JavaScript `Napi::TypedArray` or `false` -otherwise. - -#### IsObject -```cpp -bool Napi::Value::IsObject() const; -``` - -Returns `true` if the underlying value is a JavaScript `Napi::Object` or `false` -otherwise. - -#### IsFunction -```cpp -bool Napi::Value::IsFunction() const; -``` - -Returns `true` if the underlying value is a JavaScript `Napi::Function` or `false` -otherwise. - -#### IsPromise -```cpp -bool Napi::Value::IsPromise() const; -``` - -Returns `true` if the underlying value is a JavaScript `Napi::Promise` or `false` -otherwise. - -#### IsDataView -```cpp -bool Napi::Value::IsDataView() const; -``` - -Returns `true` if the underlying value is a JavaScript `Napi::DataView` or `false` -otherwise. - -#### IsBuffer -```cpp -bool Napi::Value::IsBuffer() const; -``` - -Returns `true` if the underlying value is a Node.js `Napi::Buffer` or `false` -otherwise. - -#### IsExternal -```cpp -bool Napi::Value::IsExternal() const; -``` - -Returns `true` if the underlying value is a N-API external object or `false` -otherwise. - -#### IsDate -```cpp -bool Napi::Value::IsDate() const; -``` - -Returns `true` if the underlying value is a JavaScript `Date` or `false` -otherwise. - -#### ToBoolean -```cpp -Napi::Boolean Napi::Value::ToBoolean() const; -``` - -Returns a `Napi::Boolean` representing the `Napi::Value`. - -This is a wrapper around `napi_coerce_to_boolean`. This will throw a JavaScript -exception if the coercion fails. If C++ exceptions are not being used, callers -should check the result of `Env::IsExceptionPending` before attempting to use -the returned value. - -#### ToNumber -```cpp -Napi::Number Napi::Value::ToNumber() const; -``` - -Returns a `Napi::Number` representing the `Napi::Value`. - -Note: -This can cause script code to be executed according to JavaScript semantics. -This is a wrapper around `napi_coerce_to_number`. This will throw a JavaScript -exception if the coercion fails. If C++ exceptions are not being used, callers -should check the result of `Env::IsExceptionPending` before attempting to use -the returned value. - -#### ToString -```cpp -Napi::String Napi::Value::ToString() const; -``` - -Returns a `Napi::String` representing the `Napi::Value`. - -Note that this can cause script code to be executed according to JavaScript -semantics. This is a wrapper around `napi_coerce_to_string`. This will throw a -JavaScript exception if the coercion fails. If C++ exceptions are not being -used, callers should check the result of `Env::IsExceptionPending` before -attempting to use the returned value. - -#### ToObject -```cpp -Napi::Object Napi::Value::ToObject() const; -``` - -Returns a `Napi::Object` representing the `Napi::Value`. - -This is a wrapper around `napi_coerce_to_object`. This will throw a JavaScript -exception if the coercion fails. If C++ exceptions are not being used, callers -should check the result of `Env::IsExceptionPending` before attempting to use -the returned value. - -## Name - -Names are JavaScript values that can be used as a property name. There are two -specialized types of names supported in Node.js Addon API [`Napi::String`](string.md) -and [`Napi::Symbol`](symbol.md). - -### Methods - -#### Constructor -```cpp -Napi::Name::Name(); -``` - -Returns an empty `Napi::Name`. - -```cpp -Napi::Name::Name(napi_env env, napi_value value); -``` -- `[in] env` - The environment in which to create the array. -- `[in] value` - The primitive to wrap. - -Returns a `Napi::Name` created from the JavaScript primitive. - -Note: -The value is not coerced to a string. - -## Array - -Arrays are native representations of JavaScript Arrays. `Napi::Array` is a wrapper -around `napi_value` representing a JavaScript Array. - -[`Napi::TypedArray`][] and [`Napi::ArrayBuffer`][] correspond to JavaScript data -types such as [`Int32Array`][] and [`ArrayBuffer`][], respectively, that can be -used for transferring large amounts of data from JavaScript to the native side. -An example illustrating the use of a JavaScript-provided `ArrayBuffer` in native -code is available [here](https://github.com/nodejs/node-addon-examples/tree/master/array_buffer_to_native/node-addon-api). - -### Constructor -```cpp -Napi::Array::Array(); -``` - -Returns an empty array. - -If an error occurs, a `Napi::Error` will be thrown. If C++ exceptions are not -being used, callers should check the result of `Env::IsExceptionPending` before -attempting to use the returned value. - -```cpp -Napi::Array::Array(napi_env env, napi_value value); -``` -- `[in] env` - The environment in which to create the array. -- `[in] value` - The primitive to wrap. - -Returns a `Napi::Array` wrapping a `napi_value`. - -If an error occurs, a `Napi::Error` will get thrown. If C++ exceptions are not -being used, callers should check the result of `Env::IsExceptionPending` before -attempting to use the returned value. - -### Methods - -#### New -```cpp -static Napi::Array Napi::Array::New(napi_env env); -``` -- `[in] env` - The environment in which to create the array. - -Returns a new `Napi::Array`. - -If an error occurs, a `Napi::Error` will get thrown. If C++ exceptions are not -being used, callers should check the result of `Env::IsExceptionPending` before -attempting to use the returned value. - -#### New - -```cpp -static Napi::Array Napi::Array::New(napi_env env, size_t length); -``` -- `[in] env` - The environment in which to create the array. -- `[in] length` - The length of the array. - -Returns a new `Napi::Array` with the given length. - -If an error occurs, a `Napi::Error` will get thrown. If C++ exceptions are not -being used, callers should check the result of `Env::IsExceptionPending` before -attempting to use the returned value. - -#### Length -```cpp -uint32_t Napi::Array::Length() const; -``` - -Returns the length of the array. - -Note: -This can execute JavaScript code implicitly according to JavaScript semantics. -If an error occurs, a `Napi::Error` will get thrown. If C++ exceptions are not -being used, callers should check the result of `Env::IsExceptionPending` before -attempting to use the returned value. - -[`Napi::TypedArray`]: ./typed_array.md -[`Napi::ArrayBuffer`]: ./array_buffer.md -[`Int32Array`]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Int32Array -[`ArrayBuffer`]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer diff --git a/doc/bigint.md b/doc/bigint.md index 33ada43b3..d6f2ea68e 100644 --- a/doc/bigint.md +++ b/doc/bigint.md @@ -1,5 +1,7 @@ # BigInt +Class `Napi::Bigint` inherits from class [`Napi::Value`][]. + A JavaScript BigInt value. ## Methods @@ -91,3 +93,5 @@ void Napi::BigInt::ToWords(int* sign_bit, size_t* word_count, uint64_t* words); Returns a single `BigInt` value into a sign bit, 64-bit little-endian array, and the number of elements in the array. + +[`Napi::Value`]: ./value.md diff --git a/doc/boolean.md b/doc/boolean.md index 01b6a4c0a..d07daa210 100644 --- a/doc/boolean.md +++ b/doc/boolean.md @@ -1,5 +1,7 @@ # Boolean +Class `Napi::Boolean` inherits from class [`Napi::Value`][]. + `Napi::Boolean` class is a representation of the JavaScript `Boolean` object. The `Napi::Boolean` class inherits its behavior from the `Napi::Value` class (for more info see: [`Napi::Value`](value.md)). @@ -62,3 +64,5 @@ Napi::Boolean::operator bool() const; ``` Returns the boolean primitive type of the corresponding `Napi::Boolean` object. + +[`Napi::Value`]: ./value.md diff --git a/doc/buffer.md b/doc/buffer.md index 8f76b200d..97ed48a5a 100644 --- a/doc/buffer.md +++ b/doc/buffer.md @@ -1,5 +1,7 @@ # Buffer +Class `Napi::Buffer` inherits from class [`Napi::Uint8Array`][]. + The `Napi::Buffer` class creates a projection of raw data that can be consumed by script. @@ -138,3 +140,5 @@ size_t Napi::Buffer::Length() const; ``` Returns the number of `T` elements in the external data. + +[`Napi::Uint8Array`]: ./typed_array_of.md diff --git a/doc/dataview.md b/doc/dataview.md index 64b865b1c..66fb28919 100644 --- a/doc/dataview.md +++ b/doc/dataview.md @@ -1,5 +1,7 @@ # DataView +Class `Napi::DataView` inherits from class [`Napi::Object`][]. + The `Napi::DataView` class corresponds to the [JavaScript `DataView`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView) class. @@ -242,3 +244,5 @@ void Napi::DataView::SetUint32(size_t byteOffset, uint32_t value) const; - `[in] byteOffset`: The offset, in byte, from the start of the view where to read the data. - `[in] value`: The value to set. + +[`Napi::Object`]: ./object.md diff --git a/doc/date.md b/doc/date.md index 959b4b9a6..4c5fefa5e 100644 --- a/doc/date.md +++ b/doc/date.md @@ -1,8 +1,8 @@ # Date `Napi::Date` class is a representation of the JavaScript `Date` object. The -`Napi::Date` class inherits its behavior from `Napi::Value` class -(for more info see [`Napi::Value`](value.md)) +`Napi::Date` class inherits its behavior from the `Napi::Value` class +(for more info see [`Napi::Value`](value.md)). ## Methods diff --git a/doc/error.md b/doc/error.md index 1526bddf0..7530262d7 100644 --- a/doc/error.md +++ b/doc/error.md @@ -1,5 +1,7 @@ # Error +Class `Napi::Error` inherits from class [`Napi::ObjectReference`][] and class [`std::exception`][]. + The `Napi::Error` class is a representation of the JavaScript `Error` object that is thrown when runtime errors occur. The Error object can also be used as a base object for user-defined exceptions. @@ -113,3 +115,6 @@ const char* Napi::Error::what() const NAPI_NOEXCEPT override; Returns a pointer to a null-terminated string that is used to identify the exception. This method can be used only if the exception mechanism is enabled. + +[`Napi::ObjectReference`]: ./object_reference.md +[`std::exception`]: http://cplusplus.com/reference/exception/exception/ diff --git a/doc/external.md b/doc/external.md index 4022b61dd..814eb037c 100644 --- a/doc/external.md +++ b/doc/external.md @@ -1,5 +1,7 @@ # External (template) +Class `Napi::External` inherits from class [`Napi::Value`][]. + The `Napi::External` template class implements the ability to create a `Napi::Value` object with arbitrary C++ data. It is the user's responsibility to manage the memory for the arbitrary C++ data. `Napi::External` objects can be created with an optional Finalizer function and optional Hint value. The Finalizer function, if specified, is called when your `Napi::External` object is released by Node's garbage collector. It gives your code the opportunity to free any dynamically created data. If you specify a Hint value, it is passed to your Finalizer function. @@ -57,3 +59,5 @@ T* Napi::External::Data() const; ``` Returns a pointer to the arbitrary C++ data held by the `Napi::External` object. + +[`Napi::Value`]: ./value.md diff --git a/doc/hierarchy.md b/doc/hierarchy.md new file mode 100644 index 000000000..e40a65ff9 --- /dev/null +++ b/doc/hierarchy.md @@ -0,0 +1,91 @@ +# Full Class Hierarchy + +| Class | Parent Class(es) | +|---|---| +| [`Napi::Addon`][] | [`Napi::InstanceWrap`][] | +| [`Napi::Array`][] | [`Napi::Object`][] | +| [`Napi::ArrayBuffer`][] | [`Napi::Object`][] | +| [`Napi::AsyncContext`][] | | +| [`Napi::AsyncProgressQueueWorker`][] | `Napi::AsyncProgressWorkerBase` | +| [`Napi::AsyncProgressWorker`][] | `Napi::AsyncProgressWorkerBase` | +| [`Napi::AsyncWorker`][] | | +| [`Napi::BigInt`][] | [`Napi::Value`][] | +| [`Napi::Boolean`][] | [`Napi::Value`][] | +| [`Napi::Buffer`][] | [`Napi::Uint8Array`][] | +| [`Napi::CallbackInfo`][] | | +| [`Napi::CallbackScope`][] | | +| [`Napi::ClassPropertyDescriptor`][] | | +| [`Napi::DataView`][] | [`Napi::Object`][] | +| [`Napi::Date`][] | [`Napi::Value`][] | +| [`Napi::Env`][] | | +| [`Napi::Error`][] | [`Napi::ObjectReference`][], [`std::exception`][] | +| [`Napi::EscapableHandleScope`][] | | +| [`Napi::External`][] | [`Napi::Value`][] | +| [`Napi::Function`][] | [`Napi::Object`][] | +| [`Napi::FunctionReference`][] | [`Napi::Reference`][] | +| [`Napi::HandleScope`][] | | +| [`Napi::InstanceWrap`][] | | +| [`Napi::MemoryManagement`][] | | +| [`Napi::Name`][] | [`Napi::Value`][] | +| [`Napi::Number`][] | [`Napi::Value`][] | +| [`Napi::Object`][] | [`Napi::Value`][] | +| [`Napi::ObjectReference`][] | [`Napi::Reference`][] | +| [`Napi::ObjectWrap`][] | [`Napi::InstanceWrap`][], [`Napi::Reference`][] | +| [`Napi::Promise`][] | [`Napi::Object`][] | +| [`Napi::PropertyDescriptor`][] | | +| [`Napi::RangeError`][] | [`Napi::Error`][] | +| [`Napi::Reference`] | | +| [`Napi::String`][] | [`Napi::Name`][] | +| [`Napi::Symbol`][] | [`Napi::Name`][] | +| [`Napi::ThreadSafeFunction`][] | | +| [`Napi::TypeError`][] | [`Napi::Error`][] | +| [`Napi::TypedArray`][] | [`Napi::Object`][] | +| [`Napi::TypedArrayOf`][] | [`Napi::TypedArray`][] | +| [`Napi::Value`][] | | +| [`Napi::VersionManagement`][] | | + +[`Napi::Addon`]: ./addon.md +[`Napi::Array`]: ./array.md +[`Napi::ArrayBuffer`]: ./array_buffer.md +[`Napi::AsyncContext`]: ./async_context.md +[`Napi::AsyncProgressQueueWorker`]: ./async_worker_variants.md#asyncprogressqueueworker +[`Napi::AsyncProgressWorker`]: ./async_worker_variants.md#asyncprogressworker +[`Napi::AsyncWorker`]: ./async_worker.md +[`Napi::BigInt`]: ./bigint.md +[`Napi::Boolean`]: ./boolean.md +[`Napi::Buffer`]: ./buffer.md +[`Napi::CallbackInfo`]: ./callbackinfo.md +[`Napi::CallbackScope`]: ./callback_scope.md +[`Napi::ClassPropertyDescriptor`]: ./class_property_descriptor.md +[`Napi::DataView`]: ./dataview.md +[`Napi::Date`]: ./date.md +[`Napi::Env`]: ./env.md +[`Napi::Error`]: ./error.md +[`Napi::EscapableHandleScope`]: ./escapable_handle_scope.md +[`Napi::External`]: ./external.md +[`Napi::Function`]: ./function.md +[`Napi::FunctionReference`]: ./function_reference.md +[`Napi::HandleScope`]: ./handle_scope.md +[`Napi::InstanceWrap`]: ./instance_wrap.md +[`Napi::MemoryManagement`]: ./memory_management.md +[`Napi::Name`]: ./name.md +[`Napi::Number`]: ./number.md +[`Napi::Object`]: ./object.md +[`Napi::ObjectReference`]: ./object_reference.md +[`Napi::ObjectWrap`]: ./object_wrap.md +[`Napi::Promise`]: ./promise.md +[`Napi::PropertyDescriptor`]: ./property_descriptor.md +[`Napi::RangeError`]: ./range_error.md +[`Napi::Reference`]: ./reference.md +[`Napi::Reference`]: ./reference.md +[`Napi::Reference`]: ./reference.md +[`Napi::String`]: ./string.md +[`Napi::Symbol`]: ./symbol.md +[`Napi::ThreadSafeFunction`]: ./thread_safe_function.md +[`Napi::TypeError`]: ./type_error.md +[`Napi::TypedArray`]: ./typed_array.md +[`Napi::TypedArrayOf`]: ./typed_array_of.md +[`Napi::Uint8Array`]: ./typed_array_of.md +[`Napi::Value`]: ./value.md +[`Napi::VersionManagement`]: ./version_management.md +[`std::exception`]: http://cplusplus.com/reference/exception/exception/ diff --git a/doc/instance_wrap.md b/doc/instance_wrap.md new file mode 100644 index 000000000..1238e7e29 --- /dev/null +++ b/doc/instance_wrap.md @@ -0,0 +1,408 @@ +# InstanceWrap + +This class serves as the base class for [`Napi::ObjectWrap`][] and +[`Napi::Addon`][]. + +In the case of [`Napi::Addon`][] it provides the +methods for exposing functions to JavaScript on instances of an add-on. + +As a base class for [`Napi::ObjectWrap`][] it provides the methods for +exposing instance methods of JavaScript objects instantiated from the JavaScript +class corresponding to the subclass of [`Napi::ObjectWrap`][]. + +## Methods + +### InstanceMethod + +Creates a property descriptor that represents a method exposed on JavaScript +instances of this class. + +```cpp +template +static Napi::ClassPropertyDescriptor +Napi::InstanceWrap::InstanceMethod(const char* utf8name, + InstanceVoidMethodCallback method, + napi_property_attributes attributes = napi_default, + void* data = nullptr); +``` + +- `[in] utf8name`: Null-terminated string that represents the name of the method +provided by instances of the class. +- `[in] method`: The native function that represents a method provided by the +add-on. +- `[in] attributes`: The attributes associated with the property. One or more of +`napi_property_attributes`. +- `[in] data`: User-provided data passed into the method when it is invoked. + +Returns a `Napi::ClassPropertyDescriptor` object that represents a method +provided by instances of the class. The method must be of the form + +```cpp +void MethodName(const Napi::CallbackInfo& info); +``` + +### InstanceMethod + +Creates a property descriptor that represents a method exposed on JavaScript +instances of this class. + +```cpp +template +static Napi::ClassPropertyDescriptor +Napi::InstanceWrap::InstanceMethod(const char* utf8name, + InstanceMethodCallback method, + napi_property_attributes attributes = napi_default, + void* data = nullptr); +``` + +- `[in] utf8name`: Null-terminated string that represents the name of the method +provided by instances of the class. +- `[in] method`: The native function that represents a method provided by the +add-on. +- `[in] attributes`: The attributes associated with the property. One or more of +`napi_property_attributes`. +- `[in] data`: User-provided data passed into the method when it is invoked. + +Returns a `Napi::ClassPropertyDescriptor` object that represents a method +provided by instances of the class. The method must be of the form + +```cpp +Napi::Value MethodName(const Napi::CallbackInfo& info); +``` + +### InstanceMethod + +Creates a property descriptor that represents a method exposed on JavaScript +instances of this class. + +```cpp +template +static Napi::ClassPropertyDescriptor +Napi::InstanceWrap::InstanceMethod(Napi::Symbol name, + InstanceVoidMethodCallback method, + napi_property_attributes attributes = napi_default, + void* data = nullptr); +``` + +- `[in] name`: JavaScript symbol that represents the name of the method provided +by instances of the class. +- `[in] method`: The native function that represents a method provided by the +add-on. +- `[in] attributes`: The attributes associated with the property. One or more of +`napi_property_attributes`. +- `[in] data`: User-provided data passed into the method when it is invoked. + +Returns a `Napi::ClassPropertyDescriptor` object that represents a method +provided by instances of the class. The method must be of the form + +```cpp +void MethodName(const Napi::CallbackInfo& info); +``` + +### InstanceMethod + +Creates a property descriptor that represents a method exposed on JavaScript +instances of this class. + +```cpp +template +static Napi::ClassPropertyDescriptor +Napi::InstanceWrap::InstanceMethod(Napi::Symbol name, + InstanceMethodCallback method, + napi_property_attributes attributes = napi_default, + void* data = nullptr); +``` + +- `[in] name`: JavaScript symbol that represents the name of the method provided +by instances of the class. +- `[in] method`: The native function that represents a method provided by the +add-on. +- `[in] attributes`: The attributes associated with the property. One or more of +`napi_property_attributes`. +- `[in] data`: User-provided data passed into the method when it is invoked. + +Returns a `Napi::ClassPropertyDescriptor` object that represents a method +provided by instances of the class. The method must be of the form + +```cpp +Napi::Value MethodName(const Napi::CallbackInfo& info); +``` + +### InstanceMethod + +Creates a property descriptor that represents a method exposed on JavaScript +instances of this class. + +```cpp +