Skip to content

Commit 4173b09

Browse files
rolftimmermansmhdawson
authored andcommitted
Allow easy definition of iterators.
PR-URL: #143 Reviewed-By: Jason Ginchereau <[email protected]> Reviewed-By: Michael Dawson <[email protected]>
1 parent a875093 commit 4173b09

File tree

4 files changed

+84
-1
lines changed

4 files changed

+84
-1
lines changed

napi-inl.h

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -594,6 +594,10 @@ inline Symbol Symbol::New(napi_env env, napi_value description) {
594594
return Symbol(env, value);
595595
}
596596

597+
inline Symbol Symbol::WellKnown(napi_env env, const std::string& name) {
598+
return Napi::Env(env).Global().Get("Symbol").As<Object>().Get(name).As<Symbol>();
599+
}
600+
597601
inline Symbol::Symbol() : Name() {
598602
}
599603

@@ -2510,6 +2514,41 @@ inline ClassPropertyDescriptor<T> ObjectWrap<T>::InstanceMethod(
25102514
return desc;
25112515
}
25122516

2517+
template <typename T>
2518+
inline ClassPropertyDescriptor<T> ObjectWrap<T>::InstanceMethod(
2519+
Symbol name,
2520+
InstanceVoidMethodCallback method,
2521+
napi_property_attributes attributes,
2522+
void* data) {
2523+
// TODO: Delete when the class is destroyed
2524+
InstanceVoidMethodCallbackData* callbackData =
2525+
new InstanceVoidMethodCallbackData({ method, data});
2526+
2527+
napi_property_descriptor desc = {};
2528+
desc.name = name;
2529+
desc.method = T::InstanceVoidMethodCallbackWrapper;
2530+
desc.data = callbackData;
2531+
desc.attributes = attributes;
2532+
return desc;
2533+
}
2534+
2535+
template <typename T>
2536+
inline ClassPropertyDescriptor<T> ObjectWrap<T>::InstanceMethod(
2537+
Symbol name,
2538+
InstanceMethodCallback method,
2539+
napi_property_attributes attributes,
2540+
void* data) {
2541+
// TODO: Delete when the class is destroyed
2542+
InstanceMethodCallbackData* callbackData = new InstanceMethodCallbackData({ method, data });
2543+
2544+
napi_property_descriptor desc = {};
2545+
desc.name = name;
2546+
desc.method = T::InstanceMethodCallbackWrapper;
2547+
desc.data = callbackData;
2548+
desc.attributes = attributes;
2549+
return desc;
2550+
}
2551+
25132552
template <typename T>
25142553
inline ClassPropertyDescriptor<T> ObjectWrap<T>::InstanceAccessor(
25152554
const char* utf8name,

napi.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,9 @@ namespace Napi {
330330
napi_value description ///< String value describing the symbol
331331
);
332332

333+
/// Get a public Symbol (e.g. Symbol.iterator).
334+
static Symbol WellKnown(napi_env, const std::string& name);
335+
333336
Symbol(); ///< Creates a new _empty_ Symbol instance.
334337
Symbol(napi_env env, napi_value value); ///< Wraps a N-API value primitive.
335338
};
@@ -1305,6 +1308,14 @@ namespace Napi {
13051308
InstanceMethodCallback method,
13061309
napi_property_attributes attributes = napi_default,
13071310
void* data = nullptr);
1311+
static PropertyDescriptor InstanceMethod(Symbol name,
1312+
InstanceVoidMethodCallback method,
1313+
napi_property_attributes attributes = napi_default,
1314+
void* data = nullptr);
1315+
static PropertyDescriptor InstanceMethod(Symbol name,
1316+
InstanceMethodCallback method,
1317+
napi_property_attributes attributes = napi_default,
1318+
void* data = nullptr);
13081319
static PropertyDescriptor InstanceAccessor(const char* utf8name,
13091320
InstanceGetterCallback getter,
13101321
InstanceSetterCallback setter,

test/objectwrap.cc

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,26 @@
11
#include <napi.h>
22

3+
class TestIter : public Napi::ObjectWrap<TestIter> {
4+
public:
5+
TestIter(const Napi::CallbackInfo& info) : Napi::ObjectWrap<TestIter>(info) {}
6+
7+
Napi::Value Next(const Napi::CallbackInfo& info) {
8+
auto object = Napi::Object::New(info.Env());
9+
object.Set("done", Napi::Boolean::New(info.Env(), true));
10+
return object;
11+
}
12+
13+
static void Initialize(Napi::Env env, Napi::Object exports) {
14+
Constructor = Napi::Persistent(DefineClass(env, "TestIter", {
15+
InstanceMethod("next", &TestIter::Next),
16+
}));
17+
}
18+
19+
static Napi::FunctionReference Constructor;
20+
};
21+
22+
Napi::FunctionReference TestIter::Constructor;
23+
324
class Test : public Napi::ObjectWrap<Test> {
425
public:
526
Test(const Napi::CallbackInfo& info) :
@@ -14,10 +35,15 @@ class Test : public Napi::ObjectWrap<Test> {
1435
return Napi::Number::New(info.Env(), value);
1536
}
1637

38+
Napi::Value Iter(const Napi::CallbackInfo& info) {
39+
return TestIter::Constructor.New({});
40+
}
41+
1742
static void Initialize(Napi::Env env, Napi::Object exports) {
1843
exports.Set("Test", DefineClass(env, "Test", {
1944
InstanceMethod("test_set", &Test::Set),
20-
InstanceMethod("test_get", &Test::Get)
45+
InstanceMethod("test_get", &Test::Get),
46+
InstanceMethod(Napi::Symbol::WellKnown(env, "iterator"), &Test::Iter)
2147
}));
2248
}
2349

@@ -28,5 +54,6 @@ class Test : public Napi::ObjectWrap<Test> {
2854
Napi::Object InitObjectWrap(Napi::Env env) {
2955
Napi::Object exports = Napi::Object::New(env);
3056
Test::Initialize(env, exports);
57+
TestIter::Initialize(env, exports);
3158
return exports;
3259
}

test/objectwrap.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,14 @@ function test(binding) {
1313
assert.strictEqual(obj.test_get(), 90);
1414
}
1515

16+
function testIter(obj) {
17+
for (const value of obj) {
18+
}
19+
}
20+
1621
function testObj(obj) {
1722
testSetGet(obj);
23+
testIter(obj);
1824
}
1925

2026
testObj(new Test());

0 commit comments

Comments
 (0)