Sphinx 7.2.5__py3-none-any.whl → 7.3.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of Sphinx might be problematic. Click here for more details.
- sphinx/__init__.py +8 -9
- sphinx/addnodes.py +31 -28
- sphinx/application.py +9 -15
- sphinx/builders/__init__.py +5 -6
- sphinx/builders/_epub_base.py +17 -9
- sphinx/builders/changes.py +10 -5
- sphinx/builders/dirhtml.py +4 -2
- sphinx/builders/dummy.py +3 -2
- sphinx/builders/epub3.py +5 -3
- sphinx/builders/gettext.py +24 -7
- sphinx/builders/html/__init__.py +88 -96
- sphinx/builders/html/_assets.py +16 -16
- sphinx/builders/html/transforms.py +4 -2
- sphinx/builders/latex/__init__.py +40 -33
- sphinx/builders/latex/nodes.py +6 -2
- sphinx/builders/latex/transforms.py +17 -8
- sphinx/builders/latex/util.py +1 -1
- sphinx/builders/linkcheck.py +86 -27
- sphinx/builders/manpage.py +8 -6
- sphinx/builders/singlehtml.py +5 -4
- sphinx/builders/texinfo.py +18 -14
- sphinx/builders/text.py +3 -2
- sphinx/builders/xml.py +5 -2
- sphinx/cmd/build.py +119 -76
- sphinx/cmd/make_mode.py +21 -20
- sphinx/cmd/quickstart.py +13 -16
- sphinx/config.py +432 -250
- sphinx/deprecation.py +23 -13
- sphinx/directives/__init__.py +8 -8
- sphinx/directives/code.py +7 -7
- sphinx/directives/other.py +23 -13
- sphinx/directives/patches.py +7 -6
- sphinx/domains/__init__.py +2 -2
- sphinx/domains/c/__init__.py +796 -0
- sphinx/domains/c/_ast.py +1421 -0
- sphinx/domains/c/_ids.py +65 -0
- sphinx/domains/c/_parser.py +1048 -0
- sphinx/domains/c/_symbol.py +700 -0
- sphinx/domains/changeset.py +11 -7
- sphinx/domains/citation.py +5 -2
- sphinx/domains/cpp/__init__.py +1089 -0
- sphinx/domains/cpp/_ast.py +3635 -0
- sphinx/domains/cpp/_ids.py +537 -0
- sphinx/domains/cpp/_parser.py +2117 -0
- sphinx/domains/cpp/_symbol.py +1092 -0
- sphinx/domains/index.py +6 -4
- sphinx/domains/javascript.py +16 -13
- sphinx/domains/math.py +9 -4
- sphinx/domains/python/__init__.py +890 -0
- sphinx/domains/python/_annotations.py +507 -0
- sphinx/domains/python/_object.py +426 -0
- sphinx/domains/rst.py +12 -7
- sphinx/domains/{std.py → std/__init__.py} +19 -16
- sphinx/environment/__init__.py +21 -19
- sphinx/environment/adapters/indexentries.py +2 -2
- sphinx/environment/adapters/toctree.py +10 -9
- sphinx/environment/collectors/__init__.py +6 -3
- sphinx/environment/collectors/asset.py +4 -3
- sphinx/environment/collectors/dependencies.py +3 -2
- sphinx/environment/collectors/metadata.py +6 -5
- sphinx/environment/collectors/title.py +3 -2
- sphinx/environment/collectors/toctree.py +5 -4
- sphinx/errors.py +13 -2
- sphinx/events.py +14 -9
- sphinx/ext/apidoc.py +9 -11
- sphinx/ext/autodoc/__init__.py +105 -71
- sphinx/ext/autodoc/directive.py +7 -6
- sphinx/ext/autodoc/importer.py +132 -52
- sphinx/ext/autodoc/mock.py +7 -5
- sphinx/ext/autodoc/preserve_defaults.py +4 -3
- sphinx/ext/autodoc/type_comment.py +2 -1
- sphinx/ext/autodoc/typehints.py +5 -4
- sphinx/ext/autosectionlabel.py +3 -2
- sphinx/ext/autosummary/__init__.py +21 -17
- sphinx/ext/autosummary/generate.py +9 -9
- sphinx/ext/coverage.py +26 -20
- sphinx/ext/doctest.py +38 -33
- sphinx/ext/duration.py +1 -0
- sphinx/ext/extlinks.py +4 -3
- sphinx/ext/githubpages.py +3 -2
- sphinx/ext/graphviz.py +10 -7
- sphinx/ext/ifconfig.py +5 -5
- sphinx/ext/imgconverter.py +6 -5
- sphinx/ext/imgmath.py +9 -8
- sphinx/ext/inheritance_diagram.py +31 -31
- sphinx/ext/intersphinx.py +140 -23
- sphinx/ext/linkcode.py +3 -2
- sphinx/ext/mathjax.py +2 -1
- sphinx/ext/napoleon/__init__.py +12 -7
- sphinx/ext/napoleon/docstring.py +34 -32
- sphinx/ext/todo.py +10 -7
- sphinx/ext/viewcode.py +12 -11
- sphinx/extension.py +18 -8
- sphinx/highlighting.py +39 -20
- sphinx/io.py +17 -8
- sphinx/jinja2glue.py +16 -15
- sphinx/locale/__init__.py +30 -23
- sphinx/locale/ar/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/ar/LC_MESSAGES/sphinx.po +818 -761
- sphinx/locale/bg/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/bg/LC_MESSAGES/sphinx.po +811 -754
- sphinx/locale/bn/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/bn/LC_MESSAGES/sphinx.po +835 -778
- sphinx/locale/ca/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/ca/LC_MESSAGES/sphinx.po +864 -807
- sphinx/locale/cak/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/cak/LC_MESSAGES/sphinx.po +816 -759
- sphinx/locale/cs/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/cs/LC_MESSAGES/sphinx.po +837 -780
- sphinx/locale/cy/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/cy/LC_MESSAGES/sphinx.po +819 -762
- sphinx/locale/da/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/da/LC_MESSAGES/sphinx.po +838 -781
- sphinx/locale/de/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/de/LC_MESSAGES/sphinx.po +838 -781
- sphinx/locale/de_DE/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/de_DE/LC_MESSAGES/sphinx.po +811 -754
- sphinx/locale/el/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/el/LC_MESSAGES/sphinx.po +853 -796
- sphinx/locale/en_DE/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/en_DE/LC_MESSAGES/sphinx.po +811 -754
- sphinx/locale/en_FR/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/en_FR/LC_MESSAGES/sphinx.po +811 -754
- sphinx/locale/en_GB/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/en_GB/LC_MESSAGES/sphinx.po +856 -799
- sphinx/locale/en_HK/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/en_HK/LC_MESSAGES/sphinx.po +811 -754
- sphinx/locale/eo/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/eo/LC_MESSAGES/sphinx.po +820 -763
- sphinx/locale/es/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/es/LC_MESSAGES/sphinx.po +856 -799
- sphinx/locale/es_CO/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/es_CO/LC_MESSAGES/sphinx.po +811 -754
- sphinx/locale/et/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/et/LC_MESSAGES/sphinx.po +845 -788
- sphinx/locale/eu/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/eu/LC_MESSAGES/sphinx.po +837 -780
- sphinx/locale/fa/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/fa/LC_MESSAGES/sphinx.po +854 -797
- sphinx/locale/fi/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/fi/LC_MESSAGES/sphinx.po +816 -759
- sphinx/locale/fr/LC_MESSAGES/sphinx.js +1 -1
- sphinx/locale/fr/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/fr/LC_MESSAGES/sphinx.po +904 -847
- sphinx/locale/fr_FR/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/fr_FR/LC_MESSAGES/sphinx.po +811 -754
- sphinx/locale/gl/LC_MESSAGES/sphinx.js +54 -54
- sphinx/locale/gl/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/gl/LC_MESSAGES/sphinx.po +1506 -1449
- sphinx/locale/he/LC_MESSAGES/sphinx.js +1 -1
- sphinx/locale/he/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/he/LC_MESSAGES/sphinx.po +823 -766
- sphinx/locale/hi/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/hi/LC_MESSAGES/sphinx.po +853 -796
- sphinx/locale/hi_IN/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/hi_IN/LC_MESSAGES/sphinx.po +811 -754
- sphinx/locale/hr/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/hr/LC_MESSAGES/sphinx.po +844 -787
- sphinx/locale/hu/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/hu/LC_MESSAGES/sphinx.po +837 -780
- sphinx/locale/id/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/id/LC_MESSAGES/sphinx.po +854 -797
- sphinx/locale/is/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/is/LC_MESSAGES/sphinx.po +811 -754
- sphinx/locale/it/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/it/LC_MESSAGES/sphinx.po +837 -780
- sphinx/locale/ja/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/ja/LC_MESSAGES/sphinx.po +853 -796
- sphinx/locale/ka/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/ka/LC_MESSAGES/sphinx.po +848 -791
- sphinx/locale/ko/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/ko/LC_MESSAGES/sphinx.po +855 -798
- sphinx/locale/lt/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/lt/LC_MESSAGES/sphinx.po +837 -780
- sphinx/locale/lv/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/lv/LC_MESSAGES/sphinx.po +837 -780
- sphinx/locale/mk/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/mk/LC_MESSAGES/sphinx.po +825 -768
- sphinx/locale/nb_NO/LC_MESSAGES/sphinx.js +27 -27
- sphinx/locale/nb_NO/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/nb_NO/LC_MESSAGES/sphinx.po +876 -818
- sphinx/locale/ne/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/ne/LC_MESSAGES/sphinx.po +837 -780
- sphinx/locale/nl/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/nl/LC_MESSAGES/sphinx.po +844 -787
- sphinx/locale/pl/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/pl/LC_MESSAGES/sphinx.po +845 -788
- sphinx/locale/pt/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/pt/LC_MESSAGES/sphinx.po +811 -754
- sphinx/locale/pt_BR/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/pt_BR/LC_MESSAGES/sphinx.po +908 -851
- sphinx/locale/pt_PT/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/pt_PT/LC_MESSAGES/sphinx.po +837 -780
- sphinx/locale/ro/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/ro/LC_MESSAGES/sphinx.po +837 -780
- sphinx/locale/ru/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/ru/LC_MESSAGES/sphinx.po +838 -781
- sphinx/locale/si/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/si/LC_MESSAGES/sphinx.po +823 -766
- sphinx/locale/sk/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/sk/LC_MESSAGES/sphinx.po +854 -797
- sphinx/locale/sl/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/sl/LC_MESSAGES/sphinx.po +832 -775
- sphinx/locale/sphinx.pot +813 -755
- sphinx/locale/sq/LC_MESSAGES/sphinx.js +1 -1
- sphinx/locale/sq/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/sq/LC_MESSAGES/sphinx.po +865 -808
- sphinx/locale/sr/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/sr/LC_MESSAGES/sphinx.po +835 -778
- sphinx/locale/sr@latin/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/sr_RS/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/sv/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/sv/LC_MESSAGES/sphinx.po +837 -780
- sphinx/locale/ta/LC_MESSAGES/sphinx.js +54 -54
- sphinx/locale/ta/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/ta/LC_MESSAGES/sphinx.po +1530 -1473
- sphinx/locale/te/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/te/LC_MESSAGES/sphinx.po +811 -754
- sphinx/locale/tr/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/tr/LC_MESSAGES/sphinx.po +853 -796
- sphinx/locale/uk_UA/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/uk_UA/LC_MESSAGES/sphinx.po +833 -776
- sphinx/locale/ur/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/ur/LC_MESSAGES/sphinx.po +811 -754
- sphinx/locale/vi/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/vi/LC_MESSAGES/sphinx.po +837 -780
- sphinx/locale/yue/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/yue/LC_MESSAGES/sphinx.po +811 -754
- sphinx/locale/zh_CN/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/zh_CN/LC_MESSAGES/sphinx.po +855 -798
- sphinx/locale/zh_HK/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/zh_HK/LC_MESSAGES/sphinx.po +811 -754
- sphinx/locale/zh_TW/LC_MESSAGES/sphinx.js +1 -1
- sphinx/locale/zh_TW/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/zh_TW/LC_MESSAGES/sphinx.po +879 -822
- sphinx/locale/zh_TW.Big5/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/zh_TW.Big5/LC_MESSAGES/sphinx.po +811 -754
- sphinx/parsers.py +7 -5
- sphinx/project.py +18 -11
- sphinx/pycode/__init__.py +6 -5
- sphinx/pycode/ast.py +23 -8
- sphinx/pycode/parser.py +6 -5
- sphinx/registry.py +12 -6
- sphinx/roles.py +103 -57
- sphinx/search/__init__.py +17 -18
- sphinx/search/da.py +2 -2
- sphinx/search/de.py +2 -2
- sphinx/search/en.py +1 -1
- sphinx/search/es.py +2 -2
- sphinx/search/fi.py +2 -2
- sphinx/search/fr.py +2 -2
- sphinx/search/hu.py +2 -2
- sphinx/search/it.py +2 -2
- sphinx/search/ja.py +13 -22
- sphinx/search/nl.py +2 -2
- sphinx/search/no.py +2 -2
- sphinx/search/pt.py +2 -2
- sphinx/search/ro.py +1 -1
- sphinx/search/ru.py +2 -2
- sphinx/search/sv.py +2 -2
- sphinx/search/tr.py +1 -1
- sphinx/search/zh.py +2 -3
- sphinx/templates/graphviz/graphviz.css +1 -1
- sphinx/testing/fixtures.py +41 -24
- sphinx/testing/path.py +1 -1
- sphinx/testing/util.py +142 -53
- sphinx/texinputs/sphinx.xdy +1 -1
- sphinx/texinputs/sphinxlatextables.sty +1 -1
- sphinx/texinputs/sphinxpackagesubstitutefont.sty +21 -0
- sphinx/themes/agogo/layout.html +4 -4
- sphinx/themes/agogo/static/agogo.css_t +1 -1
- sphinx/themes/agogo/theme.toml +22 -0
- sphinx/themes/basic/defindex.html +1 -1
- sphinx/themes/basic/domainindex.html +1 -1
- sphinx/themes/basic/genindex-single.html +1 -1
- sphinx/themes/basic/genindex-split.html +1 -1
- sphinx/themes/basic/genindex.html +1 -1
- sphinx/themes/basic/globaltoc.html +1 -1
- sphinx/themes/basic/layout.html +1 -1
- sphinx/themes/basic/localtoc.html +1 -1
- sphinx/themes/basic/page.html +1 -1
- sphinx/themes/basic/relations.html +1 -1
- sphinx/themes/basic/search.html +5 -20
- sphinx/themes/basic/searchbox.html +3 -3
- sphinx/themes/basic/searchfield.html +3 -3
- sphinx/themes/basic/sourcelink.html +1 -1
- sphinx/themes/basic/static/basic.css_t +1 -1
- sphinx/themes/basic/static/doctools.js +1 -1
- sphinx/themes/basic/static/language_data.js_t +2 -2
- sphinx/themes/basic/static/searchtools.js +105 -60
- sphinx/themes/basic/theme.toml +23 -0
- sphinx/themes/bizstyle/layout.html +1 -6
- sphinx/themes/bizstyle/static/bizstyle.css_t +1 -1
- sphinx/themes/bizstyle/static/bizstyle.js_t +1 -1
- sphinx/themes/bizstyle/static/css3-mediaqueries_src.js +3 -3
- sphinx/themes/bizstyle/theme.toml +12 -0
- sphinx/themes/classic/layout.html +1 -1
- sphinx/themes/classic/static/classic.css_t +1 -1
- sphinx/themes/classic/static/sidebar.js_t +1 -1
- sphinx/themes/classic/theme.toml +34 -0
- sphinx/themes/default/theme.toml +2 -0
- sphinx/themes/epub/epub-cover.html +1 -1
- sphinx/themes/epub/layout.html +1 -1
- sphinx/themes/epub/static/epub.css_t +1 -1
- sphinx/themes/epub/theme.toml +10 -0
- sphinx/themes/haiku/layout.html +3 -3
- sphinx/themes/haiku/static/haiku.css_t +2 -2
- sphinx/themes/haiku/theme.toml +16 -0
- sphinx/themes/nature/static/nature.css_t +1 -1
- sphinx/themes/nature/theme.toml +6 -0
- sphinx/themes/nonav/layout.html +1 -1
- sphinx/themes/nonav/static/nonav.css_t +1 -1
- sphinx/themes/nonav/theme.toml +10 -0
- sphinx/themes/pyramid/static/epub.css_t +1 -1
- sphinx/themes/pyramid/static/pyramid.css_t +1 -1
- sphinx/themes/pyramid/theme.toml +6 -0
- sphinx/themes/scrolls/artwork/logo.svg +1 -1
- sphinx/themes/scrolls/layout.html +2 -2
- sphinx/themes/scrolls/static/scrolls.css_t +1 -1
- sphinx/themes/scrolls/theme.toml +15 -0
- sphinx/themes/sphinxdoc/static/sphinxdoc.css_t +1 -1
- sphinx/themes/sphinxdoc/theme.toml +6 -0
- sphinx/themes/traditional/static/traditional.css_t +1 -1
- sphinx/themes/traditional/theme.toml +9 -0
- sphinx/theming.py +427 -131
- sphinx/transforms/__init__.py +21 -24
- sphinx/transforms/compact_bullet_list.py +5 -5
- sphinx/transforms/i18n.py +30 -28
- sphinx/transforms/post_transforms/__init__.py +9 -7
- sphinx/transforms/post_transforms/code.py +4 -1
- sphinx/transforms/post_transforms/images.py +17 -13
- sphinx/transforms/references.py +3 -1
- sphinx/util/__init__.py +15 -11
- sphinx/util/_io.py +34 -0
- sphinx/util/_pathlib.py +23 -18
- sphinx/util/build_phase.py +1 -0
- sphinx/util/cfamily.py +19 -11
- sphinx/util/console.py +101 -21
- sphinx/util/display.py +3 -2
- sphinx/util/docfields.py +12 -8
- sphinx/util/docutils.py +21 -35
- sphinx/util/exceptions.py +3 -2
- sphinx/util/fileutil.py +5 -5
- sphinx/util/http_date.py +9 -2
- sphinx/util/i18n.py +40 -9
- sphinx/util/inspect.py +317 -245
- sphinx/util/inventory.py +22 -5
- sphinx/util/logging.py +81 -7
- sphinx/util/matching.py +2 -1
- sphinx/util/math.py +1 -2
- sphinx/util/nodes.py +39 -29
- sphinx/util/osutil.py +25 -6
- sphinx/util/parallel.py +6 -1
- sphinx/util/requests.py +8 -5
- sphinx/util/rst.py +8 -6
- sphinx/util/tags.py +3 -3
- sphinx/util/template.py +8 -3
- sphinx/util/typing.py +76 -42
- sphinx/versioning.py +6 -2
- sphinx/writers/html.py +1 -1
- sphinx/writers/html5.py +17 -13
- sphinx/writers/latex.py +12 -12
- sphinx/writers/manpage.py +13 -7
- sphinx/writers/texinfo.py +13 -10
- sphinx/writers/text.py +13 -23
- sphinx/writers/xml.py +1 -1
- sphinx-7.2.5.dist-info/LICENSE → sphinx-7.3.0.dist-info/LICENSE.rst +1 -1
- {sphinx-7.2.5.dist-info → sphinx-7.3.0.dist-info}/METADATA +13 -12
- sphinx-7.3.0.dist-info/RECORD +581 -0
- sphinx/domains/c.py +0 -3906
- sphinx/domains/cpp.py +0 -8233
- sphinx/domains/python.py +0 -1769
- sphinx/themes/agogo/theme.conf +0 -20
- sphinx/themes/basic/theme.conf +0 -16
- sphinx/themes/bizstyle/theme.conf +0 -10
- sphinx/themes/classic/theme.conf +0 -32
- sphinx/themes/default/theme.conf +0 -2
- sphinx/themes/epub/theme.conf +0 -8
- sphinx/themes/haiku/theme.conf +0 -14
- sphinx/themes/nature/theme.conf +0 -4
- sphinx/themes/nonav/theme.conf +0 -8
- sphinx/themes/pyramid/theme.conf +0 -4
- sphinx/themes/scrolls/theme.conf +0 -13
- sphinx/themes/sphinxdoc/theme.conf +0 -4
- sphinx/themes/traditional/theme.conf +0 -7
- sphinx-7.2.5.dist-info/RECORD +0 -569
- {sphinx-7.2.5.dist-info → sphinx-7.3.0.dist-info}/WHEEL +0 -0
- {sphinx-7.2.5.dist-info → sphinx-7.3.0.dist-info}/entry_points.txt +0 -0
|
@@ -0,0 +1,796 @@
|
|
|
1
|
+
"""The C language domain."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from typing import TYPE_CHECKING, Any, ClassVar
|
|
6
|
+
|
|
7
|
+
from docutils import nodes
|
|
8
|
+
from docutils.parsers.rst import directives
|
|
9
|
+
|
|
10
|
+
from sphinx import addnodes
|
|
11
|
+
from sphinx.directives import ObjectDescription
|
|
12
|
+
from sphinx.domains import Domain, ObjType
|
|
13
|
+
from sphinx.domains.c._ast import (
|
|
14
|
+
ASTDeclaration,
|
|
15
|
+
ASTIdentifier,
|
|
16
|
+
ASTNestedName,
|
|
17
|
+
)
|
|
18
|
+
from sphinx.domains.c._ids import _macroKeywords, _max_id
|
|
19
|
+
from sphinx.domains.c._parser import DefinitionParser
|
|
20
|
+
from sphinx.domains.c._symbol import Symbol, _DuplicateSymbolError
|
|
21
|
+
from sphinx.locale import _, __
|
|
22
|
+
from sphinx.roles import SphinxRole, XRefRole
|
|
23
|
+
from sphinx.transforms import SphinxTransform
|
|
24
|
+
from sphinx.transforms.post_transforms import ReferencesResolver
|
|
25
|
+
from sphinx.util import logging
|
|
26
|
+
from sphinx.util.cfamily import (
|
|
27
|
+
DefinitionError,
|
|
28
|
+
NoOldIdError,
|
|
29
|
+
anon_identifier_re,
|
|
30
|
+
)
|
|
31
|
+
from sphinx.util.docfields import Field, GroupedField, TypedField
|
|
32
|
+
from sphinx.util.docutils import SphinxDirective
|
|
33
|
+
from sphinx.util.nodes import make_refnode
|
|
34
|
+
|
|
35
|
+
if TYPE_CHECKING:
|
|
36
|
+
from collections.abc import Iterator
|
|
37
|
+
|
|
38
|
+
from docutils.nodes import Element, Node, TextElement, system_message
|
|
39
|
+
|
|
40
|
+
from sphinx.addnodes import pending_xref
|
|
41
|
+
from sphinx.application import Sphinx
|
|
42
|
+
from sphinx.builders import Builder
|
|
43
|
+
from sphinx.domains.c._symbol import LookupKey
|
|
44
|
+
from sphinx.environment import BuildEnvironment
|
|
45
|
+
from sphinx.util.typing import ExtensionMetadata, OptionSpec
|
|
46
|
+
|
|
47
|
+
logger = logging.getLogger(__name__)
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def _make_phony_error_name() -> ASTNestedName:
|
|
51
|
+
return ASTNestedName([ASTIdentifier("PhonyNameDueToError")], rooted=False)
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
class CObject(ObjectDescription[ASTDeclaration]):
|
|
55
|
+
"""
|
|
56
|
+
Description of a C language object.
|
|
57
|
+
"""
|
|
58
|
+
|
|
59
|
+
option_spec: ClassVar[OptionSpec] = {
|
|
60
|
+
'no-index-entry': directives.flag,
|
|
61
|
+
'no-contents-entry': directives.flag,
|
|
62
|
+
'no-typesetting': directives.flag,
|
|
63
|
+
'noindexentry': directives.flag,
|
|
64
|
+
'nocontentsentry': directives.flag,
|
|
65
|
+
'single-line-parameter-list': directives.flag,
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
def _add_enumerator_to_parent(self, ast: ASTDeclaration) -> None:
|
|
69
|
+
assert ast.objectType == 'enumerator'
|
|
70
|
+
# find the parent, if it exists && is an enum
|
|
71
|
+
# then add the name to the parent scope
|
|
72
|
+
symbol = ast.symbol
|
|
73
|
+
assert symbol
|
|
74
|
+
assert symbol.ident is not None
|
|
75
|
+
parentSymbol = symbol.parent
|
|
76
|
+
assert parentSymbol
|
|
77
|
+
if parentSymbol.parent is None:
|
|
78
|
+
# TODO: we could warn, but it is somewhat equivalent to
|
|
79
|
+
# enumeratorss, without the enum
|
|
80
|
+
return # no parent
|
|
81
|
+
parentDecl = parentSymbol.declaration
|
|
82
|
+
if parentDecl is None:
|
|
83
|
+
# the parent is not explicitly declared
|
|
84
|
+
# TODO: we could warn, but?
|
|
85
|
+
return
|
|
86
|
+
if parentDecl.objectType != 'enum':
|
|
87
|
+
# TODO: maybe issue a warning, enumerators in non-enums is weird,
|
|
88
|
+
# but it is somewhat equivalent to enumeratorss, without the enum
|
|
89
|
+
return
|
|
90
|
+
if parentDecl.directiveType != 'enum':
|
|
91
|
+
return
|
|
92
|
+
|
|
93
|
+
targetSymbol = parentSymbol.parent
|
|
94
|
+
s = targetSymbol.find_identifier(symbol.ident, matchSelf=False, recurseInAnon=True,
|
|
95
|
+
searchInSiblings=False)
|
|
96
|
+
if s is not None:
|
|
97
|
+
# something is already declared with that name
|
|
98
|
+
return
|
|
99
|
+
declClone = symbol.declaration.clone()
|
|
100
|
+
declClone.enumeratorScopedSymbol = symbol
|
|
101
|
+
Symbol(parent=targetSymbol, ident=symbol.ident,
|
|
102
|
+
declaration=declClone,
|
|
103
|
+
docname=self.env.docname, line=self.get_source_info()[1])
|
|
104
|
+
|
|
105
|
+
def add_target_and_index(self, ast: ASTDeclaration, sig: str,
|
|
106
|
+
signode: TextElement) -> None:
|
|
107
|
+
ids = []
|
|
108
|
+
for i in range(1, _max_id + 1):
|
|
109
|
+
try:
|
|
110
|
+
id = ast.get_id(version=i)
|
|
111
|
+
ids.append(id)
|
|
112
|
+
except NoOldIdError:
|
|
113
|
+
assert i < _max_id
|
|
114
|
+
# let's keep the newest first
|
|
115
|
+
ids.reverse()
|
|
116
|
+
newestId = ids[0]
|
|
117
|
+
assert newestId # shouldn't be None
|
|
118
|
+
|
|
119
|
+
name = ast.symbol.get_full_nested_name().get_display_string().lstrip('.')
|
|
120
|
+
if newestId not in self.state.document.ids:
|
|
121
|
+
# always add the newest id
|
|
122
|
+
assert newestId
|
|
123
|
+
signode['ids'].append(newestId)
|
|
124
|
+
# only add compatibility ids when there are no conflicts
|
|
125
|
+
for id in ids[1:]:
|
|
126
|
+
if not id: # is None when the element didn't exist in that version
|
|
127
|
+
continue
|
|
128
|
+
if id not in self.state.document.ids:
|
|
129
|
+
signode['ids'].append(id)
|
|
130
|
+
|
|
131
|
+
self.state.document.note_explicit_target(signode)
|
|
132
|
+
|
|
133
|
+
if 'no-index-entry' not in self.options:
|
|
134
|
+
indexText = self.get_index_text(name)
|
|
135
|
+
self.indexnode['entries'].append(('single', indexText, newestId, '', None))
|
|
136
|
+
|
|
137
|
+
@property
|
|
138
|
+
def object_type(self) -> str:
|
|
139
|
+
raise NotImplementedError
|
|
140
|
+
|
|
141
|
+
@property
|
|
142
|
+
def display_object_type(self) -> str:
|
|
143
|
+
return self.object_type
|
|
144
|
+
|
|
145
|
+
def get_index_text(self, name: str) -> str:
|
|
146
|
+
return _('%s (C %s)') % (name, self.display_object_type)
|
|
147
|
+
|
|
148
|
+
def parse_definition(self, parser: DefinitionParser) -> ASTDeclaration:
|
|
149
|
+
return parser.parse_declaration(self.object_type, self.objtype)
|
|
150
|
+
|
|
151
|
+
def describe_signature(self, signode: TextElement, ast: ASTDeclaration,
|
|
152
|
+
options: dict) -> None:
|
|
153
|
+
ast.describe_signature(signode, 'lastIsName', self.env, options)
|
|
154
|
+
|
|
155
|
+
def run(self) -> list[Node]:
|
|
156
|
+
env = self.state.document.settings.env # from ObjectDescription.run
|
|
157
|
+
if 'c:parent_symbol' not in env.temp_data:
|
|
158
|
+
root = env.domaindata['c']['root_symbol']
|
|
159
|
+
env.temp_data['c:parent_symbol'] = root
|
|
160
|
+
env.ref_context['c:parent_key'] = root.get_lookup_key()
|
|
161
|
+
|
|
162
|
+
# When multiple declarations are made in the same directive
|
|
163
|
+
# they need to know about each other to provide symbol lookup for function parameters.
|
|
164
|
+
# We use last_symbol to store the latest added declaration in a directive.
|
|
165
|
+
env.temp_data['c:last_symbol'] = None
|
|
166
|
+
return super().run()
|
|
167
|
+
|
|
168
|
+
def handle_signature(self, sig: str, signode: TextElement) -> ASTDeclaration:
|
|
169
|
+
parentSymbol: Symbol = self.env.temp_data['c:parent_symbol']
|
|
170
|
+
|
|
171
|
+
max_len = (self.env.config.c_maximum_signature_line_length
|
|
172
|
+
or self.env.config.maximum_signature_line_length
|
|
173
|
+
or 0)
|
|
174
|
+
signode['multi_line_parameter_list'] = (
|
|
175
|
+
'single-line-parameter-list' not in self.options
|
|
176
|
+
and (len(sig) > max_len > 0)
|
|
177
|
+
)
|
|
178
|
+
|
|
179
|
+
parser = DefinitionParser(sig, location=signode, config=self.env.config)
|
|
180
|
+
try:
|
|
181
|
+
ast = self.parse_definition(parser)
|
|
182
|
+
parser.assert_end()
|
|
183
|
+
except DefinitionError as e:
|
|
184
|
+
logger.warning(e, location=signode)
|
|
185
|
+
# It is easier to assume some phony name than handling the error in
|
|
186
|
+
# the possibly inner declarations.
|
|
187
|
+
name = _make_phony_error_name()
|
|
188
|
+
symbol = parentSymbol.add_name(name)
|
|
189
|
+
self.env.temp_data['c:last_symbol'] = symbol
|
|
190
|
+
raise ValueError from e
|
|
191
|
+
|
|
192
|
+
try:
|
|
193
|
+
symbol = parentSymbol.add_declaration(
|
|
194
|
+
ast, docname=self.env.docname, line=self.get_source_info()[1])
|
|
195
|
+
# append the new declaration to the sibling list
|
|
196
|
+
assert symbol.siblingAbove is None
|
|
197
|
+
assert symbol.siblingBelow is None
|
|
198
|
+
symbol.siblingAbove = self.env.temp_data['c:last_symbol']
|
|
199
|
+
if symbol.siblingAbove is not None:
|
|
200
|
+
assert symbol.siblingAbove.siblingBelow is None
|
|
201
|
+
symbol.siblingAbove.siblingBelow = symbol
|
|
202
|
+
self.env.temp_data['c:last_symbol'] = symbol
|
|
203
|
+
except _DuplicateSymbolError as e:
|
|
204
|
+
# Assume we are actually in the old symbol,
|
|
205
|
+
# instead of the newly created duplicate.
|
|
206
|
+
self.env.temp_data['c:last_symbol'] = e.symbol
|
|
207
|
+
msg = __("Duplicate C declaration, also defined at %s:%s.\n"
|
|
208
|
+
"Declaration is '.. c:%s:: %s'.")
|
|
209
|
+
msg = msg % (e.symbol.docname, e.symbol.line, self.display_object_type, sig)
|
|
210
|
+
logger.warning(msg, location=signode)
|
|
211
|
+
|
|
212
|
+
if ast.objectType == 'enumerator':
|
|
213
|
+
self._add_enumerator_to_parent(ast)
|
|
214
|
+
|
|
215
|
+
# note: handle_signature may be called multiple time per directive,
|
|
216
|
+
# if it has multiple signatures, so don't mess with the original options.
|
|
217
|
+
options = dict(self.options)
|
|
218
|
+
self.describe_signature(signode, ast, options)
|
|
219
|
+
return ast
|
|
220
|
+
|
|
221
|
+
def before_content(self) -> None:
|
|
222
|
+
lastSymbol: Symbol = self.env.temp_data['c:last_symbol']
|
|
223
|
+
assert lastSymbol
|
|
224
|
+
self.oldParentSymbol = self.env.temp_data['c:parent_symbol']
|
|
225
|
+
self.oldParentKey: LookupKey = self.env.ref_context['c:parent_key']
|
|
226
|
+
self.env.temp_data['c:parent_symbol'] = lastSymbol
|
|
227
|
+
self.env.ref_context['c:parent_key'] = lastSymbol.get_lookup_key()
|
|
228
|
+
|
|
229
|
+
def after_content(self) -> None:
|
|
230
|
+
self.env.temp_data['c:parent_symbol'] = self.oldParentSymbol
|
|
231
|
+
self.env.ref_context['c:parent_key'] = self.oldParentKey
|
|
232
|
+
|
|
233
|
+
|
|
234
|
+
class CMemberObject(CObject):
|
|
235
|
+
object_type = 'member'
|
|
236
|
+
|
|
237
|
+
@property
|
|
238
|
+
def display_object_type(self) -> str:
|
|
239
|
+
# the distinction between var and member is only cosmetic
|
|
240
|
+
assert self.objtype in ('member', 'var')
|
|
241
|
+
return self.objtype
|
|
242
|
+
|
|
243
|
+
|
|
244
|
+
_function_doc_field_types = [
|
|
245
|
+
TypedField('parameter', label=_('Parameters'),
|
|
246
|
+
names=('param', 'parameter', 'arg', 'argument'),
|
|
247
|
+
typerolename='expr', typenames=('type',)),
|
|
248
|
+
GroupedField('retval', label=_('Return values'),
|
|
249
|
+
names=('retvals', 'retval'),
|
|
250
|
+
can_collapse=True),
|
|
251
|
+
Field('returnvalue', label=_('Returns'), has_arg=False,
|
|
252
|
+
names=('returns', 'return')),
|
|
253
|
+
Field('returntype', label=_('Return type'), has_arg=False,
|
|
254
|
+
names=('rtype',)),
|
|
255
|
+
]
|
|
256
|
+
|
|
257
|
+
|
|
258
|
+
class CFunctionObject(CObject):
|
|
259
|
+
object_type = 'function'
|
|
260
|
+
|
|
261
|
+
doc_field_types = _function_doc_field_types.copy()
|
|
262
|
+
|
|
263
|
+
|
|
264
|
+
class CMacroObject(CObject):
|
|
265
|
+
object_type = 'macro'
|
|
266
|
+
|
|
267
|
+
doc_field_types = _function_doc_field_types.copy()
|
|
268
|
+
|
|
269
|
+
|
|
270
|
+
class CStructObject(CObject):
|
|
271
|
+
object_type = 'struct'
|
|
272
|
+
|
|
273
|
+
|
|
274
|
+
class CUnionObject(CObject):
|
|
275
|
+
object_type = 'union'
|
|
276
|
+
|
|
277
|
+
|
|
278
|
+
class CEnumObject(CObject):
|
|
279
|
+
object_type = 'enum'
|
|
280
|
+
|
|
281
|
+
|
|
282
|
+
class CEnumeratorObject(CObject):
|
|
283
|
+
object_type = 'enumerator'
|
|
284
|
+
|
|
285
|
+
|
|
286
|
+
class CTypeObject(CObject):
|
|
287
|
+
object_type = 'type'
|
|
288
|
+
|
|
289
|
+
|
|
290
|
+
class CNamespaceObject(SphinxDirective):
|
|
291
|
+
"""
|
|
292
|
+
This directive is just to tell Sphinx that we're documenting stuff in
|
|
293
|
+
namespace foo.
|
|
294
|
+
"""
|
|
295
|
+
|
|
296
|
+
has_content = False
|
|
297
|
+
required_arguments = 1
|
|
298
|
+
optional_arguments = 0
|
|
299
|
+
final_argument_whitespace = True
|
|
300
|
+
option_spec: ClassVar[OptionSpec] = {}
|
|
301
|
+
|
|
302
|
+
def run(self) -> list[Node]:
|
|
303
|
+
rootSymbol = self.env.domaindata['c']['root_symbol']
|
|
304
|
+
if self.arguments[0].strip() in ('NULL', '0', 'nullptr'):
|
|
305
|
+
symbol = rootSymbol
|
|
306
|
+
stack: list[Symbol] = []
|
|
307
|
+
else:
|
|
308
|
+
parser = DefinitionParser(self.arguments[0],
|
|
309
|
+
location=self.get_location(),
|
|
310
|
+
config=self.env.config)
|
|
311
|
+
try:
|
|
312
|
+
name = parser.parse_namespace_object()
|
|
313
|
+
parser.assert_end()
|
|
314
|
+
except DefinitionError as e:
|
|
315
|
+
logger.warning(e, location=self.get_location())
|
|
316
|
+
name = _make_phony_error_name()
|
|
317
|
+
symbol = rootSymbol.add_name(name)
|
|
318
|
+
stack = [symbol]
|
|
319
|
+
self.env.temp_data['c:parent_symbol'] = symbol
|
|
320
|
+
self.env.temp_data['c:namespace_stack'] = stack
|
|
321
|
+
self.env.ref_context['c:parent_key'] = symbol.get_lookup_key()
|
|
322
|
+
return []
|
|
323
|
+
|
|
324
|
+
|
|
325
|
+
class CNamespacePushObject(SphinxDirective):
|
|
326
|
+
has_content = False
|
|
327
|
+
required_arguments = 1
|
|
328
|
+
optional_arguments = 0
|
|
329
|
+
final_argument_whitespace = True
|
|
330
|
+
option_spec: ClassVar[OptionSpec] = {}
|
|
331
|
+
|
|
332
|
+
def run(self) -> list[Node]:
|
|
333
|
+
if self.arguments[0].strip() in ('NULL', '0', 'nullptr'):
|
|
334
|
+
return []
|
|
335
|
+
parser = DefinitionParser(self.arguments[0],
|
|
336
|
+
location=self.get_location(),
|
|
337
|
+
config=self.env.config)
|
|
338
|
+
try:
|
|
339
|
+
name = parser.parse_namespace_object()
|
|
340
|
+
parser.assert_end()
|
|
341
|
+
except DefinitionError as e:
|
|
342
|
+
logger.warning(e, location=self.get_location())
|
|
343
|
+
name = _make_phony_error_name()
|
|
344
|
+
oldParent = self.env.temp_data.get('c:parent_symbol', None)
|
|
345
|
+
if not oldParent:
|
|
346
|
+
oldParent = self.env.domaindata['c']['root_symbol']
|
|
347
|
+
symbol = oldParent.add_name(name)
|
|
348
|
+
stack = self.env.temp_data.get('c:namespace_stack', [])
|
|
349
|
+
stack.append(symbol)
|
|
350
|
+
self.env.temp_data['c:parent_symbol'] = symbol
|
|
351
|
+
self.env.temp_data['c:namespace_stack'] = stack
|
|
352
|
+
self.env.ref_context['c:parent_key'] = symbol.get_lookup_key()
|
|
353
|
+
return []
|
|
354
|
+
|
|
355
|
+
|
|
356
|
+
class CNamespacePopObject(SphinxDirective):
|
|
357
|
+
has_content = False
|
|
358
|
+
required_arguments = 0
|
|
359
|
+
optional_arguments = 0
|
|
360
|
+
final_argument_whitespace = True
|
|
361
|
+
option_spec: ClassVar[OptionSpec] = {}
|
|
362
|
+
|
|
363
|
+
def run(self) -> list[Node]:
|
|
364
|
+
stack = self.env.temp_data.get('c:namespace_stack', None)
|
|
365
|
+
if not stack or len(stack) == 0:
|
|
366
|
+
logger.warning("C namespace pop on empty stack. Defaulting to global scope.",
|
|
367
|
+
location=self.get_location())
|
|
368
|
+
stack = []
|
|
369
|
+
else:
|
|
370
|
+
stack.pop()
|
|
371
|
+
if len(stack) > 0:
|
|
372
|
+
symbol = stack[-1]
|
|
373
|
+
else:
|
|
374
|
+
symbol = self.env.domaindata['c']['root_symbol']
|
|
375
|
+
self.env.temp_data['c:parent_symbol'] = symbol
|
|
376
|
+
self.env.temp_data['c:namespace_stack'] = stack
|
|
377
|
+
self.env.ref_context['c:parent_key'] = symbol.get_lookup_key()
|
|
378
|
+
return []
|
|
379
|
+
|
|
380
|
+
|
|
381
|
+
class AliasNode(nodes.Element):
|
|
382
|
+
def __init__(
|
|
383
|
+
self,
|
|
384
|
+
sig: str,
|
|
385
|
+
aliasOptions: dict,
|
|
386
|
+
document: Any,
|
|
387
|
+
env: BuildEnvironment | None = None,
|
|
388
|
+
parentKey: LookupKey | None = None,
|
|
389
|
+
) -> None:
|
|
390
|
+
super().__init__()
|
|
391
|
+
self.sig = sig
|
|
392
|
+
self.aliasOptions = aliasOptions
|
|
393
|
+
self.document = document
|
|
394
|
+
if env is not None:
|
|
395
|
+
if 'c:parent_symbol' not in env.temp_data:
|
|
396
|
+
root = env.domaindata['c']['root_symbol']
|
|
397
|
+
env.temp_data['c:parent_symbol'] = root
|
|
398
|
+
env.ref_context['c:parent_key'] = root.get_lookup_key()
|
|
399
|
+
self.parentKey = env.ref_context['c:parent_key']
|
|
400
|
+
else:
|
|
401
|
+
assert parentKey is not None
|
|
402
|
+
self.parentKey = parentKey
|
|
403
|
+
|
|
404
|
+
def copy(self) -> AliasNode:
|
|
405
|
+
return self.__class__(self.sig, self.aliasOptions, self.document,
|
|
406
|
+
env=None, parentKey=self.parentKey)
|
|
407
|
+
|
|
408
|
+
|
|
409
|
+
class AliasTransform(SphinxTransform):
|
|
410
|
+
default_priority = ReferencesResolver.default_priority - 1
|
|
411
|
+
|
|
412
|
+
def _render_symbol(self, s: Symbol, maxdepth: int, skipThis: bool,
|
|
413
|
+
aliasOptions: dict, renderOptions: dict,
|
|
414
|
+
document: Any) -> list[Node]:
|
|
415
|
+
if maxdepth == 0:
|
|
416
|
+
recurse = True
|
|
417
|
+
elif maxdepth == 1:
|
|
418
|
+
recurse = False
|
|
419
|
+
else:
|
|
420
|
+
maxdepth -= 1
|
|
421
|
+
recurse = True
|
|
422
|
+
|
|
423
|
+
nodes: list[Node] = []
|
|
424
|
+
if not skipThis:
|
|
425
|
+
signode = addnodes.desc_signature('', '')
|
|
426
|
+
nodes.append(signode)
|
|
427
|
+
s.declaration.describe_signature(signode, 'markName', self.env, renderOptions)
|
|
428
|
+
|
|
429
|
+
if recurse:
|
|
430
|
+
if skipThis:
|
|
431
|
+
childContainer: list[Node] | addnodes.desc = nodes
|
|
432
|
+
else:
|
|
433
|
+
content = addnodes.desc_content()
|
|
434
|
+
desc = addnodes.desc()
|
|
435
|
+
content.append(desc)
|
|
436
|
+
desc.document = document
|
|
437
|
+
desc['domain'] = 'c'
|
|
438
|
+
# 'desctype' is a backwards compatible attribute
|
|
439
|
+
desc['objtype'] = desc['desctype'] = 'alias'
|
|
440
|
+
desc['no-index'] = True
|
|
441
|
+
childContainer = desc
|
|
442
|
+
|
|
443
|
+
for sChild in s.children:
|
|
444
|
+
if sChild.declaration is None:
|
|
445
|
+
continue
|
|
446
|
+
childNodes = self._render_symbol(
|
|
447
|
+
sChild, maxdepth=maxdepth, skipThis=False,
|
|
448
|
+
aliasOptions=aliasOptions, renderOptions=renderOptions,
|
|
449
|
+
document=document)
|
|
450
|
+
childContainer.extend(childNodes)
|
|
451
|
+
|
|
452
|
+
if not skipThis and len(desc.children) != 0:
|
|
453
|
+
nodes.append(content)
|
|
454
|
+
return nodes
|
|
455
|
+
|
|
456
|
+
def apply(self, **kwargs: Any) -> None:
|
|
457
|
+
for node in self.document.findall(AliasNode):
|
|
458
|
+
sig = node.sig
|
|
459
|
+
parentKey = node.parentKey
|
|
460
|
+
try:
|
|
461
|
+
parser = DefinitionParser(sig, location=node,
|
|
462
|
+
config=self.env.config)
|
|
463
|
+
name = parser.parse_xref_object()
|
|
464
|
+
except DefinitionError as e:
|
|
465
|
+
logger.warning(e, location=node)
|
|
466
|
+
name = None
|
|
467
|
+
|
|
468
|
+
if name is None:
|
|
469
|
+
# could not be parsed, so stop here
|
|
470
|
+
signode = addnodes.desc_signature(sig, '')
|
|
471
|
+
signode.clear()
|
|
472
|
+
signode += addnodes.desc_name(sig, sig)
|
|
473
|
+
node.replace_self(signode)
|
|
474
|
+
continue
|
|
475
|
+
|
|
476
|
+
rootSymbol: Symbol = self.env.domains['c'].data['root_symbol']
|
|
477
|
+
parentSymbol: Symbol | None = rootSymbol.direct_lookup(parentKey)
|
|
478
|
+
if not parentSymbol:
|
|
479
|
+
logger.debug("Target: %s", sig)
|
|
480
|
+
logger.debug("ParentKey: %s", parentKey)
|
|
481
|
+
logger.debug(rootSymbol.dump(1))
|
|
482
|
+
assert parentSymbol # should be there
|
|
483
|
+
|
|
484
|
+
s = parentSymbol.find_declaration(
|
|
485
|
+
name, 'any',
|
|
486
|
+
matchSelf=True, recurseInAnon=True)
|
|
487
|
+
if s is None:
|
|
488
|
+
signode = addnodes.desc_signature(sig, '')
|
|
489
|
+
node.append(signode)
|
|
490
|
+
signode.clear()
|
|
491
|
+
signode += addnodes.desc_name(sig, sig)
|
|
492
|
+
|
|
493
|
+
logger.warning("Could not find C declaration for alias '%s'." % name,
|
|
494
|
+
location=node)
|
|
495
|
+
node.replace_self(signode)
|
|
496
|
+
continue
|
|
497
|
+
# Declarations like .. var:: int Missing::var
|
|
498
|
+
# may introduce symbols without declarations.
|
|
499
|
+
# But if we skip the root then it is ok to start recursion from it.
|
|
500
|
+
if not node.aliasOptions['noroot'] and s.declaration is None:
|
|
501
|
+
signode = addnodes.desc_signature(sig, '')
|
|
502
|
+
node.append(signode)
|
|
503
|
+
signode.clear()
|
|
504
|
+
signode += addnodes.desc_name(sig, sig)
|
|
505
|
+
|
|
506
|
+
logger.warning(
|
|
507
|
+
"Can not render C declaration for alias '%s'. No such declaration." % name,
|
|
508
|
+
location=node)
|
|
509
|
+
node.replace_self(signode)
|
|
510
|
+
continue
|
|
511
|
+
|
|
512
|
+
nodes = self._render_symbol(s, maxdepth=node.aliasOptions['maxdepth'],
|
|
513
|
+
skipThis=node.aliasOptions['noroot'],
|
|
514
|
+
aliasOptions=node.aliasOptions,
|
|
515
|
+
renderOptions={}, document=node.document)
|
|
516
|
+
node.replace_self(nodes)
|
|
517
|
+
|
|
518
|
+
|
|
519
|
+
class CAliasObject(ObjectDescription):
|
|
520
|
+
option_spec: ClassVar[OptionSpec] = {
|
|
521
|
+
'maxdepth': directives.nonnegative_int,
|
|
522
|
+
'noroot': directives.flag,
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
def run(self) -> list[Node]:
|
|
526
|
+
"""
|
|
527
|
+
On purpose this doesn't call the ObjectDescription version, but is based on it.
|
|
528
|
+
Each alias signature may expand into multiple real signatures if 'noroot'.
|
|
529
|
+
The code is therefore based on the ObjectDescription version.
|
|
530
|
+
"""
|
|
531
|
+
if ':' in self.name:
|
|
532
|
+
self.domain, self.objtype = self.name.split(':', 1)
|
|
533
|
+
else:
|
|
534
|
+
self.domain, self.objtype = '', self.name
|
|
535
|
+
|
|
536
|
+
node = addnodes.desc()
|
|
537
|
+
node.document = self.state.document
|
|
538
|
+
node['domain'] = self.domain
|
|
539
|
+
# 'desctype' is a backwards compatible attribute
|
|
540
|
+
node['objtype'] = node['desctype'] = self.objtype
|
|
541
|
+
node['no-index'] = True
|
|
542
|
+
|
|
543
|
+
self.names: list[str] = []
|
|
544
|
+
aliasOptions = {
|
|
545
|
+
'maxdepth': self.options.get('maxdepth', 1),
|
|
546
|
+
'noroot': 'noroot' in self.options,
|
|
547
|
+
}
|
|
548
|
+
if aliasOptions['noroot'] and aliasOptions['maxdepth'] == 1:
|
|
549
|
+
logger.warning("Error in C alias declaration."
|
|
550
|
+
" Requested 'noroot' but 'maxdepth' 1."
|
|
551
|
+
" When skipping the root declaration,"
|
|
552
|
+
" need 'maxdepth' 0 for infinite or at least 2.",
|
|
553
|
+
location=self.get_location())
|
|
554
|
+
for sig in self.get_signatures():
|
|
555
|
+
node.append(AliasNode(sig, aliasOptions, self.state.document, env=self.env))
|
|
556
|
+
return [node]
|
|
557
|
+
|
|
558
|
+
|
|
559
|
+
class CXRefRole(XRefRole):
|
|
560
|
+
def process_link(self, env: BuildEnvironment, refnode: Element,
|
|
561
|
+
has_explicit_title: bool, title: str, target: str) -> tuple[str, str]:
|
|
562
|
+
refnode.attributes.update(env.ref_context)
|
|
563
|
+
|
|
564
|
+
if not has_explicit_title:
|
|
565
|
+
# major hax: replace anon names via simple string manipulation.
|
|
566
|
+
# Can this actually fail?
|
|
567
|
+
title = anon_identifier_re.sub("[anonymous]", str(title))
|
|
568
|
+
|
|
569
|
+
if not has_explicit_title:
|
|
570
|
+
target = target.lstrip('~') # only has a meaning for the title
|
|
571
|
+
# if the first character is a tilde, don't display the module/class
|
|
572
|
+
# parts of the contents
|
|
573
|
+
if title[0:1] == '~':
|
|
574
|
+
title = title[1:]
|
|
575
|
+
dot = title.rfind('.')
|
|
576
|
+
if dot != -1:
|
|
577
|
+
title = title[dot + 1:]
|
|
578
|
+
return title, target
|
|
579
|
+
|
|
580
|
+
|
|
581
|
+
class CExprRole(SphinxRole):
|
|
582
|
+
def __init__(self, asCode: bool) -> None:
|
|
583
|
+
super().__init__()
|
|
584
|
+
if asCode:
|
|
585
|
+
# render the expression as inline code
|
|
586
|
+
self.class_type = 'c-expr'
|
|
587
|
+
else:
|
|
588
|
+
# render the expression as inline text
|
|
589
|
+
self.class_type = 'c-texpr'
|
|
590
|
+
|
|
591
|
+
def run(self) -> tuple[list[Node], list[system_message]]:
|
|
592
|
+
text = self.text.replace('\n', ' ')
|
|
593
|
+
parser = DefinitionParser(text, location=self.get_location(),
|
|
594
|
+
config=self.env.config)
|
|
595
|
+
# attempt to mimic XRefRole classes, except that...
|
|
596
|
+
try:
|
|
597
|
+
ast = parser.parse_expression()
|
|
598
|
+
except DefinitionError as ex:
|
|
599
|
+
logger.warning('Unparseable C expression: %r\n%s', text, ex,
|
|
600
|
+
location=self.get_location())
|
|
601
|
+
# see below
|
|
602
|
+
return [addnodes.desc_inline('c', text, text, classes=[self.class_type])], []
|
|
603
|
+
parentSymbol = self.env.temp_data.get('c:parent_symbol', None)
|
|
604
|
+
if parentSymbol is None:
|
|
605
|
+
parentSymbol = self.env.domaindata['c']['root_symbol']
|
|
606
|
+
# ...most if not all of these classes should really apply to the individual references,
|
|
607
|
+
# not the container node
|
|
608
|
+
signode = addnodes.desc_inline('c', classes=[self.class_type])
|
|
609
|
+
ast.describe_signature(signode, 'markType', self.env, parentSymbol)
|
|
610
|
+
return [signode], []
|
|
611
|
+
|
|
612
|
+
|
|
613
|
+
class CDomain(Domain):
|
|
614
|
+
"""C language domain."""
|
|
615
|
+
|
|
616
|
+
name = 'c'
|
|
617
|
+
label = 'C'
|
|
618
|
+
object_types = {
|
|
619
|
+
# 'identifier' is the one used for xrefs generated in signatures, not in roles
|
|
620
|
+
'member': ObjType(_('member'), 'var', 'member', 'data', 'identifier'),
|
|
621
|
+
'var': ObjType(_('variable'), 'var', 'member', 'data', 'identifier'),
|
|
622
|
+
'function': ObjType(_('function'), 'func', 'identifier', 'type'),
|
|
623
|
+
'macro': ObjType(_('macro'), 'macro', 'identifier'),
|
|
624
|
+
'struct': ObjType(_('struct'), 'struct', 'identifier', 'type'),
|
|
625
|
+
'union': ObjType(_('union'), 'union', 'identifier', 'type'),
|
|
626
|
+
'enum': ObjType(_('enum'), 'enum', 'identifier', 'type'),
|
|
627
|
+
'enumerator': ObjType(_('enumerator'), 'enumerator', 'identifier'),
|
|
628
|
+
'type': ObjType(_('type'), 'identifier', 'type'),
|
|
629
|
+
# generated object types
|
|
630
|
+
'functionParam': ObjType(_('function parameter'), 'identifier', 'var', 'member', 'data'), # NoQA: E501
|
|
631
|
+
}
|
|
632
|
+
|
|
633
|
+
directives = {
|
|
634
|
+
'member': CMemberObject,
|
|
635
|
+
'var': CMemberObject,
|
|
636
|
+
'function': CFunctionObject,
|
|
637
|
+
'macro': CMacroObject,
|
|
638
|
+
'struct': CStructObject,
|
|
639
|
+
'union': CUnionObject,
|
|
640
|
+
'enum': CEnumObject,
|
|
641
|
+
'enumerator': CEnumeratorObject,
|
|
642
|
+
'type': CTypeObject,
|
|
643
|
+
# scope control
|
|
644
|
+
'namespace': CNamespaceObject,
|
|
645
|
+
'namespace-push': CNamespacePushObject,
|
|
646
|
+
'namespace-pop': CNamespacePopObject,
|
|
647
|
+
# other
|
|
648
|
+
'alias': CAliasObject,
|
|
649
|
+
}
|
|
650
|
+
roles = {
|
|
651
|
+
'member': CXRefRole(),
|
|
652
|
+
'data': CXRefRole(),
|
|
653
|
+
'var': CXRefRole(),
|
|
654
|
+
'func': CXRefRole(fix_parens=True),
|
|
655
|
+
'macro': CXRefRole(),
|
|
656
|
+
'struct': CXRefRole(),
|
|
657
|
+
'union': CXRefRole(),
|
|
658
|
+
'enum': CXRefRole(),
|
|
659
|
+
'enumerator': CXRefRole(),
|
|
660
|
+
'type': CXRefRole(),
|
|
661
|
+
'expr': CExprRole(asCode=True),
|
|
662
|
+
'texpr': CExprRole(asCode=False),
|
|
663
|
+
}
|
|
664
|
+
initial_data: dict[str, Symbol | dict[str, tuple[str, str, str]]] = {
|
|
665
|
+
'root_symbol': Symbol(None, None, None, None, None),
|
|
666
|
+
'objects': {}, # fullname -> docname, node_id, objtype
|
|
667
|
+
}
|
|
668
|
+
|
|
669
|
+
def clear_doc(self, docname: str) -> None:
|
|
670
|
+
if Symbol.debug_show_tree:
|
|
671
|
+
logger.debug("clear_doc: %s", docname)
|
|
672
|
+
logger.debug("\tbefore:")
|
|
673
|
+
logger.debug(self.data['root_symbol'].dump(1))
|
|
674
|
+
logger.debug("\tbefore end")
|
|
675
|
+
|
|
676
|
+
rootSymbol = self.data['root_symbol']
|
|
677
|
+
rootSymbol.clear_doc(docname)
|
|
678
|
+
|
|
679
|
+
if Symbol.debug_show_tree:
|
|
680
|
+
logger.debug("\tafter:")
|
|
681
|
+
logger.debug(self.data['root_symbol'].dump(1))
|
|
682
|
+
logger.debug("\tafter end")
|
|
683
|
+
logger.debug("clear_doc end: %s", docname)
|
|
684
|
+
|
|
685
|
+
def process_doc(self, env: BuildEnvironment, docname: str,
|
|
686
|
+
document: nodes.document) -> None:
|
|
687
|
+
if Symbol.debug_show_tree:
|
|
688
|
+
logger.debug("process_doc: %s", docname)
|
|
689
|
+
logger.debug(self.data['root_symbol'].dump(0))
|
|
690
|
+
logger.debug("process_doc end: %s", docname)
|
|
691
|
+
|
|
692
|
+
def process_field_xref(self, pnode: pending_xref) -> None:
|
|
693
|
+
pnode.attributes.update(self.env.ref_context)
|
|
694
|
+
|
|
695
|
+
def merge_domaindata(self, docnames: list[str], otherdata: dict[str, Any]) -> None:
|
|
696
|
+
if Symbol.debug_show_tree:
|
|
697
|
+
logger.debug("merge_domaindata:")
|
|
698
|
+
logger.debug("\tself:")
|
|
699
|
+
logger.debug(self.data['root_symbol'].dump(1))
|
|
700
|
+
logger.debug("\tself end")
|
|
701
|
+
logger.debug("\tother:")
|
|
702
|
+
logger.debug(otherdata['root_symbol'].dump(1))
|
|
703
|
+
logger.debug("\tother end")
|
|
704
|
+
logger.debug("merge_domaindata end")
|
|
705
|
+
|
|
706
|
+
self.data['root_symbol'].merge_with(otherdata['root_symbol'],
|
|
707
|
+
docnames, self.env)
|
|
708
|
+
ourObjects = self.data['objects']
|
|
709
|
+
for fullname, (fn, id_, objtype) in otherdata['objects'].items():
|
|
710
|
+
if fn in docnames:
|
|
711
|
+
if fullname not in ourObjects:
|
|
712
|
+
ourObjects[fullname] = (fn, id_, objtype)
|
|
713
|
+
# no need to warn on duplicates, the symbol merge already does that
|
|
714
|
+
|
|
715
|
+
def _resolve_xref_inner(self, env: BuildEnvironment, fromdocname: str, builder: Builder,
|
|
716
|
+
typ: str, target: str, node: pending_xref,
|
|
717
|
+
contnode: Element) -> tuple[Element | None, str | None]:
|
|
718
|
+
parser = DefinitionParser(target, location=node, config=env.config)
|
|
719
|
+
try:
|
|
720
|
+
name = parser.parse_xref_object()
|
|
721
|
+
except DefinitionError as e:
|
|
722
|
+
logger.warning('Unparseable C cross-reference: %r\n%s', target, e,
|
|
723
|
+
location=node)
|
|
724
|
+
return None, None
|
|
725
|
+
parentKey: LookupKey = node.get("c:parent_key", None)
|
|
726
|
+
rootSymbol = self.data['root_symbol']
|
|
727
|
+
if parentKey:
|
|
728
|
+
parentSymbol: Symbol = rootSymbol.direct_lookup(parentKey)
|
|
729
|
+
if not parentSymbol:
|
|
730
|
+
logger.debug("Target: %s", target)
|
|
731
|
+
logger.debug("ParentKey: %s", parentKey)
|
|
732
|
+
logger.debug(rootSymbol.dump(1))
|
|
733
|
+
assert parentSymbol # should be there
|
|
734
|
+
else:
|
|
735
|
+
parentSymbol = rootSymbol
|
|
736
|
+
s = parentSymbol.find_declaration(name, typ,
|
|
737
|
+
matchSelf=True, recurseInAnon=True)
|
|
738
|
+
if s is None or s.declaration is None:
|
|
739
|
+
return None, None
|
|
740
|
+
|
|
741
|
+
# TODO: check role type vs. object type
|
|
742
|
+
|
|
743
|
+
declaration = s.declaration
|
|
744
|
+
displayName = name.get_display_string()
|
|
745
|
+
docname = s.docname
|
|
746
|
+
assert docname
|
|
747
|
+
|
|
748
|
+
return make_refnode(builder, fromdocname, docname,
|
|
749
|
+
declaration.get_newest_id(), contnode, displayName,
|
|
750
|
+
), declaration.objectType
|
|
751
|
+
|
|
752
|
+
def resolve_xref(self, env: BuildEnvironment, fromdocname: str, builder: Builder,
|
|
753
|
+
typ: str, target: str, node: pending_xref,
|
|
754
|
+
contnode: Element) -> Element | None:
|
|
755
|
+
return self._resolve_xref_inner(env, fromdocname, builder, typ,
|
|
756
|
+
target, node, contnode)[0]
|
|
757
|
+
|
|
758
|
+
def resolve_any_xref(self, env: BuildEnvironment, fromdocname: str, builder: Builder,
|
|
759
|
+
target: str, node: pending_xref, contnode: Element,
|
|
760
|
+
) -> list[tuple[str, Element]]:
|
|
761
|
+
with logging.suppress_logging():
|
|
762
|
+
retnode, objtype = self._resolve_xref_inner(env, fromdocname, builder,
|
|
763
|
+
'any', target, node, contnode)
|
|
764
|
+
if retnode:
|
|
765
|
+
return [('c:' + self.role_for_objtype(objtype), retnode)]
|
|
766
|
+
return []
|
|
767
|
+
|
|
768
|
+
def get_objects(self) -> Iterator[tuple[str, str, str, str, str, int]]:
|
|
769
|
+
rootSymbol = self.data['root_symbol']
|
|
770
|
+
for symbol in rootSymbol.get_all_symbols():
|
|
771
|
+
if symbol.declaration is None:
|
|
772
|
+
continue
|
|
773
|
+
assert symbol.docname
|
|
774
|
+
fullNestedName = symbol.get_full_nested_name()
|
|
775
|
+
name = str(fullNestedName).lstrip('.')
|
|
776
|
+
dispname = fullNestedName.get_display_string().lstrip('.')
|
|
777
|
+
objectType = symbol.declaration.objectType
|
|
778
|
+
docname = symbol.docname
|
|
779
|
+
newestId = symbol.declaration.get_newest_id()
|
|
780
|
+
yield (name, dispname, objectType, docname, newestId, 1)
|
|
781
|
+
|
|
782
|
+
|
|
783
|
+
def setup(app: Sphinx) -> ExtensionMetadata:
|
|
784
|
+
app.add_domain(CDomain)
|
|
785
|
+
app.add_config_value("c_id_attributes", [], 'env')
|
|
786
|
+
app.add_config_value("c_paren_attributes", [], 'env')
|
|
787
|
+
app.add_config_value("c_extra_keywords", _macroKeywords, 'env')
|
|
788
|
+
app.add_config_value("c_maximum_signature_line_length", None, 'env', types={int, None})
|
|
789
|
+
app.add_post_transform(AliasTransform)
|
|
790
|
+
|
|
791
|
+
return {
|
|
792
|
+
'version': 'builtin',
|
|
793
|
+
'env_version': 3,
|
|
794
|
+
'parallel_read_safe': True,
|
|
795
|
+
'parallel_write_safe': True,
|
|
796
|
+
}
|