Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
doc: add a autodoxyvar directive
authorMartin Quinson <martin.quinson@ens-rennes.fr>
Sun, 10 Nov 2019 16:59:08 +0000 (17:59 +0100)
committerMartin Quinson <martin.quinson@ens-rennes.fr>
Sun, 10 Nov 2019 18:09:06 +0000 (19:09 +0100)
There is too much shared content between this directive and the
autodoxymethod, but I'm getting tired of that game.

docs/find-missing.py
docs/source/_ext/autodoxy/autodoxy/__init__.py
docs/source/_ext/autodoxy/autodoxy/autodoxy.py

index d6f80db..471dce2 100755 (executable)
@@ -176,6 +176,20 @@ with os.popen('grep autodoxymethod:: source/*rst|sed \'s/^.*autodoxymethod:: //\
             doxy_funs[klass][obj].remove(args)
             if len(doxy_funs[klass][obj]) == 0:
                 del doxy_funs[klass][obj]
+with os.popen('grep autodoxyvar:: source/*rst|sed \'s/^.*autodoxyvar:: //\'') as pse:
+    for line in (l.strip() for l in pse):
+        (klass, var) = line.rsplit('::', 1)
+
+        if not klass in doxy_vars:
+            print("Warning: {} documented, but class {} not found in doxygen.".format(line, klass))
+            continue
+        if not var in doxy_vars[klass]:
+            print("Warning: Object {} documented but not found in {}".format(line, klass))
+        else:
+#            print("Found {} in {}".format(line, klass))
+            doxy_vars[klass].remove(var)
+            if len(doxy_funs[klass]) == 0:
+                del doxy_funs[klass]
 
 # Dump the undocumented Doxygen declarations 
 for obj in doxy_funs:
@@ -185,5 +199,5 @@ for obj in doxy_funs:
 
 for obj in doxy_vars:
     for meth in doxy_vars[obj]:
-        print("Missing decl: .. autodoxyfield:: {}::{}".format(obj, meth))
+        print("Missing decl: .. autodoxyvar:: {}::{}".format(obj, meth))
 
index 3e06d7b..232dfc9 100644 (file)
@@ -37,7 +37,7 @@ def get_doxygen_root():
 
 def setup(app):
     import sphinx.ext.autosummary
-    from autodoxy.autodoxy import DoxygenClassDocumenter, DoxygenMethodDocumenter
+    from autodoxy.autodoxy import DoxygenClassDocumenter, DoxygenMethodDocumenter, DoxygenVariableDocumenter
     from autodoxy.autosummary import DoxygenAutosummary, DoxygenAutoEnum
     from autodoxy.autosummary.generate import process_generate_options
 
@@ -49,6 +49,7 @@ def setup(app):
 
     app.add_autodocumenter(DoxygenClassDocumenter)
     app.add_autodocumenter(DoxygenMethodDocumenter)
+    app.add_autodocumenter(DoxygenVariableDocumenter)
     app.add_config_value("doxygen_xml", "", True)
 
     app.add_directive('autodoxysummary', DoxygenAutosummary)
index af8c96f..fd7537c 100644 (file)
@@ -183,7 +183,6 @@ class DoxygenClassDocumenter(DoxygenDocumenter):
         # Uncomment to view the generated rst for the class.
         # print('\n'.join(self.directive.result))
 
-
 class DoxygenMethodDocumenter(DoxygenDocumenter):
     objtype = 'doxymethod'
     directivetype = 'function'
@@ -280,3 +279,86 @@ class DoxygenMethodDocumenter(DoxygenDocumenter):
 
     def document_members(self, all_members=False):
         pass
+
+class DoxygenVariableDocumenter(DoxygenDocumenter):
+    objtype = 'doxyvar'
+    directivetype = 'var'
+    domain = 'cpp'
+    priority = 100
+
+    @classmethod
+    def can_document_member(cls, member, membername, isattr, parent):
+        if ET.iselement(member) and member.tag == 'memberdef' and member.get('kind') == 'variable':
+            return True
+        return False
+
+    def import_object(self):
+        if ET.iselement(self.object):
+            # self.object already set from DoxygenDocumenter.parse_name(),
+            # caused by passing in the `id` of the node instead of just a
+            # classname or method name
+            return True
+
+        (obj, var) = self.fullname.rsplit('::', 1)
+
+        xpath_query = ('.//compoundname[text()="{:s}"]/../sectiondef[@kind="public-attrib" or @kind="public-static-attrib"]'
+                       '/memberdef[@kind="variable"]/name[text()="{:s}"]/..').format(obj, var)
+#        print("fullname {}".format(self.fullname))
+        match = get_doxygen_root().xpath(xpath_query)
+        if len(match) == 0:
+            logger = logging.getLogger(__name__)
+
+            logger.warning("[autodoxy] WARNING: could not find variable {}::{} in Doxygen files".format(obj, var))
+            return False
+        self.object = match[0]
+        return True
+
+    def parse_id(self, id):
+        xp = './/*[@id="%s"]' % id
+        match = get_doxygen_root().xpath(xp)
+        if len(match) > 0:
+            match = match[0]
+            self.fullname = match.find('./definition').text.split()[-1]
+            self.modname = self.fullname
+            self.objname = match.find('./name').text
+            self.object = match
+        return False
+
+    def format_name(self):
+        def text(el):
+            if el.text is not None:
+                return el.text
+            return ''
+
+        def tail(el):
+            if el.tail is not None:
+                return el.tail
+            return ''
+
+        rtype_el = self.object.find('type')
+        rtype_el_ref = rtype_el.find('ref')
+        if rtype_el_ref is not None:
+            rtype = text(rtype_el) + text(rtype_el_ref) + tail(rtype_el_ref)
+        else:
+            rtype = rtype_el.text
+
+ #       print("rtype: {}".format(rtype))
+        signame = (rtype and (rtype + ' ') or '') + self.objname
+        return self.format_template_name() + signame
+
+    def get_doc(self, encoding):
+        detaileddescription = self.object.find('detaileddescription')
+        doc = [format_xml_paragraph(detaileddescription)]
+        return doc
+
+    def format_template_name(self):
+        types = [e.text for e in self.object.findall('templateparamlist/param/type')]
+        if len(types) == 0:
+            return ''
+        ret = 'template <%s>' % ','.join(types)
+#        print ("template: {}".format(ret))
+        return ret
+
+    def document_members(self, all_members=False):
+        pass
+