[gjs: 1/2] gobject: Handle CONSTRUCT_ONLY flag




commit 1b68e2e9f3579340bb65eb36d1e9e65e548c660e
Author: Florian Müllner <fmuellner gnome org>
Date:   Tue Dec 17 04:06:57 2019 +0100

    gobject: Handle CONSTRUCT_ONLY flag
    
    CONSTRUCT_ONLY properties are supposed to be only writable during
    construction, however this is currently only enforced on the C level.
    
    Add some minimal handling for GObjects defined in JS as well, by
    redefining the property as read-only when set from the underlying
    C code. We know that call happens only during construction, as
    g_object_set_property() and friends handle the flag themselves,
    and turning the JS property read-only will prevent changes from
    javascript (unless it is explicitly made writable again).

 gi/gobject.cpp                          |  6 ++++++
 installed-tests/js/testGObjectClass.js  | 11 +++++------
 installed-tests/js/testLegacyGObject.js | 11 +++++------
 3 files changed, 16 insertions(+), 12 deletions(-)
---
diff --git a/gi/gobject.cpp b/gi/gobject.cpp
index 7a430255..7b0d9f4f 100644
--- a/gi/gobject.cpp
+++ b/gi/gobject.cpp
@@ -67,6 +67,12 @@ static bool jsobj_set_gproperty(JSContext* cx, JS::HandleObject object,
         return false;
 
     GjsAutoChar underscore_name = gjs_hyphen_to_underscore(pspec->name);
+
+    if (pspec->flags & G_PARAM_CONSTRUCT_ONLY)
+        return JS_DefineProperty(
+            cx, object, underscore_name, jsvalue,
+            GJS_MODULE_PROP_FLAGS | JSPROP_READONLY);
+
     return JS_SetProperty(cx, object, underscore_name, jsvalue);
 }
 
diff --git a/installed-tests/js/testGObjectClass.js b/installed-tests/js/testGObjectClass.js
index ced92ad3..0878841c 100644
--- a/installed-tests/js/testGObjectClass.js
+++ b/installed-tests/js/testGObjectClass.js
@@ -65,12 +65,7 @@ const MyObject = GObject.registerClass({
     }
 
     set construct(val) {
-        // this should be called at most once
-        if (this._constructCalled)
-            throw Error('Construct-Only property set more than once');
-
         this._constructProp = val;
-        this._constructCalled = true;
     }
 
     notifyProp() {
@@ -214,13 +209,17 @@ describe('GObject class with decorator', function () {
         expect(myInstance3.construct).toEqual('quz');
     });
 
+    it('does not allow changing CONSTRUCT_ONLY properties', function () {
+        myInstance.construct = 'val';
+        expect(myInstance.construct).toEqual('default');
+    });
+
     it('has a name', function () {
         expect(MyObject.name).toEqual('MyObject');
     });
 
     // the following would (should) cause a CRITICAL:
     // myInstance.readonly = 'val';
-    // myInstance.construct = 'val';
 
     it('has a notify signal', function () {
         let notifySpy = jasmine.createSpy('notifySpy');
diff --git a/installed-tests/js/testLegacyGObject.js b/installed-tests/js/testLegacyGObject.js
index f30bc906..c0b6017c 100644
--- a/installed-tests/js/testLegacyGObject.js
+++ b/installed-tests/js/testLegacyGObject.js
@@ -74,12 +74,7 @@ const MyObject = new GObject.Class({
     },
 
     set construct(val) {
-        // this should be called at most once
-        if (this._constructCalled)
-            throw Error('Construct-Only property set more than once');
-
         this._constructProp = val;
-        this._constructCalled = true;
     },
 
     notify_prop() {
@@ -220,13 +215,17 @@ describe('GObject class', function () {
         expect(myInstance3.construct).toEqual('quz');
     });
 
+    it('does not allow changing CONSTRUCT_ONLY properties', function () {
+        myInstance.construct = 'val';
+        expect(myInstance.construct).toEqual('default');
+    });
+
     it('has a name', function () {
         expect(MyObject.name).toEqual('MyObject');
     });
 
     // the following would (should) cause a CRITICAL:
     // myInstance.readonly = 'val';
-    // myInstance.construct = 'val';
 
     it('has a notify signal', function () {
         let notifySpy = jasmine.createSpy('notifySpy');


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