[gjs/wip/inheritance-warning: 61/63] object: Throw if constructing an unregistered object inheriting from GObject



commit 72062b5e036821731116a9263b55ee647e3bdadf
Author: Philip Chimento <philip endlessm com>
Date:   Tue Aug 27 15:03:28 2019 +0300

    object: Throw if constructing an unregistered object inheriting from GObject
    
    When a class inherits from a GObject class, it must be always registered
    using GObject.registerClass, however gjs was accepting this silently,
    until the object wasn't passed around.
    
    To make this clearer, verify if the object's new.target is set and
    if it has the '$gtype' own property defined. Throws otherwise.
    
    Signed-off-by: Marco Trevisan (TreviƱo) <mail 3v1n0 net>

 gi/object.cpp | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)
---
diff --git a/gi/object.cpp b/gi/object.cpp
index a28f4979..6012e5b2 100644
--- a/gi/object.cpp
+++ b/gi/object.cpp
@@ -1528,6 +1528,23 @@ bool ObjectInstance::constructor_impl(JSContext* context,
                                       const JS::CallArgs& argv) {
     JS::RootedValue initer(context);
     GjsContextPrivate* gjs = GjsContextPrivate::from_cx(context);
+    const auto& new_target = argv.newTarget();
+    bool has_gtype;
+
+    g_assert(new_target.isObject() && "new.target needs to be an object");
+    JS::RootedObject rooted_target(context, &new_target.toObject());
+    if (!JS_HasOwnPropertyById(context, rooted_target, gjs->atoms().gtype(),
+                               &has_gtype))
+        return false;
+
+    if (!has_gtype) {
+        gjs_throw(context,
+                  "Tried to construct an object without a GType; are "
+                  "you using GObject.registerClass() when inheriting "
+                  "from a GObject type?");
+        return false;
+    }
+
     return gjs_object_require_property(context, object, "GObject instance",
                                        gjs->atoms().init(), &initer) &&
            gjs->call_function(object, initer, argv, argv.rval());


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