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,1092 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import TYPE_CHECKING, Any, Callable, NoReturn
|
|
4
|
+
|
|
5
|
+
from sphinx.domains.cpp._ast import (
|
|
6
|
+
ASTDeclaration,
|
|
7
|
+
ASTIdentifier,
|
|
8
|
+
ASTNestedName,
|
|
9
|
+
ASTNestedNameElement,
|
|
10
|
+
ASTOperator,
|
|
11
|
+
ASTTemplateArgs,
|
|
12
|
+
ASTTemplateDeclarationPrefix,
|
|
13
|
+
ASTTemplateIntroduction,
|
|
14
|
+
ASTTemplateParams,
|
|
15
|
+
)
|
|
16
|
+
from sphinx.locale import __
|
|
17
|
+
from sphinx.util import logging
|
|
18
|
+
|
|
19
|
+
if TYPE_CHECKING:
|
|
20
|
+
from collections.abc import Iterator
|
|
21
|
+
|
|
22
|
+
from sphinx.environment import BuildEnvironment
|
|
23
|
+
|
|
24
|
+
logger = logging.getLogger(__name__)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class _DuplicateSymbolError(Exception):
|
|
28
|
+
def __init__(self, symbol: Symbol, declaration: ASTDeclaration) -> None:
|
|
29
|
+
assert symbol
|
|
30
|
+
assert declaration
|
|
31
|
+
self.symbol = symbol
|
|
32
|
+
self.declaration = declaration
|
|
33
|
+
|
|
34
|
+
def __str__(self) -> str:
|
|
35
|
+
return "Internal C++ duplicate symbol error:\n%s" % self.symbol.dump(0)
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
class SymbolLookupResult:
|
|
39
|
+
def __init__(self, symbols: Iterator[Symbol], parentSymbol: Symbol,
|
|
40
|
+
identOrOp: ASTIdentifier | ASTOperator, templateParams: Any,
|
|
41
|
+
templateArgs: ASTTemplateArgs) -> None:
|
|
42
|
+
self.symbols = symbols
|
|
43
|
+
self.parentSymbol = parentSymbol
|
|
44
|
+
self.identOrOp = identOrOp
|
|
45
|
+
self.templateParams = templateParams
|
|
46
|
+
self.templateArgs = templateArgs
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
class LookupKey:
|
|
50
|
+
def __init__(self, data: list[tuple[ASTNestedNameElement,
|
|
51
|
+
ASTTemplateParams | ASTTemplateIntroduction,
|
|
52
|
+
str]]) -> None:
|
|
53
|
+
self.data = data
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def _is_specialization(templateParams: ASTTemplateParams | ASTTemplateIntroduction,
|
|
57
|
+
templateArgs: ASTTemplateArgs) -> bool:
|
|
58
|
+
# Checks if `templateArgs` does not exactly match `templateParams`.
|
|
59
|
+
# the names of the template parameters must be given exactly as args
|
|
60
|
+
# and params that are packs must in the args be the name expanded
|
|
61
|
+
if len(templateParams.params) != len(templateArgs.args):
|
|
62
|
+
return True
|
|
63
|
+
# having no template params and no arguments is also a specialization
|
|
64
|
+
if len(templateParams.params) == 0:
|
|
65
|
+
return True
|
|
66
|
+
for i in range(len(templateParams.params)):
|
|
67
|
+
param = templateParams.params[i]
|
|
68
|
+
arg = templateArgs.args[i]
|
|
69
|
+
# TODO: doing this by string manipulation is probably not the most efficient
|
|
70
|
+
paramName = str(param.name)
|
|
71
|
+
argTxt = str(arg)
|
|
72
|
+
isArgPackExpansion = argTxt.endswith('...')
|
|
73
|
+
if param.isPack != isArgPackExpansion:
|
|
74
|
+
return True
|
|
75
|
+
argName = argTxt[:-3] if isArgPackExpansion else argTxt
|
|
76
|
+
if paramName != argName:
|
|
77
|
+
return True
|
|
78
|
+
return False
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
class Symbol:
|
|
82
|
+
debug_indent = 0
|
|
83
|
+
debug_indent_string = " "
|
|
84
|
+
debug_lookup = False # overridden by the corresponding config value
|
|
85
|
+
debug_show_tree = False # overridden by the corresponding config value
|
|
86
|
+
|
|
87
|
+
def __copy__(self) -> NoReturn:
|
|
88
|
+
raise AssertionError # shouldn't happen
|
|
89
|
+
|
|
90
|
+
def __deepcopy__(self, memo: Any) -> Symbol:
|
|
91
|
+
if self.parent:
|
|
92
|
+
raise AssertionError # shouldn't happen
|
|
93
|
+
# the domain base class makes a copy of the initial data, which is fine
|
|
94
|
+
return Symbol(None, None, None, None, None, None, None)
|
|
95
|
+
|
|
96
|
+
@staticmethod
|
|
97
|
+
def debug_print(*args: Any) -> None:
|
|
98
|
+
logger.debug(Symbol.debug_indent_string * Symbol.debug_indent, end="")
|
|
99
|
+
logger.debug(*args)
|
|
100
|
+
|
|
101
|
+
def _assert_invariants(self) -> None:
|
|
102
|
+
if not self.parent:
|
|
103
|
+
# parent == None means global scope, so declaration means a parent
|
|
104
|
+
assert not self.identOrOp
|
|
105
|
+
assert not self.templateParams
|
|
106
|
+
assert not self.templateArgs
|
|
107
|
+
assert not self.declaration
|
|
108
|
+
assert not self.docname
|
|
109
|
+
else:
|
|
110
|
+
if self.declaration:
|
|
111
|
+
assert self.docname
|
|
112
|
+
|
|
113
|
+
def __setattr__(self, key: str, value: Any) -> None:
|
|
114
|
+
if key == "children":
|
|
115
|
+
raise AssertionError
|
|
116
|
+
return super().__setattr__(key, value)
|
|
117
|
+
|
|
118
|
+
def __init__(self, parent: Symbol | None,
|
|
119
|
+
identOrOp: ASTIdentifier | ASTOperator | None,
|
|
120
|
+
templateParams: ASTTemplateParams | ASTTemplateIntroduction | None,
|
|
121
|
+
templateArgs: Any, declaration: ASTDeclaration | None,
|
|
122
|
+
docname: str | None, line: int | None) -> None:
|
|
123
|
+
self.parent = parent
|
|
124
|
+
# declarations in a single directive are linked together
|
|
125
|
+
self.siblingAbove: Symbol | None = None
|
|
126
|
+
self.siblingBelow: Symbol | None = None
|
|
127
|
+
self.identOrOp = identOrOp
|
|
128
|
+
# Ensure the same symbol for `A` is created for:
|
|
129
|
+
#
|
|
130
|
+
# .. cpp:class:: template <typename T> class A
|
|
131
|
+
#
|
|
132
|
+
# and
|
|
133
|
+
#
|
|
134
|
+
# .. cpp:function:: template <typename T> int A<T>::foo()
|
|
135
|
+
if (templateArgs is not None and
|
|
136
|
+
not _is_specialization(templateParams, templateArgs)):
|
|
137
|
+
templateArgs = None
|
|
138
|
+
self.templateParams = templateParams # template<templateParams>
|
|
139
|
+
self.templateArgs = templateArgs # identifier<templateArgs>
|
|
140
|
+
self.declaration = declaration
|
|
141
|
+
self.docname = docname
|
|
142
|
+
self.line = line
|
|
143
|
+
self.isRedeclaration = False
|
|
144
|
+
self._assert_invariants()
|
|
145
|
+
|
|
146
|
+
# Remember to modify Symbol.remove if modifications to the parent change.
|
|
147
|
+
self._children: list[Symbol] = []
|
|
148
|
+
self._anonChildren: list[Symbol] = []
|
|
149
|
+
# note: _children includes _anonChildren
|
|
150
|
+
if self.parent:
|
|
151
|
+
self.parent._children.append(self)
|
|
152
|
+
if self.declaration:
|
|
153
|
+
self.declaration.symbol = self
|
|
154
|
+
|
|
155
|
+
# Do symbol addition after self._children has been initialised.
|
|
156
|
+
self._add_template_and_function_params()
|
|
157
|
+
|
|
158
|
+
def _fill_empty(self, declaration: ASTDeclaration, docname: str, line: int) -> None:
|
|
159
|
+
self._assert_invariants()
|
|
160
|
+
assert self.declaration is None
|
|
161
|
+
assert self.docname is None
|
|
162
|
+
assert self.line is None
|
|
163
|
+
assert declaration is not None
|
|
164
|
+
assert docname is not None
|
|
165
|
+
assert line is not None
|
|
166
|
+
self.declaration = declaration
|
|
167
|
+
self.declaration.symbol = self
|
|
168
|
+
self.docname = docname
|
|
169
|
+
self.line = line
|
|
170
|
+
self._assert_invariants()
|
|
171
|
+
# and symbol addition should be done as well
|
|
172
|
+
self._add_template_and_function_params()
|
|
173
|
+
|
|
174
|
+
def _add_template_and_function_params(self) -> None:
|
|
175
|
+
if Symbol.debug_lookup:
|
|
176
|
+
Symbol.debug_indent += 1
|
|
177
|
+
Symbol.debug_print("_add_template_and_function_params:")
|
|
178
|
+
# Note: we may be called from _fill_empty, so the symbols we want
|
|
179
|
+
# to add may actually already be present (as empty symbols).
|
|
180
|
+
|
|
181
|
+
# add symbols for the template params
|
|
182
|
+
if self.templateParams:
|
|
183
|
+
for tp in self.templateParams.params:
|
|
184
|
+
if not tp.get_identifier():
|
|
185
|
+
continue
|
|
186
|
+
# only add a declaration if we our self are from a declaration
|
|
187
|
+
if self.declaration:
|
|
188
|
+
decl = ASTDeclaration(objectType='templateParam', declaration=tp)
|
|
189
|
+
else:
|
|
190
|
+
decl = None
|
|
191
|
+
nne = ASTNestedNameElement(tp.get_identifier(), None)
|
|
192
|
+
nn = ASTNestedName([nne], [False], rooted=False)
|
|
193
|
+
self._add_symbols(nn, [], decl, self.docname, self.line)
|
|
194
|
+
# add symbols for function parameters, if any
|
|
195
|
+
if self.declaration is not None and self.declaration.function_params is not None:
|
|
196
|
+
for fp in self.declaration.function_params:
|
|
197
|
+
if fp.arg is None:
|
|
198
|
+
continue
|
|
199
|
+
nn = fp.arg.name
|
|
200
|
+
if nn is None:
|
|
201
|
+
continue
|
|
202
|
+
# (comparing to the template params: we have checked that we are a declaration)
|
|
203
|
+
decl = ASTDeclaration(objectType='functionParam', declaration=fp)
|
|
204
|
+
assert not nn.rooted
|
|
205
|
+
assert len(nn.names) == 1
|
|
206
|
+
self._add_symbols(nn, [], decl, self.docname, self.line)
|
|
207
|
+
if Symbol.debug_lookup:
|
|
208
|
+
Symbol.debug_indent -= 1
|
|
209
|
+
|
|
210
|
+
def remove(self) -> None:
|
|
211
|
+
if self.parent is None:
|
|
212
|
+
return
|
|
213
|
+
assert self in self.parent._children
|
|
214
|
+
self.parent._children.remove(self)
|
|
215
|
+
self.parent = None
|
|
216
|
+
|
|
217
|
+
def clear_doc(self, docname: str) -> None:
|
|
218
|
+
newChildren: list[Symbol] = []
|
|
219
|
+
for sChild in self._children:
|
|
220
|
+
sChild.clear_doc(docname)
|
|
221
|
+
if sChild.declaration and sChild.docname == docname:
|
|
222
|
+
sChild.declaration = None
|
|
223
|
+
sChild.docname = None
|
|
224
|
+
sChild.line = None
|
|
225
|
+
if sChild.siblingAbove is not None:
|
|
226
|
+
sChild.siblingAbove.siblingBelow = sChild.siblingBelow
|
|
227
|
+
if sChild.siblingBelow is not None:
|
|
228
|
+
sChild.siblingBelow.siblingAbove = sChild.siblingAbove
|
|
229
|
+
sChild.siblingAbove = None
|
|
230
|
+
sChild.siblingBelow = None
|
|
231
|
+
newChildren.append(sChild)
|
|
232
|
+
self._children = newChildren
|
|
233
|
+
|
|
234
|
+
def get_all_symbols(self) -> Iterator[Any]:
|
|
235
|
+
yield self
|
|
236
|
+
for sChild in self._children:
|
|
237
|
+
yield from sChild.get_all_symbols()
|
|
238
|
+
|
|
239
|
+
@property
|
|
240
|
+
def children_recurse_anon(self) -> Iterator[Symbol]:
|
|
241
|
+
for c in self._children:
|
|
242
|
+
yield c
|
|
243
|
+
if not c.identOrOp.is_anon():
|
|
244
|
+
continue
|
|
245
|
+
|
|
246
|
+
yield from c.children_recurse_anon
|
|
247
|
+
|
|
248
|
+
def get_lookup_key(self) -> LookupKey:
|
|
249
|
+
# The pickle files for the environment and for each document are distinct.
|
|
250
|
+
# The environment has all the symbols, but the documents has xrefs that
|
|
251
|
+
# must know their scope. A lookup key is essentially a specification of
|
|
252
|
+
# how to find a specific symbol.
|
|
253
|
+
symbols = []
|
|
254
|
+
s = self
|
|
255
|
+
while s.parent:
|
|
256
|
+
symbols.append(s)
|
|
257
|
+
s = s.parent
|
|
258
|
+
symbols.reverse()
|
|
259
|
+
key = []
|
|
260
|
+
for s in symbols:
|
|
261
|
+
nne = ASTNestedNameElement(s.identOrOp, s.templateArgs)
|
|
262
|
+
if s.declaration is not None:
|
|
263
|
+
key.append((nne, s.templateParams, s.declaration.get_newest_id()))
|
|
264
|
+
else:
|
|
265
|
+
key.append((nne, s.templateParams, None))
|
|
266
|
+
return LookupKey(key)
|
|
267
|
+
|
|
268
|
+
def get_full_nested_name(self) -> ASTNestedName:
|
|
269
|
+
symbols = []
|
|
270
|
+
s = self
|
|
271
|
+
while s.parent:
|
|
272
|
+
symbols.append(s)
|
|
273
|
+
s = s.parent
|
|
274
|
+
symbols.reverse()
|
|
275
|
+
names = []
|
|
276
|
+
templates = []
|
|
277
|
+
for s in symbols:
|
|
278
|
+
names.append(ASTNestedNameElement(s.identOrOp, s.templateArgs))
|
|
279
|
+
templates.append(False)
|
|
280
|
+
return ASTNestedName(names, templates, rooted=False)
|
|
281
|
+
|
|
282
|
+
def _find_first_named_symbol(self, identOrOp: ASTIdentifier | ASTOperator,
|
|
283
|
+
templateParams: ASTTemplateParams | ASTTemplateIntroduction,
|
|
284
|
+
templateArgs: ASTTemplateArgs | None,
|
|
285
|
+
templateShorthand: bool, matchSelf: bool,
|
|
286
|
+
recurseInAnon: bool, correctPrimaryTemplateArgs: bool,
|
|
287
|
+
) -> Symbol | None:
|
|
288
|
+
if Symbol.debug_lookup:
|
|
289
|
+
Symbol.debug_print("_find_first_named_symbol ->")
|
|
290
|
+
res = self._find_named_symbols(identOrOp, templateParams, templateArgs,
|
|
291
|
+
templateShorthand, matchSelf, recurseInAnon,
|
|
292
|
+
correctPrimaryTemplateArgs,
|
|
293
|
+
searchInSiblings=False)
|
|
294
|
+
try:
|
|
295
|
+
return next(res)
|
|
296
|
+
except StopIteration:
|
|
297
|
+
return None
|
|
298
|
+
|
|
299
|
+
def _find_named_symbols(self, identOrOp: ASTIdentifier | ASTOperator,
|
|
300
|
+
templateParams: ASTTemplateParams | ASTTemplateIntroduction,
|
|
301
|
+
templateArgs: ASTTemplateArgs,
|
|
302
|
+
templateShorthand: bool, matchSelf: bool,
|
|
303
|
+
recurseInAnon: bool, correctPrimaryTemplateArgs: bool,
|
|
304
|
+
searchInSiblings: bool) -> Iterator[Symbol]:
|
|
305
|
+
if Symbol.debug_lookup:
|
|
306
|
+
Symbol.debug_indent += 1
|
|
307
|
+
Symbol.debug_print("_find_named_symbols:")
|
|
308
|
+
Symbol.debug_indent += 1
|
|
309
|
+
Symbol.debug_print("self:")
|
|
310
|
+
logger.debug(self.to_string(Symbol.debug_indent + 1), end="")
|
|
311
|
+
Symbol.debug_print("identOrOp: ", identOrOp)
|
|
312
|
+
Symbol.debug_print("templateParams: ", templateParams)
|
|
313
|
+
Symbol.debug_print("templateArgs: ", templateArgs)
|
|
314
|
+
Symbol.debug_print("templateShorthand: ", templateShorthand)
|
|
315
|
+
Symbol.debug_print("matchSelf: ", matchSelf)
|
|
316
|
+
Symbol.debug_print("recurseInAnon: ", recurseInAnon)
|
|
317
|
+
Symbol.debug_print("correctPrimaryTemplateAargs:", correctPrimaryTemplateArgs)
|
|
318
|
+
Symbol.debug_print("searchInSiblings: ", searchInSiblings)
|
|
319
|
+
|
|
320
|
+
if correctPrimaryTemplateArgs:
|
|
321
|
+
if templateParams is not None and templateArgs is not None:
|
|
322
|
+
# If both are given, but it's not a specialization, then do lookup as if
|
|
323
|
+
# there is no argument list.
|
|
324
|
+
# For example: template<typename T> int A<T>::var;
|
|
325
|
+
if not _is_specialization(templateParams, templateArgs):
|
|
326
|
+
templateArgs = None
|
|
327
|
+
|
|
328
|
+
def matches(s: Symbol) -> bool:
|
|
329
|
+
if s.identOrOp != identOrOp:
|
|
330
|
+
return False
|
|
331
|
+
if (s.templateParams is None) != (templateParams is None):
|
|
332
|
+
if templateParams is not None:
|
|
333
|
+
# we query with params, they must match params
|
|
334
|
+
return False
|
|
335
|
+
if not templateShorthand:
|
|
336
|
+
# we don't query with params, and we do care about them
|
|
337
|
+
return False
|
|
338
|
+
if templateParams:
|
|
339
|
+
# TODO: do better comparison
|
|
340
|
+
if str(s.templateParams) != str(templateParams):
|
|
341
|
+
return False
|
|
342
|
+
if (s.templateArgs is None) != (templateArgs is None):
|
|
343
|
+
return False
|
|
344
|
+
if s.templateArgs:
|
|
345
|
+
# TODO: do better comparison
|
|
346
|
+
if str(s.templateArgs) != str(templateArgs):
|
|
347
|
+
return False
|
|
348
|
+
return True
|
|
349
|
+
|
|
350
|
+
def candidates() -> Iterator[Symbol]:
|
|
351
|
+
s = self
|
|
352
|
+
if Symbol.debug_lookup:
|
|
353
|
+
Symbol.debug_print("searching in self:")
|
|
354
|
+
logger.debug(s.to_string(Symbol.debug_indent + 1), end="")
|
|
355
|
+
while True:
|
|
356
|
+
if matchSelf:
|
|
357
|
+
yield s
|
|
358
|
+
if recurseInAnon:
|
|
359
|
+
yield from s.children_recurse_anon
|
|
360
|
+
else:
|
|
361
|
+
yield from s._children
|
|
362
|
+
|
|
363
|
+
if s.siblingAbove is None:
|
|
364
|
+
break
|
|
365
|
+
s = s.siblingAbove
|
|
366
|
+
if Symbol.debug_lookup:
|
|
367
|
+
Symbol.debug_print("searching in sibling:")
|
|
368
|
+
logger.debug(s.to_string(Symbol.debug_indent + 1), end="")
|
|
369
|
+
|
|
370
|
+
for s in candidates():
|
|
371
|
+
if Symbol.debug_lookup:
|
|
372
|
+
Symbol.debug_print("candidate:")
|
|
373
|
+
logger.debug(s.to_string(Symbol.debug_indent + 1), end="")
|
|
374
|
+
if matches(s):
|
|
375
|
+
if Symbol.debug_lookup:
|
|
376
|
+
Symbol.debug_indent += 1
|
|
377
|
+
Symbol.debug_print("matches")
|
|
378
|
+
Symbol.debug_indent -= 3
|
|
379
|
+
yield s
|
|
380
|
+
if Symbol.debug_lookup:
|
|
381
|
+
Symbol.debug_indent += 2
|
|
382
|
+
if Symbol.debug_lookup:
|
|
383
|
+
Symbol.debug_indent -= 2
|
|
384
|
+
|
|
385
|
+
def _symbol_lookup(
|
|
386
|
+
self,
|
|
387
|
+
nestedName: ASTNestedName,
|
|
388
|
+
templateDecls: list[Any],
|
|
389
|
+
onMissingQualifiedSymbol: Callable[
|
|
390
|
+
[Symbol, ASTIdentifier | ASTOperator, Any, ASTTemplateArgs], Symbol | None,
|
|
391
|
+
],
|
|
392
|
+
strictTemplateParamArgLists: bool, ancestorLookupType: str,
|
|
393
|
+
templateShorthand: bool, matchSelf: bool,
|
|
394
|
+
recurseInAnon: bool, correctPrimaryTemplateArgs: bool,
|
|
395
|
+
searchInSiblings: bool,
|
|
396
|
+
) -> SymbolLookupResult:
|
|
397
|
+
# ancestorLookupType: if not None, specifies the target type of the lookup
|
|
398
|
+
if Symbol.debug_lookup:
|
|
399
|
+
Symbol.debug_indent += 1
|
|
400
|
+
Symbol.debug_print("_symbol_lookup:")
|
|
401
|
+
Symbol.debug_indent += 1
|
|
402
|
+
Symbol.debug_print("self:")
|
|
403
|
+
logger.debug(self.to_string(Symbol.debug_indent + 1), end="")
|
|
404
|
+
Symbol.debug_print("nestedName: ", nestedName)
|
|
405
|
+
Symbol.debug_print("templateDecls: ", ",".join(str(t) for t in templateDecls))
|
|
406
|
+
Symbol.debug_print("strictTemplateParamArgLists:", strictTemplateParamArgLists)
|
|
407
|
+
Symbol.debug_print("ancestorLookupType:", ancestorLookupType)
|
|
408
|
+
Symbol.debug_print("templateShorthand: ", templateShorthand)
|
|
409
|
+
Symbol.debug_print("matchSelf: ", matchSelf)
|
|
410
|
+
Symbol.debug_print("recurseInAnon: ", recurseInAnon)
|
|
411
|
+
Symbol.debug_print("correctPrimaryTemplateArgs: ", correctPrimaryTemplateArgs)
|
|
412
|
+
Symbol.debug_print("searchInSiblings: ", searchInSiblings)
|
|
413
|
+
|
|
414
|
+
if strictTemplateParamArgLists:
|
|
415
|
+
# Each template argument list must have a template parameter list.
|
|
416
|
+
# But to declare a template there must be an additional template parameter list.
|
|
417
|
+
assert (nestedName.num_templates() == len(templateDecls) or
|
|
418
|
+
nestedName.num_templates() + 1 == len(templateDecls))
|
|
419
|
+
else:
|
|
420
|
+
assert len(templateDecls) <= nestedName.num_templates() + 1
|
|
421
|
+
|
|
422
|
+
names = nestedName.names
|
|
423
|
+
|
|
424
|
+
# find the right starting point for lookup
|
|
425
|
+
parentSymbol = self
|
|
426
|
+
if nestedName.rooted:
|
|
427
|
+
while parentSymbol.parent:
|
|
428
|
+
parentSymbol = parentSymbol.parent
|
|
429
|
+
if ancestorLookupType is not None:
|
|
430
|
+
# walk up until we find the first identifier
|
|
431
|
+
firstName = names[0]
|
|
432
|
+
if not firstName.is_operator():
|
|
433
|
+
while parentSymbol.parent:
|
|
434
|
+
if parentSymbol.find_identifier(firstName.identOrOp,
|
|
435
|
+
matchSelf=matchSelf,
|
|
436
|
+
recurseInAnon=recurseInAnon,
|
|
437
|
+
searchInSiblings=searchInSiblings):
|
|
438
|
+
# if we are in the scope of a constructor but wants to
|
|
439
|
+
# reference the class we need to walk one extra up
|
|
440
|
+
if (len(names) == 1 and ancestorLookupType == 'class' and matchSelf and
|
|
441
|
+
parentSymbol.parent and
|
|
442
|
+
parentSymbol.parent.identOrOp == firstName.identOrOp):
|
|
443
|
+
pass
|
|
444
|
+
else:
|
|
445
|
+
break
|
|
446
|
+
parentSymbol = parentSymbol.parent
|
|
447
|
+
|
|
448
|
+
if Symbol.debug_lookup:
|
|
449
|
+
Symbol.debug_print("starting point:")
|
|
450
|
+
logger.debug(parentSymbol.to_string(Symbol.debug_indent + 1), end="")
|
|
451
|
+
|
|
452
|
+
# and now the actual lookup
|
|
453
|
+
iTemplateDecl = 0
|
|
454
|
+
for name in names[:-1]:
|
|
455
|
+
identOrOp = name.identOrOp
|
|
456
|
+
templateArgs = name.templateArgs
|
|
457
|
+
if strictTemplateParamArgLists:
|
|
458
|
+
# there must be a parameter list
|
|
459
|
+
if templateArgs:
|
|
460
|
+
assert iTemplateDecl < len(templateDecls)
|
|
461
|
+
templateParams = templateDecls[iTemplateDecl]
|
|
462
|
+
iTemplateDecl += 1
|
|
463
|
+
else:
|
|
464
|
+
templateParams = None
|
|
465
|
+
else:
|
|
466
|
+
# take the next template parameter list if there is one
|
|
467
|
+
# otherwise it's ok
|
|
468
|
+
if templateArgs and iTemplateDecl < len(templateDecls):
|
|
469
|
+
templateParams = templateDecls[iTemplateDecl]
|
|
470
|
+
iTemplateDecl += 1
|
|
471
|
+
else:
|
|
472
|
+
templateParams = None
|
|
473
|
+
|
|
474
|
+
symbol = parentSymbol._find_first_named_symbol(
|
|
475
|
+
identOrOp,
|
|
476
|
+
templateParams, templateArgs,
|
|
477
|
+
templateShorthand=templateShorthand,
|
|
478
|
+
matchSelf=matchSelf,
|
|
479
|
+
recurseInAnon=recurseInAnon,
|
|
480
|
+
correctPrimaryTemplateArgs=correctPrimaryTemplateArgs)
|
|
481
|
+
if symbol is None:
|
|
482
|
+
symbol = onMissingQualifiedSymbol(parentSymbol, identOrOp,
|
|
483
|
+
templateParams, templateArgs)
|
|
484
|
+
if symbol is None:
|
|
485
|
+
if Symbol.debug_lookup:
|
|
486
|
+
Symbol.debug_indent -= 2
|
|
487
|
+
return None
|
|
488
|
+
# We have now matched part of a nested name, and need to match more
|
|
489
|
+
# so even if we should matchSelf before, we definitely shouldn't
|
|
490
|
+
# even more. (see also issue #2666)
|
|
491
|
+
matchSelf = False
|
|
492
|
+
parentSymbol = symbol
|
|
493
|
+
|
|
494
|
+
if Symbol.debug_lookup:
|
|
495
|
+
Symbol.debug_print("handle last name from:")
|
|
496
|
+
logger.debug(parentSymbol.to_string(Symbol.debug_indent + 1), end="")
|
|
497
|
+
|
|
498
|
+
# handle the last name
|
|
499
|
+
name = names[-1]
|
|
500
|
+
identOrOp = name.identOrOp
|
|
501
|
+
templateArgs = name.templateArgs
|
|
502
|
+
if iTemplateDecl < len(templateDecls):
|
|
503
|
+
assert iTemplateDecl + 1 == len(templateDecls)
|
|
504
|
+
templateParams = templateDecls[iTemplateDecl]
|
|
505
|
+
else:
|
|
506
|
+
assert iTemplateDecl == len(templateDecls)
|
|
507
|
+
templateParams = None
|
|
508
|
+
|
|
509
|
+
symbols = parentSymbol._find_named_symbols(
|
|
510
|
+
identOrOp, templateParams, templateArgs,
|
|
511
|
+
templateShorthand=templateShorthand, matchSelf=matchSelf,
|
|
512
|
+
recurseInAnon=recurseInAnon, correctPrimaryTemplateArgs=False,
|
|
513
|
+
searchInSiblings=searchInSiblings)
|
|
514
|
+
if Symbol.debug_lookup:
|
|
515
|
+
symbols = list(symbols) # type: ignore[assignment]
|
|
516
|
+
Symbol.debug_indent -= 2
|
|
517
|
+
return SymbolLookupResult(symbols, parentSymbol,
|
|
518
|
+
identOrOp, templateParams, templateArgs)
|
|
519
|
+
|
|
520
|
+
def _add_symbols(
|
|
521
|
+
self,
|
|
522
|
+
nestedName: ASTNestedName,
|
|
523
|
+
templateDecls: list[Any],
|
|
524
|
+
declaration: ASTDeclaration | None,
|
|
525
|
+
docname: str | None,
|
|
526
|
+
line: int | None,
|
|
527
|
+
) -> Symbol:
|
|
528
|
+
# Used for adding a whole path of symbols, where the last may or may not
|
|
529
|
+
# be an actual declaration.
|
|
530
|
+
|
|
531
|
+
if Symbol.debug_lookup:
|
|
532
|
+
Symbol.debug_indent += 1
|
|
533
|
+
Symbol.debug_print("_add_symbols:")
|
|
534
|
+
Symbol.debug_indent += 1
|
|
535
|
+
Symbol.debug_print("tdecls:", ",".join(str(t) for t in templateDecls))
|
|
536
|
+
Symbol.debug_print("nn: ", nestedName)
|
|
537
|
+
Symbol.debug_print("decl: ", declaration)
|
|
538
|
+
Symbol.debug_print(f"location: {docname}:{line}")
|
|
539
|
+
|
|
540
|
+
def onMissingQualifiedSymbol(parentSymbol: Symbol,
|
|
541
|
+
identOrOp: ASTIdentifier | ASTOperator,
|
|
542
|
+
templateParams: Any, templateArgs: ASTTemplateArgs,
|
|
543
|
+
) -> Symbol | None:
|
|
544
|
+
if Symbol.debug_lookup:
|
|
545
|
+
Symbol.debug_indent += 1
|
|
546
|
+
Symbol.debug_print("_add_symbols, onMissingQualifiedSymbol:")
|
|
547
|
+
Symbol.debug_indent += 1
|
|
548
|
+
Symbol.debug_print("templateParams:", templateParams)
|
|
549
|
+
Symbol.debug_print("identOrOp: ", identOrOp)
|
|
550
|
+
Symbol.debug_print("templateARgs: ", templateArgs)
|
|
551
|
+
Symbol.debug_indent -= 2
|
|
552
|
+
return Symbol(parent=parentSymbol, identOrOp=identOrOp,
|
|
553
|
+
templateParams=templateParams,
|
|
554
|
+
templateArgs=templateArgs, declaration=None,
|
|
555
|
+
docname=None, line=None)
|
|
556
|
+
|
|
557
|
+
lookupResult = self._symbol_lookup(nestedName, templateDecls,
|
|
558
|
+
onMissingQualifiedSymbol,
|
|
559
|
+
strictTemplateParamArgLists=True,
|
|
560
|
+
ancestorLookupType=None,
|
|
561
|
+
templateShorthand=False,
|
|
562
|
+
matchSelf=False,
|
|
563
|
+
recurseInAnon=False,
|
|
564
|
+
correctPrimaryTemplateArgs=True,
|
|
565
|
+
searchInSiblings=False)
|
|
566
|
+
assert lookupResult is not None # we create symbols all the way, so that can't happen
|
|
567
|
+
symbols = list(lookupResult.symbols)
|
|
568
|
+
if len(symbols) == 0:
|
|
569
|
+
if Symbol.debug_lookup:
|
|
570
|
+
Symbol.debug_print("_add_symbols, result, no symbol:")
|
|
571
|
+
Symbol.debug_indent += 1
|
|
572
|
+
Symbol.debug_print("templateParams:", lookupResult.templateParams)
|
|
573
|
+
Symbol.debug_print("identOrOp: ", lookupResult.identOrOp)
|
|
574
|
+
Symbol.debug_print("templateArgs: ", lookupResult.templateArgs)
|
|
575
|
+
Symbol.debug_print("declaration: ", declaration)
|
|
576
|
+
Symbol.debug_print(f"location: {docname}:{line}")
|
|
577
|
+
Symbol.debug_indent -= 1
|
|
578
|
+
symbol = Symbol(parent=lookupResult.parentSymbol,
|
|
579
|
+
identOrOp=lookupResult.identOrOp,
|
|
580
|
+
templateParams=lookupResult.templateParams,
|
|
581
|
+
templateArgs=lookupResult.templateArgs,
|
|
582
|
+
declaration=declaration,
|
|
583
|
+
docname=docname, line=line)
|
|
584
|
+
if Symbol.debug_lookup:
|
|
585
|
+
Symbol.debug_indent -= 2
|
|
586
|
+
return symbol
|
|
587
|
+
|
|
588
|
+
if Symbol.debug_lookup:
|
|
589
|
+
Symbol.debug_print("_add_symbols, result, symbols:")
|
|
590
|
+
Symbol.debug_indent += 1
|
|
591
|
+
Symbol.debug_print("number symbols:", len(symbols))
|
|
592
|
+
Symbol.debug_indent -= 1
|
|
593
|
+
|
|
594
|
+
if not declaration:
|
|
595
|
+
if Symbol.debug_lookup:
|
|
596
|
+
Symbol.debug_print("no declaration")
|
|
597
|
+
Symbol.debug_indent -= 2
|
|
598
|
+
# good, just a scope creation
|
|
599
|
+
# TODO: what if we have more than one symbol?
|
|
600
|
+
return symbols[0]
|
|
601
|
+
|
|
602
|
+
noDecl = []
|
|
603
|
+
withDecl = []
|
|
604
|
+
dupDecl = []
|
|
605
|
+
for s in symbols:
|
|
606
|
+
if s.declaration is None:
|
|
607
|
+
noDecl.append(s)
|
|
608
|
+
elif s.isRedeclaration:
|
|
609
|
+
dupDecl.append(s)
|
|
610
|
+
else:
|
|
611
|
+
withDecl.append(s)
|
|
612
|
+
if Symbol.debug_lookup:
|
|
613
|
+
Symbol.debug_print("#noDecl: ", len(noDecl))
|
|
614
|
+
Symbol.debug_print("#withDecl:", len(withDecl))
|
|
615
|
+
Symbol.debug_print("#dupDecl: ", len(dupDecl))
|
|
616
|
+
# With partial builds we may start with a large symbol tree stripped of declarations.
|
|
617
|
+
# Essentially any combination of noDecl, withDecl, and dupDecls seems possible.
|
|
618
|
+
# TODO: make partial builds fully work. What should happen when the primary symbol gets
|
|
619
|
+
# deleted, and other duplicates exist? The full document should probably be rebuild.
|
|
620
|
+
|
|
621
|
+
# First check if one of those with a declaration matches.
|
|
622
|
+
# If it's a function, we need to compare IDs,
|
|
623
|
+
# otherwise there should be only one symbol with a declaration.
|
|
624
|
+
def makeCandSymbol() -> Symbol:
|
|
625
|
+
if Symbol.debug_lookup:
|
|
626
|
+
Symbol.debug_print("begin: creating candidate symbol")
|
|
627
|
+
symbol = Symbol(parent=lookupResult.parentSymbol,
|
|
628
|
+
identOrOp=lookupResult.identOrOp,
|
|
629
|
+
templateParams=lookupResult.templateParams,
|
|
630
|
+
templateArgs=lookupResult.templateArgs,
|
|
631
|
+
declaration=declaration,
|
|
632
|
+
docname=docname, line=line)
|
|
633
|
+
if Symbol.debug_lookup:
|
|
634
|
+
Symbol.debug_print("end: creating candidate symbol")
|
|
635
|
+
return symbol
|
|
636
|
+
if len(withDecl) == 0:
|
|
637
|
+
candSymbol = None
|
|
638
|
+
else:
|
|
639
|
+
candSymbol = makeCandSymbol()
|
|
640
|
+
|
|
641
|
+
def handleDuplicateDeclaration(symbol: Symbol, candSymbol: Symbol) -> None:
|
|
642
|
+
if Symbol.debug_lookup:
|
|
643
|
+
Symbol.debug_indent += 1
|
|
644
|
+
Symbol.debug_print("redeclaration")
|
|
645
|
+
Symbol.debug_indent -= 1
|
|
646
|
+
Symbol.debug_indent -= 2
|
|
647
|
+
# Redeclaration of the same symbol.
|
|
648
|
+
# Let the new one be there, but raise an error to the client
|
|
649
|
+
# so it can use the real symbol as subscope.
|
|
650
|
+
# This will probably result in a duplicate id warning.
|
|
651
|
+
candSymbol.isRedeclaration = True
|
|
652
|
+
raise _DuplicateSymbolError(symbol, declaration)
|
|
653
|
+
|
|
654
|
+
if declaration.objectType != "function":
|
|
655
|
+
assert len(withDecl) <= 1
|
|
656
|
+
handleDuplicateDeclaration(withDecl[0], candSymbol)
|
|
657
|
+
# (not reachable)
|
|
658
|
+
|
|
659
|
+
# a function, so compare IDs
|
|
660
|
+
candId = declaration.get_newest_id()
|
|
661
|
+
if Symbol.debug_lookup:
|
|
662
|
+
Symbol.debug_print("candId:", candId)
|
|
663
|
+
for symbol in withDecl:
|
|
664
|
+
# but all existing must be functions as well,
|
|
665
|
+
# otherwise we declare it to be a duplicate
|
|
666
|
+
if symbol.declaration.objectType != 'function':
|
|
667
|
+
handleDuplicateDeclaration(symbol, candSymbol)
|
|
668
|
+
# (not reachable)
|
|
669
|
+
oldId = symbol.declaration.get_newest_id()
|
|
670
|
+
if Symbol.debug_lookup:
|
|
671
|
+
Symbol.debug_print("oldId: ", oldId)
|
|
672
|
+
if candId == oldId:
|
|
673
|
+
handleDuplicateDeclaration(symbol, candSymbol)
|
|
674
|
+
# (not reachable)
|
|
675
|
+
# no candidate symbol found with matching ID
|
|
676
|
+
# if there is an empty symbol, fill that one
|
|
677
|
+
if len(noDecl) == 0:
|
|
678
|
+
if Symbol.debug_lookup:
|
|
679
|
+
Symbol.debug_print("no match, no empty")
|
|
680
|
+
if candSymbol is not None:
|
|
681
|
+
Symbol.debug_print("result is already created candSymbol")
|
|
682
|
+
else:
|
|
683
|
+
Symbol.debug_print("result is makeCandSymbol()")
|
|
684
|
+
Symbol.debug_indent -= 2
|
|
685
|
+
if candSymbol is not None:
|
|
686
|
+
return candSymbol
|
|
687
|
+
else:
|
|
688
|
+
return makeCandSymbol()
|
|
689
|
+
else:
|
|
690
|
+
if Symbol.debug_lookup:
|
|
691
|
+
Symbol.debug_print(
|
|
692
|
+
"no match, but fill an empty declaration, candSybmol is not None?:",
|
|
693
|
+
candSymbol is not None,
|
|
694
|
+
)
|
|
695
|
+
Symbol.debug_indent -= 2
|
|
696
|
+
if candSymbol is not None:
|
|
697
|
+
candSymbol.remove()
|
|
698
|
+
# assert len(noDecl) == 1
|
|
699
|
+
# TODO: enable assertion when we at some point find out how to do cleanup
|
|
700
|
+
# for now, just take the first one, it should work fine ... right?
|
|
701
|
+
symbol = noDecl[0]
|
|
702
|
+
# If someone first opened the scope, and then later
|
|
703
|
+
# declares it, e.g,
|
|
704
|
+
# .. namespace:: Test
|
|
705
|
+
# .. namespace:: nullptr
|
|
706
|
+
# .. class:: Test
|
|
707
|
+
symbol._fill_empty(declaration, docname, line)
|
|
708
|
+
return symbol
|
|
709
|
+
|
|
710
|
+
def merge_with(self, other: Symbol, docnames: list[str],
|
|
711
|
+
env: BuildEnvironment) -> None:
|
|
712
|
+
if Symbol.debug_lookup:
|
|
713
|
+
Symbol.debug_indent += 1
|
|
714
|
+
Symbol.debug_print("merge_with:")
|
|
715
|
+
assert other is not None
|
|
716
|
+
|
|
717
|
+
def unconditionalAdd(self: Symbol, otherChild: Symbol) -> None:
|
|
718
|
+
# TODO: hmm, should we prune by docnames?
|
|
719
|
+
self._children.append(otherChild)
|
|
720
|
+
otherChild.parent = self
|
|
721
|
+
otherChild._assert_invariants()
|
|
722
|
+
|
|
723
|
+
if Symbol.debug_lookup:
|
|
724
|
+
Symbol.debug_indent += 1
|
|
725
|
+
for otherChild in other._children:
|
|
726
|
+
if Symbol.debug_lookup:
|
|
727
|
+
Symbol.debug_print("otherChild:\n", otherChild.to_string(Symbol.debug_indent))
|
|
728
|
+
Symbol.debug_indent += 1
|
|
729
|
+
if otherChild.isRedeclaration:
|
|
730
|
+
unconditionalAdd(self, otherChild)
|
|
731
|
+
if Symbol.debug_lookup:
|
|
732
|
+
Symbol.debug_print("isRedeclaration")
|
|
733
|
+
Symbol.debug_indent -= 1
|
|
734
|
+
continue
|
|
735
|
+
candiateIter = self._find_named_symbols(
|
|
736
|
+
identOrOp=otherChild.identOrOp,
|
|
737
|
+
templateParams=otherChild.templateParams,
|
|
738
|
+
templateArgs=otherChild.templateArgs,
|
|
739
|
+
templateShorthand=False, matchSelf=False,
|
|
740
|
+
recurseInAnon=False, correctPrimaryTemplateArgs=False,
|
|
741
|
+
searchInSiblings=False)
|
|
742
|
+
candidates = list(candiateIter)
|
|
743
|
+
|
|
744
|
+
if Symbol.debug_lookup:
|
|
745
|
+
Symbol.debug_print("raw candidate symbols:", len(candidates))
|
|
746
|
+
symbols = [s for s in candidates if not s.isRedeclaration]
|
|
747
|
+
if Symbol.debug_lookup:
|
|
748
|
+
Symbol.debug_print("non-duplicate candidate symbols:", len(symbols))
|
|
749
|
+
|
|
750
|
+
if len(symbols) == 0:
|
|
751
|
+
unconditionalAdd(self, otherChild)
|
|
752
|
+
if Symbol.debug_lookup:
|
|
753
|
+
Symbol.debug_indent -= 1
|
|
754
|
+
continue
|
|
755
|
+
|
|
756
|
+
ourChild = None
|
|
757
|
+
if otherChild.declaration is None:
|
|
758
|
+
if Symbol.debug_lookup:
|
|
759
|
+
Symbol.debug_print("no declaration in other child")
|
|
760
|
+
ourChild = symbols[0]
|
|
761
|
+
else:
|
|
762
|
+
queryId = otherChild.declaration.get_newest_id()
|
|
763
|
+
if Symbol.debug_lookup:
|
|
764
|
+
Symbol.debug_print("queryId: ", queryId)
|
|
765
|
+
for symbol in symbols:
|
|
766
|
+
if symbol.declaration is None:
|
|
767
|
+
if Symbol.debug_lookup:
|
|
768
|
+
Symbol.debug_print("empty candidate")
|
|
769
|
+
# if in the end we have non-matching, but have an empty one,
|
|
770
|
+
# then just continue with that
|
|
771
|
+
ourChild = symbol
|
|
772
|
+
continue
|
|
773
|
+
candId = symbol.declaration.get_newest_id()
|
|
774
|
+
if Symbol.debug_lookup:
|
|
775
|
+
Symbol.debug_print("candidate:", candId)
|
|
776
|
+
if candId == queryId:
|
|
777
|
+
ourChild = symbol
|
|
778
|
+
break
|
|
779
|
+
if Symbol.debug_lookup:
|
|
780
|
+
Symbol.debug_indent -= 1
|
|
781
|
+
if ourChild is None:
|
|
782
|
+
unconditionalAdd(self, otherChild)
|
|
783
|
+
continue
|
|
784
|
+
if otherChild.declaration and otherChild.docname in docnames:
|
|
785
|
+
if not ourChild.declaration:
|
|
786
|
+
ourChild._fill_empty(otherChild.declaration,
|
|
787
|
+
otherChild.docname, otherChild.line)
|
|
788
|
+
elif ourChild.docname != otherChild.docname:
|
|
789
|
+
name = str(ourChild.declaration)
|
|
790
|
+
msg = __("Duplicate C++ declaration, also defined at %s:%s.\n"
|
|
791
|
+
"Declaration is '.. cpp:%s:: %s'.")
|
|
792
|
+
msg = msg % (ourChild.docname, ourChild.line,
|
|
793
|
+
ourChild.declaration.directiveType, name)
|
|
794
|
+
logger.warning(msg, location=(otherChild.docname, otherChild.line))
|
|
795
|
+
else:
|
|
796
|
+
if (otherChild.declaration.objectType ==
|
|
797
|
+
ourChild.declaration.objectType and
|
|
798
|
+
otherChild.declaration.objectType in
|
|
799
|
+
('templateParam', 'functionParam') and
|
|
800
|
+
ourChild.parent.declaration == otherChild.parent.declaration):
|
|
801
|
+
# `ourChild` was just created during merging by the call
|
|
802
|
+
# to `_fill_empty` on the parent and can be ignored.
|
|
803
|
+
pass
|
|
804
|
+
else:
|
|
805
|
+
# Both have declarations, and in the same docname.
|
|
806
|
+
# This can apparently happen, it should be safe to
|
|
807
|
+
# just ignore it, right?
|
|
808
|
+
# Hmm, only on duplicate declarations, right?
|
|
809
|
+
msg = "Internal C++ domain error during symbol merging.\n"
|
|
810
|
+
msg += "ourChild:\n" + ourChild.to_string(1)
|
|
811
|
+
msg += "\notherChild:\n" + otherChild.to_string(1)
|
|
812
|
+
logger.warning(msg, location=otherChild.docname)
|
|
813
|
+
ourChild.merge_with(otherChild, docnames, env)
|
|
814
|
+
if Symbol.debug_lookup:
|
|
815
|
+
Symbol.debug_indent -= 2
|
|
816
|
+
|
|
817
|
+
def add_name(self, nestedName: ASTNestedName,
|
|
818
|
+
templatePrefix: ASTTemplateDeclarationPrefix | None = None) -> Symbol:
|
|
819
|
+
if Symbol.debug_lookup:
|
|
820
|
+
Symbol.debug_indent += 1
|
|
821
|
+
Symbol.debug_print("add_name:")
|
|
822
|
+
if templatePrefix:
|
|
823
|
+
templateDecls = templatePrefix.templates
|
|
824
|
+
else:
|
|
825
|
+
templateDecls = []
|
|
826
|
+
res = self._add_symbols(nestedName, templateDecls,
|
|
827
|
+
declaration=None, docname=None, line=None)
|
|
828
|
+
if Symbol.debug_lookup:
|
|
829
|
+
Symbol.debug_indent -= 1
|
|
830
|
+
return res
|
|
831
|
+
|
|
832
|
+
def add_declaration(self, declaration: ASTDeclaration,
|
|
833
|
+
docname: str, line: int) -> Symbol:
|
|
834
|
+
if Symbol.debug_lookup:
|
|
835
|
+
Symbol.debug_indent += 1
|
|
836
|
+
Symbol.debug_print("add_declaration:")
|
|
837
|
+
assert declaration is not None
|
|
838
|
+
assert docname is not None
|
|
839
|
+
assert line is not None
|
|
840
|
+
nestedName = declaration.name
|
|
841
|
+
if declaration.templatePrefix:
|
|
842
|
+
templateDecls = declaration.templatePrefix.templates
|
|
843
|
+
else:
|
|
844
|
+
templateDecls = []
|
|
845
|
+
res = self._add_symbols(nestedName, templateDecls, declaration, docname, line)
|
|
846
|
+
if Symbol.debug_lookup:
|
|
847
|
+
Symbol.debug_indent -= 1
|
|
848
|
+
return res
|
|
849
|
+
|
|
850
|
+
def find_identifier(self, identOrOp: ASTIdentifier | ASTOperator,
|
|
851
|
+
matchSelf: bool, recurseInAnon: bool, searchInSiblings: bool,
|
|
852
|
+
) -> Symbol | None:
|
|
853
|
+
if Symbol.debug_lookup:
|
|
854
|
+
Symbol.debug_indent += 1
|
|
855
|
+
Symbol.debug_print("find_identifier:")
|
|
856
|
+
Symbol.debug_indent += 1
|
|
857
|
+
Symbol.debug_print("identOrOp: ", identOrOp)
|
|
858
|
+
Symbol.debug_print("matchSelf: ", matchSelf)
|
|
859
|
+
Symbol.debug_print("recurseInAnon: ", recurseInAnon)
|
|
860
|
+
Symbol.debug_print("searchInSiblings:", searchInSiblings)
|
|
861
|
+
logger.debug(self.to_string(Symbol.debug_indent + 1), end="")
|
|
862
|
+
Symbol.debug_indent -= 2
|
|
863
|
+
current = self
|
|
864
|
+
while current is not None:
|
|
865
|
+
if Symbol.debug_lookup:
|
|
866
|
+
Symbol.debug_indent += 2
|
|
867
|
+
Symbol.debug_print("trying:")
|
|
868
|
+
logger.debug(current.to_string(Symbol.debug_indent + 1), end="")
|
|
869
|
+
Symbol.debug_indent -= 2
|
|
870
|
+
if matchSelf and current.identOrOp == identOrOp:
|
|
871
|
+
return current
|
|
872
|
+
children = current.children_recurse_anon if recurseInAnon else current._children
|
|
873
|
+
for s in children:
|
|
874
|
+
if s.identOrOp == identOrOp:
|
|
875
|
+
return s
|
|
876
|
+
if not searchInSiblings:
|
|
877
|
+
break
|
|
878
|
+
current = current.siblingAbove
|
|
879
|
+
return None
|
|
880
|
+
|
|
881
|
+
def direct_lookup(self, key: LookupKey) -> Symbol:
|
|
882
|
+
if Symbol.debug_lookup:
|
|
883
|
+
Symbol.debug_indent += 1
|
|
884
|
+
Symbol.debug_print("direct_lookup:")
|
|
885
|
+
Symbol.debug_indent += 1
|
|
886
|
+
s = self
|
|
887
|
+
for name, templateParams, id_ in key.data:
|
|
888
|
+
if id_ is not None:
|
|
889
|
+
res = None
|
|
890
|
+
for cand in s._children:
|
|
891
|
+
if cand.declaration is None:
|
|
892
|
+
continue
|
|
893
|
+
if cand.declaration.get_newest_id() == id_:
|
|
894
|
+
res = cand
|
|
895
|
+
break
|
|
896
|
+
s = res
|
|
897
|
+
else:
|
|
898
|
+
identOrOp = name.identOrOp
|
|
899
|
+
templateArgs = name.templateArgs
|
|
900
|
+
s = s._find_first_named_symbol(identOrOp,
|
|
901
|
+
templateParams, templateArgs,
|
|
902
|
+
templateShorthand=False,
|
|
903
|
+
matchSelf=False,
|
|
904
|
+
recurseInAnon=False,
|
|
905
|
+
correctPrimaryTemplateArgs=False)
|
|
906
|
+
if Symbol.debug_lookup:
|
|
907
|
+
Symbol.debug_print("name: ", name)
|
|
908
|
+
Symbol.debug_print("templateParams:", templateParams)
|
|
909
|
+
Symbol.debug_print("id: ", id_)
|
|
910
|
+
if s is not None:
|
|
911
|
+
logger.debug(s.to_string(Symbol.debug_indent + 1), end="")
|
|
912
|
+
else:
|
|
913
|
+
Symbol.debug_print("not found")
|
|
914
|
+
if s is None:
|
|
915
|
+
if Symbol.debug_lookup:
|
|
916
|
+
Symbol.debug_indent -= 2
|
|
917
|
+
return None
|
|
918
|
+
if Symbol.debug_lookup:
|
|
919
|
+
Symbol.debug_indent -= 2
|
|
920
|
+
return s
|
|
921
|
+
|
|
922
|
+
def find_name(
|
|
923
|
+
self,
|
|
924
|
+
nestedName: ASTNestedName,
|
|
925
|
+
templateDecls: list[Any],
|
|
926
|
+
typ: str,
|
|
927
|
+
templateShorthand: bool,
|
|
928
|
+
matchSelf: bool,
|
|
929
|
+
recurseInAnon: bool,
|
|
930
|
+
searchInSiblings: bool,
|
|
931
|
+
) -> tuple[list[Symbol] | None, str]:
|
|
932
|
+
# templateShorthand: missing template parameter lists for templates is ok
|
|
933
|
+
# If the first component is None,
|
|
934
|
+
# then the second component _may_ be a string explaining why.
|
|
935
|
+
if Symbol.debug_lookup:
|
|
936
|
+
Symbol.debug_indent += 1
|
|
937
|
+
Symbol.debug_print("find_name:")
|
|
938
|
+
Symbol.debug_indent += 1
|
|
939
|
+
Symbol.debug_print("self:")
|
|
940
|
+
logger.debug(self.to_string(Symbol.debug_indent + 1), end="")
|
|
941
|
+
Symbol.debug_print("nestedName: ", nestedName)
|
|
942
|
+
Symbol.debug_print("templateDecls: ", templateDecls)
|
|
943
|
+
Symbol.debug_print("typ: ", typ)
|
|
944
|
+
Symbol.debug_print("templateShorthand:", templateShorthand)
|
|
945
|
+
Symbol.debug_print("matchSelf: ", matchSelf)
|
|
946
|
+
Symbol.debug_print("recurseInAnon: ", recurseInAnon)
|
|
947
|
+
Symbol.debug_print("searchInSiblings: ", searchInSiblings)
|
|
948
|
+
|
|
949
|
+
class QualifiedSymbolIsTemplateParam(Exception):
|
|
950
|
+
pass
|
|
951
|
+
|
|
952
|
+
def onMissingQualifiedSymbol(parentSymbol: Symbol,
|
|
953
|
+
identOrOp: ASTIdentifier | ASTOperator,
|
|
954
|
+
templateParams: Any,
|
|
955
|
+
templateArgs: ASTTemplateArgs) -> Symbol | None:
|
|
956
|
+
# TODO: Maybe search without template args?
|
|
957
|
+
# Though, the correctPrimaryTemplateArgs does
|
|
958
|
+
# that for primary templates.
|
|
959
|
+
# Is there another case where it would be good?
|
|
960
|
+
if parentSymbol.declaration is not None:
|
|
961
|
+
if parentSymbol.declaration.objectType == 'templateParam':
|
|
962
|
+
raise QualifiedSymbolIsTemplateParam
|
|
963
|
+
return None
|
|
964
|
+
|
|
965
|
+
try:
|
|
966
|
+
lookupResult = self._symbol_lookup(nestedName, templateDecls,
|
|
967
|
+
onMissingQualifiedSymbol,
|
|
968
|
+
strictTemplateParamArgLists=False,
|
|
969
|
+
ancestorLookupType=typ,
|
|
970
|
+
templateShorthand=templateShorthand,
|
|
971
|
+
matchSelf=matchSelf,
|
|
972
|
+
recurseInAnon=recurseInAnon,
|
|
973
|
+
correctPrimaryTemplateArgs=False,
|
|
974
|
+
searchInSiblings=searchInSiblings)
|
|
975
|
+
except QualifiedSymbolIsTemplateParam:
|
|
976
|
+
return None, "templateParamInQualified"
|
|
977
|
+
|
|
978
|
+
if lookupResult is None:
|
|
979
|
+
# if it was a part of the qualification that could not be found
|
|
980
|
+
if Symbol.debug_lookup:
|
|
981
|
+
Symbol.debug_indent -= 2
|
|
982
|
+
return None, None
|
|
983
|
+
|
|
984
|
+
res = list(lookupResult.symbols)
|
|
985
|
+
if len(res) != 0:
|
|
986
|
+
if Symbol.debug_lookup:
|
|
987
|
+
Symbol.debug_indent -= 2
|
|
988
|
+
return res, None
|
|
989
|
+
|
|
990
|
+
if lookupResult.parentSymbol.declaration is not None:
|
|
991
|
+
if lookupResult.parentSymbol.declaration.objectType == 'templateParam':
|
|
992
|
+
return None, "templateParamInQualified"
|
|
993
|
+
|
|
994
|
+
# try without template params and args
|
|
995
|
+
symbol = lookupResult.parentSymbol._find_first_named_symbol(
|
|
996
|
+
lookupResult.identOrOp, None, None,
|
|
997
|
+
templateShorthand=templateShorthand, matchSelf=matchSelf,
|
|
998
|
+
recurseInAnon=recurseInAnon, correctPrimaryTemplateArgs=False)
|
|
999
|
+
if Symbol.debug_lookup:
|
|
1000
|
+
Symbol.debug_indent -= 2
|
|
1001
|
+
if symbol is not None:
|
|
1002
|
+
return [symbol], None
|
|
1003
|
+
else:
|
|
1004
|
+
return None, None
|
|
1005
|
+
|
|
1006
|
+
def find_declaration(self, declaration: ASTDeclaration, typ: str, templateShorthand: bool,
|
|
1007
|
+
matchSelf: bool, recurseInAnon: bool) -> Symbol | None:
|
|
1008
|
+
# templateShorthand: missing template parameter lists for templates is ok
|
|
1009
|
+
if Symbol.debug_lookup:
|
|
1010
|
+
Symbol.debug_indent += 1
|
|
1011
|
+
Symbol.debug_print("find_declaration:")
|
|
1012
|
+
nestedName = declaration.name
|
|
1013
|
+
if declaration.templatePrefix:
|
|
1014
|
+
templateDecls = declaration.templatePrefix.templates
|
|
1015
|
+
else:
|
|
1016
|
+
templateDecls = []
|
|
1017
|
+
|
|
1018
|
+
def onMissingQualifiedSymbol(parentSymbol: Symbol,
|
|
1019
|
+
identOrOp: ASTIdentifier | ASTOperator,
|
|
1020
|
+
templateParams: Any,
|
|
1021
|
+
templateArgs: ASTTemplateArgs) -> Symbol | None:
|
|
1022
|
+
return None
|
|
1023
|
+
|
|
1024
|
+
lookupResult = self._symbol_lookup(nestedName, templateDecls,
|
|
1025
|
+
onMissingQualifiedSymbol,
|
|
1026
|
+
strictTemplateParamArgLists=False,
|
|
1027
|
+
ancestorLookupType=typ,
|
|
1028
|
+
templateShorthand=templateShorthand,
|
|
1029
|
+
matchSelf=matchSelf,
|
|
1030
|
+
recurseInAnon=recurseInAnon,
|
|
1031
|
+
correctPrimaryTemplateArgs=False,
|
|
1032
|
+
searchInSiblings=False)
|
|
1033
|
+
if Symbol.debug_lookup:
|
|
1034
|
+
Symbol.debug_indent -= 1
|
|
1035
|
+
if lookupResult is None:
|
|
1036
|
+
return None
|
|
1037
|
+
|
|
1038
|
+
symbols = list(lookupResult.symbols)
|
|
1039
|
+
if len(symbols) == 0:
|
|
1040
|
+
return None
|
|
1041
|
+
|
|
1042
|
+
querySymbol = Symbol(parent=lookupResult.parentSymbol,
|
|
1043
|
+
identOrOp=lookupResult.identOrOp,
|
|
1044
|
+
templateParams=lookupResult.templateParams,
|
|
1045
|
+
templateArgs=lookupResult.templateArgs,
|
|
1046
|
+
declaration=declaration,
|
|
1047
|
+
docname='fakeDocnameForQuery',
|
|
1048
|
+
line=42)
|
|
1049
|
+
queryId = declaration.get_newest_id()
|
|
1050
|
+
for symbol in symbols:
|
|
1051
|
+
if symbol.declaration is None:
|
|
1052
|
+
continue
|
|
1053
|
+
candId = symbol.declaration.get_newest_id()
|
|
1054
|
+
if candId == queryId:
|
|
1055
|
+
querySymbol.remove()
|
|
1056
|
+
return symbol
|
|
1057
|
+
querySymbol.remove()
|
|
1058
|
+
return None
|
|
1059
|
+
|
|
1060
|
+
def to_string(self, indent: int) -> str:
|
|
1061
|
+
res = [Symbol.debug_indent_string * indent]
|
|
1062
|
+
if not self.parent:
|
|
1063
|
+
res.append('::')
|
|
1064
|
+
else:
|
|
1065
|
+
if self.templateParams:
|
|
1066
|
+
res.append(str(self.templateParams))
|
|
1067
|
+
res.append('\n')
|
|
1068
|
+
res.append(Symbol.debug_indent_string * indent)
|
|
1069
|
+
if self.identOrOp:
|
|
1070
|
+
res.append(str(self.identOrOp))
|
|
1071
|
+
else:
|
|
1072
|
+
res.append(str(self.declaration))
|
|
1073
|
+
if self.templateArgs:
|
|
1074
|
+
res.append(str(self.templateArgs))
|
|
1075
|
+
if self.declaration:
|
|
1076
|
+
res.append(": ")
|
|
1077
|
+
if self.isRedeclaration:
|
|
1078
|
+
res.append('!!duplicate!! ')
|
|
1079
|
+
res.append("{" + self.declaration.objectType + "} ")
|
|
1080
|
+
res.append(str(self.declaration))
|
|
1081
|
+
if self.docname:
|
|
1082
|
+
res.append('\t(')
|
|
1083
|
+
res.append(self.docname)
|
|
1084
|
+
res.append(')')
|
|
1085
|
+
res.append('\n')
|
|
1086
|
+
return ''.join(res)
|
|
1087
|
+
|
|
1088
|
+
def dump(self, indent: int) -> str:
|
|
1089
|
+
return ''.join([
|
|
1090
|
+
self.to_string(indent),
|
|
1091
|
+
*(c.dump(indent + 1) for c in self._children),
|
|
1092
|
+
])
|