scanner: Filter interface prerequisites and class implements for unknown types
authorColin Walters <walters@verbum.org>
Wed, 25 Aug 2010 21:50:54 +0000 (17:50 -0400)
committerColin Walters <walters@verbum.org>
Tue, 31 Aug 2010 20:05:58 +0000 (16:05 -0400)
This works around the hidden GtkFileChooserEmbed interface of GtkFileChooserWidget.

giscanner/introspectablepass.py
giscanner/maintransformer.py
giscanner/transformer.py

index a880912..61604b1 100644 (file)
@@ -156,4 +156,6 @@ class IntrospectablePass(object):
             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
index a7cc615..30b087d 100644 (file)
@@ -621,6 +621,17 @@ class MainTransformer(object):
             self._transformer.log_symbol_warning(node.symbol,
                 "Virtual slot %r not found for %r annotation" % (invoker_name, TAG_VFUNC))
 
+    def _resolve_and_filter_type_list(self, typelist):
+        """Given a list of Type instances, return a new list of types with
+the ones that failed to resolve removed."""
+        # Create a copy we'll modify
+        new_typelist = list(typelist)
+        for typeval in typelist:
+            resolved = self._transformer.resolve_type(typeval)
+            if not resolved:
+                new_typelist.remove(typeval)
+        return new_typelist
+
     def _pass_type_resolution(self, node, chain):
         if isinstance(node, ast.Alias):
             self._transformer.resolve_type(node.target)
@@ -648,18 +659,19 @@ class MainTransformer(object):
                     node.parent = parent
                     break
             else:
-                node.parent = ast.Type(target_giname='GObject.Object')
+                if isinstance(node, ast.Interface) or not node.fundamental:
+                    node.parent = ast.Type(target_giname='GObject.Object')
+                else:
+                    node.parent = None
             for prop in node.properties:
                 self._transformer.resolve_type(prop.type)
             for sig in node.signals:
                 for param in sig.parameters:
                     self._transformer.resolve_type(param.type)
         if isinstance(node, ast.Class):
-            for iface in node.interfaces:
-                self._transformer.resolve_type(iface)
+            node.interfaces = self._resolve_and_filter_type_list(node.interfaces)
         if isinstance(node, ast.Interface):
-            for iface in node.prerequisites:
-                self._transformer.resolve_type(iface)
+            node.prerequisites = self._resolve_and_filter_type_list(node.prerequisites)
         return True
 
     def _resolve_quarks(self):
index 0eb129c..647dde7 100644 (file)
@@ -759,7 +759,9 @@ it is always biggest (i.e. last)."""
     def create_type_from_user_string(self, typestr):
         """Parse a C type string (as might be given from an
         annotation) and resolve it.  For compatibility, we can consume
-both GI type string (utf8, Foo.Bar) style, as well as C (char *, FooBar) style."""
+both GI type string (utf8, Foo.Bar) style, as well as C (char *, FooBar) style.
+
+Note that type resolution may not succeed."""
         if '.' in typestr:
             container = self._create_bare_container_type(typestr)
             if container:
@@ -784,18 +786,18 @@ both GI type string (utf8, Foo.Bar) style, as well as C (char *, FooBar) style."
                 target = namespace.get_by_ctype(pointer_stripped)
             if target:
                 typeval.target_giname = '%s.%s' % (namespace.name, target.name)
-                return
+                return True
+        return False
 
     def resolve_type(self, typeval):
         if isinstance(typeval, (ast.Array, ast.List)):
-            self.resolve_type(typeval.element_type)
-            return
+            return self.resolve_type(typeval.element_type)
         elif isinstance(typeval, ast.Map):
-            self.resolve_type(typeval.key_type)
-            self.resolve_type(typeval.value_type)
-            return
+            key_resolved = self.resolve_type(typeval.key_type)
+            value_resolved = self.resolve_type(typeval.value_type)
+            return key_resolved and value_resolved
         elif typeval.resolved:
-            return
+            return True
         elif typeval.ctype:
             return self._resolve_type_from_ctype(typeval)