Skip to content

Commit 60e86a9

Browse files
drorglkkoopa
authored andcommitted
Add data to SetMethod and SetPrototypeMethod (#876)
1 parent c98d7aa commit 60e86a9

5 files changed

Lines changed: 249 additions & 7 deletions

File tree

doc/methods.md

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -478,10 +478,12 @@ Signature:
478478
```c++
479479
void Nan::SetMethod(v8::Local<v8::Object> recv,
480480
const char *name,
481-
Nan::FunctionCallback callback)
481+
Nan::FunctionCallback callback,
482+
v8::Local<v8::Value> data = v8::Local<v8::Value>())
482483
void Nan::SetMethod(v8::Local<v8::Template> templ,
483484
const char *name,
484-
Nan::FunctionCallback callback)
485+
Nan::FunctionCallback callback,
486+
v8::Local<v8::Value> data = v8::Local<v8::Value>())
485487
```
486488
487489
<a name="api_nan_set_prototype_method"></a>
@@ -494,7 +496,8 @@ Signature:
494496
```c++
495497
void Nan::SetPrototypeMethod(v8::Local<v8::FunctionTemplate> recv,
496498
const char* name,
497-
Nan::FunctionCallback callback)
499+
Nan::FunctionCallback callback,
500+
v8::Local<v8::Value> data = v8::Local<v8::Value>())
498501
```
499502

500503
<a name="api_nan_set_accessor"></a>

nan.h

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2469,9 +2469,10 @@ template <typename T, template <typename> class HandleType>
24692469
inline void SetMethod(
24702470
HandleType<T> recv
24712471
, const char *name
2472-
, FunctionCallback callback) {
2472+
, FunctionCallback callback
2473+
, v8::Local<v8::Value> data = v8::Local<v8::Value>()) {
24732474
HandleScope scope;
2474-
v8::Local<v8::FunctionTemplate> t = New<v8::FunctionTemplate>(callback);
2475+
v8::Local<v8::FunctionTemplate> t = New<v8::FunctionTemplate>(callback, data);
24752476
v8::Local<v8::String> fn_name = New(name).ToLocalChecked();
24762477
t->SetClassName(fn_name);
24772478
// Note(@agnat): Pass an empty T* as discriminator. See note on
@@ -2481,11 +2482,13 @@ inline void SetMethod(
24812482

24822483
inline void SetPrototypeMethod(
24832484
v8::Local<v8::FunctionTemplate> recv
2484-
, const char* name, FunctionCallback callback) {
2485+
, const char* name
2486+
, FunctionCallback callback
2487+
, v8::Local<v8::Value> data = v8::Local<v8::Value>()) {
24852488
HandleScope scope;
24862489
v8::Local<v8::FunctionTemplate> t = New<v8::FunctionTemplate>(
24872490
callback
2488-
, v8::Local<v8::Value>()
2491+
, data
24892492
, New<v8::Signature>(recv));
24902493
v8::Local<v8::String> fn_name = New(name).ToLocalChecked();
24912494
recv->PrototypeTemplate()->Set(fn_name, t);

test/binding.gyp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,4 +185,8 @@
185185
"target_name" : "stringify"
186186
, "sources" : [ "cpp/json-stringify.cpp" ]
187187
}
188+
, {
189+
"target_name":"methodswithdata"
190+
, "sources" :["cpp/methodswithdata.cpp"]
191+
}
188192
]}

test/cpp/methodswithdata.cpp

Lines changed: 194 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
1+
/*********************************************************************
2+
* NAN - Native Abstractions for Node.js
3+
*
4+
* Copyright (c) 2019 NAN contributors
5+
*
6+
* MIT License <https://github.com/nodejs/nan/blob/master/LICENSE.md>
7+
********************************************************************/
8+
9+
#include <nan.h>
10+
11+
using namespace Nan; // NOLINT(build/namespaces)
12+
13+
NAN_METHOD(TestWithData) {
14+
info.GetReturnValue().Set(false);
15+
{
16+
std::string datavalue = *Nan::Utf8String(info.Data());
17+
if (datavalue != "test-value")return;
18+
}
19+
info.GetReturnValue().Set(true);
20+
}
21+
22+
class SetterGetter : public ObjectWrap {
23+
public:
24+
static NAN_MODULE_INIT(Init);
25+
static v8::Local<v8::Value> NewInstance ();
26+
static NAN_METHOD(New);
27+
static NAN_METHOD(Log);
28+
static NAN_GETTER(GetProp1);
29+
static NAN_GETTER(GetProp2);
30+
static NAN_SETTER(SetProp2);
31+
32+
SetterGetter();
33+
34+
char log[1024];
35+
char prop1[256];
36+
char prop2[256];
37+
};
38+
39+
static Persistent<v8::FunctionTemplate> settergetter_constructor;
40+
41+
SetterGetter::SetterGetter() {
42+
log[0] = '\0';
43+
strncpy(prop1, "this is property 1", sizeof (prop1) - 1);
44+
prop1[sizeof (prop1) - 1] = '\0';
45+
prop2[0] = '\0';
46+
}
47+
48+
v8::Local<v8::Value> SetterGetter::NewInstance () {
49+
EscapableHandleScope scope;
50+
v8::Local<v8::FunctionTemplate> constructorHandle =
51+
Nan::New(settergetter_constructor);
52+
v8::Local<v8::Object> instance =
53+
Nan::NewInstance(
54+
Nan::GetFunction(constructorHandle).ToLocalChecked()).ToLocalChecked();
55+
return scope.Escape(instance);
56+
}
57+
58+
NAN_METHOD(SetterGetter::New) {
59+
std::string datavalue = *Nan::Utf8String(info.Data());
60+
assert(datavalue == "new-data");
61+
62+
SetterGetter* settergetter = new SetterGetter();
63+
assert(strlen(settergetter->log) < sizeof (settergetter->log));
64+
strncat(
65+
settergetter->log
66+
, "New()\n"
67+
, sizeof (settergetter->log) - 1 - strlen(settergetter->log));
68+
settergetter->Wrap(info.This());
69+
70+
info.GetReturnValue().Set(info.This());
71+
}
72+
73+
NAN_GETTER(SetterGetter::GetProp1) {
74+
std::string datavalue = *Nan::Utf8String(info.Data());
75+
assert(datavalue == "prop1-data");
76+
SetterGetter* settergetter =
77+
ObjectWrap::Unwrap<SetterGetter>(info.Holder());
78+
assert(strlen(settergetter->log) < sizeof (settergetter->log));
79+
strncat(
80+
settergetter->log
81+
, "Prop1:GETTER("
82+
, sizeof (settergetter->log) - 1 - strlen(settergetter->log));
83+
assert(strlen(settergetter->log) < sizeof (settergetter->log));
84+
strncat(
85+
settergetter->log
86+
, settergetter->prop1
87+
, sizeof (settergetter->log) - 1 - strlen(settergetter->log));
88+
assert(strlen(settergetter->log) < sizeof (settergetter->log));
89+
strncat(
90+
settergetter->log
91+
, ")\n"
92+
, sizeof (settergetter->log) - 1 - strlen(settergetter->log));
93+
94+
info.GetReturnValue().Set(Nan::New(settergetter->prop1).ToLocalChecked());
95+
}
96+
97+
NAN_GETTER(SetterGetter::GetProp2) {
98+
std::string datavalue = *Nan::Utf8String(info.Data());
99+
assert(datavalue == "prop2-data");
100+
101+
SetterGetter* settergetter =
102+
ObjectWrap::Unwrap<SetterGetter>(info.Holder());
103+
assert(strlen(settergetter->log) < sizeof (settergetter->log));
104+
strncat(
105+
settergetter->log
106+
, "Prop2:GETTER("
107+
, sizeof (settergetter->log) - 1 - strlen(settergetter->log));
108+
assert(strlen(settergetter->log) < sizeof (settergetter->log));
109+
strncat(
110+
settergetter->log
111+
, settergetter->prop2
112+
, sizeof (settergetter->log) - 1 - strlen(settergetter->log));
113+
assert(strlen(settergetter->log) < sizeof (settergetter->log));
114+
strncat(
115+
settergetter->log
116+
, ")\n"
117+
, sizeof (settergetter->log) - 1 - strlen(settergetter->log));
118+
119+
info.GetReturnValue().Set(Nan::New(settergetter->prop2).ToLocalChecked());
120+
}
121+
122+
NAN_SETTER(SetterGetter::SetProp2) {
123+
std::string datavalue = *Nan::Utf8String(info.Data());
124+
assert(datavalue == "prop2-data");
125+
126+
SetterGetter* settergetter =
127+
ObjectWrap::Unwrap<SetterGetter>(info.Holder());
128+
strncpy(
129+
settergetter->prop2
130+
, *Utf8String(value)
131+
, sizeof (settergetter->prop2));
132+
settergetter->prop2[sizeof (settergetter->prop2) - 1] = '\0';
133+
assert(strlen(settergetter->log) < sizeof (settergetter->log));
134+
strncat(
135+
settergetter->log
136+
, "Prop2:SETTER("
137+
, sizeof (settergetter->log) - 1 - strlen(settergetter->log));
138+
assert(strlen(settergetter->log) < sizeof (settergetter->log));
139+
strncat(
140+
settergetter->log
141+
, settergetter->prop2
142+
, sizeof (settergetter->log) - 1 - strlen(settergetter->log));
143+
assert(strlen(settergetter->log) < sizeof (settergetter->log));
144+
strncat(
145+
settergetter->log
146+
, ")\n"
147+
, sizeof (settergetter->log) - 1 - strlen(settergetter->log));
148+
}
149+
150+
NAN_METHOD(SetterGetter::Log) {
151+
SetterGetter* settergetter =
152+
ObjectWrap::Unwrap<SetterGetter>(info.Holder());
153+
154+
info.GetReturnValue().Set(Nan::New(settergetter->log).ToLocalChecked());
155+
}
156+
157+
NAN_METHOD(CreateNew) {
158+
std::string datavalue = *Nan::Utf8String(info.Data());
159+
assert(datavalue == "create-data");
160+
161+
info.GetReturnValue().Set(SetterGetter::NewInstance());
162+
}
163+
164+
NAN_MODULE_INIT(Init) {
165+
SetMethod(target, "testWithData", TestWithData, New("test-value").ToLocalChecked());
166+
167+
v8::Local<v8::FunctionTemplate> tpl =
168+
Nan::New<v8::FunctionTemplate>(SetterGetter::New, New("new-data").ToLocalChecked());
169+
settergetter_constructor.Reset(tpl);
170+
tpl->SetClassName(Nan::New<v8::String>("SetterGetter").ToLocalChecked());
171+
tpl->InstanceTemplate()->SetInternalFieldCount(1);
172+
SetPrototypeMethod(tpl, "log", SetterGetter::Log,Nan::New("log-data").ToLocalChecked());
173+
v8::Local<v8::ObjectTemplate> itpl = tpl->InstanceTemplate();
174+
SetAccessor(
175+
itpl
176+
, Nan::New("prop1").ToLocalChecked()
177+
, SetterGetter::GetProp1
178+
, 0
179+
, Nan::New("prop1-data").ToLocalChecked());
180+
SetAccessor(
181+
itpl
182+
, Nan::New<v8::String>("prop2").ToLocalChecked()
183+
, SetterGetter::GetProp2
184+
, SetterGetter::SetProp2
185+
, Nan::New("prop2-data").ToLocalChecked()
186+
);
187+
188+
v8::Local<v8::Function> createnew =
189+
Nan::GetFunction(
190+
Nan::New<v8::FunctionTemplate>(CreateNew, Nan::New("create-data").ToLocalChecked())).ToLocalChecked();
191+
Set(target, Nan::New<v8::String>("create").ToLocalChecked(), createnew);
192+
}
193+
194+
NODE_MODULE(methodswithdata, Init)

test/js/methodswithdata-test.js

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/*********************************************************************
2+
* NAN - Native Abstractions for Node.js
3+
*
4+
* Copyright (c) 2019 NAN contributors
5+
*
6+
* MIT License <https://github.com/nodejs/nan/blob/master/LICENSE.md>
7+
********************************************************************/
8+
9+
const test = require('tap').test
10+
, testRoot = require('path').resolve(__dirname, '..')
11+
, bindings = require('bindings')({ module_root: testRoot, bindings: 'methodswithdata' })
12+
13+
test('SetMethod with data', function (t) {
14+
t.plan(1);
15+
t.ok(bindings.testWithData());
16+
});
17+
18+
test('accessors with data', function (t) {
19+
t.plan(7)
20+
var settergetter = bindings.create()
21+
t.equal(settergetter.prop1, 'this is property 1')
22+
t.ok(settergetter.prop2 === '')
23+
settergetter.prop2 = 'setting a value'
24+
t.equal(settergetter.prop2, 'setting a value')
25+
t.equal(settergetter.log(),
26+
'New()\n' +
27+
'Prop1:GETTER(this is property 1)\n' +
28+
'Prop2:GETTER()\n' +
29+
'Prop2:SETTER(setting a value)\n' +
30+
'Prop2:GETTER(setting a value)\n'
31+
)
32+
var derived = Object.create(settergetter)
33+
t.equal(derived.prop1, 'this is property 1')
34+
derived.prop2 = 'setting a new value'
35+
t.equal(derived.prop2, 'setting a new value')
36+
t.equal(settergetter.prop2, 'setting a new value')
37+
})
38+

0 commit comments

Comments
 (0)