at master 4.4 kB view raw
1From 7b2d3699ad117199bc316c7007cc5984c3b09368 Mon Sep 17 00:00:00 2001 2From: Maximiliano Sandoval <msandova@gnome.org> 3Date: Thu, 20 Mar 2025 22:52:54 +0100 4Subject: [PATCH] scanner: Prefer some getters over others 5 6At the moment the current set of heuristics to determine a getter for a 7property is good for finding *a* getter. However, if there are multiple 8candidates we might declare the wrong method as a getter. 9 10We introduce a priority system to determine which getter candidate is 11the most appropriate as the getter. The weight were chosen with gaps in 12between so that new and better heuristics have space to thrive. 13 14For a property named `p`, these are the possible getter candidates: 15 16 - A method declared via the `(getter p)` annotation 17 - The method `get_p` 18 - The method `is_p` 19 - The method `p` 20 21we declare the getter to be the first candidate in the list for which a 22method of the same name is available. 23 24See https://gitlab.gnome.org/GNOME/gjs/-/issues/681. 25--- 26 giscanner/maintransformer.py | 22 +++++++++++++++------- 27 1 file changed, 15 insertions(+), 7 deletions(-) 28 29diff --git a/giscanner/maintransformer.py b/giscanner/maintransformer.py 30index a81b1777..9aaf2578 100644 31--- a/giscanner/maintransformer.py 32+++ b/giscanner/maintransformer.py 33@@ -1612,7 +1612,10 @@ method or constructor of some type.""" 34 if not prop.introspectable: 35 continue 36 setter = None 37- getter = [] 38+ # They keys are method names of candidates for getters. The values 39+ # are priority weights that measure how tasteful was the heuristic 40+ # used to propose their candidate. 41+ getter = {} 42 if prop.setter is None: 43 if prop.writable and not prop.construct_only: 44 setter = 'set_' + normalized_name 45@@ -1620,17 +1623,17 @@ method or constructor of some type.""" 46 setter = prop.setter 47 if prop.getter is None: 48 if prop.readable: 49- getter = ['get_' + normalized_name] 50+ getter[f"get_{normalized_name}"] = 50 51 # Heuristic: boolean properties can have getters that are 52 # prefixed by is_property_name, like: gtk_window_is_maximized() 53 if prop.type.is_equiv(ast.TYPE_BOOLEAN) and not normalized_name.startswith("is_"): 54- getter.append(f"is_{normalized_name}") 55+ getter[f"is_{normalized_name}"] = 25 56 # Heuristic: read-only properties can have getters that are 57 # just the property name, like: gtk_widget_has_focus() 58 if not prop.writable and prop.type.is_equiv(ast.TYPE_BOOLEAN): 59- getter.append(normalized_name) 60+ getter[normalized_name] = 10 61 else: 62- getter = [prop.getter] 63+ getter[prop.getter] = 99 64 for method in node.methods: 65 if not method.introspectable: 66 continue 67@@ -1645,7 +1648,7 @@ method or constructor of some type.""" 68 method.set_property = prop.name 69 prop.setter = method.name 70 continue 71- if getter is not [] and method.name in getter: 72+ if getter is not {} and method.name in getter: 73 if method.get_property is None: 74 method.get_property = prop.name 75 elif method.get_property != prop.name: 76@@ -1654,7 +1657,12 @@ method or constructor of some type.""" 77 "mismatched '(get-property %s)' annotation" % 78 (method.symbol, prop.name, method.get_property)) 79 method.get_property = prop.name 80- prop.getter = method.name 81+ # Check the priority of the last matching getter 82+ current_priority = -1 83+ if current_getter := prop.getter: 84+ current_priority = getter.get(current_getter, -1) 85+ if getter[method.name] >= current_priority: 86+ prop.getter = method.name 87 continue 88 89 def _pass_member_numeric_name(self, node): 90-- 912.48.1 92