[gjs: 1/2] boxed: Implement newEnumerate hook for boxed objects
- From: Philip Chimento <pchimento src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gjs: 1/2] boxed: Implement newEnumerate hook for boxed objects
- Date: Sun, 8 Mar 2020 23:45:15 +0000 (UTC)
commit 054e69103da42219466f7a0d891c02aacbaf2f4f
Author: Ole Jørgen Brønner <olejorgenb yahoo no>
Date: Sun Mar 8 14:49:47 2020 +0100
boxed: Implement newEnumerate hook for boxed objects
Before: Object.getOwnPropertyNames did not return names of methods not yet
called/accessed
Now: all method names are returned regardless of the earlier access patterns.
Note: *fields* are always resolved so there's no need to introspect them again.
gi/boxed.cpp | 26 +++++++++++++++++++++++++-
gi/boxed.h | 5 +++++
installed-tests/js/testIntrospection.js | 10 ++++++++++
3 files changed, 40 insertions(+), 1 deletion(-)
---
diff --git a/gi/boxed.cpp b/gi/boxed.cpp
index 5630e626..9c1bd8a7 100644
--- a/gi/boxed.cpp
+++ b/gi/boxed.cpp
@@ -96,6 +96,30 @@ bool BoxedPrototype::resolve_impl(JSContext* cx, JS::HandleObject obj,
return true;
}
+// See GIWrapperBase::new_enumerate().
+bool BoxedPrototype::new_enumerate_impl(JSContext* cx, JS::HandleObject,
+ JS::MutableHandleIdVector properties,
+ bool only_enumerable G_GNUC_UNUSED) {
+ int n_methods = g_struct_info_get_n_methods(info());
+ for (int i = 0; i < n_methods; i++) {
+ GjsAutoFunctionInfo meth_info = g_struct_info_get_method(info(), i);
+ GIFunctionInfoFlags flags = g_function_info_get_flags(meth_info);
+
+ if (flags & GI_FUNCTION_IS_METHOD) {
+ const char* name = meth_info.name();
+ jsid id = gjs_intern_string_to_id(cx, name);
+ if (id == JSID_VOID)
+ return false;
+ if (!properties.append(id)) {
+ JS_ReportOutOfMemory(cx);
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
+
/*
* BoxedBase::get_copy_source():
*
@@ -724,7 +748,7 @@ const struct JSClassOps BoxedBase::class_ops = {
nullptr, // addProperty
nullptr, // deleteProperty
nullptr, // enumerate
- nullptr, // newEnumerate
+ &BoxedBase::new_enumerate,
&BoxedBase::resolve,
nullptr, // mayResolve
&BoxedBase::finalize,
diff --git a/gi/boxed.h b/gi/boxed.h
index 9e1312ec..e69ffe2a 100644
--- a/gi/boxed.h
+++ b/gi/boxed.h
@@ -148,6 +148,11 @@ class BoxedPrototype : public GIWrapperPrototype<BoxedBase, BoxedPrototype,
GJS_JSAPI_RETURN_CONVENTION
bool resolve_impl(JSContext* cx, JS::HandleObject obj, JS::HandleId id,
const char* prop_name, bool* resolved);
+
+ GJS_JSAPI_RETURN_CONVENTION
+ bool new_enumerate_impl(JSContext* cx, JS::HandleObject obj,
+ JS::MutableHandleIdVector properties,
+ bool only_enumerable);
void trace_impl(JSTracer* trc);
// Helper methods
diff --git a/installed-tests/js/testIntrospection.js b/installed-tests/js/testIntrospection.js
index f81751b0..e4fba950 100644
--- a/installed-tests/js/testIntrospection.js
+++ b/installed-tests/js/testIntrospection.js
@@ -122,3 +122,13 @@ describe('Gdk.Atom', function () {
expect(Gdk.Atom.intern('NONE', false)).toBe(null);
});
});
+
+describe('Complete enumeration (boxed types)', function () {
+ it('enumerates all properties', function () {
+ // Note: this test breaks down if other code access all the methods of Rectangle
+ const rect = new Gdk.Rectangle();
+ const names = Object.getOwnPropertyNames(Object.getPrototypeOf(rect));
+ const expectAtLeast = ['equal', 'intersect', 'union', 'x', 'y', 'width', 'height'];
+ expect(names).toEqual(jasmine.arrayContaining(expectAtLeast));
+ });
+});
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]