Skip to content

Commit

Permalink
core, feat: support for defining iterator operators.
Browse files Browse the repository at this point in the history
  • Loading branch information
xicilion committed Apr 23, 2021
1 parent da0b4fe commit 174d450
Show file tree
Hide file tree
Showing 12 changed files with 88 additions and 50 deletions.
19 changes: 15 additions & 4 deletions fibjs/include/ClassInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,17 @@ class ClassInfo {
return true;
}

v8::Local<v8::Name> get_prop_name(Isolate* isolate, const char* name)
{
if (name[0] != '@')
return isolate->NewString(name);

if (!qstrcmp("iterator", name + 1))
return v8::Symbol::GetIterator(isolate->m_isolate);

return isolate->NewString(name);
}

bool has(const char* name)
{
int32_t i;
Expand Down Expand Up @@ -209,7 +220,7 @@ class ClassInfo {
;

if (!skips || !skips[j])
o->Set(isolate->NewString(m_cd.cms[i].name),
o->Set(get_prop_name(isolate, m_cd.cms[i].name),
isolate->NewFunction(m_cd.cms[i].name, m_cd.cms[i].invoker));
}
}
Expand All @@ -231,7 +242,7 @@ class ClassInfo {
;

if (!skips || !skips[j])
o->SetAccessor(_context, isolate->NewString(m_cd.cps[i].name),
o->SetAccessor(_context, get_prop_name(isolate, m_cd.cps[i].name),
m_cd.cps[i].getter, m_cd.cps[i].setter)
.ToChecked();
}
Expand Down Expand Up @@ -336,12 +347,12 @@ class ClassInfo {

for (i = 0; i < m_cd.mc; i++)
if (!m_cd.cms[i].is_static)
pt->Set(isolate->NewString(m_cd.cms[i].name),
pt->Set(get_prop_name(isolate, m_cd.cms[i].name),
v8::FunctionTemplate::New(isolate->m_isolate, m_cd.cms[i].invoker));

for (i = 0; i < m_cd.pc; i++)
if (!m_cd.cps[i].is_static)
pt->SetAccessor(isolate->NewString(m_cd.cps[i].name),
pt->SetAccessor(get_prop_name(isolate, m_cd.cps[i].name),
m_cd.cps[i].getter, m_cd.cps[i].setter,
v8::Local<v8::Value>(), v8::DEFAULT, v8::DontDelete);

Expand Down
17 changes: 6 additions & 11 deletions fibjs/include/Iterator.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,16 @@ class Iterator : public Iterator_base {
, m_index(0)
, m_done(false)
{
v8::Local<v8::Object> o = wrap();
Isolate* isolate = holder();

o->Set(v8::Symbol::GetIterator(isolate->m_isolate),
isolate->NewFunction("Iterator", s_static_iterator, o));
}

public:
// Iterator_base
virtual result_t symbol_iterator(obj_ptr<Iterator_base>& retVal)
{
retVal = this;
return 0;
}

virtual result_t next(obj_ptr<NextType>& retVal)
{
retVal = new NextType();
Expand All @@ -46,12 +47,6 @@ class Iterator : public Iterator_base {
return 0;
}

private:
static void s_static_iterator(const v8::FunctionCallbackInfo<v8::Value>& args)
{
args.GetReturnValue().Set(args.Data());
}

private:
obj_ptr<object_base> m_obj;
std::function<void(size_t, v8::Local<v8::Value>&)> m_proc;
Expand Down
18 changes: 18 additions & 0 deletions fibjs/include/ifs/Iterator.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ class Iterator_base : public object_base {

public:
// Iterator_base
virtual result_t symbol_iterator(obj_ptr<Iterator_base>& retVal) = 0;
virtual result_t next(obj_ptr<NextType>& retVal) = 0;

public:
Expand All @@ -54,6 +55,7 @@ class Iterator_base : public object_base {
}

public:
static void s_symbol_iterator(const v8::FunctionCallbackInfo<v8::Value>& args);
static void s_next(const v8::FunctionCallbackInfo<v8::Value>& args);
};
}
Expand All @@ -62,6 +64,7 @@ namespace fibjs {
inline ClassInfo& Iterator_base::class_info()
{
static ClassData::ClassMethod s_method[] = {
{ "@iterator", s_symbol_iterator, false },
{ "next", s_next, false }
};

Expand All @@ -75,6 +78,21 @@ inline ClassInfo& Iterator_base::class_info()
return s_ci;
}

inline void Iterator_base::s_symbol_iterator(const v8::FunctionCallbackInfo<v8::Value>& args)
{
obj_ptr<Iterator_base> vr;

METHOD_NAME("Iterator.@iterator");
METHOD_INSTANCE(Iterator_base);
METHOD_ENTER();

METHOD_OVER(0, 0);

hr = pInst->symbol_iterator(vr);

METHOD_RETURN();
}

inline void Iterator_base::s_next(const v8::FunctionCallbackInfo<v8::Value>& args)
{
obj_ptr<NextType> vr;
Expand Down
5 changes: 5 additions & 0 deletions idl/zh-cn/Iterator.idl
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
/*! @brief 迭代器对象,用于遍历集合数据 */
interface Iterator : object
{
/*! @brief 查询当前对象元素的迭代器
@return 返回当前对象元素的迭代器
*/
Iterator @iterator();

/*! @brief 迭代下一个元素
@return 返回下一个元素,或者标记迭代结束 */
(Value value, Boolean done) next();
Expand Down
24 changes: 13 additions & 11 deletions tools/util/gen_code.js
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,7 @@ function gen_code(cls, def, baseFolder) {

if (ov.type) txts.push(` ${get_rtype(ov.type)} vr;\n`);

txts.push(` METHOD_NAME("${cls}.${ov.name}");`);
txts.push(` METHOD_NAME("${cls}.${ov.symbol}${ov.name}");`);
txts.push(` METHOD_ENTER();\n`);
make_ov_params(static_ovs);

Expand All @@ -258,7 +258,7 @@ function gen_code(cls, def, baseFolder) {

if (ov.type) txts.push(` ${get_rtype(ov.type)} vr;\n`);

txts.push(` METHOD_NAME("${cls}.${ov.name}");`);
txts.push(` METHOD_NAME("${cls}.${ov.symbol}${ov.name}");`);
txts.push(` METHOD_INSTANCE(${cls}_base);`);
txts.push(` METHOD_ENTER();\n`);
make_ov_params(inst_mem_ovs);
Expand Down Expand Up @@ -321,13 +321,13 @@ function gen_code(cls, def, baseFolder) {

txts.push(`inline void ${cls}_base::${get_stub_func_prefix(fn, def)}get_${get_name(fname, fn, def)}(v8::Local<v8::Name> property, const v8::PropertyCallbackInfo<v8::Value>& args)\n{\n ${get_rtype(fn.type)} vr;\n`);

txts.push(` METHOD_NAME("${cls}.${fname}");`);
txts.push(` METHOD_NAME("${cls}.${fn.symbol}${fname}");`);
if (!fstatic)
txts.push(` METHOD_INSTANCE(${cls}_base);`);
txts.push(` PROPERTY_ENTER();\n`);

if (fn.deprecated)
txts.push(` DEPRECATED_SOON("${cls}.${fname}");\n`);
txts.push(` DEPRECATED_SOON("${cls}.${fn.symbol}${fname}");\n`);

if (fstatic)
txts.push(` hr = get_${get_name(fname, fn, def)}(vr);\n`);
Expand All @@ -337,13 +337,13 @@ function gen_code(cls, def, baseFolder) {

if (!fn.readonly) {
txts.push(`inline void ${cls}_base::${get_stub_func_prefix(fn, def)}set_${get_name(fname, fn, def)}(v8::Local<v8::Name> property, v8::Local<v8::Value> value, const v8::PropertyCallbackInfo<void>& args)\n{`);
txts.push(` METHOD_NAME("${cls}.${fname}");`);
txts.push(` METHOD_NAME("${cls}.${fn.symbol}${fname}");`);
if (!fstatic)
txts.push(` METHOD_INSTANCE(${cls}_base);`);
txts.push(` PROPERTY_ENTER();\n PROPERTY_VAL(${get_rtype(fn.type)});\n`);

if (fn.deprecated)
txts.push(` DEPRECATED_SOON("${cls}.${fname}");\n`);
txts.push(` DEPRECATED_SOON("${cls}.${fn.symbol}${fname}");\n`);

if (fstatic)
txts.push(` hr = set_${get_name(fname, fn, def)}(v0);\n`);
Expand Down Expand Up @@ -550,6 +550,8 @@ function gen_code(cls, def, baseFolder) {
if (fn.static) return base
if (is_func_Function(fn, def)) return base
if (is_func_new(fn, def)) return base
if (fn.symbol)
return `symbol_${base}`;

return base
}
Expand Down Expand Up @@ -807,9 +809,9 @@ function gen_code(cls, def, baseFolder) {
if (recorder_insts.isRecorded(ov.name)) return;

if (ov.memType == "method") {
deflist.push(` { "${fname}", ${get_stub_func_prefix(ov, def)}${get_name(fname, ov, def)}, false }`);
deflist.push(` { "${fn.symbol}${fname}", ${get_stub_func_prefix(ov, def)}${get_name(fname, ov, def)}, false }`);
if (ov.async)
deflist.push(` { "${fname}Sync", ${get_stub_func_prefix(ov, def)}${get_name(fname, ov, def)}, false }`);
deflist.push(` { "${fn.symbol}${fname}Sync", ${get_stub_func_prefix(ov, def)}${get_name(fname, ov, def)}, false }`);

recorder_insts.record(ov.name);
}
Expand All @@ -820,9 +822,9 @@ function gen_code(cls, def, baseFolder) {
if (recorder_statics.isRecorded(ov.name)) return;

if (ov.memType == "method") {
deflist.push(` { "${fname}", ${get_stub_func_prefix(ov, def)}${get_name(fname, ov, def)}, true }`);
deflist.push(` { "${fn.symbol}${fname}", ${get_stub_func_prefix(ov, def)}${get_name(fname, ov, def)}, true }`);
if (ov.async)
deflist.push(` { "${fname}Sync", ${get_stub_func_prefix(ov, def)}${get_name(fname, ov, def)}, true }`);
deflist.push(` { "${fn.symbol}${fname}Sync", ${get_stub_func_prefix(ov, def)}${get_name(fname, ov, def)}, true }`);

recorder_statics.record(ov.name);
}
Expand Down Expand Up @@ -860,7 +862,7 @@ function gen_code(cls, def, baseFolder) {
if (fn.memType == 'prop') {
var fname = fn.name;
deflist.push([
` { "${fname}", ${get_stub_func_prefix(fn, def)}get_${get_name(fname, fn, def)}, `,
` { "${fn.symbol}${fname}", ${get_stub_func_prefix(fn, def)}get_${get_name(fname, fn, def)}, `,
`${fn.readonly ? `block_set` : (`${get_stub_func_prefix(fn, def)}set_` + get_name(fname, fn, def))}, `,
`${fn.static ? `true` : `false`} }`
].join(''));
Expand Down
16 changes: 8 additions & 8 deletions tools/util/gen_docs.js
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ module.exports = function (defs, docsFolder) {

t = t.replace(re, function (u) {
urls.push(u);
return `[u_r_l::${urls.length-1}]`;
return `[u_r_l::${urls.length - 1}]`;
});

t = t.replace(/(\w+)(\.(\w+))?/g, function (k, k1, k2, k3) {
Expand Down Expand Up @@ -226,7 +226,7 @@ module.exports = function (defs, docsFolder) {
} else if (m.memType == 'operator')
lines.push('operator' + m.name.replace(/\[|\]/g, s => `\\${s}`));
else
lines.push(m.name + (m.memType == 'method' ? '()' : ''));
lines.push(m.symbol + m.name + (m.memType == 'method' ? '()' : ''));
}
}
});
Expand All @@ -241,32 +241,32 @@ module.exports = function (defs, docsFolder) {
return m.memType == 'method' && m.name == n;
});

member_output('下标操作', function (m) {
return m.memType == 'operator';
member_output('操作符', function (m) {
return m.memType == 'operator' || m.symbol;
});

member_output('对象', function (m) {
return m.memType == 'object';
});

member_output('静态函数', function (m, n) {
return m.memType == 'method' && m.name !== n && m.static;
return m.memType == 'method' && m.name !== n && m.static && !m.symbol;
});

member_output('静态属性', function (m) {
return m.memType == 'prop' && m.static;
return m.memType == 'prop' && m.static && !m.symbol;
});

member_output('常量', function (m) {
return m.memType == 'const';
});

member_output('成员属性', function (m) {
return m.memType == 'prop' && !m.static;
return m.memType == 'prop' && !m.static && !m.symbol;
});

member_output('成员函数', function (m, n) {
return m.memType == 'method' && m.name !== n && !m.static;
return m.memType == 'method' && m.name !== n && !m.static && !m.symbol;
});

txts.push(lines.join(';'));
Expand Down
13 changes: 10 additions & 3 deletions tools/util/idl-def.pegjs
Original file line number Diff line number Diff line change
Expand Up @@ -52,19 +52,21 @@ constMember
comments: comments.join(""),
deprecated: deprecated,
const: constMode,
symbol: '',
name: name,
default: def
};
}

prop
= comments:_* deprecated:deprecatedToken? _* staticMode:staticToken? _* readonly:readonlyToken? _* type:Identifier _* name:Identifier _* ";" {
= comments:_* deprecated:deprecatedToken? _* staticMode:staticToken? _* readonly:readonlyToken? _* type:Identifier _* symbol:"@"? name:Identifier _* ";" {
return {
memType: "prop",
comments: comments.join(""),
deprecated: deprecated,
static: staticMode,
readonly: readonly,
symbol: symbol ? '@' : '',
name: name,
type: type
};
Expand All @@ -77,6 +79,7 @@ operator
comments: comments.join(""),
deprecated: deprecated,
readonly: readonly,
symbol: '',
name: index ? "[String]" : "[]",
type: type,
index: index
Expand All @@ -89,6 +92,7 @@ object
memType: "object",
comments: comments.join(""),
deprecated: deprecated,
symbol: '',
name: name,
type: type,
newable: true
Expand All @@ -101,31 +105,34 @@ object1
memType: "object",
comments: comments.join(""),
deprecated: deprecated,
symbol: '',
name: type,
type: type
};
}

method
= comments:_* _* deprecated:deprecatedToken? _* staticMode:staticToken? _* name:Identifier _* "(" params:params? _* ")" _* async:asyncToken? ";" {
= comments:_* _* deprecated:deprecatedToken? _* staticMode:staticToken? _* symbol:"@"? name:Identifier _* "(" params:params? _* ")" _* async:asyncToken? ";" {
return {
memType: "method",
comments: comments.join(""),
deprecated: deprecated,
static: staticMode,
async: async,
symbol: symbol ? '@' : '',
name: name,
type: null,
params: params
};
}
/ comments:_* _* deprecated:deprecatedToken? _* staticMode:staticToken? _* type:method_type _* name:Identifier _* "(" params:params? _* ")" _* async:asyncToken? ";" {
/ comments:_* _* deprecated:deprecatedToken? _* staticMode:staticToken? _* type:method_type _* symbol:"@"? name:Identifier _* "(" params:params? _* ")" _* async:asyncToken? ";" {
return {
memType: "method",
comments: comments.join(""),
deprecated: deprecated,
static: staticMode,
async: async,
symbol: symbol ? '@' : '',
name: name,
type: type,
params: params
Expand Down
Loading

0 comments on commit 174d450

Please sign in to comment.