[gjs/ewlsh/fix-enumerate] gi: Only enumerate properties which GJS defines




commit 8eea8afb3fc11fd6d6fd06fc58ea78baeea14aef
Author: Evan Welsh <contact evanwelsh com>
Date:   Sat Jul 17 15:08:35 2021 -0700

    gi: Only enumerate properties which GJS defines

 gi/ns.cpp                               | 40 +++++++++++++++++++++++++++++++++
 installed-tests/js/testIntrospection.js |  9 ++++++++
 2 files changed, 49 insertions(+)
---
diff --git a/gi/ns.cpp b/gi/ns.cpp
index 5a30ca73..8f30824c 100644
--- a/gi/ns.cpp
+++ b/gi/ns.cpp
@@ -29,6 +29,42 @@
 #include "gjs/mem-private.h"
 #include "util/log.h"
 
+[[nodiscard]] static bool type_is_enumerable(GIInfoType info_type) {
+    bool is_enumerable = false;
+    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:
+            is_enumerable = true;
+            break;
+        // 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:
+            is_enumerable = false;
+            break;
+    }
+
+    return is_enumerable;
+}
+
 class Ns : private GjsAutoChar, public CWrapper<Ns> {
     friend CWrapperPointerOps<Ns>;
     friend CWrapper<Ns>;
@@ -106,6 +142,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 .*/);
+    });
 });


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]