[gobject-introspection/ebassi/property-annotation] Ignore accessor annotations for non-introspectable properties



commit 18f04d8e4f1eaf511655622d9c58b9652d9b8413
Author: Emmanuele Bassi <ebassi gnome org>
Date:   Tue Jul 27 14:47:15 2021 +0100

    Ignore accessor annotations for non-introspectable properties
    
    If a property is not introspectable we need to decouple it from its
    accessors; the property data will not be compiled into the typelib,
    and when the compiler will try to resolve the offsets into the binary
    blob we'll get a fatal exception.

 giscanner/introspectablepass.py | 28 +++++++++++++++++++++++++---
 giscanner/maintransformer.py    |  4 ++++
 2 files changed, 29 insertions(+), 3 deletions(-)
---
diff --git a/giscanner/introspectablepass.py b/giscanner/introspectablepass.py
index e2056b42..305e192e 100644
--- a/giscanner/introspectablepass.py
+++ b/giscanner/introspectablepass.py
@@ -37,6 +37,7 @@ class IntrospectablePass(object):
         self._namespace.walk(self._analyze_node)
         self._namespace.walk(self._introspectable_callable_analysis)
         self._namespace.walk(self._introspectable_callable_analysis)
+        self._namespace.walk(self._introspectable_property_analysis)
         self._namespace.walk(self._introspectable_pass3)
         self._namespace.walk(self._remove_non_reachable_backcompat_copies)
 
@@ -209,6 +210,30 @@ class IntrospectablePass(object):
                 return True
         return True
 
+    def _introspectable_property_analysis(self, obj, stack):
+        if obj.skip:
+            return False
+        if isinstance(obj, (ast.Class, ast.Interface)):
+            for prop in obj.properties:
+                if not self._type_is_introspectable(prop.type):
+                    prop.introspectable = False
+                    prop.setter = None
+                    prop.getter = None
+            for method in obj.methods:
+                set_property = method.set_property
+                if set_property is not None:
+                    for prop in obj.properties:
+                        if prop.name == set_property and not prop.introspectable:
+                            method.set_property = None
+                            break
+                get_property = method.get_property
+                if get_property is not None:
+                    for prop in obj.properties:
+                        if prop.name == get_property and not prop.introspectable:
+                            method.get_property = None
+                            break
+        return True
+
     def _introspectable_pass3(self, obj, stack):
         if obj.skip:
             return False
@@ -223,9 +248,6 @@ class IntrospectablePass(object):
                         field.introspectable = False
         # Propagate introspectability for properties
         if isinstance(obj, (ast.Class, ast.Interface)):
-            for prop in obj.properties:
-                if not self._type_is_introspectable(prop.type):
-                    prop.introspectable = False
             for sig in obj.signals:
                 self._introspectable_callable_analysis(sig, [obj])
         return True
diff --git a/giscanner/maintransformer.py b/giscanner/maintransformer.py
index 4e4a5573..3da86797 100644
--- a/giscanner/maintransformer.py
+++ b/giscanner/maintransformer.py
@@ -1466,6 +1466,8 @@ method or constructor of some type."""
     def _pair_property_accessors(self, node):
         """Look for accessor methods for class properties"""
         for prop in node.properties:
+            if not prop.introspectable:
+                continue
             if prop.setter is None:
                 normalized_name = prop.name.replace('-', '_')
                 if prop.writable and not prop.construct_only:
@@ -1486,6 +1488,8 @@ method or constructor of some type."""
             else:
                 getter = [prop.getter]
             for method in node.methods:
+                if not method.introspectable:
+                    continue
                 if setter is not None and method.name == setter:
                     if method.set_property is None:
                         method.set_property = prop.name


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