[gobject-introspection/ebassi/symbol-collision] Handle property name collisions




commit 6a95be0e5484140ad9aa2e11e9946795d9f879ea
Author: Emmanuele Bassi <ebassi gnome org>
Date:   Sun Jun 13 14:01:55 2021 +0100

    Handle property name collisions
    
    Properties cannot have the same name as signals and methods, as they
    will break various language bindings.
    
    Since listing this requirement only in the documentation has been
    insufficient, we should emit a warning, and hope that library developers
    will pay attention to it.
    
    Fixes: #386

 giscanner/introspectablepass.py | 36 ++++++++++++++++++++++++++++++++++++
 1 file changed, 36 insertions(+)
---
diff --git a/giscanner/introspectablepass.py b/giscanner/introspectablepass.py
index e2056b42..9198603a 100644
--- a/giscanner/introspectablepass.py
+++ b/giscanner/introspectablepass.py
@@ -39,6 +39,7 @@ class IntrospectablePass(object):
         self._namespace.walk(self._introspectable_callable_analysis)
         self._namespace.walk(self._introspectable_pass3)
         self._namespace.walk(self._remove_non_reachable_backcompat_copies)
+        self._namespace.walk(self._introspectable_symbol_collisions)
 
     def _parameter_warning(self, parent, param, text, position=None):
         # Suppress VFunctions and Callbacks warnings for now
@@ -238,3 +239,38 @@ class IntrospectablePass(object):
             if not obj.introspectable:
                 obj.internal_skipped = True
         return True
+
+    def _property_warning(self, parent, prop, text, position=None):
+        context = "property %s:%s: " % (parent.name, prop.name, )
+        message.warn_node(parent, context + text, positions=position)
+
+    def _property_signal_collision(self, obj, prop):
+        for s in obj.signals:
+            if s.skip or not s.introspectable:
+                continue
+            if s.name.replace('-', '_') == prop.name.replace('-', '_'):
+                self._property_warning(obj, prop, "Properties cannot have the same name as signals")
+                return True
+        return False
+
+    def _property_method_collision(self, obj, prop):
+        for m in obj.methods:
+            if m.skip or not m.introspectable:
+                continue
+            if m.name == prop.name.replace('-', '_'):
+                self._property_warning(obj, prop, "Properties cannot have the same name as methods")
+                return True
+        return False
+
+    def _introspectable_symbol_collisions(self, obj, stack):
+        if obj.skip:
+            return False
+        if isinstance(obj, (ast.Class, ast.Interface)):
+            for prop in obj.properties:
+                if prop.skip or not prop.introspectable:
+                    continue
+                if self._property_signal_collision(obj, prop):
+                    prop.introspectable = False
+                elif self._property_method_collision(obj, prop):
+                    prop.introspectable = False
+        return True


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