[gobject-introspection/ebassi/property-annotation: 32/33] scanner: Try to pair properties with accessor methods




commit 1d24c86a789b60ab2c31284e8b396b8196ccf1da
Author: Emmanuele Bassi <ebassi gnome org>
Date:   Thu Jun 17 18:05:09 2021 +0100

    scanner: Try to pair properties with accessor methods
    
    The heuristic is pretty trivial: for any given non-construct-only,
    writable property, we check if there's a `set_<property>` method; for
    any given readable property, we check if there's a `get_<property>`
    method.

 giscanner/maintransformer.py           | 21 +++++++++++++++++++++
 tests/scanner/Regress-1.0-expected.gir | 11 +++++++++--
 2 files changed, 30 insertions(+), 2 deletions(-)
---
diff --git a/giscanner/maintransformer.py b/giscanner/maintransformer.py
index 33f58485..dc8bd3c2 100644
--- a/giscanner/maintransformer.py
+++ b/giscanner/maintransformer.py
@@ -92,6 +92,7 @@ class MainTransformer(object):
                 self._pair_function(node)
             if isinstance(node, (ast.Class, ast.Interface)):
                 self._pair_class_virtuals(node)
+                self._pair_property_accessors(node)
 
         # Some annotations need to be post function pairing
         self._namespace.walk(self._pass_read_annotations2)
@@ -1462,6 +1463,26 @@ method or constructor of some type."""
                 self._apply_annotations_callable(vfunc, [], block)
                 break
 
+    def _pair_property_accessors(self, node):
+        """Look for accessor methods for class properties"""
+        for prop in node.properties:
+            normalized_name = prop.name.replace('-', '_')
+            if prop.writable and not prop.construct_only:
+                setter = 'set_' + normalized_name
+            else:
+                setter = None
+            if prop.readable:
+                getter = 'get_' + normalized_name
+            else:
+                getter = None
+            for method in node.methods:
+                if setter is not None and method.name == setter:
+                    prop.setter = method.name
+                    continue
+                if getter is not None and method.name == getter:
+                    prop.getter = method.name
+                    continue
+
     def _pass3(self, node, chain):
         """Pass 3 is after we've loaded GType data and performed type
         closure."""
diff --git a/tests/scanner/Regress-1.0-expected.gir b/tests/scanner/Regress-1.0-expected.gir
index bc8eb9f2..4786080e 100644
--- a/tests/scanner/Regress-1.0-expected.gir
+++ b/tests/scanner/Regress-1.0-expected.gir
@@ -4730,7 +4730,10 @@ raise an error.</doc>
           </parameter>
         </parameters>
       </method>
-      <property name="bare" writable="1" transfer-ownership="none">
+      <property name="bare"
+                writable="1"
+                transfer-ownership="none"
+                setter="set_bare">
         <type name="GObject.Object"/>
       </property>
       <property name="boxed" writable="1" transfer-ownership="none">
@@ -5679,7 +5682,11 @@ the introspection client langage.</doc>
           </parameter>
         </parameters>
       </method>
-      <property name="testbool" writable="1" transfer-ownership="none">
+      <property name="testbool"
+                writable="1"
+                transfer-ownership="none"
+                setter="set_testbool"
+                getter="get_testbool">
         <type name="gboolean" c:type="gboolean"/>
       </property>
       <field name="parent_instance">


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