···
+
From 7b2d3699ad117199bc316c7007cc5984c3b09368 Mon Sep 17 00:00:00 2001
+
From: Maximiliano Sandoval <msandova@gnome.org>
+
Date: Thu, 20 Mar 2025 22:52:54 +0100
+
Subject: [PATCH] scanner: Prefer some getters over others
+
At the moment the current set of heuristics to determine a getter for a
+
property is good for finding *a* getter. However, if there are multiple
+
candidates we might declare the wrong method as a getter.
+
We introduce a priority system to determine which getter candidate is
+
the most appropriate as the getter. The weight were chosen with gaps in
+
between so that new and better heuristics have space to thrive.
+
For a property named `p`, these are the possible getter candidates:
+
- A method declared via the `(getter p)` annotation
+
we declare the getter to be the first candidate in the list for which a
+
method of the same name is available.
+
See https://gitlab.gnome.org/GNOME/gjs/-/issues/681.
+
giscanner/maintransformer.py | 22 +++++++++++++++-------
+
1 file changed, 15 insertions(+), 7 deletions(-)
+
diff --git a/giscanner/maintransformer.py b/giscanner/maintransformer.py
+
index a81b1777..9aaf2578 100644
+
--- a/giscanner/maintransformer.py
+
+++ b/giscanner/maintransformer.py
+
@@ -1612,7 +1612,10 @@ method or constructor of some type."""
+
if not prop.introspectable:
+
+ # They keys are method names of candidates for getters. The values
+
+ # are priority weights that measure how tasteful was the heuristic
+
+ # used to propose their candidate.
+
if prop.setter is None:
+
if prop.writable and not prop.construct_only:
+
setter = 'set_' + normalized_name
+
@@ -1620,17 +1623,17 @@ method or constructor of some type."""
+
if prop.getter is None:
+
- getter = ['get_' + normalized_name]
+
+ getter[f"get_{normalized_name}"] = 50
+
# Heuristic: boolean properties can have getters that are
+
# prefixed by is_property_name, like: gtk_window_is_maximized()
+
if prop.type.is_equiv(ast.TYPE_BOOLEAN) and not normalized_name.startswith("is_"):
+
- getter.append(f"is_{normalized_name}")
+
+ getter[f"is_{normalized_name}"] = 25
+
# Heuristic: read-only properties can have getters that are
+
# just the property name, like: gtk_widget_has_focus()
+
if not prop.writable and prop.type.is_equiv(ast.TYPE_BOOLEAN):
+
- getter.append(normalized_name)
+
+ getter[normalized_name] = 10
+
- getter = [prop.getter]
+
+ getter[prop.getter] = 99
+
for method in node.methods:
+
if not method.introspectable:
+
@@ -1645,7 +1648,7 @@ method or constructor of some type."""
+
method.set_property = prop.name
+
prop.setter = method.name
+
- if getter is not [] and method.name in getter:
+
+ if getter is not {} and method.name in getter:
+
if method.get_property is None:
+
method.get_property = prop.name
+
elif method.get_property != prop.name:
+
@@ -1654,7 +1657,12 @@ method or constructor of some type."""
+
"mismatched '(get-property %s)' annotation" %
+
(method.symbol, prop.name, method.get_property))
+
method.get_property = prop.name
+
- prop.getter = method.name
+
+ # Check the priority of the last matching getter
+
+ current_priority = -1
+
+ if current_getter := prop.getter:
+
+ current_priority = getter.get(current_getter, -1)
+
+ if getter[method.name] >= current_priority:
+
+ prop.getter = method.name
+
def _pass_member_numeric_name(self, node):