File tree Expand file tree Collapse file tree 6 files changed +78
-4
lines changed Expand file tree Collapse file tree 6 files changed +78
-4
lines changed Original file line number Diff line number Diff line change @@ -4630,9 +4630,11 @@ inline napi_value InstanceWrap<T>::WrappedMethod(
46304630// //////////////////////////////////////////////////////////////////////////////
46314631
46324632template <typename T>
4633- inline ObjectWrap<T>::ObjectWrap (const Napi::CallbackInfo& callbackInfo) {
4633+ template <typename ConstructorTrait>
4634+ inline ObjectWrap<T>::ObjectWrap (const Napi::CallbackInfo& callbackInfo,
4635+ ConstructorTrait) {
46344636 napi_env env = callbackInfo.Env ();
4635- napi_value wrapper = callbackInfo. This ( );
4637+ napi_value wrapper = ConstructorTrait::GetThis (callbackInfo );
46364638 napi_status status;
46374639 napi_ref ref;
46384640 T* instance = static_cast <T*>(this );
@@ -5030,7 +5032,7 @@ inline napi_value ObjectWrap<T>::ConstructorCallbackWrapper(
50305032 instance->_construction_failed = false ;
50315033 }
50325034#endif // NODE_ADDON_API_CPP_EXCEPTIONS
5033- return callbackInfo. This ();
5035+ return instance-> Value ();
50345036 });
50355037
50365038 return wrapper;
Original file line number Diff line number Diff line change @@ -2359,6 +2359,10 @@ class InstanceWrap {
23592359 }
23602360};
23612361
2362+ struct ConstructorTrait {
2363+ static napi_value GetThis (const CallbackInfo& info) { return info.This (); }
2364+ };
2365+
23622366// / Base class to be extended by C++ classes exposed to JavaScript; each C++
23632367// / class instance gets "wrapped" by a JavaScript object that is managed by this
23642368// / class.
@@ -2389,7 +2393,9 @@ class InstanceWrap {
23892393template <typename T>
23902394class ObjectWrap : public InstanceWrap <T>, public Reference<Object> {
23912395 public:
2392- ObjectWrap (const CallbackInfo& callbackInfo);
2396+ template <typename ConstructorTrait = struct ConstructorTrait >
2397+ ObjectWrap (const CallbackInfo& callbackInfo,
2398+ ConstructorTrait = ConstructorTrait());
23932399 virtual ~ObjectWrap ();
23942400
23952401 static T* Unwrap (Object wrapper);
Original file line number Diff line number Diff line change @@ -69,6 +69,7 @@ Object InitTypedArray(Env env);
6969Object InitGlobalObject (Env env);
7070Object InitObjectWrap (Env env);
7171Object InitObjectWrapConstructorException (Env env);
72+ Object InitObjectWrapConstructorTrait (Env env);
7273Object InitObjectWrapFunction (Env env);
7374Object InitObjectWrapRemoveWrap (Env env);
7475Object InitObjectWrapMultipleInheritance (Env env);
@@ -168,6 +169,8 @@ Object Init(Env env, Object exports) {
168169 exports.Set (" objectwrap" , InitObjectWrap (env));
169170 exports.Set (" objectwrapConstructorException" ,
170171 InitObjectWrapConstructorException (env));
172+ exports.Set (" objectwrap_constructor_trait" ,
173+ InitObjectWrapConstructorTrait (env));
171174 exports.Set (" objectwrap_function" , InitObjectWrapFunction (env));
172175 exports.Set (" objectwrap_removewrap" , InitObjectWrapRemoveWrap (env));
173176 exports.Set (" objectwrap_multiple_inheritance" ,
Original file line number Diff line number Diff line change 7373 'typedarray.cc' ,
7474 'objectwrap.cc' ,
7575 'objectwrap_constructor_exception.cc' ,
76+ 'objectwrap_constructor_trait.cc' ,
7677 'objectwrap_function.cc' ,
7778 'objectwrap_removewrap.cc' ,
7879 'objectwrap_multiple_inheritance.cc' ,
Original file line number Diff line number Diff line change 1+ #include < napi.h>
2+ #include " test_helper.h"
3+
4+ struct EventTargetTrait {
5+ static napi_value GetThis (const Napi::CallbackInfo& info) {
6+ Napi::Function eventTargetCons =
7+ MaybeUnwrap (info.Env ().Global ().Get (" EventTarget" ))
8+ .As <Napi::Function>();
9+ Napi::Object eventTarget = MaybeUnwrap (eventTargetCons.New ({}));
10+ return eventTarget;
11+ }
12+ };
13+
14+ class TestOverride : public Napi ::ObjectWrap<TestOverride> {
15+ public:
16+ TestOverride (const Napi::CallbackInfo& info)
17+ : Napi::ObjectWrap<TestOverride>(info, EventTargetTrait()) {}
18+
19+ Napi::Value IsTestOverride (const Napi::CallbackInfo& info) {
20+ TestOverride* self = Unwrap (info.This ().As <Napi::Object>());
21+ return Napi::Boolean::New (info.Env (), self != nullptr );
22+ }
23+
24+ static void Initialize (Napi::Env env, Napi::Object exports) {
25+ Napi::Function cons = DefineClass (
26+ env,
27+ " TestOverride" ,
28+ {InstanceAccessor<&TestOverride::IsTestOverride>(" isTestOverride" )});
29+
30+ exports.Set (" TestOverride" , cons);
31+ }
32+ };
33+
34+ Napi::Object InitObjectWrapConstructorTrait (Napi::Env env) {
35+ Napi::Object exports = Napi::Object::New (env);
36+ TestOverride::Initialize (env, exports);
37+ return exports;
38+ }
Original file line number Diff line number Diff line change 1+ 'use strict' ;
2+
3+ const assert = require ( 'assert' ) ;
4+
5+ const test = bindingName => {
6+ const binding = require ( bindingName ) ;
7+ const TestOverride = binding . objectwrap_constructor_trait . TestOverride ;
8+ // TODO(legendecas): Expose Object.setPrototypeOf in node-api.
9+ Object . setPrototypeOf ( TestOverride , EventTarget ) ;
10+ Object . setPrototypeOf ( TestOverride . prototype , EventTarget . prototype ) ;
11+
12+ const test = new TestOverride ( ) ;
13+ Object . setPrototypeOf ( test , TestOverride . prototype ) ;
14+
15+ // Verify that the TestOverride class is an EventTarget instance and has both
16+ // EventTarget brand and TestOverride brand.
17+ assert ( test instanceof EventTarget ) ;
18+ // Verify TestOverride brand.
19+ assert . strictEqual ( test . isTestOverride , true ) ;
20+ // Verify EventTarget brand.
21+ test . addEventListener ( 'test' , ( ) => { } ) ;
22+ } ;
23+
24+ module . exports = require ( './common' ) . runTestWithBindingPath ( test ) ;
You can’t perform that action at this time.
0 commit comments