From 81d0f69f7cb76b9a77a9638711095800f3f1d05b Mon Sep 17 00:00:00 2001 From: Martin Quinson Date: Sun, 10 Nov 2019 17:59:08 +0100 Subject: [PATCH] doc: add a autodoxyvar directive There is too much shared content between this directive and the autodoxymethod, but I'm getting tired of that game. --- docs/find-missing.py | 16 +++- .../source/_ext/autodoxy/autodoxy/__init__.py | 3 +- .../source/_ext/autodoxy/autodoxy/autodoxy.py | 84 ++++++++++++++++++- 3 files changed, 100 insertions(+), 3 deletions(-) diff --git a/docs/find-missing.py b/docs/find-missing.py index d6f80db963..471dce250b 100755 --- a/docs/find-missing.py +++ b/docs/find-missing.py @@ -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)) diff --git a/docs/source/_ext/autodoxy/autodoxy/__init__.py b/docs/source/_ext/autodoxy/autodoxy/__init__.py index 3e06d7bfbf..232dfc91b4 100644 --- a/docs/source/_ext/autodoxy/autodoxy/__init__.py +++ b/docs/source/_ext/autodoxy/autodoxy/__init__.py @@ -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) diff --git a/docs/source/_ext/autodoxy/autodoxy/autodoxy.py b/docs/source/_ext/autodoxy/autodoxy/autodoxy.py index af8c96fbc7..fd7537cd93 100644 --- a/docs/source/_ext/autodoxy/autodoxy/autodoxy.py +++ b/docs/source/_ext/autodoxy/autodoxy/autodoxy.py @@ -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 + -- 2.20.1