Sphinx 7.2.6__py3-none-any.whl → 7.3.1__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 +4 -9
- 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 +102 -36
- 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.6.dist-info/LICENSE → sphinx-7.3.1.dist-info/LICENSE.rst +1 -1
- {sphinx-7.2.6.dist-info → sphinx-7.3.1.dist-info}/METADATA +14 -12
- sphinx-7.3.1.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.6.dist-info/RECORD +0 -569
- {sphinx-7.2.6.dist-info → sphinx-7.3.1.dist-info}/WHEEL +0 -0
- {sphinx-7.2.6.dist-info → sphinx-7.3.1.dist-info}/entry_points.txt +0 -0
|
@@ -0,0 +1,700 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import TYPE_CHECKING, Any, Callable
|
|
4
|
+
|
|
5
|
+
from sphinx.domains.c._ast import (
|
|
6
|
+
ASTDeclaration,
|
|
7
|
+
ASTIdentifier,
|
|
8
|
+
ASTNestedName,
|
|
9
|
+
)
|
|
10
|
+
from sphinx.locale import __
|
|
11
|
+
from sphinx.util import logging
|
|
12
|
+
|
|
13
|
+
if TYPE_CHECKING:
|
|
14
|
+
from collections.abc import Iterator
|
|
15
|
+
|
|
16
|
+
from typing_extensions import Self
|
|
17
|
+
|
|
18
|
+
from sphinx.environment import BuildEnvironment
|
|
19
|
+
|
|
20
|
+
logger = logging.getLogger(__name__)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class _DuplicateSymbolError(Exception):
|
|
24
|
+
def __init__(self, symbol: Symbol, declaration: ASTDeclaration) -> None:
|
|
25
|
+
assert symbol
|
|
26
|
+
assert declaration
|
|
27
|
+
self.symbol = symbol
|
|
28
|
+
self.declaration = declaration
|
|
29
|
+
|
|
30
|
+
def __str__(self) -> str:
|
|
31
|
+
return "Internal C duplicate symbol error:\n%s" % self.symbol.dump(0)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class SymbolLookupResult:
|
|
35
|
+
def __init__(self, symbols: Iterator[Symbol], parentSymbol: Symbol,
|
|
36
|
+
ident: ASTIdentifier) -> None:
|
|
37
|
+
self.symbols = symbols
|
|
38
|
+
self.parentSymbol = parentSymbol
|
|
39
|
+
self.ident = ident
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
class LookupKey:
|
|
43
|
+
def __init__(self, data: list[tuple[ASTIdentifier, str]]) -> None:
|
|
44
|
+
self.data = data
|
|
45
|
+
|
|
46
|
+
def __str__(self) -> str:
|
|
47
|
+
inner = ', '.join(f"({ident}, {id_})" for ident, id_ in self.data)
|
|
48
|
+
return f'[{inner}]'
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
class Symbol:
|
|
52
|
+
debug_indent = 0
|
|
53
|
+
debug_indent_string = " "
|
|
54
|
+
debug_lookup = False
|
|
55
|
+
debug_show_tree = False
|
|
56
|
+
|
|
57
|
+
def __copy__(self) -> Self:
|
|
58
|
+
raise AssertionError # shouldn't happen
|
|
59
|
+
|
|
60
|
+
def __deepcopy__(self, memo: Any) -> Symbol:
|
|
61
|
+
if self.parent:
|
|
62
|
+
raise AssertionError # shouldn't happen
|
|
63
|
+
# the domain base class makes a copy of the initial data, which is fine
|
|
64
|
+
return Symbol(None, None, None, None, None)
|
|
65
|
+
|
|
66
|
+
@staticmethod
|
|
67
|
+
def debug_print(*args: Any) -> None:
|
|
68
|
+
msg = Symbol.debug_indent_string * Symbol.debug_indent
|
|
69
|
+
msg += "".join(str(e) for e in args)
|
|
70
|
+
logger.debug(msg)
|
|
71
|
+
|
|
72
|
+
def _assert_invariants(self) -> None:
|
|
73
|
+
if not self.parent:
|
|
74
|
+
# parent == None means global scope, so declaration means a parent
|
|
75
|
+
assert not self.declaration
|
|
76
|
+
assert not self.docname
|
|
77
|
+
else:
|
|
78
|
+
if self.declaration:
|
|
79
|
+
assert self.docname
|
|
80
|
+
|
|
81
|
+
def __setattr__(self, key: str, value: Any) -> None:
|
|
82
|
+
if key == "children":
|
|
83
|
+
raise AssertionError
|
|
84
|
+
return super().__setattr__(key, value)
|
|
85
|
+
|
|
86
|
+
def __init__(
|
|
87
|
+
self,
|
|
88
|
+
parent: Symbol | None,
|
|
89
|
+
ident: ASTIdentifier | None,
|
|
90
|
+
declaration: ASTDeclaration | None,
|
|
91
|
+
docname: str | None,
|
|
92
|
+
line: int | None,
|
|
93
|
+
) -> None:
|
|
94
|
+
self.parent = parent
|
|
95
|
+
# declarations in a single directive are linked together
|
|
96
|
+
self.siblingAbove: Symbol | None = None
|
|
97
|
+
self.siblingBelow: Symbol | None = None
|
|
98
|
+
self.ident = ident
|
|
99
|
+
self.declaration = declaration
|
|
100
|
+
self.docname = docname
|
|
101
|
+
self.line = line
|
|
102
|
+
self.isRedeclaration = False
|
|
103
|
+
self._assert_invariants()
|
|
104
|
+
|
|
105
|
+
# Remember to modify Symbol.remove if modifications to the parent change.
|
|
106
|
+
self._children: list[Symbol] = []
|
|
107
|
+
self._anonChildren: list[Symbol] = []
|
|
108
|
+
# note: _children includes _anonChildren
|
|
109
|
+
if self.parent:
|
|
110
|
+
self.parent._children.append(self)
|
|
111
|
+
if self.declaration:
|
|
112
|
+
self.declaration.symbol = self
|
|
113
|
+
|
|
114
|
+
# Do symbol addition after self._children has been initialised.
|
|
115
|
+
self._add_function_params()
|
|
116
|
+
|
|
117
|
+
def _fill_empty(self, declaration: ASTDeclaration, docname: str, line: int) -> None:
|
|
118
|
+
self._assert_invariants()
|
|
119
|
+
assert self.declaration is None
|
|
120
|
+
assert self.docname is None
|
|
121
|
+
assert self.line is None
|
|
122
|
+
assert declaration is not None
|
|
123
|
+
assert docname is not None
|
|
124
|
+
assert line is not None
|
|
125
|
+
self.declaration = declaration
|
|
126
|
+
self.declaration.symbol = self
|
|
127
|
+
self.docname = docname
|
|
128
|
+
self.line = line
|
|
129
|
+
self._assert_invariants()
|
|
130
|
+
# and symbol addition should be done as well
|
|
131
|
+
self._add_function_params()
|
|
132
|
+
|
|
133
|
+
def _add_function_params(self) -> None:
|
|
134
|
+
if Symbol.debug_lookup:
|
|
135
|
+
Symbol.debug_indent += 1
|
|
136
|
+
Symbol.debug_print("_add_function_params:")
|
|
137
|
+
# Note: we may be called from _fill_empty, so the symbols we want
|
|
138
|
+
# to add may actually already be present (as empty symbols).
|
|
139
|
+
|
|
140
|
+
# add symbols for function parameters, if any
|
|
141
|
+
if self.declaration is not None and self.declaration.function_params is not None:
|
|
142
|
+
for p in self.declaration.function_params:
|
|
143
|
+
if p.arg is None:
|
|
144
|
+
continue
|
|
145
|
+
nn = p.arg.name
|
|
146
|
+
if nn is None:
|
|
147
|
+
continue
|
|
148
|
+
# (comparing to the template params: we have checked that we are a declaration)
|
|
149
|
+
decl = ASTDeclaration('functionParam', None, p)
|
|
150
|
+
assert not nn.rooted
|
|
151
|
+
assert len(nn.names) == 1
|
|
152
|
+
self._add_symbols(nn, decl, self.docname, self.line)
|
|
153
|
+
if Symbol.debug_lookup:
|
|
154
|
+
Symbol.debug_indent -= 1
|
|
155
|
+
|
|
156
|
+
def remove(self) -> None:
|
|
157
|
+
if self.parent is None:
|
|
158
|
+
return
|
|
159
|
+
assert self in self.parent._children
|
|
160
|
+
self.parent._children.remove(self)
|
|
161
|
+
self.parent = None
|
|
162
|
+
|
|
163
|
+
def clear_doc(self, docname: str) -> None:
|
|
164
|
+
for sChild in self._children:
|
|
165
|
+
sChild.clear_doc(docname)
|
|
166
|
+
if sChild.declaration and sChild.docname == docname:
|
|
167
|
+
sChild.declaration = None
|
|
168
|
+
sChild.docname = None
|
|
169
|
+
sChild.line = None
|
|
170
|
+
if sChild.siblingAbove is not None:
|
|
171
|
+
sChild.siblingAbove.siblingBelow = sChild.siblingBelow
|
|
172
|
+
if sChild.siblingBelow is not None:
|
|
173
|
+
sChild.siblingBelow.siblingAbove = sChild.siblingAbove
|
|
174
|
+
sChild.siblingAbove = None
|
|
175
|
+
sChild.siblingBelow = None
|
|
176
|
+
|
|
177
|
+
def get_all_symbols(self) -> Iterator[Symbol]:
|
|
178
|
+
yield self
|
|
179
|
+
for sChild in self._children:
|
|
180
|
+
yield from sChild.get_all_symbols()
|
|
181
|
+
|
|
182
|
+
@property
|
|
183
|
+
def children(self) -> Iterator[Symbol]:
|
|
184
|
+
yield from self._children
|
|
185
|
+
|
|
186
|
+
@property
|
|
187
|
+
def children_recurse_anon(self) -> Iterator[Symbol]:
|
|
188
|
+
for c in self._children:
|
|
189
|
+
yield c
|
|
190
|
+
if not c.ident.is_anon():
|
|
191
|
+
continue
|
|
192
|
+
yield from c.children_recurse_anon
|
|
193
|
+
|
|
194
|
+
def get_lookup_key(self) -> LookupKey:
|
|
195
|
+
# The pickle files for the environment and for each document are distinct.
|
|
196
|
+
# The environment has all the symbols, but the documents has xrefs that
|
|
197
|
+
# must know their scope. A lookup key is essentially a specification of
|
|
198
|
+
# how to find a specific symbol.
|
|
199
|
+
symbols = []
|
|
200
|
+
s = self
|
|
201
|
+
while s.parent:
|
|
202
|
+
symbols.append(s)
|
|
203
|
+
s = s.parent
|
|
204
|
+
symbols.reverse()
|
|
205
|
+
key = []
|
|
206
|
+
for s in symbols:
|
|
207
|
+
if s.declaration is not None:
|
|
208
|
+
# TODO: do we need the ID?
|
|
209
|
+
key.append((s.ident, s.declaration.get_newest_id()))
|
|
210
|
+
else:
|
|
211
|
+
key.append((s.ident, None))
|
|
212
|
+
return LookupKey(key)
|
|
213
|
+
|
|
214
|
+
def get_full_nested_name(self) -> ASTNestedName:
|
|
215
|
+
symbols = []
|
|
216
|
+
s = self
|
|
217
|
+
while s.parent:
|
|
218
|
+
symbols.append(s)
|
|
219
|
+
s = s.parent
|
|
220
|
+
symbols.reverse()
|
|
221
|
+
names = [s.ident for s in symbols]
|
|
222
|
+
return ASTNestedName(names, rooted=False)
|
|
223
|
+
|
|
224
|
+
def _find_first_named_symbol(self, ident: ASTIdentifier,
|
|
225
|
+
matchSelf: bool, recurseInAnon: bool) -> Symbol | None:
|
|
226
|
+
# TODO: further simplification from C++ to C
|
|
227
|
+
if Symbol.debug_lookup:
|
|
228
|
+
Symbol.debug_print("_find_first_named_symbol ->")
|
|
229
|
+
res = self._find_named_symbols(ident, matchSelf, recurseInAnon,
|
|
230
|
+
searchInSiblings=False)
|
|
231
|
+
try:
|
|
232
|
+
return next(res)
|
|
233
|
+
except StopIteration:
|
|
234
|
+
return None
|
|
235
|
+
|
|
236
|
+
def _find_named_symbols(self, ident: ASTIdentifier,
|
|
237
|
+
matchSelf: bool, recurseInAnon: bool,
|
|
238
|
+
searchInSiblings: bool) -> Iterator[Symbol]:
|
|
239
|
+
# TODO: further simplification from C++ to C
|
|
240
|
+
if Symbol.debug_lookup:
|
|
241
|
+
Symbol.debug_indent += 1
|
|
242
|
+
Symbol.debug_print("_find_named_symbols:")
|
|
243
|
+
Symbol.debug_indent += 1
|
|
244
|
+
Symbol.debug_print("self:")
|
|
245
|
+
logger.debug(self.to_string(Symbol.debug_indent + 1, addEndNewline=False))
|
|
246
|
+
Symbol.debug_print("ident: ", ident)
|
|
247
|
+
Symbol.debug_print("matchSelf: ", matchSelf)
|
|
248
|
+
Symbol.debug_print("recurseInAnon: ", recurseInAnon)
|
|
249
|
+
Symbol.debug_print("searchInSiblings: ", searchInSiblings)
|
|
250
|
+
|
|
251
|
+
def candidates() -> Iterator[Symbol]:
|
|
252
|
+
s = self
|
|
253
|
+
if Symbol.debug_lookup:
|
|
254
|
+
Symbol.debug_print("searching in self:")
|
|
255
|
+
logger.debug(s.to_string(Symbol.debug_indent + 1, addEndNewline=False))
|
|
256
|
+
while True:
|
|
257
|
+
if matchSelf:
|
|
258
|
+
yield s
|
|
259
|
+
if recurseInAnon:
|
|
260
|
+
yield from s.children_recurse_anon
|
|
261
|
+
else:
|
|
262
|
+
yield from s._children
|
|
263
|
+
|
|
264
|
+
if s.siblingAbove is None:
|
|
265
|
+
break
|
|
266
|
+
s = s.siblingAbove
|
|
267
|
+
if Symbol.debug_lookup:
|
|
268
|
+
Symbol.debug_print("searching in sibling:")
|
|
269
|
+
logger.debug(s.to_string(Symbol.debug_indent + 1, addEndNewline=False))
|
|
270
|
+
|
|
271
|
+
for s in candidates():
|
|
272
|
+
if Symbol.debug_lookup:
|
|
273
|
+
Symbol.debug_print("candidate:")
|
|
274
|
+
logger.debug(s.to_string(Symbol.debug_indent + 1, addEndNewline=False))
|
|
275
|
+
if s.ident == ident:
|
|
276
|
+
if Symbol.debug_lookup:
|
|
277
|
+
Symbol.debug_indent += 1
|
|
278
|
+
Symbol.debug_print("matches")
|
|
279
|
+
Symbol.debug_indent -= 3
|
|
280
|
+
yield s
|
|
281
|
+
if Symbol.debug_lookup:
|
|
282
|
+
Symbol.debug_indent += 2
|
|
283
|
+
if Symbol.debug_lookup:
|
|
284
|
+
Symbol.debug_indent -= 2
|
|
285
|
+
|
|
286
|
+
def _symbol_lookup(
|
|
287
|
+
self,
|
|
288
|
+
nestedName: ASTNestedName,
|
|
289
|
+
onMissingQualifiedSymbol: Callable[[Symbol, ASTIdentifier], Symbol | None],
|
|
290
|
+
ancestorLookupType: str | None,
|
|
291
|
+
matchSelf: bool,
|
|
292
|
+
recurseInAnon: bool,
|
|
293
|
+
searchInSiblings: bool,
|
|
294
|
+
) -> SymbolLookupResult | None:
|
|
295
|
+
# TODO: further simplification from C++ to C
|
|
296
|
+
# ancestorLookupType: if not None, specifies the target type of the lookup
|
|
297
|
+
if Symbol.debug_lookup:
|
|
298
|
+
Symbol.debug_indent += 1
|
|
299
|
+
Symbol.debug_print("_symbol_lookup:")
|
|
300
|
+
Symbol.debug_indent += 1
|
|
301
|
+
Symbol.debug_print("self:")
|
|
302
|
+
logger.debug(self.to_string(Symbol.debug_indent + 1, addEndNewline=False))
|
|
303
|
+
Symbol.debug_print("nestedName: ", nestedName)
|
|
304
|
+
Symbol.debug_print("ancestorLookupType:", ancestorLookupType)
|
|
305
|
+
Symbol.debug_print("matchSelf: ", matchSelf)
|
|
306
|
+
Symbol.debug_print("recurseInAnon: ", recurseInAnon)
|
|
307
|
+
Symbol.debug_print("searchInSiblings: ", searchInSiblings)
|
|
308
|
+
|
|
309
|
+
names = nestedName.names
|
|
310
|
+
|
|
311
|
+
# find the right starting point for lookup
|
|
312
|
+
parentSymbol = self
|
|
313
|
+
if nestedName.rooted:
|
|
314
|
+
while parentSymbol.parent:
|
|
315
|
+
parentSymbol = parentSymbol.parent
|
|
316
|
+
if ancestorLookupType is not None:
|
|
317
|
+
# walk up until we find the first identifier
|
|
318
|
+
firstName = names[0]
|
|
319
|
+
while parentSymbol.parent:
|
|
320
|
+
if parentSymbol.find_identifier(firstName,
|
|
321
|
+
matchSelf=matchSelf,
|
|
322
|
+
recurseInAnon=recurseInAnon,
|
|
323
|
+
searchInSiblings=searchInSiblings):
|
|
324
|
+
break
|
|
325
|
+
parentSymbol = parentSymbol.parent
|
|
326
|
+
|
|
327
|
+
if Symbol.debug_lookup:
|
|
328
|
+
Symbol.debug_print("starting point:")
|
|
329
|
+
logger.debug(parentSymbol.to_string(Symbol.debug_indent + 1, addEndNewline=False))
|
|
330
|
+
|
|
331
|
+
# and now the actual lookup
|
|
332
|
+
for ident in names[:-1]:
|
|
333
|
+
symbol = parentSymbol._find_first_named_symbol(
|
|
334
|
+
ident, matchSelf=matchSelf, recurseInAnon=recurseInAnon)
|
|
335
|
+
if symbol is None:
|
|
336
|
+
symbol = onMissingQualifiedSymbol(parentSymbol, ident)
|
|
337
|
+
if symbol is None:
|
|
338
|
+
if Symbol.debug_lookup:
|
|
339
|
+
Symbol.debug_indent -= 2
|
|
340
|
+
return None
|
|
341
|
+
# We have now matched part of a nested name, and need to match more
|
|
342
|
+
# so even if we should matchSelf before, we definitely shouldn't
|
|
343
|
+
# even more. (see also issue #2666)
|
|
344
|
+
matchSelf = False
|
|
345
|
+
parentSymbol = symbol
|
|
346
|
+
|
|
347
|
+
if Symbol.debug_lookup:
|
|
348
|
+
Symbol.debug_print("handle last name from:")
|
|
349
|
+
logger.debug(parentSymbol.to_string(Symbol.debug_indent + 1, addEndNewline=False))
|
|
350
|
+
|
|
351
|
+
# handle the last name
|
|
352
|
+
ident = names[-1]
|
|
353
|
+
|
|
354
|
+
symbols = parentSymbol._find_named_symbols(
|
|
355
|
+
ident, matchSelf=matchSelf,
|
|
356
|
+
recurseInAnon=recurseInAnon,
|
|
357
|
+
searchInSiblings=searchInSiblings)
|
|
358
|
+
if Symbol.debug_lookup:
|
|
359
|
+
symbols = list(symbols) # type: ignore[assignment]
|
|
360
|
+
Symbol.debug_indent -= 2
|
|
361
|
+
return SymbolLookupResult(symbols, parentSymbol, ident)
|
|
362
|
+
|
|
363
|
+
def _add_symbols(
|
|
364
|
+
self,
|
|
365
|
+
nestedName: ASTNestedName,
|
|
366
|
+
declaration: ASTDeclaration | None,
|
|
367
|
+
docname: str | None,
|
|
368
|
+
line: int | None,
|
|
369
|
+
) -> Symbol:
|
|
370
|
+
# TODO: further simplification from C++ to C
|
|
371
|
+
# Used for adding a whole path of symbols, where the last may or may not
|
|
372
|
+
# be an actual declaration.
|
|
373
|
+
|
|
374
|
+
if Symbol.debug_lookup:
|
|
375
|
+
Symbol.debug_indent += 1
|
|
376
|
+
Symbol.debug_print("_add_symbols:")
|
|
377
|
+
Symbol.debug_indent += 1
|
|
378
|
+
Symbol.debug_print("nn: ", nestedName)
|
|
379
|
+
Symbol.debug_print("decl: ", declaration)
|
|
380
|
+
Symbol.debug_print(f"location: {docname}:{line}")
|
|
381
|
+
|
|
382
|
+
def onMissingQualifiedSymbol(parentSymbol: Symbol, ident: ASTIdentifier) -> Symbol:
|
|
383
|
+
if Symbol.debug_lookup:
|
|
384
|
+
Symbol.debug_indent += 1
|
|
385
|
+
Symbol.debug_print("_add_symbols, onMissingQualifiedSymbol:")
|
|
386
|
+
Symbol.debug_indent += 1
|
|
387
|
+
Symbol.debug_print("ident: ", ident)
|
|
388
|
+
Symbol.debug_indent -= 2
|
|
389
|
+
return Symbol(parent=parentSymbol, ident=ident,
|
|
390
|
+
declaration=None, docname=None, line=None)
|
|
391
|
+
|
|
392
|
+
lookupResult = self._symbol_lookup(nestedName,
|
|
393
|
+
onMissingQualifiedSymbol,
|
|
394
|
+
ancestorLookupType=None,
|
|
395
|
+
matchSelf=False,
|
|
396
|
+
recurseInAnon=False,
|
|
397
|
+
searchInSiblings=False)
|
|
398
|
+
assert lookupResult is not None # we create symbols all the way, so that can't happen
|
|
399
|
+
symbols = list(lookupResult.symbols)
|
|
400
|
+
if len(symbols) == 0:
|
|
401
|
+
if Symbol.debug_lookup:
|
|
402
|
+
Symbol.debug_print("_add_symbols, result, no symbol:")
|
|
403
|
+
Symbol.debug_indent += 1
|
|
404
|
+
Symbol.debug_print("ident: ", lookupResult.ident)
|
|
405
|
+
Symbol.debug_print("declaration: ", declaration)
|
|
406
|
+
Symbol.debug_print(f"location: {docname}:{line}")
|
|
407
|
+
Symbol.debug_indent -= 1
|
|
408
|
+
symbol = Symbol(parent=lookupResult.parentSymbol,
|
|
409
|
+
ident=lookupResult.ident,
|
|
410
|
+
declaration=declaration,
|
|
411
|
+
docname=docname, line=line)
|
|
412
|
+
if Symbol.debug_lookup:
|
|
413
|
+
Symbol.debug_indent -= 2
|
|
414
|
+
return symbol
|
|
415
|
+
|
|
416
|
+
if Symbol.debug_lookup:
|
|
417
|
+
Symbol.debug_print("_add_symbols, result, symbols:")
|
|
418
|
+
Symbol.debug_indent += 1
|
|
419
|
+
Symbol.debug_print("number symbols:", len(symbols))
|
|
420
|
+
Symbol.debug_indent -= 1
|
|
421
|
+
|
|
422
|
+
if not declaration:
|
|
423
|
+
if Symbol.debug_lookup:
|
|
424
|
+
Symbol.debug_print("no declaration")
|
|
425
|
+
Symbol.debug_indent -= 2
|
|
426
|
+
# good, just a scope creation
|
|
427
|
+
# TODO: what if we have more than one symbol?
|
|
428
|
+
return symbols[0]
|
|
429
|
+
|
|
430
|
+
noDecl = []
|
|
431
|
+
withDecl = []
|
|
432
|
+
dupDecl = []
|
|
433
|
+
for s in symbols:
|
|
434
|
+
if s.declaration is None:
|
|
435
|
+
noDecl.append(s)
|
|
436
|
+
elif s.isRedeclaration:
|
|
437
|
+
dupDecl.append(s)
|
|
438
|
+
else:
|
|
439
|
+
withDecl.append(s)
|
|
440
|
+
if Symbol.debug_lookup:
|
|
441
|
+
Symbol.debug_print("#noDecl: ", len(noDecl))
|
|
442
|
+
Symbol.debug_print("#withDecl:", len(withDecl))
|
|
443
|
+
Symbol.debug_print("#dupDecl: ", len(dupDecl))
|
|
444
|
+
|
|
445
|
+
# With partial builds we may start with a large symbol tree stripped of declarations.
|
|
446
|
+
# Essentially any combination of noDecl, withDecl, and dupDecls seems possible.
|
|
447
|
+
# TODO: make partial builds fully work. What should happen when the primary symbol gets
|
|
448
|
+
# deleted, and other duplicates exist? The full document should probably be rebuild.
|
|
449
|
+
|
|
450
|
+
# First check if one of those with a declaration matches.
|
|
451
|
+
# If it's a function, we need to compare IDs,
|
|
452
|
+
# otherwise there should be only one symbol with a declaration.
|
|
453
|
+
def makeCandSymbol() -> Symbol:
|
|
454
|
+
if Symbol.debug_lookup:
|
|
455
|
+
Symbol.debug_print("begin: creating candidate symbol")
|
|
456
|
+
symbol = Symbol(parent=lookupResult.parentSymbol,
|
|
457
|
+
ident=lookupResult.ident,
|
|
458
|
+
declaration=declaration,
|
|
459
|
+
docname=docname, line=line)
|
|
460
|
+
if Symbol.debug_lookup:
|
|
461
|
+
Symbol.debug_print("end: creating candidate symbol")
|
|
462
|
+
return symbol
|
|
463
|
+
|
|
464
|
+
if len(withDecl) == 0:
|
|
465
|
+
candSymbol = None
|
|
466
|
+
else:
|
|
467
|
+
candSymbol = makeCandSymbol()
|
|
468
|
+
|
|
469
|
+
def handleDuplicateDeclaration(symbol: Symbol, candSymbol: Symbol) -> None:
|
|
470
|
+
if Symbol.debug_lookup:
|
|
471
|
+
Symbol.debug_indent += 1
|
|
472
|
+
Symbol.debug_print("redeclaration")
|
|
473
|
+
Symbol.debug_indent -= 1
|
|
474
|
+
Symbol.debug_indent -= 2
|
|
475
|
+
# Redeclaration of the same symbol.
|
|
476
|
+
# Let the new one be there, but raise an error to the client
|
|
477
|
+
# so it can use the real symbol as subscope.
|
|
478
|
+
# This will probably result in a duplicate id warning.
|
|
479
|
+
candSymbol.isRedeclaration = True
|
|
480
|
+
raise _DuplicateSymbolError(symbol, declaration)
|
|
481
|
+
|
|
482
|
+
if declaration.objectType != "function":
|
|
483
|
+
assert len(withDecl) <= 1
|
|
484
|
+
handleDuplicateDeclaration(withDecl[0], candSymbol)
|
|
485
|
+
# (not reachable)
|
|
486
|
+
|
|
487
|
+
# a function, so compare IDs
|
|
488
|
+
candId = declaration.get_newest_id()
|
|
489
|
+
if Symbol.debug_lookup:
|
|
490
|
+
Symbol.debug_print("candId:", candId)
|
|
491
|
+
for symbol in withDecl:
|
|
492
|
+
oldId = symbol.declaration.get_newest_id()
|
|
493
|
+
if Symbol.debug_lookup:
|
|
494
|
+
Symbol.debug_print("oldId: ", oldId)
|
|
495
|
+
if candId == oldId:
|
|
496
|
+
handleDuplicateDeclaration(symbol, candSymbol)
|
|
497
|
+
# (not reachable)
|
|
498
|
+
# no candidate symbol found with matching ID
|
|
499
|
+
# if there is an empty symbol, fill that one
|
|
500
|
+
if len(noDecl) == 0:
|
|
501
|
+
if Symbol.debug_lookup:
|
|
502
|
+
Symbol.debug_print(
|
|
503
|
+
"no match, no empty, candSybmol is not None?:", candSymbol is not None,
|
|
504
|
+
)
|
|
505
|
+
Symbol.debug_indent -= 2
|
|
506
|
+
if candSymbol is not None:
|
|
507
|
+
return candSymbol
|
|
508
|
+
else:
|
|
509
|
+
return makeCandSymbol()
|
|
510
|
+
else:
|
|
511
|
+
if Symbol.debug_lookup:
|
|
512
|
+
Symbol.debug_print(
|
|
513
|
+
"no match, but fill an empty declaration, candSybmol is not None?:",
|
|
514
|
+
candSymbol is not None)
|
|
515
|
+
Symbol.debug_indent -= 2
|
|
516
|
+
if candSymbol is not None:
|
|
517
|
+
candSymbol.remove()
|
|
518
|
+
# assert len(noDecl) == 1
|
|
519
|
+
# TODO: enable assertion when we at some point find out how to do cleanup
|
|
520
|
+
# for now, just take the first one, it should work fine ... right?
|
|
521
|
+
symbol = noDecl[0]
|
|
522
|
+
# If someone first opened the scope, and then later
|
|
523
|
+
# declares it, e.g,
|
|
524
|
+
# .. namespace:: Test
|
|
525
|
+
# .. namespace:: nullptr
|
|
526
|
+
# .. class:: Test
|
|
527
|
+
symbol._fill_empty(declaration, docname, line)
|
|
528
|
+
return symbol
|
|
529
|
+
|
|
530
|
+
def merge_with(self, other: Symbol, docnames: list[str],
|
|
531
|
+
env: BuildEnvironment) -> None:
|
|
532
|
+
if Symbol.debug_lookup:
|
|
533
|
+
Symbol.debug_indent += 1
|
|
534
|
+
Symbol.debug_print("merge_with:")
|
|
535
|
+
assert other is not None
|
|
536
|
+
for otherChild in other._children:
|
|
537
|
+
ourChild = self._find_first_named_symbol(
|
|
538
|
+
ident=otherChild.ident, matchSelf=False,
|
|
539
|
+
recurseInAnon=False)
|
|
540
|
+
if ourChild is None:
|
|
541
|
+
# TODO: hmm, should we prune by docnames?
|
|
542
|
+
self._children.append(otherChild)
|
|
543
|
+
otherChild.parent = self
|
|
544
|
+
otherChild._assert_invariants()
|
|
545
|
+
continue
|
|
546
|
+
if otherChild.declaration and otherChild.docname in docnames:
|
|
547
|
+
if not ourChild.declaration:
|
|
548
|
+
ourChild._fill_empty(otherChild.declaration,
|
|
549
|
+
otherChild.docname, otherChild.line)
|
|
550
|
+
elif ourChild.docname != otherChild.docname:
|
|
551
|
+
name = str(ourChild.declaration)
|
|
552
|
+
msg = __("Duplicate C declaration, also defined at %s:%s.\n"
|
|
553
|
+
"Declaration is '.. c:%s:: %s'.")
|
|
554
|
+
msg = msg % (ourChild.docname, ourChild.line,
|
|
555
|
+
ourChild.declaration.directiveType, name)
|
|
556
|
+
logger.warning(msg, location=(otherChild.docname, otherChild.line))
|
|
557
|
+
else:
|
|
558
|
+
# Both have declarations, and in the same docname.
|
|
559
|
+
# This can apparently happen, it should be safe to
|
|
560
|
+
# just ignore it, right?
|
|
561
|
+
pass
|
|
562
|
+
ourChild.merge_with(otherChild, docnames, env)
|
|
563
|
+
if Symbol.debug_lookup:
|
|
564
|
+
Symbol.debug_indent -= 1
|
|
565
|
+
|
|
566
|
+
def add_name(self, nestedName: ASTNestedName) -> Symbol:
|
|
567
|
+
if Symbol.debug_lookup:
|
|
568
|
+
Symbol.debug_indent += 1
|
|
569
|
+
Symbol.debug_print("add_name:")
|
|
570
|
+
res = self._add_symbols(nestedName, declaration=None, docname=None, line=None)
|
|
571
|
+
if Symbol.debug_lookup:
|
|
572
|
+
Symbol.debug_indent -= 1
|
|
573
|
+
return res
|
|
574
|
+
|
|
575
|
+
def add_declaration(self, declaration: ASTDeclaration,
|
|
576
|
+
docname: str, line: int) -> Symbol:
|
|
577
|
+
if Symbol.debug_lookup:
|
|
578
|
+
Symbol.debug_indent += 1
|
|
579
|
+
Symbol.debug_print("add_declaration:")
|
|
580
|
+
assert declaration is not None
|
|
581
|
+
assert docname is not None
|
|
582
|
+
assert line is not None
|
|
583
|
+
nestedName = declaration.name
|
|
584
|
+
res = self._add_symbols(nestedName, declaration, docname, line)
|
|
585
|
+
if Symbol.debug_lookup:
|
|
586
|
+
Symbol.debug_indent -= 1
|
|
587
|
+
return res
|
|
588
|
+
|
|
589
|
+
def find_identifier(self, ident: ASTIdentifier,
|
|
590
|
+
matchSelf: bool, recurseInAnon: bool, searchInSiblings: bool,
|
|
591
|
+
) -> Symbol | None:
|
|
592
|
+
if Symbol.debug_lookup:
|
|
593
|
+
Symbol.debug_indent += 1
|
|
594
|
+
Symbol.debug_print("find_identifier:")
|
|
595
|
+
Symbol.debug_indent += 1
|
|
596
|
+
Symbol.debug_print("ident: ", ident)
|
|
597
|
+
Symbol.debug_print("matchSelf: ", matchSelf)
|
|
598
|
+
Symbol.debug_print("recurseInAnon: ", recurseInAnon)
|
|
599
|
+
Symbol.debug_print("searchInSiblings:", searchInSiblings)
|
|
600
|
+
logger.debug(self.to_string(Symbol.debug_indent + 1, addEndNewline=False))
|
|
601
|
+
Symbol.debug_indent -= 2
|
|
602
|
+
current = self
|
|
603
|
+
while current is not None:
|
|
604
|
+
if Symbol.debug_lookup:
|
|
605
|
+
Symbol.debug_indent += 2
|
|
606
|
+
Symbol.debug_print("trying:")
|
|
607
|
+
logger.debug(current.to_string(Symbol.debug_indent + 1, addEndNewline=False))
|
|
608
|
+
Symbol.debug_indent -= 2
|
|
609
|
+
if matchSelf and current.ident == ident:
|
|
610
|
+
return current
|
|
611
|
+
children = current.children_recurse_anon if recurseInAnon else current._children
|
|
612
|
+
for s in children:
|
|
613
|
+
if s.ident == ident:
|
|
614
|
+
return s
|
|
615
|
+
if not searchInSiblings:
|
|
616
|
+
break
|
|
617
|
+
current = current.siblingAbove
|
|
618
|
+
return None
|
|
619
|
+
|
|
620
|
+
def direct_lookup(self, key: LookupKey) -> Symbol | None:
|
|
621
|
+
if Symbol.debug_lookup:
|
|
622
|
+
Symbol.debug_indent += 1
|
|
623
|
+
Symbol.debug_print("direct_lookup:")
|
|
624
|
+
Symbol.debug_indent += 1
|
|
625
|
+
s = self
|
|
626
|
+
for name, id_ in key.data:
|
|
627
|
+
res = None
|
|
628
|
+
for cand in s._children:
|
|
629
|
+
if cand.ident == name:
|
|
630
|
+
res = cand
|
|
631
|
+
break
|
|
632
|
+
s = res
|
|
633
|
+
if Symbol.debug_lookup:
|
|
634
|
+
Symbol.debug_print("name: ", name)
|
|
635
|
+
Symbol.debug_print("id: ", id_)
|
|
636
|
+
if s is not None:
|
|
637
|
+
logger.debug(s.to_string(Symbol.debug_indent + 1, addEndNewline=False))
|
|
638
|
+
else:
|
|
639
|
+
Symbol.debug_print("not found")
|
|
640
|
+
if s is None:
|
|
641
|
+
if Symbol.debug_lookup:
|
|
642
|
+
Symbol.debug_indent -= 2
|
|
643
|
+
return None
|
|
644
|
+
if Symbol.debug_lookup:
|
|
645
|
+
Symbol.debug_indent -= 2
|
|
646
|
+
return s
|
|
647
|
+
|
|
648
|
+
def find_declaration(self, nestedName: ASTNestedName, typ: str,
|
|
649
|
+
matchSelf: bool, recurseInAnon: bool) -> Symbol | None:
|
|
650
|
+
# templateShorthand: missing template parameter lists for templates is ok
|
|
651
|
+
if Symbol.debug_lookup:
|
|
652
|
+
Symbol.debug_indent += 1
|
|
653
|
+
Symbol.debug_print("find_declaration:")
|
|
654
|
+
|
|
655
|
+
def onMissingQualifiedSymbol(
|
|
656
|
+
parentSymbol: Symbol,
|
|
657
|
+
ident: ASTIdentifier,
|
|
658
|
+
) -> Symbol | None:
|
|
659
|
+
return None
|
|
660
|
+
|
|
661
|
+
lookupResult = self._symbol_lookup(nestedName,
|
|
662
|
+
onMissingQualifiedSymbol,
|
|
663
|
+
ancestorLookupType=typ,
|
|
664
|
+
matchSelf=matchSelf,
|
|
665
|
+
recurseInAnon=recurseInAnon,
|
|
666
|
+
searchInSiblings=False)
|
|
667
|
+
if Symbol.debug_lookup:
|
|
668
|
+
Symbol.debug_indent -= 1
|
|
669
|
+
if lookupResult is None:
|
|
670
|
+
return None
|
|
671
|
+
|
|
672
|
+
symbols = list(lookupResult.symbols)
|
|
673
|
+
if len(symbols) == 0:
|
|
674
|
+
return None
|
|
675
|
+
return symbols[0]
|
|
676
|
+
|
|
677
|
+
def to_string(self, indent: int, *, addEndNewline: bool = True) -> str:
|
|
678
|
+
res = [Symbol.debug_indent_string * indent]
|
|
679
|
+
if not self.parent:
|
|
680
|
+
res.append('::')
|
|
681
|
+
else:
|
|
682
|
+
if self.ident:
|
|
683
|
+
res.append(str(self.ident))
|
|
684
|
+
else:
|
|
685
|
+
res.append(str(self.declaration))
|
|
686
|
+
if self.declaration:
|
|
687
|
+
res.append(": ")
|
|
688
|
+
if self.isRedeclaration:
|
|
689
|
+
res.append('!!duplicate!! ')
|
|
690
|
+
res.append(str(self.declaration))
|
|
691
|
+
if self.docname:
|
|
692
|
+
res.append('\t(')
|
|
693
|
+
res.append(self.docname)
|
|
694
|
+
res.append(')')
|
|
695
|
+
if addEndNewline:
|
|
696
|
+
res.append('\n')
|
|
697
|
+
return ''.join(res)
|
|
698
|
+
|
|
699
|
+
def dump(self, indent: int) -> str:
|
|
700
|
+
return ''.join([self.to_string(indent), *(c.dump(indent + 1) for c in self._children)])
|