[gjs: 2/3] GObject: Don't overwrite toString() method with one from Interface



commit d008cd5c23e935358ff8e1930a58be0f84cfba59
Author: Marco Trevisan (TreviƱo) <mail 3v1n0 net>
Date:   Wed May 29 00:34:39 2019 -0500

    GObject: Don't overwrite toString() method with one from Interface
    
    Since commit 0fa00d49 objects implementing JS-defined interfaces don't
    have a valid toString() method defined, and calling it would lead to:
    
    JS ERROR: TypeError: GObject_Interface.prototype.toString called on
                         incompatible GObject_Object
    
    While calling print on it to an '<invalid string>'.
    
    This happens because InterfaceBase doesn't define a to_string()
    implementation, falling back to the GIWrapperBase one which will try to
    convert the current object to an InterfaceBase one even if it is
    actually an ObjectBase, causing InterfaceBase::for_js_typecheck on it to
    fail.
    
    So, don't copy the toString() method from the interfaces to the object
    when creating the class that implements the interface.
    
    Added a test to verify that this is actually true.
    
    Fixes https://gitlab.gnome.org/GNOME/gjs/issues/252

 installed-tests/js/testGObjectInterface.js | 5 +++++
 modules/overrides/GObject.js               | 7 ++++---
 2 files changed, 9 insertions(+), 3 deletions(-)
---
diff --git a/installed-tests/js/testGObjectInterface.js b/installed-tests/js/testGObjectInterface.js
index daefb683..48ddf56a 100644
--- a/installed-tests/js/testGObjectInterface.js
+++ b/installed-tests/js/testGObjectInterface.js
@@ -284,4 +284,9 @@ describe('GObject interface', function () {
         expect(obj instanceof AGObjectInterface).toBeTruthy();
         expect(obj.interface_prop).toEqual('foobar');  // override not needed
     });
+
+    it('has a toString() defintion', function () {
+        expect(new GObjectImplementingGObjectInterface().toString()).toMatch(
+            /\[object instance wrapper GType:Gjs_GObjectImplementingGObjectInterface jsobj@0x[a-f0-9]+ 
native@0x[a-f0-9]+\]/);
+    });
 });
diff --git a/modules/overrides/GObject.js b/modules/overrides/GObject.js
index c6ea6ad9..d33f7429 100644
--- a/modules/overrides/GObject.js
+++ b/modules/overrides/GObject.js
@@ -126,9 +126,9 @@ function _propertiesAsArray(klass) {
     return propertiesArray;
 }
 
-function _copyAllDescriptors(target, source) {
+function _copyAllDescriptors(target, source, filter) {
     Object.getOwnPropertyNames(source)
-    .filter(key => !['prototype', 'constructor'].includes(key))
+    .filter(key => !['prototype', 'constructor'].concat(filter).includes(key))
     .concat(Object.getOwnPropertySymbols(source))
     .forEach(key => {
         let descriptor = Object.getOwnPropertyDescriptor(source, key);
@@ -354,7 +354,8 @@ function _init() {
 
         _copyAllDescriptors(newClass, klass);
         gobjectInterfaces.forEach(iface =>
-            _copyAllDescriptors(newClass.prototype, iface.prototype));
+            _copyAllDescriptors(newClass.prototype, iface.prototype,
+                ['toString']));
         _copyAllDescriptors(newClass.prototype, klass.prototype);
 
         Object.getOwnPropertyNames(newClass.prototype)


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