summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhilip Chimento <philip.chimento@gmail.com>2021-07-17 22:45:19 +0000
committerPhilip Chimento <philip.chimento@gmail.com>2021-07-17 22:45:19 +0000
commitf71c22aa104e154761c2b660f71e485967333d8c (patch)
tree33e391910b441d65c2e30328bd6207640a89a560
parent83aab56f178b4e15ddf185693b8e20aa2f4cfc5d (diff)
parentf5ca2aee15ad8c9fa8beb18685e7a95968cf53f0 (diff)
downloadgjs-f71c22aa104e154761c2b660f71e485967333d8c.tar.gz
Merge branch 'ewlsh/fix-enumerate' into 'master'
gi: Only enumerate properties which GJS defines See merge request GNOME/gjs!643
-rw-r--r--gi/ns.cpp34
-rw-r--r--installed-tests/js/testIntrospection.js9
2 files changed, 43 insertions, 0 deletions
diff --git a/gi/ns.cpp b/gi/ns.cpp
index 5a30ca73..063b31f0 100644
--- a/gi/ns.cpp
+++ b/gi/ns.cpp
@@ -29,6 +29,36 @@
#include "gjs/mem-private.h"
#include "util/log.h"
+[[nodiscard]] static bool type_is_enumerable(GIInfoType info_type) {
+ switch (info_type) {
+ case GI_INFO_TYPE_BOXED:
+ case GI_INFO_TYPE_STRUCT:
+ case GI_INFO_TYPE_UNION:
+ case GI_INFO_TYPE_OBJECT:
+ case GI_INFO_TYPE_ENUM:
+ case GI_INFO_TYPE_FLAGS:
+ case GI_INFO_TYPE_INTERFACE:
+ case GI_INFO_TYPE_FUNCTION:
+ case GI_INFO_TYPE_CONSTANT:
+ return true;
+ // Don't enumerate types which GJS doesn't define on namespaces.
+ // See gjs_define_info
+ case GI_INFO_TYPE_INVALID:
+ case GI_INFO_TYPE_INVALID_0:
+ case GI_INFO_TYPE_CALLBACK:
+ case GI_INFO_TYPE_VALUE:
+ case GI_INFO_TYPE_SIGNAL:
+ case GI_INFO_TYPE_VFUNC:
+ case GI_INFO_TYPE_PROPERTY:
+ case GI_INFO_TYPE_FIELD:
+ case GI_INFO_TYPE_ARG:
+ case GI_INFO_TYPE_TYPE:
+ case GI_INFO_TYPE_UNRESOLVED:
+ default:
+ return false;
+ }
+}
+
class Ns : private GjsAutoChar, public CWrapper<Ns> {
friend CWrapperPointerOps<Ns>;
friend CWrapper<Ns>;
@@ -106,6 +136,10 @@ class Ns : private GjsAutoChar, public CWrapper<Ns> {
for (int k = 0; k < n; k++) {
GjsAutoBaseInfo info = g_irepository_get_info(nullptr, get(), k);
+ GIInfoType info_type = g_base_info_get_type(info);
+ if (!type_is_enumerable(info_type))
+ continue;
+
const char* name = info.name();
jsid id = gjs_intern_string_to_id(cx, name);
diff --git a/installed-tests/js/testIntrospection.js b/installed-tests/js/testIntrospection.js
index 5e2ee7df..19b89584 100644
--- a/installed-tests/js/testIntrospection.js
+++ b/installed-tests/js/testIntrospection.js
@@ -166,4 +166,13 @@ describe('Complete enumeration of GIRepositoryNamespace (new_enumerate)', functi
const expectAtLeast = ['KEY_ybelowdot', 'EventSequence', 'ByteOrder', 'Window'];
expect(names).toEqual(jasmine.arrayContaining(expectAtLeast));
});
+
+ it('all enumerated properties are defined', function () {
+ const names = Object.keys(Gdk);
+
+ expect(() => {
+ // Access each enumerated property to check it can be defined.
+ names.forEach((name) => Gdk[name]);
+ }).not.toThrowError(/API of type .* not implemented, cannot define .*/);
+ });
});