Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support members in a Doxygen 1.9.7 group #934

Draft
wants to merge 69 commits into
base: main
Choose a base branch
from

Conversation

JasperCraeghs
Copy link

@JasperCraeghs JasperCraeghs commented Jun 28, 2023

Needed to support XML output generated by Doxygen 1.9.7, which no longer contains duplicate member definitions (memberdef). The XML of the source file now contains a member reference (member) and only the XML of the group contains the member definition.

I tested these changes on large, internal projects that use Doxygen groups and the doxygenfunction directive. I also added a regression test: 5b23a92

I am not confident that all of the changes I made are strictly necessary.

Closes #923

@JasperCraeghs JasperCraeghs changed the title Support member references for members in group (Doxygen 1.9.7) Support members in a Doxygen 1.9.7 group Jun 28, 2023
@D4N
Copy link
Contributor

D4N commented Jul 23, 2023

I have tried your PR hoping to fix #935 as well, but instead building the documentation with make html fails differently with doxygen 1.9.7 on Fedora Rawhide:

> /builddir/build/BUILD/breathe-4.35.0/breathe/renderer/filter.py(351)__call__()                                                                                                             
-> return getattr(self.selector(node_stack), self.attribute_name)                                                                                                                            
(Pdb)                                                                                                                                                                                        
make[1]: Leaving directory '/builddir/build/BUILD/breathe-4.35.0/documentation'                                                                                                              
fatal: not a git repository (or any of the parent directories): .git                                                                                                                         
Exception occurred while building, starting debugger:                                                                                                                                        
Traceback (most recent call last):                                                                                                                                                           
  File "/usr/lib/python3.12/site-packages/sphinx/cmd/build.py", line 285, in build_main                                                                                                      
    app.build(args.force_all, args.filenames)                                                                                                                                                
  File "/usr/lib/python3.12/site-packages/sphinx/application.py", line 353, in build
    self.builder.build_update()
  File "/usr/lib/python3.12/site-packages/sphinx/builders/__init__.py", line 311, in build_update
    self.build(to_build,
  File "/usr/lib/python3.12/site-packages/sphinx/builders/__init__.py", line 328, in build
    updated_docnames = set(self.read())
                           ^^^^^^^^^^^
  File "/usr/lib/python3.12/site-packages/sphinx/builders/__init__.py", line 435, in read
    self._read_serial(docnames)
  File "/usr/lib/python3.12/site-packages/sphinx/builders/__init__.py", line 456, in _read_serial
    self.read_doc(docname)
  File "/usr/lib/python3.12/site-packages/sphinx/builders/__init__.py", line 512, in read_doc
    publisher.publish()
  File "/usr/lib/python3.12/site-packages/docutils/core.py", line 224, in publish
    self.document = self.reader.read(self.source, self.parser,
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/site-packages/sphinx/io.py", line 108, in read
    self.parse()
  File "/usr/lib/python3.12/site-packages/docutils/readers/__init__.py", line 76, in parse
    self.parser.parse(self.input, document)
  File "/usr/lib/python3.12/site-packages/sphinx/parsers.py", line 80, in parse
    self.statemachine.run(inputlines, document, inliner=self.inliner)
  File "/usr/lib/python3.12/site-packages/docutils/parsers/rst/states.py", line 169, in run
    results = StateMachineWS.run(self, input_lines, input_offset,
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/site-packages/docutils/statemachine.py", line 233, in run                                                                                                        
    context, next_state, result = self.check_line(
                                  ^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/site-packages/docutils/statemachine.py", line 445, in check_line
    return method(match, context, next_state)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/site-packages/docutils/parsers/rst/states.py", line 2785, in underline
    self.section(title, source, style, lineno - 1, messages)
  File "/usr/lib/python3.12/site-packages/docutils/parsers/rst/states.py", line 325, in section
    self.new_subsection(title, lineno, messages)
  File "/usr/lib/python3.12/site-packages/docutils/parsers/rst/states.py", line 391, in new_subsection
    newabsoffset = self.nested_parse(
                   ^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/site-packages/docutils/parsers/rst/states.py", line 279, in nested_parse
    state_machine.run(block, input_offset, memo=self.memo,
  File "/usr/lib/python3.12/site-packages/docutils/parsers/rst/states.py", line 195, in run
    results = StateMachineWS.run(self, input_lines, input_offset)
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/site-packages/docutils/statemachine.py", line 233, in run
    context, next_state, result = self.check_line(
                                  ^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/site-packages/docutils/statemachine.py", line 445, in check_line
    return method(match, context, next_state)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/site-packages/docutils/parsers/rst/states.py", line 2355, in explicit_markup
    nodelist, blank_finish = self.explicit_construct(match)
                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/site-packages/docutils/parsers/rst/states.py", line 2367, in explicit_construct
    return method(self, expmatch)
           ^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/site-packages/docutils/parsers/rst/states.py", line 2104, in directive
    return self.run_directive(
           ^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/site-packages/docutils/parsers/rst/states.py", line 2154, in run_directive
    result = directive_instance.run()
             ^^^^^^^^^^^^^^^^^^^^^^^^
  File "/builddir/build/BUILD/breathe-4.35.0/breathe/directives/content_block.py", line 74, in run
    contents_finder.filter_(filter_, contents)
  File "/builddir/build/BUILD/breathe-4.35.0/breathe/finder/factory.py", line 55, in filter_
    item_finder.filter_([_FakeParentNode()], filter_, matches)
  File "/builddir/build/BUILD/breathe-4.35.0/breathe/finder/index.py", line 48, in filter_
    member_finder.filter_(node_stack, filter_, member_matches)
  File "/builddir/build/BUILD/breathe-4.35.0/breathe/finder/index.py", line 69, in filter_
    if filter_.allow(node_stack):
       ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/builddir/build/BUILD/breathe-4.35.0/breathe/renderer/filter.py", line 524, in allow
    if filter_.allow(node_stack):
       ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/builddir/build/BUILD/breathe-4.35.0/breathe/renderer/filter.py", line 510, in allow
    if not filter_.allow(node_stack):
           ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/builddir/build/BUILD/breathe-4.35.0/breathe/renderer/filter.py", line 430, in allow
    name = self.accessor(node_stack)
           ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/builddir/build/BUILD/breathe-4.35.0/breathe/renderer/filter.py", line 351, in __call__
    return getattr(self.selector(node_stack), self.attribute_name)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AttributeError: 'MemberTypeSub' object has no attribute 'prot'

Fix mistake in spelling of inheritance
@JasperCraeghs
Copy link
Author

I can't find the cause of the error you reported. Does the error occur with Doxygen 1.9.8 as well?

@yselkowitz
Copy link

I see a different error with 1.9.8 built myself on Fedora rawhide:

/usr/bin/make -C documentation html
make[1]: Entering directory '/builddir/build/BUILD/breathe-4.35.0/documentation'
sphinx-build -b html -P -d build/doctrees  -v -W -E source build/html
Running Sphinx v7.0.1
Using Doxygen v1.9.8
Adding copy buttons to code blocks...
making output directory... done
locale_dir /builddir/build/BUILD/breathe-4.35.0/documentation/source/locales/en/LC_MESSAGES does not exists
locale_dir /builddir/build/BUILD/breathe-4.35.0/documentation/source/locales/en/LC_MESSAGES does not exists
building [mo]: targets for 0 po files that are out of date
writing output... 
building [html]: targets for 41 source files that are out of date
updating environment: locale_dir /builddir/build/BUILD/breathe-4.35.0/documentation/source/locales/en/LC_MESSAGES does not exists
[new config] 41 added, 0 changed, 0 removed
reading sources... [  2%] autofile
reading sources... [  4%] autoindex
reading sources... [  7%] class
reading sources... [  9%] codeblocks
reading sources... [ 12%] codeguide
reading sources... [ 14%] concept
reading sources... [ 17%] contributing
reading sources... [ 19%] credits
reading sources... [ 21%] customcss
reading sources... [ 24%] define
reading sources... [ 26%] differences
reading sources... [ 29%] directives
reading sources... [ 31%] domains
reading sources... [ 34%] dot_graphs
reading sources... [ 36%] doxygen
reading sources... [ 39%] embeddedrst
reading sources... [ 41%] enum
reading sources... [ 43%] enumvalue
reading sources... [ 46%] file
reading sources... [ 48%] function
reading sources... [ 51%] group
reading sources... [ 53%] groups
reading sources... [ 56%] index
reading sources... [ 58%] inline
reading sources... [ 60%] latexmath
reading sources... [ 63%] lists
reading sources... [ 65%] markups
reading sources... [ 68%] members
reading sources... [ 70%] namespace
reading sources... [ 73%] page
reading sources... [ 75%] quickstart
reading sources... [ 78%] readthedocs
reading sources... [ 80%] specific
reading sources... [ 82%] struct
reading sources... [ 85%] tables
reading sources... [ 87%] template
reading sources... [ 90%] testpages
reading sources... [ 92%] tinyxml
reading sources... [ 95%] typedef
reading sources... [ 97%] union
reading sources... [100%] variable

> /usr/lib/python3.12/site-packages/sphinx/util/logging.py(424)filter()
-> raise exc
(Pdb) 
make[1]: Leaving directory '/builddir/build/BUILD/breathe-4.35.0/documentation'

RPM build errors:
fatal: not a git repository (or any of the parent directories): .git
Exception occurred while building, starting debugger:
Traceback (most recent call last):
  File "/usr/lib/python3.12/site-packages/sphinx/cmd/build.py", line 285, in build_main
    app.build(args.force_all, args.filenames)
  File "/usr/lib/python3.12/site-packages/sphinx/application.py", line 351, in build
    self.builder.build_update()
  File "/usr/lib/python3.12/site-packages/sphinx/builders/__init__.py", line 294, in build_update
    self.build(to_build,
  File "/usr/lib/python3.12/site-packages/sphinx/builders/__init__.py", line 310, in build
    with logging.pending_warnings():
  File "/usr/lib64/python3.12/contextlib.py", line 144, in __exit__
    next(self.gen)
  File "/usr/lib/python3.12/site-packages/sphinx/util/logging.py", line 219, in pending_warnings
    memhandler.flushTo(logger)
  File "/usr/lib/python3.12/site-packages/sphinx/util/logging.py", line 184, in flushTo
    logger.handle(record)
  File "/usr/lib64/python3.12/logging/__init__.py", line 1700, in handle
    self.callHandlers(record)
  File "/usr/lib64/python3.12/logging/__init__.py", line 1762, in callHandlers
    hdlr.handle(record)
  File "/usr/lib64/python3.12/logging/__init__.py", line 1022, in handle
    rv = self.filter(record)
         ^^^^^^^^^^^^^^^^^^^
  File "/usr/lib64/python3.12/logging/__init__.py", line 858, in filter
    result = f.filter(record)
             ^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/site-packages/sphinx/util/logging.py", line 424, in filter
    raise exc
sphinx.errors.SphinxWarning: /builddir/build/BUILD/breathe-4.35.0/documentation/source/specific.rst:195:Invalid C++ declaration: Expected identifier in nested name. [error at 0]
  
  ^
make[1]: *** [Makefile:56: html] Error 2

@JasperCraeghs JasperCraeghs marked this pull request as draft November 1, 2023 11:25
@JasperCraeghs
Copy link
Author

@D4N I fixed the issue you reported. Thank you for catching and reporting it!

@yselkowitz I'm pretty sure you didn't use the changes in this PR.

Doxygen 1.9.8 is similar to 1.9.7 concerning the changes that are needed to support members in a Doxygen group.

This PR does not resolve #935.

@JasperCraeghs
Copy link
Author

@michaeljones Can you please review this pull request?

@JasperCraeghs JasperCraeghs marked this pull request as ready for review November 1, 2023 16:21
@michaeljones
Copy link
Collaborator

I appreciate you've put effort in here but unfortunately I'm not very active on this project at the moment. We're looking for the project to be better funded. Other maintainers might have time to assess this and do the necessary follow up work.

@JasperCraeghs
Copy link
Author

JasperCraeghs commented Dec 21, 2023

I have a C function MinLengthCheck that is added to two different Doxygen subgroups, once in the .c file and once in the .h files. The function is documented by Doxygen>=1.9.7 in two group__*.xml files with an identical memberdef element. This results in the following warning:

doc/source/generated/example.txt:126: WARNING: doxygenfunction: Unable to resolve function "MinLengthCheck" with arguments None in doxygen xml output for project "my-lib" from directory: /home/developer/repo/build/doc/doxygen_xml/my-lib/xml.
Potential matches:
- bool MinLengthCheck(MyConfig_t *config, uint8_t minimum_length)
- bool MinLengthCheck(MyConfig_t *config, uint8_t minimum_length)

These two matches have the same signature. I am unsure how to best resolve this issue. Suggestions are welcome.

@JasperCraeghs
Copy link
Author

JasperCraeghs commented Dec 21, 2023

I resolved the issue I raised above by checking if the signatures of the results are identical. If they are, return the first result instead of raising a warning. Done in 5c3b6fb and 5f5f7ce.

@JasperCraeghs
Copy link
Author

@Rouslan I kindly invite you to merge your #967 into this PR and resolve the merge conflicts. Please let me know whether you're up for it or not. When that's done, I can test your contribution in our internal projects. It's very much possible that some of my changes in this PR are not optimal. Feel free to make drastic changes. I'm sure that you have more knowledge about the internals of breathe than I do.

@michaeljones The company I work for, Melexis, has planned to make several one-time payments to fund breathe and sponsor Sphinx separately on a monthly basis. We are on the waitlist of GitHub's beta program for sponsorship via invoice.

@Rouslan
Copy link

Rouslan commented Feb 8, 2024

I'll do it. It might take a little while because your changes are mostly in parts that have been rewritten, so I'll need to rewrite your code too.

@Rouslan
Copy link

Rouslan commented Feb 10, 2024

I might be doing something wrong, but I can't seem to push to the fork. Despite having accepted the invitation to act as a collaborator, each time I try to push, I get a message saying:

remote: Permission to JasperCraeghs/breathe.git denied to Rouslan.
fatal: unable to access 'https://github.com/JasperCraeghs/breathe.git/': The requested URL returned error: 403

Any idea as to what could be the problem?

@Rouslan
Copy link

Rouslan commented Feb 11, 2024

I created a pull request as a workaround and approved it myself.

Anyway, I'm still a bit hazy on how some of the parts of Breathe fit together so I'm not confident that I didn't break anything. If you find any bugs, don't hesitate to tell me. I removed the change you made to the documentation and turned it into a proper test. Now that Doxygen 1.9.7 is tested in the Github Actions, in addition to 1.9.4, one of the tests I added fails due to the issue described in #935.

@JasperCraeghs
Copy link
Author

It works in my projects. Thank you so much!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

doxygenfunction: Cannot find function
6 participants