[gjs/ewlsh/construct-only-props: 2/2] Allow users to implement construct-only props with getters




commit ca861a9fcb0ae40b3924af5e862afe72cea19d34
Author: Evan Welsh <contact evanwelsh com>
Date:   Sun Jan 30 17:25:23 2022 -0800

    Allow users to implement construct-only props with getters

 gi/gobject.cpp                         | 17 +++++++++++++++++
 installed-tests/js/testGObjectClass.js |  8 +++++++-
 2 files changed, 24 insertions(+), 1 deletion(-)
---
diff --git a/gi/gobject.cpp b/gi/gobject.cpp
index 95b033787..2ab1f28ba 100644
--- a/gi/gobject.cpp
+++ b/gi/gobject.cpp
@@ -64,6 +64,7 @@ static bool jsobj_set_gproperty(JSContext* cx, JS::HandleObject object,
         if (g_param_spec_get_qdata(pspec, ObjectBase::custom_property_quark())) {
             JS::Rooted<mozilla::Maybe<JS::PropertyDescriptor>> jsprop(cx);
             JS::RootedObject holder(cx);
+            JS::RootedObject getter(cx);
 
             // Ensure to call any associated setter method
             if (!g_str_equal(underscore_name.get(), pspec->name)) {
@@ -76,6 +77,8 @@ static bool jsobj_set_gproperty(JSContext* cx, JS::HandleObject object,
                     !JS_SetProperty(cx, object, underscore_name, jsvalue)) {
                     return false;
                 }
+                if (jsprop.isSome() && jsprop->getter())
+                    getter.set(jsprop->getter());
             }
 
             if (!g_str_equal(camel_name.get(), pspec->name)) {
@@ -88,6 +91,8 @@ static bool jsobj_set_gproperty(JSContext* cx, JS::HandleObject object,
                     !JS_SetProperty(cx, object, camel_name, jsvalue)) {
                     return false;
                 }
+                if (!getter && jsprop.isSome() && jsprop->getter())
+                    getter.set(jsprop->getter());
             }
 
             if (!JS_GetPropertyDescriptor(cx, object, pspec->name, &jsprop,
@@ -96,6 +101,18 @@ static bool jsobj_set_gproperty(JSContext* cx, JS::HandleObject object,
             if (jsprop.isSome() && jsprop.value().setter() &&
                 !JS_SetProperty(cx, object, pspec->name, jsvalue))
                 return false;
+            if (!getter && jsprop.isSome() && jsprop->getter())
+                getter.set(jsprop->getter());
+
+            // If a getter is found, redefine the property with that getter
+            // and no setter.
+            if (getter)
+                return JS_DefineProperty(cx, object, underscore_name, getter,
+                                         nullptr, GJS_MODULE_PROP_FLAGS) &&
+                       JS_DefineProperty(cx, object, camel_name, getter,
+                                         nullptr, GJS_MODULE_PROP_FLAGS) &&
+                       JS_DefineProperty(cx, object, pspec->name, getter,
+                                         nullptr, GJS_MODULE_PROP_FLAGS);
         }
 
         return JS_DefineProperty(cx, object, underscore_name, jsvalue, flags) &&
diff --git a/installed-tests/js/testGObjectClass.js b/installed-tests/js/testGObjectClass.js
index e1c8fcf12..34741d331 100644
--- a/installed-tests/js/testGObjectClass.js
+++ b/installed-tests/js/testGObjectClass.js
@@ -144,10 +144,12 @@ const MyObjectWithCustomConstructor = GObject.registerClass({
 }, class MyObjectWithCustomConstructor extends GObject.Object {
     _readwrite;
     _readonly;
+    _constructProp;
 
     constructor({readwrite = 'foo', readonly = 'bar', construct = 'default'} = {}) {
-        super({construct});
+        super();
 
+        this._constructProp = construct;
         this._readwrite = readwrite;
         this._readonly = readonly;
     }
@@ -173,6 +175,10 @@ const MyObjectWithCustomConstructor = GObject.registerClass({
         this._readonly = 'bogus';
     }
 
+    get construct() {
+        return this._constructProp;
+    }
+
     notifyProp() {
         this._readonly = 'changed';
 


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