[gobject-introspection: 8/30] devdocs: Don't render private fields



commit 2635fb9fa3e223ae299a4306acf9dc85c6745637
Author: Philip Chimento <philip chimento gmail com>
Date:   Sat Dec 12 18:13:56 2015 -0800

    devdocs: Don't render private fields
    
    Skip private fields such as "priv" and "parent_instance". Unfortunately
    not all private structure and parent instance fields are marked private,
    and not all of them are named "priv" or "parent_instance".
    
    This also includes fields that are contained within anonymous unions.

 giscanner/doctemplates/devdocs/Gjs/_index.tmpl | 26 +++++++++++++++++----
 giscanner/docwriter.py                         | 31 ++++++++++++++++++++++++++
 2 files changed, 53 insertions(+), 4 deletions(-)
---
diff --git a/giscanner/doctemplates/devdocs/Gjs/_index.tmpl b/giscanner/doctemplates/devdocs/Gjs/_index.tmpl
index 8d45e871..6f5e9729 100644
--- a/giscanner/doctemplates/devdocs/Gjs/_index.tmpl
+++ b/giscanner/doctemplates/devdocs/Gjs/_index.tmpl
@@ -3,16 +3,34 @@
   if isinstance(node, ast.Class):
     ancestors = formatter.get_inheritable_types(node)
 
+  fields = getattr(node, 'fields', [])
+  extra_fields = [getattr(f.anonymous_node, 'fields', []) for f in fields
+    if f.anonymous_node is not None]
+  extra_fields = [field for sublist in extra_fields for field in sublist]
+  non_private_fields = [f for f in fields + extra_fields
+      if not formatter.is_private_field(node, f)]
+
   def get_ancestor_counts(*kinds):
     counts = {}
     for a in ancestors:
-      count = sum([len(getattr(a, kind, [])) for kind in kinds])
+      count = 0
+      for kind in kinds:
+        if kind == 'fields':
+          count += len(non_private_fields)
+        else:
+          count += len(getattr(a, kind, []))
       if count:
         counts[a] = count
     return counts
 
   def should_render(*kinds):
-    has_nonempty = any([getattr(node, kind, []) for kind in kinds])
+    has_nonempty = False
+    for kind in kinds:
+      if kind == 'fields':
+        if non_private_fields:
+          has_nonempty = True
+      elif getattr(node, kind, []):
+        has_nonempty = True
     return has_nonempty or get_ancestor_counts(*kinds)
 %>
 
@@ -125,7 +143,7 @@
 % if should_render('fields'):
   <h2 id="index-fields">Fields</h2>
   ${inherited('fields')}
-  % if getattr(node, 'fields', []):
+  % if non_private_fields:
     <table>
       <thead>
         <tr>
@@ -136,7 +154,7 @@
         </tr>
       </thead>
       <tbody>
-      % for f in node.fields:
+      % for f in non_private_fields:
         <tr>
           <td><span class="entry" href="#${formatter.make_anchor(f)}">${f.name}</span></td>
           <td>${formatter.format_type(f.type)}</td>
diff --git a/giscanner/docwriter.py b/giscanner/docwriter.py
index d17e8700..e1d3149e 100644
--- a/giscanner/docwriter.py
+++ b/giscanner/docwriter.py
@@ -543,6 +543,37 @@ class DocFormatter(object):
         types += [t for t in parent_chain if t is not node]
         return types
 
+    def is_private_field(self, node, f):
+        """Returns whether @f is a private field of @node (including a heuristic
+        that tries to determine whether the field is the parent instance field
+        or a private pointer but not marked as such.)"""
+
+        if f.private:
+            return True
+        if f.anonymous_node:
+            return True
+        if f.name == 'g_type_instance':
+            return True  # this field on GObject is not exposed
+
+        field_typenode = self._transformer.lookup_typenode(f.type)
+        if not field_typenode:
+            return False
+
+        if getattr(field_typenode, 'disguised', False):
+            return True  # guess that it's a pointer to a private struct
+            # this also catches fields of type GdkAtom, since that is disguised
+            # as well. Not sure whether that's correct or not.
+
+        if not isinstance(node, ast.Class):
+            return False  # parent instance heuristics only apply to classes
+
+        if node.parent_type:
+            parent_typenode = self._transformer.lookup_typenode(node.parent_type)
+            if field_typenode == parent_typenode:
+                return True  # guess that it's a parent instance field
+
+        return False
+
     def format_prerequisites(self, node):
         assert isinstance(node, ast.Interface)
 


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