From 39e031ab64633076858094b46218e371e648af6b Mon Sep 17 00:00:00 2001 From: Emmanuele Bassi Date: Sun, 13 Jun 2021 14:01:55 +0100 Subject: Handle property name collisions Properties cannot have the same name as signals, methods, and virtual functions, 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 | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/giscanner/introspectablepass.py b/giscanner/introspectablepass.py index e2056b42..84c2c8e5 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,43 @@ 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 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 False + + def _property_vfunc_collision(self, obj, prop): + for vfunc in obj.virtual_methods: + if vfunc.skip or not vfunc.introspectable: + continue + if vfunc.name == prop.name.replace('-', '_'): + self._property_warning(obj, prop, "Properties cannot have the same name as virtual methods") + 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 + self._property_signal_collision(obj, prop) + self._property_method_collision(obj, prop) + self._property_vfunc_collision(obj, prop) + return True -- cgit v1.2.1