diff --git a/documentation/doxygen.py b/documentation/doxygen.py index d2f4956e4..a4612ff70 100755 --- a/documentation/doxygen.py +++ b/documentation/doxygen.py @@ -3020,6 +3020,33 @@ def parse_xml(state: State, xml: str): # Other, grouped in sections elif compounddef_child.tag == 'sectiondef': + # If grouping is used in the documentation, Doxygen 1.9.7+ no + # longer puts the whole info into file and namespace + # docs, but instead only references, forcing the parsers + # to look for the identifier in other XML files. + # + # The reason for this, as discussed in the linked PR, is because + # some random downstream project failed due to encountering + # duplicate IDs (which are there for file/namespace members also, + # by the way! or for relatedalso members!!). And Doxygen maintainer + # VERY HELPFULLY OFFERED TO CRIPPLE THE XML OUTPUT FOR EVERYONE + # ELSE just to fix that damn thing. Once I calm down I may try to + # convince them to revert this insanity, until then enjoy the + # crappy output. + # + # Also, yes, it may happen that there are combined and + # children. But handling that means adding the same damn + # piece of code, or some dumb filtering, to all branches below, + # just to counter a dumb decision. Nope. Nononono. + is_stupid = False + for memberdef in compounddef_child: + if memberdef.tag == 'member': + logging.warning("{}: sorry, parsing of non-self-contained XML not implemented: due to https://github.com/doxygen/doxygen/issues/8790 the output will not list file / namespace {} members".format(state.current, compounddef_child.attrib['kind'])) + is_stupid = True + break + if is_stupid: + continue + if compounddef_child.attrib['kind'] == 'enum': for memberdef in compounddef_child: enum = parse_enum(state, memberdef) diff --git a/documentation/test_doxygen/compound_includes/namespaceContained-stupid.html b/documentation/test_doxygen/compound_includes/namespaceContained-stupid.html new file mode 100644 index 000000000..01d6b3a68 --- /dev/null +++ b/documentation/test_doxygen/compound_includes/namespaceContained-stupid.html @@ -0,0 +1,105 @@ + + + + + Contained namespace | My Project + + + + + +
+
+
+
+
+

+ Contained namespace +
#include <First.h>
+

+

This namespace is contained in a single file.

+ +

So it has only the global include and no per-entry includes, thus also no detailed sections because there's only brief. (Unless the includes are disabled globally or the file is not documented.)

+
+

Enums

+
+
+ enum Enum { } +
+
An enum.
+
+
+
+

Typedefs

+
+
+ using Int1 = int +
+
A typedef.
+
+
+
+

Functions

+
+
+ void foo() +
+
A function.
+
+
+
+

Variables

+
+
+ const int Var constexpr +
+
A variable.
+
+
+
+

A group

+
+
+ enum Flag { } +
+
Flag in a group.
+
+ using Main = void +
+
Alias in a group.
+
+ void* variable constexpr +
+
Variable in a group.
+
+ void bar() +
+
Function in a group.
+
+
+
+
+
+
+ + diff --git a/documentation/test_doxygen/compound_includes_disabled/namespaceContained-stupid.html b/documentation/test_doxygen/compound_includes_disabled/namespaceContained-stupid.html new file mode 100644 index 000000000..044aeb3dc --- /dev/null +++ b/documentation/test_doxygen/compound_includes_disabled/namespaceContained-stupid.html @@ -0,0 +1,104 @@ + + + + + Contained namespace | My Project + + + + + +
+
+
+
+
+

+ Contained namespace +

+

This namespace is contained in a single file.

+ +

So it has only the global include and no per-entry includes, thus also no detailed sections because there's only brief. (Unless the includes are disabled globally or the file is not documented.)

+
+

Enums

+
+
+ enum Enum { } +
+
An enum.
+
+
+
+

Typedefs

+
+
+ using Int1 = int +
+
A typedef.
+
+
+
+

Functions

+
+
+ void foo() +
+
A function.
+
+
+
+

Variables

+
+
+ const int Var constexpr +
+
A variable.
+
+
+
+

A group

+
+
+ enum Flag { } +
+
Flag in a group.
+
+ using Main = void +
+
Alias in a group.
+
+ void* variable constexpr +
+
Variable in a group.
+
+ void bar() +
+
Function in a group.
+
+
+
+
+
+
+ + diff --git a/documentation/test_doxygen/compound_modules_in_namespace/file3_8h-stupid.html b/documentation/test_doxygen/compound_modules_in_namespace/file3_8h-stupid.html new file mode 100644 index 000000000..11a3fc905 --- /dev/null +++ b/documentation/test_doxygen/compound_modules_in_namespace/file3_8h-stupid.html @@ -0,0 +1,49 @@ + + + + + file3.h file | My Project + + + + + +
+
+
+
+
+

+ file3.h file +

+

Include file with some stuff that belongs to group 1 and group 2.

+ +
+

Namespaces

+
+
namespace Namespace
+
A namespace.
+
+
+
+
+
+
+ + diff --git a/documentation/test_doxygen/compound_modules_in_namespace/namespaceNamespace-stupid.html b/documentation/test_doxygen/compound_modules_in_namespace/namespaceNamespace-stupid.html new file mode 100644 index 000000000..3f1d12a7a --- /dev/null +++ b/documentation/test_doxygen/compound_modules_in_namespace/namespaceNamespace-stupid.html @@ -0,0 +1,32 @@ + + + + + Namespace namespace | My Project + + + + + +
+
+
+
+
+

+ Namespace namespace +

+

A namespace.

+

This is a namespace. It is spread across two files.

+
+
+
+
+ + diff --git a/documentation/test_doxygen/contents_anchor_in_both_group_and_namespace/namespaceFoo-stupid.html b/documentation/test_doxygen/contents_anchor_in_both_group_and_namespace/namespaceFoo-stupid.html new file mode 100644 index 000000000..aa4dd52b0 --- /dev/null +++ b/documentation/test_doxygen/contents_anchor_in_both_group_and_namespace/namespaceFoo-stupid.html @@ -0,0 +1,31 @@ + + + + + Foo namespace | My Project + + + + + +
+
+
+
+
+

+ Foo namespace +

+

Foo.

+
+
+
+
+ + diff --git a/documentation/test_doxygen/test_compound.py b/documentation/test_doxygen/test_compound.py index 4c8d53027..e945aea6d 100644 --- a/documentation/test_doxygen/test_compound.py +++ b/documentation/test_doxygen/test_compound.py @@ -158,8 +158,17 @@ def test(self): self.run_doxygen(wildcard='*.xml') self.assertEqual(*self.actual_expected_contents('group__group1.html')) self.assertEqual(*self.actual_expected_contents('group__group2.html')) - self.assertEqual(*self.actual_expected_contents('namespaceNamespace.html')) - self.assertEqual(*self.actual_expected_contents('file3_8h.html')) + + # The change in https://github.com/doxygen/doxygen/issues/8790 is + # stupid because the XML is no longer self-contained. I refuse to + # implement parsing of nested XMLs, so the output will lack some + # members if groups are used. + if parse_version(doxygen_version()) > parse_version("1.9.7"): + self.assertEqual(*self.actual_expected_contents('namespaceNamespace.html', 'namespaceNamespace-stupid.html')) + self.assertEqual(*self.actual_expected_contents('file3_8h.html', 'file3_8h-stupid.html')) + else: + self.assertEqual(*self.actual_expected_contents('namespaceNamespace.html')) + self.assertEqual(*self.actual_expected_contents('file3_8h.html')) class Deprecated(IntegrationTestCase): def test(self): @@ -248,7 +257,16 @@ def test(self): # group, even though in a single file, should have local includes; and # the SpreadClass struct is forward-declared in another file, which # triggers a silly Doxygen bug so it has per-member includes also - self.assertEqual(*self.actual_expected_contents('namespaceContained.html')) + + # The change in https://github.com/doxygen/doxygen/issues/8790 is + # stupid because the XML is no longer self-contained. I refuse to + # implement parsing of nested XMLs, so the output will lack some + # members if groups are used. + if parse_version(doxygen_version()) > parse_version("1.9.7"): + self.assertEqual(*self.actual_expected_contents('namespaceContained.html', 'namespaceContained-stupid.html')) + else: + self.assertEqual(*self.actual_expected_contents('namespaceContained.html')) + self.assertEqual(*self.actual_expected_contents('namespaceSpread.html')) self.assertEqual(*self.actual_expected_contents('classClass.html')) self.assertEqual(*self.actual_expected_contents('group__group.html')) @@ -266,7 +284,15 @@ def test(self): # No include information as SHOW_INCLUDE_FILES is disabled globally, # and no useless detailed sections either - self.assertEqual(*self.actual_expected_contents('namespaceContained.html')) + + # The change in https://github.com/doxygen/doxygen/issues/8790 is + # stupid because the XML is no longer self-contained. I refuse to + # implement parsing of nested XMLs, so the output will lack some + # members if groups are used. + if parse_version(doxygen_version()) > parse_version("1.9.7"): + self.assertEqual(*self.actual_expected_contents('namespaceContained.html', 'namespaceContained-stupid.html')) + else: + self.assertEqual(*self.actual_expected_contents('namespaceContained.html')) self.assertEqual(*self.actual_expected_contents('namespaceSpread.html')) self.assertEqual(*self.actual_expected_contents('classClass.html')) self.assertEqual(*self.actual_expected_contents('group__group.html')) @@ -279,7 +305,16 @@ def test(self): # The files are not documented, so there should be no include # information and no useless detailed sections either -- practically # the same output as when SHOW_INCLUDE_FILES is disabled globally - self.assertEqual(*self.actual_expected_contents('namespaceContained.html', '../compound_includes_disabled/namespaceContained.html')) + + # The change in https://github.com/doxygen/doxygen/issues/8790 is + # stupid because the XML is no longer self-contained. I refuse to + # implement parsing of nested XMLs, so the output will lack some + # members if groups are used. + if parse_version(doxygen_version()) > parse_version("1.9.7"): + self.assertEqual(*self.actual_expected_contents('namespaceContained.html', '../compound_includes_disabled/namespaceContained-stupid.html')) + else: + self.assertEqual(*self.actual_expected_contents('namespaceContained.html', '../compound_includes_disabled/namespaceContained.html')) + self.assertEqual(*self.actual_expected_contents('namespaceSpread.html', '../compound_includes_disabled/namespaceSpread.html')) self.assertEqual(*self.actual_expected_contents('classClass.html', '../compound_includes_disabled/classClass.html')) self.assertEqual(*self.actual_expected_contents('group__group.html', '../compound_includes_disabled/group__group.html')) diff --git a/documentation/test_doxygen/test_contents.py b/documentation/test_doxygen/test_contents.py index 3bc42a937..3c255154e 100644 --- a/documentation/test_doxygen/test_contents.py +++ b/documentation/test_doxygen/test_contents.py @@ -443,7 +443,16 @@ def test_warnings(self): class AnchorInBothGroupAndNamespace(IntegrationTestCase): def test(self): self.run_doxygen(wildcard='*.xml') - self.assertEqual(*self.actual_expected_contents('namespaceFoo.html')) + + # The change in https://github.com/doxygen/doxygen/issues/8790 is + # stupid because the XML is no longer self-contained. I refuse to + # implement parsing of nested XMLs, so the output will lack some + # members if groups are used. + if parse_version(doxygen_version()) > parse_version("1.9.7"): + self.assertEqual(*self.actual_expected_contents('namespaceFoo.html', 'namespaceFoo-stupid.html')) + else: + self.assertEqual(*self.actual_expected_contents('namespaceFoo.html')) + self.assertEqual(*self.actual_expected_contents('group__fizzbuzz.html')) class AnchorHtmlNoPrefixBug(IntegrationTestCase): diff --git a/documentation/test_doxygen/test_undocumented.py b/documentation/test_doxygen/test_undocumented.py index a35a1be4c..b4d83a423 100644 --- a/documentation/test_doxygen/test_undocumented.py +++ b/documentation/test_doxygen/test_undocumented.py @@ -29,7 +29,7 @@ from _search import Serializer, searchdata_filename -from . import IntegrationTestCase +from . import IntegrationTestCase, doxygen_version, parse_version class Undocumented(IntegrationTestCase): def test(self): @@ -43,9 +43,18 @@ def test(self): self.assertEqual(*self.actual_expected_contents('classClass.html')) # Namespace, dir, file, group and class member listing - self.assertEqual(*self.actual_expected_contents('namespaceNamespace.html')) + + # The change in https://github.com/doxygen/doxygen/issues/8790 is + # stupid because the XML is no longer self-contained. I refuse to + # implement parsing of nested XMLs, so the output will lack some + # members if groups are used. + if parse_version(doxygen_version()) > parse_version("1.9.7"): + self.assertEqual(*self.actual_expected_contents('namespaceNamespace.html', 'namespaceNamespace-stupid.html')) + self.assertEqual(*self.actual_expected_contents('File_8h.html', 'File_8h-stupid.html')) + else: + self.assertEqual(*self.actual_expected_contents('namespaceNamespace.html')) + self.assertEqual(*self.actual_expected_contents('File_8h.html')) self.assertEqual(*self.actual_expected_contents('dir_4b0d5f8864bf89936129251a2d32609b.html')) - self.assertEqual(*self.actual_expected_contents('File_8h.html')) self.assertEqual(*self.actual_expected_contents('group__group.html')) self.assertEqual(*self.actual_expected_contents('structNamespace_1_1ClassInANamespace.html')) @@ -55,4 +64,10 @@ def test(self): with open(os.path.join(self.path, 'html', searchdata_filename.format(search_filename_prefix='searchdata')), 'rb') as f: serialized = f.read() magic, version, type_data, symbol_count, map_offset, type_map_offset = Serializer.header_struct.unpack_from(serialized) - self.assertEqual(symbol_count, 44) + + # See above, it's because certain symbols got skipped due to + # stupidity + if parse_version(doxygen_version()) > parse_version("1.9.7"): + self.assertEqual(symbol_count, 28) + else: + self.assertEqual(symbol_count, 44) diff --git a/documentation/test_doxygen/undocumented/File_8h-stupid.html b/documentation/test_doxygen/undocumented/File_8h-stupid.html new file mode 100644 index 000000000..4b7df5c21 --- /dev/null +++ b/documentation/test_doxygen/undocumented/File_8h-stupid.html @@ -0,0 +1,183 @@ + + + + + Directory/File.h file | My Project + + + + + +
+
+
+
+
+

+ Directory/File.h file +

+

+ +
+

Namespaces

+
+
namespace Namespace
+
+
+
+
+

Classes

+
+
+ class Class +
+
+
+ struct Struct +
+
+
+ union Union +
+
+
+ struct Namespace::ClassInANamespace +
+
+
+ class Namespace::ClassInANamespace::ClassInAClass +
+
+
+ class Namespace::ClassInModule +
+
+
+ struct Namespace::StructInModule +
+
+
+ union Namespace::UnionInModule +
+
+
+
+
+

Defines

+
+
+ #define A_DEFINE +
+
+
+
+
+

A group

+
+
+ #define A_DEFINE_IN_A_GROUP +
+
+
+ enum FlagInAGroup { } +
+
+
+ using MainInAGroup = void +
+
+
+ void* variableInAGroup constexpr +
+
+
+ void barInAGroup() +
+
+
+
+
+
+
+
+ + + + + diff --git a/documentation/test_doxygen/undocumented/namespaceNamespace-stupid.html b/documentation/test_doxygen/undocumented/namespaceNamespace-stupid.html new file mode 100644 index 000000000..c9dea0343 --- /dev/null +++ b/documentation/test_doxygen/undocumented/namespaceNamespace-stupid.html @@ -0,0 +1,145 @@ + + + + + Namespace namespace | My Project + + + + + +
+
+ + + + +