/* ----------------------------------------------------------------------------- * js_ctor: template for wrapping a ctor. * - $jswrapper: wrapper of called ctor * - $jsparent: mangled name of parent (or SWIG_NAPI_ObjectWrap if none) * - $jslocals: locals part of wrapper * - $jscode: code part of wrapper * - $jsargcount: number of arguments * - $jsargrequired: minimum number of arguments * - $jsmangledname: mangled name of class * - $jsmangledtype: mangled type of class * ----------------------------------------------------------------------------- */ %fragment("js_ctor", "templates") %{ template // js_ctor // This is the main constructor $jsmangledname_templ::$jsmangledname_templ(const Napi::CallbackInfo &info) : $jsparent_templ(true, info) { Napi::Env env = info.Env(); this->info = SWIGTYPE_$jsmangledtype; if (info.Length() == 1 && info[0].IsExternal()) { // This constructor has been called internally from C++/SWIG // to wrap an already existing C++ object in JS this->self = info[0].As>().Data(); this->owned = false; return; } this->owned = true; $jslocals if(static_cast(info.Length()) < $jsargrequired || static_cast(info.Length()) > $jsargcount) { SWIG_Error(SWIG_ERROR, "Illegal number of arguments for $jswrapper."); } $jscode this->self = result; return; goto fail; fail: return; } // This is the bypass constructor to be used from child classes template $jsmangledname_templ::$jsmangledname_templ(bool, const Napi::CallbackInfo &info) : $jsparent_templ(true, info) {} %} /* ----------------------------------------------------------------------------- * js_veto_ctor: a vetoing ctor for abstract classes * - $jsmangledname: mangled name of class * - $jsparent: mangled name of parent (or SWIG_NAPI_ObjectWrap if none) * ----------------------------------------------------------------------------- */ %fragment ("js_veto_ctor", "templates") %{ // js_veto_ctor template $jsmangledname_templ::$jsmangledname_templ(const Napi::CallbackInfo &info) : $jsparent_templ(true, info) { Napi::Env env = info.Env(); if (info.Length() == 1 && info[0].IsExternal()) { // This constructor has been called internally from C++/SWIG // to wrap an already existing C++ object in JS as its // base abstract class this->self = info[0].As>().Data(); this->owned = false; return; } SWIG_Error(SWIG_ERROR, "Class $jsname can not be instantiated"); return; goto fail; fail: return; } // This is the extendable constructor to be used from child classes template $jsmangledname_templ::$jsmangledname_templ(bool, const Napi::CallbackInfo &info) : $jsparent_templ(true, info) { } %} /* ----------------------------------------------------------------------------- * js_ctor_dispatcher: dispatcher for overloaded constructors * - $jsmangledname: mangled name of class * - $jsparent: mangled name of parent (or SWIG_NAPI_ObjectWrap if none) * - $jsdispatchcases: part containing code for dispatching * - $jsmangledtype: mangled type of class * ----------------------------------------------------------------------------- */ %fragment ("js_ctor_dispatcher", "templates") %{ // js_ctor_dispatcher template $jsmangledname_templ::$jsmangledname_templ(const Napi::CallbackInfo &info) : $jsparent_templ(true, info) { Napi::Env env = info.Env(); Napi::Object self; NAPI_CHECK_RESULT(info.This().ToObject(), self); this->info = SWIGTYPE_$jsmangledtype; if (info.Length() == 1 && info[0].IsExternal()) { // This constructor has been called internally from C++/SWIG // to wrap an already existing C++ object in JS this->self = info[0].As>().Data(); this->owned = false; return; } // switch all cases by means of series of if-returns. $jsdispatchcases // default: SWIG_Error(SWIG_ERROR, "Illegal arguments for construction of $jsmangledname"); goto fail; fail: return; } // This is the extendable constructor to be used from child classes template $jsmangledname_templ::$jsmangledname_templ(bool, const Napi::CallbackInfo &info) : $jsparent_templ(true, info) { } %} /* ----------------------------------------------------------------------------- * js_overloaded_ctor: template for wrapping a ctor. * - $jswrapper: wrapper of called ctor * - $jslocals: locals part of wrapper * - $jscode: code part of wrapper * - $jsargcount: number of arguments * - $jsargrequired: minimum number of arguments * - $jsmangledtype: mangled type of class * ----------------------------------------------------------------------------- */ %fragment("js_overloaded_ctor", "templates") %{ // js_overloaded_ctor template Napi::Value $jsmangledname_templ::$jswrapper(const Napi::CallbackInfo &info) { Napi::Env env = info.Env(); Napi::Object self; $jslocals NAPI_CHECK_RESULT(info.This().ToObject(), self); this->owned = true; if(static_cast(info.Length()) < $jsargrequired || static_cast(info.Length()) > $jsargcount) { SWIG_Error(SWIG_ERROR, "Illegal number of arguments for $jswrapper."); } $jscode this->self = result; goto fail; fail: return Napi::Value(); } %} /* ----------------------------------------------------------------------------- * js_ctor_dispatch_case: template for a dispatch case for calling an overloaded ctor. * - $jsargcount: number of arguments of called ctor * - $jsargrequired: minimum number of arguments * - $jswrapper: wrapper of called ctor * * Note: a try-catch-like mechanism is used to switch cases * ----------------------------------------------------------------------------- */ %fragment ("js_ctor_dispatch_case", "templates") %{ // js_ctor_dispatch_case if(static_cast(info.Length()) >= $jsargrequired && static_cast(info.Length()) <= $jsargcount) { #ifdef NAPI_CPP_EXCEPTIONS bool tryNext = false; try { $jswrapper(info); } catch (const Napi::TypeError &) { tryNext = true; } catch (const Napi::Error &e) { throw e; } if (!tryNext) return; #else $jswrapper(info); if (env.IsExceptionPending()) { Napi::Error e = env.GetAndClearPendingException(); Napi::Value typeErrorValue; bool isTypeError; Napi::Function typeErrorCons; // Yes, this is ugly // TODO: Fix this in Node.js when the core team grows up NAPI_CHECK_RESULT(env.Global().Get("TypeError"), typeErrorValue); typeErrorCons = typeErrorValue.As(); NAPI_CHECK_RESULT(e.Value().InstanceOf(typeErrorCons), isTypeError); if (!isTypeError) { // This is not the error you are looking for e.ThrowAsJavaScriptException(); SWIG_fail; } } else { return; } #endif } %} /* ----------------------------------------------------------------------------- * js_check_arg: template for checking if an argument exists * - $jsarg: number of argument * ----------------------------------------------------------------------------- */ %fragment ("js_check_arg", "templates") %{if(info.Length() > $jsarg)%} /* ----------------------------------------------------------------------------- * js_dtor: template for a destructor wrapper * - $jsmangledname: mangled class name * - $jstype: class type * ----------------------------------------------------------------------------- */ %fragment ("js_dtor", "templates") %{ // js_dtor template $jsmangledname_templ::~$jsmangledname_templ() { } %} /* ----------------------------------------------------------------------------- * js_dtoroverride: template for a destructor wrapper * - ${classname_mangled}: mangled class name * - $jstype: class type * - ${destructor_action}: The custom destructor action to invoke. * ----------------------------------------------------------------------------- */ %fragment ("js_dtoroverride", "templates") %{ // js_dtoroverride template ${classname_mangled}_templ::~${classname_mangled}_templ() { auto arg1 = reinterpret_cast<$jstype>(this->self); if (this->owned && arg1) { ${destructor_action} this->self = nullptr; } } %} /* ----------------------------------------------------------------------------- * js_global_getter: template for global getter function wrappers * - $jswrapper: wrapper function name * - $jslocals: locals part of wrapper * - $jscode: code part of wrapper * ----------------------------------------------------------------------------- */ %fragment("js_global_getter", "templates") %{ // js_global_getter Napi::Value $jswrapper(const Napi::CallbackInfo &info) { Napi::Env env = info.Env(); Napi::Value jsresult; $jslocals $jscode return jsresult; goto fail; fail: return Napi::Value(); } %} /* ----------------------------------------------------------------------------- * js_global_setter: template for global setter function wrappers * - $jswrapper: wrapper function name * - $jslocals: locals part of wrapper * - $jscode: code part of wrapper * ----------------------------------------------------------------------------- */ %fragment("js_global_setter", "templates") %{ // js_global_setter void $jswrapper(const Napi::CallbackInfo &info) { Napi::Env env = info.Env(); Napi::Value value = info.Length() > 0 ? info[0] : Napi::Value(); Napi::Value jsresult; $jslocals $jscode return; goto fail; fail: return; } %} /* ----------------------------------------------------------------------------- * jsnapi_register_global_variable: template for a statement that registers a global variable * - $jsname: variable name * - $jsparent: parent namespace * - $jsgetter: wrapper of the getter function * - $jssetter: wrapper of the setter function * * Note: this template is also used for global variables. * ----------------------------------------------------------------------------- */ %fragment("jsnapi_register_global_variable", "templates") %{ // jsnapi_register_global_variable do { Napi::PropertyDescriptor pd = Napi::PropertyDescriptor::Accessor<$jsgetter, $jssetter>("$jsname"); NAPI_CHECK_MAYBE($jsparent.DefineProperties({pd})); } while (0); %} /* ----------------------------------------------------------------------------- * js_global_function: template for function wrappers * - $jswrapper: wrapper function name * - $jslocals: locals part of wrapper * - $jsargcount: number of arguments * - $jsargrequired: minimum number of arguments * - $jscode: code part of wrapper * ----------------------------------------------------------------------------- */ %fragment("js_global_function", "templates") %{ // js_global_function Napi::Value $jswrapper(const Napi::CallbackInfo &info) { Napi::Env env = info.Env(); Napi::Value jsresult; $jslocals if(static_cast(info.Length()) < $jsargrequired || static_cast(info.Length()) > $jsargcount) { SWIG_Error(SWIG_ERROR, "Illegal number of arguments for $jswrapper."); } $jscode return jsresult; goto fail; fail: return Napi::Value(); } %} /* ----------------------------------------------------------------------------- * js_global_function_dispatcher: template for a global function dispatcher for * global overloaded functions * - $jswrapper: wrapper function name * - $jsname: name of the wrapped function * - $jslocals: locals part of wrapper * - $jscode: code part of wrapper * ----------------------------------------------------------------------------- */ %fragment("js_global_function_dispatcher", "templates") %{ // js_global_function_dispatcher Napi::Value $jswrapper(const Napi::CallbackInfo &info) { Napi::Env env = info.Env(); Napi::Value jsresult; $jscode SWIG_Error(SWIG_ERROR, "Illegal arguments for function $jsname."); goto fail; fail: return Napi::Value(); } %} /* ----------------------------------------------------------------------------- * jsnapi_register_global_function: template for a statement that registers a global function * - $jsname: function name * - $jsparent: parent namespace * - $jswrapper: name of the JS wrapper * * Note: this template is also used for global variables. * ----------------------------------------------------------------------------- */ %fragment("jsnapi_register_global_function", "templates") %{ // jsnapi_register_global_function do { Napi::PropertyDescriptor pd = Napi::PropertyDescriptor::Function("$jsname", $jswrapper); NAPI_CHECK_MAYBE($jsparent.DefineProperties({pd})); } while (0); %} /* ----------------------------------------------------------------------------- * js_getter: template for getter function wrappers * - $jsmangledname: mangled class name * - $jswrapper: wrapper function name * - $jslocals: locals part of wrapper * - $jscode: code part of wrapper * ----------------------------------------------------------------------------- */ %fragment("js_getter", "templates") %{ // js_getter template Napi::Value $jsmangledname_templ::$jswrapper(const Napi::CallbackInfo &info) { Napi::Env env = info.Env(); Napi::Value jsresult; $jslocals $jscode return jsresult; goto fail; fail: return Napi::Value(); } %} /* ----------------------------------------------------------------------------- * js_setter: template for setter function wrappers * - $jsmangledname: mangled class name * - $jswrapper: wrapper function name * - $jslocals: locals part of wrapper * - $jscode: code part of wrapper * ----------------------------------------------------------------------------- */ %fragment("js_setter", "templates") %{ // js_setter template void $jsmangledname_templ::$jswrapper(const Napi::CallbackInfo &info, const Napi::Value &value) { Napi::Env env = info.Env(); Napi::Value jsresult; $jslocals $jscode return; goto fail; fail: return; } %} /* ----------------------------------------------------------------------------- * js_function: template for function wrappers * - $jsmangledname: mangled class name * - $jswrapper: wrapper function name * - $jsargcount: minimum number of arguments * - $jsargrequired: minimum number of arguments * - $jslocals: locals part of wrapper * - $jscode: code part of wrapper * ----------------------------------------------------------------------------- */ %fragment("js_function", "templates") %{ // js_function template Napi::Value $jsmangledname_templ::$jswrapper(const Napi::CallbackInfo &info) { Napi::Env env = info.Env(); Napi::Value jsresult; $jslocals if(static_cast(info.Length()) < $jsargrequired || static_cast(info.Length()) > $jsargcount) { SWIG_Error(SWIG_ERROR, "Illegal number of arguments for $jswrapper."); } $jscode return jsresult; goto fail; fail: return Napi::Value(); } %} /* ----------------------------------------------------------------------------- * js_function_dispatcher: template for a function dispatcher for overloaded functions * - $jsmangledname: mangled class name * - $jswrapper: wrapper function name * - $jsname: name of the wrapped function * - $jslocals: locals part of wrapper * - $jscode: code part of wrapper * ----------------------------------------------------------------------------- */ %fragment("js_function_dispatcher", "templates") %{ // js_function_dispatcher template Napi::Value $jsmangledname_templ::$jswrapper(const Napi::CallbackInfo &info) { Napi::Env env = info.Env(); Napi::Value jsresult; $jscode SWIG_Error(SWIG_ERROR, "Illegal arguments for function $jsname."); goto fail; fail: return Napi::Value(); } %} /* ----------------------------------------------------------------------------- * js_overloaded_function: template for a overloaded function * - $jswrapper: wrapper function name * - $jslocals: locals part of wrapper * - $jscode: code part of wrapper * ----------------------------------------------------------------------------- */ %fragment ("js_overloaded_function", "templates") %{ // js_overloaded_function template Napi::Value $jsmangledname_templ::$jswrapper(const Napi::CallbackInfo &info) { Napi::Env env = info.Env(); Napi::Value jsresult; $jslocals $jscode return jsresult; goto fail; fail: return Napi::Value(); } %} /* ----------------------------------------------------------------------------- * js_global_overloaded_function: template for a global overloaded function * - $jswrapper: wrapper function name * - $jslocals: locals part of wrapper * - $jscode: code part of wrapper * ----------------------------------------------------------------------------- */ %fragment ("js_global_overloaded_function", "templates") %{ // js_global_overloaded_function Napi::Value $jswrapper(const Napi::CallbackInfo &info) { Napi::Env env = info.Env(); Napi::Value jsresult; $jslocals $jscode return jsresult; goto fail; fail: return Napi::Value(); } %} /* ----------------------------------------------------------------------------- * js_function_dispatch_case: template for a case used in the function dispatcher * - $jswrapper: wrapper function name * - $jsargcount: number of arguments of overloaded function * - $jsargrequired: minimum number of arguments * - $jscode: code part of wrapper * ----------------------------------------------------------------------------- */ %fragment ("js_function_dispatch_case", "templates") %{ // js_function_dispatch_case if(static_cast(info.Length()) >= $jsargrequired && static_cast(info.Length()) <= $jsargcount) { #ifdef NAPI_CPP_EXCEPTIONS bool tryNext = false; try { jsresult = $jswrapper(info); } catch (const Napi::TypeError &) { tryNext = true; } catch (const Napi::Error &e) { throw e; } if (!tryNext) return jsresult; #else $jswrapper(info); if (env.IsExceptionPending()) { Napi::Error e = env.GetAndClearPendingException(); Napi::Value typeErrorValue; bool isTypeError; Napi::Function typeErrorCons; // Yes, this is ugly // TODO: Fix this in Node.js when the core team grows up NAPI_CHECK_RESULT(env.Global().Get("TypeError"), typeErrorValue); typeErrorCons = typeErrorValue.As(); NAPI_CHECK_RESULT(e.Value().InstanceOf(typeErrorCons), isTypeError); if (!isTypeError) { // This is not the error you are looking for e.ThrowAsJavaScriptException(); SWIG_fail; } } else { return jsresult; } #endif } %} /* ----------------------------------------------------------------------------- * jsnapi_class_prologue_template: template for a class prologue * - $jsmangledname: mangled class name * - $jsparent: mangled name of parent (or SWIG_NAPI_ObjectWrap if none) * ----------------------------------------------------------------------------- */ %fragment("jsnapi_class_prologue_template", "templates") %{ // jsnapi_class_prologue_template template class $jsmangledname_templ : public $jsparent_templ { public: $jsmangledname_templ(const Napi::CallbackInfo &); $jsmangledname_templ(bool, const Napi::CallbackInfo &); %} /* ----------------------------------------------------------------------------- * jsnapi_class_dtor_declaration: template for a class destructor declaration * - $jsmangledname: mangled class name * ----------------------------------------------------------------------------- */ %fragment("jsnapi_class_dtor_declaration", "templates") %{ virtual ~$jsmangledname_templ(); %} /* ----------------------------------------------------------------------------- * jsnapi_class_method_declaration: template for a class method declaration * - $jsmangledname: mangled class name * - $jswrapper: method name * - $jsstatic: static modifier * ----------------------------------------------------------------------------- */ %fragment("jsnapi_class_method_declaration", "templates") %{ // jsnapi_class_method_declaration $jsstatic Napi::Value $jswrapper(const Napi::CallbackInfo &); %} /* ----------------------------------------------------------------------------- * jsnapi_class_setter_declaration: template for a class method declaration * - $jsmangledname: mangled class name * - $jswrapper: method name * - $jsstatic: static modifier * ----------------------------------------------------------------------------- */ %fragment("jsnapi_class_setter_declaration", "templates") %{ // jsnapi_class_setter_declaration $jsstatic void $jswrapper(const Napi::CallbackInfo &, const Napi::Value &); %} /* ----------------------------------------------------------------------------- * jsnapi_class_epilogue_template: template for a class epilogue * - $jsmangledname: mangled class name * ----------------------------------------------------------------------------- */ %fragment("jsnapi_class_epilogue_template", "templates") %{ // jsnapi_class_epilogue_template static void JS_veto_set_static_variable(const Napi::CallbackInfo &, const Napi::Value &); void JS_veto_set_variable(const Napi::CallbackInfo &, const Napi::Value &); }; template void $jsmangledname_templ::JS_veto_set_static_variable(const Napi::CallbackInfo &info, const Napi::Value &value) { SWIG_NAPI_Raise(info.Env(), "Tried to write read-only variable."); } template void $jsmangledname_templ::JS_veto_set_variable(const Napi::CallbackInfo &info, const Napi::Value &value) { SWIG_NAPI_Raise(info.Env(), "Tried to write read-only variable."); } %} /* ----------------------------------------------------------------------------- * jsnapi_class_instance: template for a class declaration instance * - $jsmangledname: mangled class name * ----------------------------------------------------------------------------- */ %fragment("jsnapi_declare_class_instance", "templates") %{ // jsnapi_class_instance class $jsmangledname_inst : public $jsmangledname_templ<$jsmangledname_inst> { public: using $jsmangledname_templ::$jsmangledname_templ; virtual ~$jsmangledname_inst() {}; static void GetMembers( Napi::Env, std::map &, std::map & ); static Napi::Function GetClass(Napi::Env); }; %} /* * Inheritance is still not officially supported in NAPI * Refer to this for my workaround: * https://mmomtchev.medium.com/c-class-inheritance-with-node-api-and-node-addon-api-c180334d9902 */ /* ----------------------------------------------------------------------------- * jsnapi_inherited_class_prologue_template: template for a class prologue * - $jsmangledname: mangled class name * - $jsparent: mangled name of parent class * ----------------------------------------------------------------------------- */ %fragment("jsnapi_inherited_class_prologue_template", "templates") %{ // jsnapi_inherited_class_prologue_template SWIG_NAPI_ClientData $jsmangledname_clientData; template class $jsmangledname_templ : public $jsparent_templ { public: $jsmangledname_templ(const Napi::CallbackInfo& info); %} /* ----------------------------------------------------------------------------- * jsnapi_getclass: template for creating a class object * - $jsname: class name * - $jsmangledname: mangled class name * - $jsfunctions: member functions * ----------------------------------------------------------------------------- */ %fragment("jsnapi_getclass", "templates") %{ /* Class: $jsname ($jsmangledname) */ // jsnapi_getclass Napi::Function $jsmangledname_inst::GetClass(Napi::Env env) { std::map members, staticMembers; GetMembers(env, members, staticMembers); std::vector<$jsmangledname_inst::PropertyDescriptor> symbolTable; for (auto it = members.begin(); it != members.end(); it++) symbolTable.push_back(it->second); for (auto it = staticMembers.begin(); it != staticMembers.end(); it++) symbolTable.push_back(it->second); return Napi::ObjectWrap<$jsmangledname_inst>::DefineClass(env, "$jsname", symbolTable); } void $jsmangledname_inst::GetMembers( Napi::Env env, std::map &members, std::map &staticMembers ) { std::map::PropertyDescriptor> baseMembers, baseStaticMembers; $jsparent_inst::GetMembers(env, baseMembers, baseStaticMembers); members.insert(baseMembers.begin(), baseMembers.end()); staticMembers.insert(staticMembers.begin(), staticMembers.end()); /* register wrapper functions */ $jsnapiwrappers /* add static class functions and variables */ $jsnapistaticwrappers } %} /* ----------------------------------------------------------------------------- * jsnapi_registerclass: template for regsitering a class object * - $jsname: class name * - $jsmangledname: mangled class name * - $jsparent: parent namespace * - $jsmangledtype: mangled class type * - $jsclassidx: class index in the class table * ----------------------------------------------------------------------------- */ %fragment("jsnapi_registerclass", "templates") %{ /* Class: $jsname ($jsmangledname) */ // jsnapi_registerclass Napi::Function $jsmangledname_ctor = $jsmangledname_inst::GetClass(env); $jsparent.Set("$jsname", $jsmangledname_ctor); if (SWIGTYPE_$jsmangledtype->clientdata == nullptr) { SWIGTYPE_$jsmangledtype->clientdata = new size_t($jsclassidx); } Napi::FunctionReference *$jsmangledname_ctor_ref = new Napi::FunctionReference(); *$jsmangledname_ctor_ref = Napi::Persistent($jsmangledname_ctor); env.GetInstanceData()->ctor[$jsclassidx] = $jsmangledname_ctor_ref; %} /* ----------------------------------------------------------------------------- * jsnapi_setup_inheritance: setup inheritance between two classes * - $jsname: class name * - $jsmangledname: mangled class name * - $jsparent: mangled name of parent class * ----------------------------------------------------------------------------- */ %fragment("jsnapi_setup_inheritance", "templates") %{ // Inheritance for $jsmangledname ($jsname) <- $jsparent // jsnapi_setup_inheritance do { Napi::Value protoBase, protoSub; NAPI_CHECK_RESULT($jsmangledname_ctor.Get("prototype"), protoSub); NAPI_CHECK_RESULT($jsparent_ctor.Get("prototype"), protoBase); NAPI_CHECK_MAYBE(setProto.Call({$jsmangledname_ctor, $jsparent_ctor})); NAPI_CHECK_MAYBE(setProto.Call({protoSub, protoBase})); } while (0); %} /* ----------------------------------------------------------------------------- * jsnapi_create_namespace: template for a statement that creates a namespace object. * - $jsmangledname: mangled namespace name * ----------------------------------------------------------------------------- */ %fragment("jsnapi_create_namespace", "templates") %{ // jsnapi_create_namespace Napi::Object $jsmangledname = Napi::Object::New(env); %} /* ----------------------------------------------------------------------------- * jsnapi_register_namespace: template for a statement that registers a namespace in a parent namespace. * - $jsname: name of namespace * - $jsmangledname: mangled name of namespace * - $jsparent: mangled name of parent namespace * ----------------------------------------------------------------------------- */ %fragment("jsnapi_register_namespace", "templates") %{ // jsnapi_register_namespace NAPI_CHECK_MAYBE($jsparent.Set("$jsname", $jsmangledname)); %} /* ----------------------------------------------------------------------------- * jsnapi_member_function_descriptor: template for a statement that registers a member function. * - $jsmangledname: mangled class name * - $jsname: name of the function * - $jswrapper: wrapper of the member function * ----------------------------------------------------------------------------- */ %fragment("jsnapi_register_member_function", "templates") %{ // jsnapi_member_function_descriptor members.erase("$jsname"); members.insert({"$jsname", $jsmangledname_templ::InstanceMethod("$jsname", &$jsmangledname_templ::$jswrapper, static_cast(napi_writable | napi_configurable)) }); %} /* ----------------------------------------------------------------------------- * jsnapi_register_member_variable: template for a statement that registers a member variable. * - $jsname: name of the function * - $jsmangledname: mangled class name * - $jsgetter: wrapper of the getter function * - $jssetter: wrapper of the setter function * ----------------------------------------------------------------------------- */ %fragment("jsnapi_register_member_variable", "templates") %{ // jsnapi_register_member_variable members.erase("$jsname"); members.insert({"$jsname", $jsmangledname_templ::InstanceAccessor("$jsname", &$jsmangledname_templ::$jsgetter, &$jsmangledname_templ::$jssetter, static_cast(napi_writable | napi_enumerable | napi_configurable)) }); %} /* ----------------------------------------------------------------------------- * jsnapi_register_static_function: template for a statement that registers a static class function. * - $jsname: function name * - $jsmangledname: mangled class name * - $jswrapper: wrapper of the function * ----------------------------------------------------------------------------- */ %fragment("jsnapi_register_static_function", "templates") %{ // jsnapi_register_static_function staticMembers.erase("$jsname"); staticMembers.insert({"$jsname", StaticMethod("$jsname", &$jsmangledname_templ::$jswrapper, static_cast(napi_writable | napi_configurable)) }); %} /* ----------------------------------------------------------------------------- * jsnapi_register_static_variable: template for a statement that registers a static variable. * - $jsname: variable name * - $jsmangledname: mangled class name * - $jsgetter: wrapper of the getter function * - $jssetter: wrapper of the setter function * ----------------------------------------------------------------------------- */ %fragment("jsnapi_register_static_variable", "templates") %{ // jsnapi_register_static_variable staticMembers.erase("$jsname"); staticMembers.insert({"$jsname", StaticAccessor("$jsname", &$jsmangledname_templ::$jsgetter, &$jsmangledname_templ::$jssetter, static_cast(napi_writable | napi_enumerable | napi_configurable)) }); %}