Sphinx 8.1.3__py3-none-any.whl → 8.2.0rc1__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 -4
- sphinx/__main__.py +2 -0
- sphinx/_cli/__init__.py +2 -5
- sphinx/_cli/util/colour.py +34 -11
- sphinx/_cli/util/errors.py +128 -61
- sphinx/addnodes.py +51 -35
- sphinx/application.py +362 -230
- sphinx/builders/__init__.py +87 -64
- sphinx/builders/_epub_base.py +65 -56
- sphinx/builders/changes.py +17 -23
- sphinx/builders/dirhtml.py +8 -13
- sphinx/builders/epub3.py +70 -38
- sphinx/builders/gettext.py +93 -73
- sphinx/builders/html/__init__.py +240 -186
- sphinx/builders/html/_assets.py +9 -2
- sphinx/builders/html/_build_info.py +3 -0
- sphinx/builders/latex/__init__.py +64 -54
- sphinx/builders/latex/constants.py +14 -11
- sphinx/builders/latex/nodes.py +2 -0
- sphinx/builders/latex/theming.py +8 -9
- sphinx/builders/latex/transforms.py +7 -5
- sphinx/builders/linkcheck.py +193 -149
- sphinx/builders/manpage.py +17 -17
- sphinx/builders/singlehtml.py +28 -16
- sphinx/builders/texinfo.py +28 -21
- sphinx/builders/text.py +10 -15
- sphinx/builders/xml.py +10 -19
- sphinx/cmd/build.py +49 -119
- sphinx/cmd/make_mode.py +35 -31
- sphinx/cmd/quickstart.py +78 -62
- sphinx/config.py +265 -163
- sphinx/directives/__init__.py +51 -54
- sphinx/directives/admonitions.py +107 -0
- sphinx/directives/code.py +24 -19
- sphinx/directives/other.py +21 -42
- sphinx/directives/patches.py +28 -16
- sphinx/domains/__init__.py +54 -31
- sphinx/domains/_domains_container.py +22 -17
- sphinx/domains/_index.py +5 -8
- sphinx/domains/c/__init__.py +366 -245
- sphinx/domains/c/_ast.py +378 -256
- sphinx/domains/c/_ids.py +89 -31
- sphinx/domains/c/_parser.py +283 -214
- sphinx/domains/c/_symbol.py +269 -198
- sphinx/domains/changeset.py +39 -24
- sphinx/domains/citation.py +54 -24
- sphinx/domains/cpp/__init__.py +517 -362
- sphinx/domains/cpp/_ast.py +999 -682
- sphinx/domains/cpp/_ids.py +133 -65
- sphinx/domains/cpp/_parser.py +746 -588
- sphinx/domains/cpp/_symbol.py +692 -489
- sphinx/domains/index.py +10 -8
- sphinx/domains/javascript.py +152 -74
- sphinx/domains/math.py +48 -40
- sphinx/domains/python/__init__.py +402 -211
- sphinx/domains/python/_annotations.py +114 -57
- sphinx/domains/python/_object.py +151 -67
- sphinx/domains/rst.py +94 -49
- sphinx/domains/std/__init__.py +510 -249
- sphinx/environment/__init__.py +345 -61
- sphinx/environment/adapters/asset.py +7 -1
- sphinx/environment/adapters/indexentries.py +15 -20
- sphinx/environment/adapters/toctree.py +19 -9
- sphinx/environment/collectors/__init__.py +3 -1
- sphinx/environment/collectors/asset.py +18 -15
- sphinx/environment/collectors/dependencies.py +8 -10
- sphinx/environment/collectors/metadata.py +6 -4
- sphinx/environment/collectors/title.py +3 -1
- sphinx/environment/collectors/toctree.py +4 -4
- sphinx/errors.py +1 -3
- sphinx/events.py +4 -4
- sphinx/ext/apidoc/__init__.py +21 -0
- sphinx/ext/apidoc/__main__.py +9 -0
- sphinx/ext/apidoc/_cli.py +356 -0
- sphinx/ext/apidoc/_generate.py +356 -0
- sphinx/ext/apidoc/_shared.py +66 -0
- sphinx/ext/autodoc/__init__.py +829 -480
- sphinx/ext/autodoc/directive.py +57 -21
- sphinx/ext/autodoc/importer.py +184 -67
- sphinx/ext/autodoc/mock.py +25 -10
- sphinx/ext/autodoc/preserve_defaults.py +17 -9
- sphinx/ext/autodoc/type_comment.py +56 -29
- sphinx/ext/autodoc/typehints.py +49 -26
- sphinx/ext/autosectionlabel.py +28 -11
- sphinx/ext/autosummary/__init__.py +271 -143
- sphinx/ext/autosummary/generate.py +121 -51
- sphinx/ext/coverage.py +152 -91
- sphinx/ext/doctest.py +169 -101
- sphinx/ext/duration.py +12 -6
- sphinx/ext/extlinks.py +33 -21
- sphinx/ext/githubpages.py +8 -8
- sphinx/ext/graphviz.py +175 -109
- sphinx/ext/ifconfig.py +11 -6
- sphinx/ext/imgconverter.py +48 -25
- sphinx/ext/imgmath.py +127 -97
- sphinx/ext/inheritance_diagram.py +177 -103
- sphinx/ext/intersphinx/__init__.py +22 -13
- sphinx/ext/intersphinx/__main__.py +3 -1
- sphinx/ext/intersphinx/_cli.py +18 -14
- sphinx/ext/intersphinx/_load.py +91 -82
- sphinx/ext/intersphinx/_resolve.py +108 -74
- sphinx/ext/intersphinx/_shared.py +2 -2
- sphinx/ext/linkcode.py +28 -12
- sphinx/ext/mathjax.py +60 -29
- sphinx/ext/napoleon/__init__.py +19 -7
- sphinx/ext/napoleon/docstring.py +229 -231
- sphinx/ext/todo.py +44 -49
- sphinx/ext/viewcode.py +105 -57
- sphinx/extension.py +3 -1
- sphinx/highlighting.py +13 -7
- sphinx/io.py +9 -13
- sphinx/jinja2glue.py +29 -26
- sphinx/locale/__init__.py +8 -9
- sphinx/parsers.py +8 -7
- sphinx/project.py +2 -2
- sphinx/pycode/__init__.py +31 -21
- sphinx/pycode/ast.py +6 -3
- sphinx/pycode/parser.py +14 -8
- sphinx/pygments_styles.py +4 -5
- sphinx/registry.py +192 -92
- sphinx/roles.py +58 -7
- sphinx/search/__init__.py +75 -54
- sphinx/search/en.py +11 -13
- sphinx/search/fi.py +1 -1
- sphinx/search/ja.py +8 -6
- sphinx/search/nl.py +1 -1
- sphinx/search/zh.py +19 -21
- sphinx/testing/fixtures.py +26 -29
- sphinx/testing/path.py +26 -62
- sphinx/testing/restructuredtext.py +14 -8
- sphinx/testing/util.py +21 -19
- sphinx/texinputs/make.bat.jinja +50 -50
- sphinx/texinputs/sphinx.sty +4 -3
- sphinx/texinputs/sphinxlatexadmonitions.sty +1 -1
- sphinx/texinputs/sphinxlatexobjects.sty +29 -10
- sphinx/themes/basic/static/searchtools.js +8 -5
- sphinx/theming.py +49 -61
- sphinx/transforms/__init__.py +17 -38
- sphinx/transforms/compact_bullet_list.py +5 -3
- sphinx/transforms/i18n.py +8 -21
- sphinx/transforms/post_transforms/__init__.py +142 -93
- sphinx/transforms/post_transforms/code.py +5 -5
- sphinx/transforms/post_transforms/images.py +28 -24
- sphinx/transforms/references.py +3 -1
- sphinx/util/__init__.py +109 -60
- sphinx/util/_files.py +39 -23
- sphinx/util/_importer.py +4 -1
- sphinx/util/_inventory_file_reader.py +76 -0
- sphinx/util/_io.py +2 -2
- sphinx/util/_lines.py +6 -3
- sphinx/util/_pathlib.py +40 -2
- sphinx/util/build_phase.py +2 -0
- sphinx/util/cfamily.py +19 -14
- sphinx/util/console.py +44 -179
- sphinx/util/display.py +9 -10
- sphinx/util/docfields.py +140 -122
- sphinx/util/docstrings.py +1 -1
- sphinx/util/docutils.py +118 -77
- sphinx/util/fileutil.py +25 -26
- sphinx/util/http_date.py +2 -0
- sphinx/util/i18n.py +77 -64
- sphinx/util/images.py +8 -6
- sphinx/util/inspect.py +147 -38
- sphinx/util/inventory.py +215 -116
- sphinx/util/logging.py +33 -33
- sphinx/util/matching.py +12 -4
- sphinx/util/nodes.py +18 -13
- sphinx/util/osutil.py +38 -39
- sphinx/util/parallel.py +22 -13
- sphinx/util/parsing.py +2 -1
- sphinx/util/png.py +6 -2
- sphinx/util/requests.py +33 -2
- sphinx/util/rst.py +3 -2
- sphinx/util/tags.py +1 -1
- sphinx/util/template.py +18 -10
- sphinx/util/texescape.py +8 -6
- sphinx/util/typing.py +148 -122
- sphinx/versioning.py +3 -3
- sphinx/writers/html.py +3 -1
- sphinx/writers/html5.py +61 -50
- sphinx/writers/latex.py +80 -65
- sphinx/writers/manpage.py +19 -38
- sphinx/writers/texinfo.py +44 -45
- sphinx/writers/text.py +48 -30
- sphinx/writers/xml.py +11 -8
- {sphinx-8.1.3.dist-info → sphinx-8.2.0rc1.dist-info}/LICENSE.rst +1 -1
- {sphinx-8.1.3.dist-info → sphinx-8.2.0rc1.dist-info}/METADATA +23 -15
- {sphinx-8.1.3.dist-info → sphinx-8.2.0rc1.dist-info}/RECORD +190 -186
- {sphinx-8.1.3.dist-info → sphinx-8.2.0rc1.dist-info}/WHEEL +1 -1
- sphinx/builders/html/transforms.py +0 -90
- sphinx/ext/apidoc.py +0 -721
- sphinx/util/exceptions.py +0 -74
- {sphinx-8.1.3.dist-info → sphinx-8.2.0rc1.dist-info}/entry_points.txt +0 -0
sphinx/domains/c/__init__.py
CHANGED
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
|
-
from
|
|
5
|
+
from types import NoneType
|
|
6
|
+
from typing import TYPE_CHECKING
|
|
6
7
|
|
|
7
8
|
from docutils import nodes
|
|
8
9
|
from docutils.parsers.rst import directives
|
|
@@ -15,7 +16,7 @@ from sphinx.domains.c._ast import (
|
|
|
15
16
|
ASTIdentifier,
|
|
16
17
|
ASTNestedName,
|
|
17
18
|
)
|
|
18
|
-
from sphinx.domains.c._ids import
|
|
19
|
+
from sphinx.domains.c._ids import _macro_keywords, _max_id
|
|
19
20
|
from sphinx.domains.c._parser import DefinitionParser
|
|
20
21
|
from sphinx.domains.c._symbol import Symbol, _DuplicateSymbolError
|
|
21
22
|
from sphinx.locale import _, __
|
|
@@ -34,6 +35,7 @@ from sphinx.util.nodes import make_refnode
|
|
|
34
35
|
|
|
35
36
|
if TYPE_CHECKING:
|
|
36
37
|
from collections.abc import Iterator, Set
|
|
38
|
+
from typing import Any, ClassVar
|
|
37
39
|
|
|
38
40
|
from docutils.nodes import Element, Node, TextElement, system_message
|
|
39
41
|
|
|
@@ -45,7 +47,7 @@ if TYPE_CHECKING:
|
|
|
45
47
|
from sphinx.util.typing import ExtensionMetadata, OptionSpec
|
|
46
48
|
|
|
47
49
|
# re-export objects for backwards compatibility
|
|
48
|
-
#
|
|
50
|
+
# See: https://github.com/sphinx-doc/sphinx/issues/12295
|
|
49
51
|
from sphinx.domains.c._ast import ( # NoQA: F401
|
|
50
52
|
ASTAlignofExpr,
|
|
51
53
|
ASTArray,
|
|
@@ -101,13 +103,11 @@ logger = logging.getLogger(__name__)
|
|
|
101
103
|
|
|
102
104
|
|
|
103
105
|
def _make_phony_error_name() -> ASTNestedName:
|
|
104
|
-
return ASTNestedName([ASTIdentifier(
|
|
106
|
+
return ASTNestedName([ASTIdentifier('PhonyNameDueToError')], rooted=False)
|
|
105
107
|
|
|
106
108
|
|
|
107
109
|
class CObject(ObjectDescription[ASTDeclaration]):
|
|
108
|
-
"""
|
|
109
|
-
Description of a C language object.
|
|
110
|
-
"""
|
|
110
|
+
"""Description of a C language object."""
|
|
111
111
|
|
|
112
112
|
option_spec: ClassVar[OptionSpec] = {
|
|
113
113
|
'no-index-entry': directives.flag,
|
|
@@ -125,38 +125,44 @@ class CObject(ObjectDescription[ASTDeclaration]):
|
|
|
125
125
|
symbol = ast.symbol
|
|
126
126
|
assert symbol
|
|
127
127
|
assert symbol.ident is not None
|
|
128
|
-
|
|
129
|
-
assert
|
|
130
|
-
if
|
|
128
|
+
parent_symbol = symbol.parent
|
|
129
|
+
assert parent_symbol
|
|
130
|
+
if parent_symbol.parent is None:
|
|
131
131
|
# TODO: we could warn, but it is somewhat equivalent to
|
|
132
132
|
# enumeratorss, without the enum
|
|
133
133
|
return # no parent
|
|
134
|
-
|
|
135
|
-
if
|
|
134
|
+
parent_decl = parent_symbol.declaration
|
|
135
|
+
if parent_decl is None:
|
|
136
136
|
# the parent is not explicitly declared
|
|
137
137
|
# TODO: we could warn, but?
|
|
138
138
|
return
|
|
139
|
-
if
|
|
139
|
+
if parent_decl.objectType != 'enum':
|
|
140
140
|
# TODO: maybe issue a warning, enumerators in non-enums is weird,
|
|
141
141
|
# but it is somewhat equivalent to enumeratorss, without the enum
|
|
142
142
|
return
|
|
143
|
-
if
|
|
143
|
+
if parent_decl.directiveType != 'enum':
|
|
144
144
|
return
|
|
145
145
|
|
|
146
|
-
|
|
147
|
-
s =
|
|
148
|
-
|
|
146
|
+
target_symbol = parent_symbol.parent
|
|
147
|
+
s = target_symbol.find_identifier(
|
|
148
|
+
symbol.ident, matchSelf=False, recurseInAnon=True, searchInSiblings=False
|
|
149
|
+
)
|
|
149
150
|
if s is not None:
|
|
150
151
|
# something is already declared with that name
|
|
151
152
|
return
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
Symbol(
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
153
|
+
decl_clone = symbol.declaration.clone()
|
|
154
|
+
decl_clone.enumeratorScopedSymbol = symbol
|
|
155
|
+
Symbol(
|
|
156
|
+
parent=target_symbol,
|
|
157
|
+
ident=symbol.ident,
|
|
158
|
+
declaration=decl_clone,
|
|
159
|
+
docname=self.env.docname,
|
|
160
|
+
line=self.get_source_info()[1],
|
|
161
|
+
)
|
|
162
|
+
|
|
163
|
+
def add_target_and_index(
|
|
164
|
+
self, ast: ASTDeclaration, sig: str, signode: TextElement
|
|
165
|
+
) -> None:
|
|
160
166
|
ids = []
|
|
161
167
|
for i in range(1, _max_id + 1):
|
|
162
168
|
try:
|
|
@@ -166,14 +172,14 @@ class CObject(ObjectDescription[ASTDeclaration]):
|
|
|
166
172
|
assert i < _max_id
|
|
167
173
|
# let's keep the newest first
|
|
168
174
|
ids.reverse()
|
|
169
|
-
|
|
170
|
-
assert
|
|
175
|
+
newest_id = ids[0]
|
|
176
|
+
assert newest_id # shouldn't be None
|
|
171
177
|
|
|
172
178
|
name = ast.symbol.get_full_nested_name().get_display_string().lstrip('.')
|
|
173
|
-
if
|
|
179
|
+
if newest_id not in self.state.document.ids:
|
|
174
180
|
# always add the newest id
|
|
175
|
-
assert
|
|
176
|
-
signode['ids'].append(
|
|
181
|
+
assert newest_id
|
|
182
|
+
signode['ids'].append(newest_id)
|
|
177
183
|
# only add compatibility ids when there are no conflicts
|
|
178
184
|
for id in ids[1:]:
|
|
179
185
|
if not id: # is None when the element didn't exist in that version
|
|
@@ -184,8 +190,14 @@ class CObject(ObjectDescription[ASTDeclaration]):
|
|
|
184
190
|
self.state.document.note_explicit_target(signode)
|
|
185
191
|
|
|
186
192
|
if 'no-index-entry' not in self.options:
|
|
187
|
-
|
|
188
|
-
self.indexnode['entries'].append((
|
|
193
|
+
index_text = self.get_index_text(name)
|
|
194
|
+
self.indexnode['entries'].append((
|
|
195
|
+
'single',
|
|
196
|
+
index_text,
|
|
197
|
+
newest_id,
|
|
198
|
+
'',
|
|
199
|
+
None,
|
|
200
|
+
))
|
|
189
201
|
|
|
190
202
|
@property
|
|
191
203
|
def object_type(self) -> str:
|
|
@@ -201,35 +213,38 @@ class CObject(ObjectDescription[ASTDeclaration]):
|
|
|
201
213
|
def parse_definition(self, parser: DefinitionParser) -> ASTDeclaration:
|
|
202
214
|
return parser.parse_declaration(self.object_type, self.objtype)
|
|
203
215
|
|
|
204
|
-
def describe_signature(
|
|
205
|
-
|
|
216
|
+
def describe_signature(
|
|
217
|
+
self, signode: TextElement, ast: ASTDeclaration, options: dict[str, Any]
|
|
218
|
+
) -> None:
|
|
206
219
|
ast.describe_signature(signode, 'lastIsName', self.env, options)
|
|
207
220
|
|
|
208
221
|
def run(self) -> list[Node]:
|
|
209
|
-
env = self.
|
|
210
|
-
if
|
|
222
|
+
env = self.env
|
|
223
|
+
if env.current_document.c_parent_symbol is None:
|
|
211
224
|
root = env.domaindata['c']['root_symbol']
|
|
212
|
-
env.
|
|
225
|
+
env.current_document.c_parent_symbol = root
|
|
213
226
|
env.ref_context['c:parent_key'] = root.get_lookup_key()
|
|
214
227
|
|
|
215
228
|
# When multiple declarations are made in the same directive
|
|
216
229
|
# they need to know about each other to provide symbol lookup for function parameters.
|
|
217
230
|
# We use last_symbol to store the latest added declaration in a directive.
|
|
218
|
-
env.
|
|
231
|
+
env.current_document.c_last_symbol = None
|
|
219
232
|
return super().run()
|
|
220
233
|
|
|
221
234
|
def handle_signature(self, sig: str, signode: TextElement) -> ASTDeclaration:
|
|
222
|
-
|
|
235
|
+
parent_symbol: Symbol = self.env.current_document.c_parent_symbol
|
|
223
236
|
|
|
224
|
-
max_len = (
|
|
225
|
-
|
|
226
|
-
|
|
237
|
+
max_len = (
|
|
238
|
+
self.config.c_maximum_signature_line_length
|
|
239
|
+
or self.config.maximum_signature_line_length
|
|
240
|
+
or 0
|
|
241
|
+
)
|
|
227
242
|
signode['multi_line_parameter_list'] = (
|
|
228
243
|
'single-line-parameter-list' not in self.options
|
|
229
244
|
and (len(sig) > max_len > 0)
|
|
230
245
|
)
|
|
231
246
|
|
|
232
|
-
parser = DefinitionParser(sig, location=signode, config=self.
|
|
247
|
+
parser = DefinitionParser(sig, location=signode, config=self.config)
|
|
233
248
|
try:
|
|
234
249
|
ast = self.parse_definition(parser)
|
|
235
250
|
parser.assert_end()
|
|
@@ -238,29 +253,40 @@ class CObject(ObjectDescription[ASTDeclaration]):
|
|
|
238
253
|
# It is easier to assume some phony name than handling the error in
|
|
239
254
|
# the possibly inner declarations.
|
|
240
255
|
name = _make_phony_error_name()
|
|
241
|
-
symbol =
|
|
242
|
-
self.env.
|
|
256
|
+
symbol = parent_symbol.add_name(name)
|
|
257
|
+
self.env.current_document.c_last_symbol = symbol
|
|
243
258
|
raise ValueError from e
|
|
244
259
|
|
|
245
260
|
try:
|
|
246
|
-
symbol =
|
|
247
|
-
ast, docname=self.env.docname, line=self.get_source_info()[1]
|
|
261
|
+
symbol = parent_symbol.add_declaration(
|
|
262
|
+
ast, docname=self.env.docname, line=self.get_source_info()[1]
|
|
263
|
+
)
|
|
248
264
|
# append the new declaration to the sibling list
|
|
249
265
|
assert symbol.siblingAbove is None
|
|
250
266
|
assert symbol.siblingBelow is None
|
|
251
|
-
symbol.siblingAbove = self.env.
|
|
267
|
+
symbol.siblingAbove = self.env.current_document.c_last_symbol
|
|
252
268
|
if symbol.siblingAbove is not None:
|
|
253
269
|
assert symbol.siblingAbove.siblingBelow is None
|
|
254
270
|
symbol.siblingAbove.siblingBelow = symbol
|
|
255
|
-
self.env.
|
|
271
|
+
self.env.current_document.c_last_symbol = symbol
|
|
256
272
|
except _DuplicateSymbolError as e:
|
|
257
273
|
# Assume we are actually in the old symbol,
|
|
258
274
|
# instead of the newly created duplicate.
|
|
259
|
-
self.env.
|
|
260
|
-
msg = __(
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
275
|
+
self.env.current_document.c_last_symbol = e.symbol
|
|
276
|
+
msg = __(
|
|
277
|
+
'Duplicate C declaration, also defined at %s:%s.\n'
|
|
278
|
+
"Declaration is '.. c:%s:: %s'."
|
|
279
|
+
)
|
|
280
|
+
logger.warning(
|
|
281
|
+
msg,
|
|
282
|
+
e.symbol.docname,
|
|
283
|
+
e.symbol.line,
|
|
284
|
+
self.display_object_type,
|
|
285
|
+
sig,
|
|
286
|
+
location=signode,
|
|
287
|
+
type='duplicate_declaration',
|
|
288
|
+
subtype='c',
|
|
289
|
+
)
|
|
264
290
|
|
|
265
291
|
if ast.objectType == 'enumerator':
|
|
266
292
|
self._add_enumerator_to_parent(ast)
|
|
@@ -272,15 +298,15 @@ class CObject(ObjectDescription[ASTDeclaration]):
|
|
|
272
298
|
return ast
|
|
273
299
|
|
|
274
300
|
def before_content(self) -> None:
|
|
275
|
-
|
|
276
|
-
assert
|
|
277
|
-
self.oldParentSymbol = self.env.
|
|
301
|
+
last_symbol: Symbol = self.env.current_document.c_last_symbol
|
|
302
|
+
assert last_symbol
|
|
303
|
+
self.oldParentSymbol = self.env.current_document.c_parent_symbol
|
|
278
304
|
self.oldParentKey: LookupKey = self.env.ref_context['c:parent_key']
|
|
279
|
-
self.env.
|
|
280
|
-
self.env.ref_context['c:parent_key'] =
|
|
305
|
+
self.env.current_document.c_parent_symbol = last_symbol
|
|
306
|
+
self.env.ref_context['c:parent_key'] = last_symbol.get_lookup_key()
|
|
281
307
|
|
|
282
308
|
def after_content(self) -> None:
|
|
283
|
-
self.env.
|
|
309
|
+
self.env.current_document.c_parent_symbol = self.oldParentSymbol
|
|
284
310
|
self.env.ref_context['c:parent_key'] = self.oldParentKey
|
|
285
311
|
|
|
286
312
|
|
|
@@ -290,21 +316,36 @@ class CMemberObject(CObject):
|
|
|
290
316
|
@property
|
|
291
317
|
def display_object_type(self) -> str:
|
|
292
318
|
# the distinction between var and member is only cosmetic
|
|
293
|
-
assert self.objtype in
|
|
319
|
+
assert self.objtype in {'member', 'var'}
|
|
294
320
|
return self.objtype
|
|
295
321
|
|
|
296
322
|
|
|
297
323
|
_function_doc_field_types = [
|
|
298
|
-
TypedField(
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
324
|
+
TypedField(
|
|
325
|
+
'parameter',
|
|
326
|
+
label=_('Parameters'),
|
|
327
|
+
names=('param', 'parameter', 'arg', 'argument'),
|
|
328
|
+
typerolename='expr',
|
|
329
|
+
typenames=('type',),
|
|
330
|
+
),
|
|
331
|
+
GroupedField(
|
|
332
|
+
'retval',
|
|
333
|
+
label=_('Return values'),
|
|
334
|
+
names=('retvals', 'retval'),
|
|
335
|
+
can_collapse=True,
|
|
336
|
+
),
|
|
337
|
+
Field(
|
|
338
|
+
'returnvalue',
|
|
339
|
+
label=_('Returns'),
|
|
340
|
+
has_arg=False,
|
|
341
|
+
names=('returns', 'return'),
|
|
342
|
+
),
|
|
343
|
+
Field(
|
|
344
|
+
'returntype',
|
|
345
|
+
label=_('Return type'),
|
|
346
|
+
has_arg=False,
|
|
347
|
+
names=('rtype',),
|
|
348
|
+
),
|
|
308
349
|
]
|
|
309
350
|
|
|
310
351
|
|
|
@@ -341,8 +382,7 @@ class CTypeObject(CObject):
|
|
|
341
382
|
|
|
342
383
|
|
|
343
384
|
class CNamespaceObject(SphinxDirective):
|
|
344
|
-
"""
|
|
345
|
-
This directive is just to tell Sphinx that we're documenting stuff in
|
|
385
|
+
"""This directive is just to tell Sphinx that we're documenting stuff in
|
|
346
386
|
namespace foo.
|
|
347
387
|
"""
|
|
348
388
|
|
|
@@ -353,24 +393,24 @@ class CNamespaceObject(SphinxDirective):
|
|
|
353
393
|
option_spec: ClassVar[OptionSpec] = {}
|
|
354
394
|
|
|
355
395
|
def run(self) -> list[Node]:
|
|
356
|
-
|
|
357
|
-
if self.arguments[0].strip() in
|
|
358
|
-
symbol =
|
|
396
|
+
root_symbol = self.env.domaindata['c']['root_symbol']
|
|
397
|
+
if self.arguments[0].strip() in {'NULL', '0', 'nullptr'}:
|
|
398
|
+
symbol = root_symbol
|
|
359
399
|
stack: list[Symbol] = []
|
|
360
400
|
else:
|
|
361
|
-
parser = DefinitionParser(
|
|
362
|
-
|
|
363
|
-
|
|
401
|
+
parser = DefinitionParser(
|
|
402
|
+
self.arguments[0], location=self.get_location(), config=self.config
|
|
403
|
+
)
|
|
364
404
|
try:
|
|
365
405
|
name = parser.parse_namespace_object()
|
|
366
406
|
parser.assert_end()
|
|
367
407
|
except DefinitionError as e:
|
|
368
408
|
logger.warning(e, location=self.get_location())
|
|
369
409
|
name = _make_phony_error_name()
|
|
370
|
-
symbol =
|
|
410
|
+
symbol = root_symbol.add_name(name)
|
|
371
411
|
stack = [symbol]
|
|
372
|
-
self.env.
|
|
373
|
-
self.env.
|
|
412
|
+
self.env.current_document.c_parent_symbol = symbol
|
|
413
|
+
self.env.current_document.c_namespace_stack = stack
|
|
374
414
|
self.env.ref_context['c:parent_key'] = symbol.get_lookup_key()
|
|
375
415
|
return []
|
|
376
416
|
|
|
@@ -383,25 +423,23 @@ class CNamespacePushObject(SphinxDirective):
|
|
|
383
423
|
option_spec: ClassVar[OptionSpec] = {}
|
|
384
424
|
|
|
385
425
|
def run(self) -> list[Node]:
|
|
386
|
-
if self.arguments[0].strip() in
|
|
426
|
+
if self.arguments[0].strip() in {'NULL', '0', 'nullptr'}:
|
|
387
427
|
return []
|
|
388
|
-
parser = DefinitionParser(
|
|
389
|
-
|
|
390
|
-
|
|
428
|
+
parser = DefinitionParser(
|
|
429
|
+
self.arguments[0], location=self.get_location(), config=self.config
|
|
430
|
+
)
|
|
391
431
|
try:
|
|
392
432
|
name = parser.parse_namespace_object()
|
|
393
433
|
parser.assert_end()
|
|
394
434
|
except DefinitionError as e:
|
|
395
435
|
logger.warning(e, location=self.get_location())
|
|
396
436
|
name = _make_phony_error_name()
|
|
397
|
-
|
|
398
|
-
if not
|
|
399
|
-
|
|
400
|
-
symbol =
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
self.env.temp_data['c:parent_symbol'] = symbol
|
|
404
|
-
self.env.temp_data['c:namespace_stack'] = stack
|
|
437
|
+
old_parent = self.env.current_document.c_parent_symbol
|
|
438
|
+
if not old_parent:
|
|
439
|
+
old_parent = self.env.domaindata['c']['root_symbol']
|
|
440
|
+
symbol = old_parent.add_name(name)
|
|
441
|
+
self.env.current_document.c_namespace_stack.append(symbol)
|
|
442
|
+
self.env.current_document.c_parent_symbol = symbol
|
|
405
443
|
self.env.ref_context['c:parent_key'] = symbol.get_lookup_key()
|
|
406
444
|
return []
|
|
407
445
|
|
|
@@ -414,19 +452,19 @@ class CNamespacePopObject(SphinxDirective):
|
|
|
414
452
|
option_spec: ClassVar[OptionSpec] = {}
|
|
415
453
|
|
|
416
454
|
def run(self) -> list[Node]:
|
|
417
|
-
stack = self.env.
|
|
418
|
-
if
|
|
419
|
-
logger.warning(
|
|
420
|
-
|
|
421
|
-
|
|
455
|
+
stack = self.env.current_document.c_namespace_stack
|
|
456
|
+
if len(stack) == 0:
|
|
457
|
+
logger.warning(
|
|
458
|
+
'C namespace pop on empty stack. Defaulting to global scope.',
|
|
459
|
+
location=self.get_location(),
|
|
460
|
+
)
|
|
422
461
|
else:
|
|
423
462
|
stack.pop()
|
|
424
463
|
if len(stack) > 0:
|
|
425
464
|
symbol = stack[-1]
|
|
426
465
|
else:
|
|
427
466
|
symbol = self.env.domaindata['c']['root_symbol']
|
|
428
|
-
self.env.
|
|
429
|
-
self.env.temp_data['c:namespace_stack'] = stack
|
|
467
|
+
self.env.current_document.c_parent_symbol = symbol
|
|
430
468
|
self.env.ref_context['c:parent_key'] = symbol.get_lookup_key()
|
|
431
469
|
return []
|
|
432
470
|
|
|
@@ -435,7 +473,7 @@ class AliasNode(nodes.Element):
|
|
|
435
473
|
def __init__(
|
|
436
474
|
self,
|
|
437
475
|
sig: str,
|
|
438
|
-
aliasOptions: dict,
|
|
476
|
+
aliasOptions: dict[str, bool],
|
|
439
477
|
document: Any,
|
|
440
478
|
env: BuildEnvironment | None = None,
|
|
441
479
|
parentKey: LookupKey | None = None,
|
|
@@ -445,9 +483,9 @@ class AliasNode(nodes.Element):
|
|
|
445
483
|
self.aliasOptions = aliasOptions
|
|
446
484
|
self.document = document
|
|
447
485
|
if env is not None:
|
|
448
|
-
if
|
|
486
|
+
if env.current_document.c_parent_symbol is None:
|
|
449
487
|
root = env.domaindata['c']['root_symbol']
|
|
450
|
-
env.
|
|
488
|
+
env.current_document.c_parent_symbol = root
|
|
451
489
|
env.ref_context['c:parent_key'] = root.get_lookup_key()
|
|
452
490
|
self.parentKey = env.ref_context['c:parent_key']
|
|
453
491
|
else:
|
|
@@ -455,16 +493,27 @@ class AliasNode(nodes.Element):
|
|
|
455
493
|
self.parentKey = parentKey
|
|
456
494
|
|
|
457
495
|
def copy(self) -> AliasNode:
|
|
458
|
-
return self.__class__(
|
|
459
|
-
|
|
496
|
+
return self.__class__(
|
|
497
|
+
self.sig,
|
|
498
|
+
self.aliasOptions,
|
|
499
|
+
self.document,
|
|
500
|
+
env=None,
|
|
501
|
+
parentKey=self.parentKey,
|
|
502
|
+
)
|
|
460
503
|
|
|
461
504
|
|
|
462
505
|
class AliasTransform(SphinxTransform):
|
|
463
506
|
default_priority = ReferencesResolver.default_priority - 1
|
|
464
507
|
|
|
465
|
-
def _render_symbol(
|
|
466
|
-
|
|
467
|
-
|
|
508
|
+
def _render_symbol(
|
|
509
|
+
self,
|
|
510
|
+
s: Symbol,
|
|
511
|
+
maxdepth: int,
|
|
512
|
+
skip_this: bool,
|
|
513
|
+
alias_options: dict[str, bool],
|
|
514
|
+
render_options: dict[str, bool],
|
|
515
|
+
document: Any,
|
|
516
|
+
) -> list[Node]:
|
|
468
517
|
if maxdepth == 0:
|
|
469
518
|
recurse = True
|
|
470
519
|
elif maxdepth == 1:
|
|
@@ -474,14 +523,16 @@ class AliasTransform(SphinxTransform):
|
|
|
474
523
|
recurse = True
|
|
475
524
|
|
|
476
525
|
nodes: list[Node] = []
|
|
477
|
-
if not
|
|
526
|
+
if not skip_this:
|
|
478
527
|
signode = addnodes.desc_signature('', '')
|
|
479
528
|
nodes.append(signode)
|
|
480
|
-
s.declaration.describe_signature(
|
|
529
|
+
s.declaration.describe_signature(
|
|
530
|
+
signode, 'markName', self.env, render_options
|
|
531
|
+
)
|
|
481
532
|
|
|
482
533
|
if recurse:
|
|
483
|
-
if
|
|
484
|
-
|
|
534
|
+
if skip_this:
|
|
535
|
+
child_container: list[Node] | addnodes.desc = nodes
|
|
485
536
|
else:
|
|
486
537
|
content = addnodes.desc_content()
|
|
487
538
|
desc = addnodes.desc()
|
|
@@ -491,28 +542,31 @@ class AliasTransform(SphinxTransform):
|
|
|
491
542
|
# 'desctype' is a backwards compatible attribute
|
|
492
543
|
desc['objtype'] = desc['desctype'] = 'alias'
|
|
493
544
|
desc['no-index'] = True
|
|
494
|
-
|
|
545
|
+
child_container = desc
|
|
495
546
|
|
|
496
|
-
for
|
|
497
|
-
if
|
|
547
|
+
for s_child in s.children:
|
|
548
|
+
if s_child.declaration is None:
|
|
498
549
|
continue
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
550
|
+
child_nodes = self._render_symbol(
|
|
551
|
+
s_child,
|
|
552
|
+
maxdepth=maxdepth,
|
|
553
|
+
skip_this=False,
|
|
554
|
+
alias_options=alias_options,
|
|
555
|
+
render_options=render_options,
|
|
556
|
+
document=document,
|
|
557
|
+
)
|
|
558
|
+
child_container.extend(child_nodes)
|
|
559
|
+
|
|
560
|
+
if not skip_this and len(desc.children) != 0:
|
|
506
561
|
nodes.append(content)
|
|
507
562
|
return nodes
|
|
508
563
|
|
|
509
564
|
def apply(self, **kwargs: Any) -> None:
|
|
510
565
|
for node in self.document.findall(AliasNode):
|
|
511
566
|
sig = node.sig
|
|
512
|
-
|
|
567
|
+
parent_key = node.parentKey
|
|
513
568
|
try:
|
|
514
|
-
parser = DefinitionParser(sig, location=node,
|
|
515
|
-
config=self.env.config)
|
|
569
|
+
parser = DefinitionParser(sig, location=node, config=self.config)
|
|
516
570
|
name = parser.parse_xref_object()
|
|
517
571
|
except DefinitionError as e:
|
|
518
572
|
logger.warning(e, location=node)
|
|
@@ -526,25 +580,26 @@ class AliasTransform(SphinxTransform):
|
|
|
526
580
|
node.replace_self(signode)
|
|
527
581
|
continue
|
|
528
582
|
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
if not
|
|
532
|
-
logger.debug(
|
|
533
|
-
logger.debug(
|
|
534
|
-
logger.debug(
|
|
535
|
-
assert
|
|
536
|
-
|
|
537
|
-
s =
|
|
538
|
-
name, 'any',
|
|
539
|
-
|
|
583
|
+
root_symbol: Symbol = self.env.domains.c_domain.data['root_symbol']
|
|
584
|
+
parent_symbol: Symbol | None = root_symbol.direct_lookup(parent_key)
|
|
585
|
+
if not parent_symbol:
|
|
586
|
+
logger.debug('Target: %s', sig)
|
|
587
|
+
logger.debug('ParentKey: %s', parent_key)
|
|
588
|
+
logger.debug(root_symbol.dump(1))
|
|
589
|
+
assert parent_symbol # should be there
|
|
590
|
+
|
|
591
|
+
s = parent_symbol.find_declaration(
|
|
592
|
+
name, 'any', matchSelf=True, recurseInAnon=True
|
|
593
|
+
)
|
|
540
594
|
if s is None:
|
|
541
595
|
signode = addnodes.desc_signature(sig, '')
|
|
542
596
|
node.append(signode)
|
|
543
597
|
signode.clear()
|
|
544
598
|
signode += addnodes.desc_name(sig, sig)
|
|
545
599
|
|
|
546
|
-
logger.warning(
|
|
547
|
-
|
|
600
|
+
logger.warning(
|
|
601
|
+
"Could not find C declaration for alias '%s'.", name, location=node
|
|
602
|
+
)
|
|
548
603
|
node.replace_self(signode)
|
|
549
604
|
continue
|
|
550
605
|
# Declarations like .. var:: int Missing::var
|
|
@@ -557,27 +612,32 @@ class AliasTransform(SphinxTransform):
|
|
|
557
612
|
signode += addnodes.desc_name(sig, sig)
|
|
558
613
|
|
|
559
614
|
logger.warning(
|
|
560
|
-
"Can not render C declaration for alias '%s'. No such declaration.",
|
|
561
|
-
|
|
615
|
+
"Can not render C declaration for alias '%s'. No such declaration.",
|
|
616
|
+
name,
|
|
617
|
+
location=node,
|
|
618
|
+
)
|
|
562
619
|
node.replace_self(signode)
|
|
563
620
|
continue
|
|
564
621
|
|
|
565
|
-
nodes = self._render_symbol(
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
622
|
+
nodes = self._render_symbol(
|
|
623
|
+
s,
|
|
624
|
+
maxdepth=node.aliasOptions['maxdepth'],
|
|
625
|
+
skip_this=node.aliasOptions['noroot'],
|
|
626
|
+
alias_options=node.aliasOptions,
|
|
627
|
+
render_options={},
|
|
628
|
+
document=node.document,
|
|
629
|
+
)
|
|
569
630
|
node.replace_self(nodes)
|
|
570
631
|
|
|
571
632
|
|
|
572
|
-
class CAliasObject(ObjectDescription):
|
|
633
|
+
class CAliasObject(ObjectDescription[str]):
|
|
573
634
|
option_spec: ClassVar[OptionSpec] = {
|
|
574
635
|
'maxdepth': directives.nonnegative_int,
|
|
575
636
|
'noroot': directives.flag,
|
|
576
637
|
}
|
|
577
638
|
|
|
578
639
|
def run(self) -> list[Node]:
|
|
579
|
-
"""
|
|
580
|
-
On purpose this doesn't call the ObjectDescription version, but is based on it.
|
|
640
|
+
"""On purpose this doesn't call the ObjectDescription version, but is based on it.
|
|
581
641
|
Each alias signature may expand into multiple real signatures if 'noroot'.
|
|
582
642
|
The code is therefore based on the ObjectDescription version.
|
|
583
643
|
"""
|
|
@@ -594,30 +654,40 @@ class CAliasObject(ObjectDescription):
|
|
|
594
654
|
node['no-index'] = True
|
|
595
655
|
|
|
596
656
|
self.names: list[str] = []
|
|
597
|
-
|
|
657
|
+
alias_options = {
|
|
598
658
|
'maxdepth': self.options.get('maxdepth', 1),
|
|
599
659
|
'noroot': 'noroot' in self.options,
|
|
600
660
|
}
|
|
601
|
-
if
|
|
602
|
-
logger.warning(
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
661
|
+
if alias_options['noroot'] and alias_options['maxdepth'] == 1:
|
|
662
|
+
logger.warning(
|
|
663
|
+
'Error in C alias declaration.'
|
|
664
|
+
" Requested 'noroot' but 'maxdepth' 1."
|
|
665
|
+
' When skipping the root declaration,'
|
|
666
|
+
" need 'maxdepth' 0 for infinite or at least 2.",
|
|
667
|
+
location=self.get_location(),
|
|
668
|
+
)
|
|
607
669
|
for sig in self.get_signatures():
|
|
608
|
-
node.append(
|
|
670
|
+
node.append(
|
|
671
|
+
AliasNode(sig, alias_options, self.state.document, env=self.env)
|
|
672
|
+
)
|
|
609
673
|
return [node]
|
|
610
674
|
|
|
611
675
|
|
|
612
676
|
class CXRefRole(XRefRole):
|
|
613
|
-
def process_link(
|
|
614
|
-
|
|
677
|
+
def process_link(
|
|
678
|
+
self,
|
|
679
|
+
env: BuildEnvironment,
|
|
680
|
+
refnode: Element,
|
|
681
|
+
has_explicit_title: bool,
|
|
682
|
+
title: str,
|
|
683
|
+
target: str,
|
|
684
|
+
) -> tuple[str, str]:
|
|
615
685
|
refnode.attributes.update(env.ref_context)
|
|
616
686
|
|
|
617
687
|
if not has_explicit_title:
|
|
618
688
|
# major hax: replace anon names via simple string manipulation.
|
|
619
689
|
# Can this actually fail?
|
|
620
|
-
title = anon_identifier_re.sub(
|
|
690
|
+
title = anon_identifier_re.sub('[anonymous]', str(title))
|
|
621
691
|
|
|
622
692
|
if not has_explicit_title:
|
|
623
693
|
target = target.lstrip('~') # only has a meaning for the title
|
|
@@ -627,7 +697,7 @@ class CXRefRole(XRefRole):
|
|
|
627
697
|
title = title[1:]
|
|
628
698
|
dot = title.rfind('.')
|
|
629
699
|
if dot != -1:
|
|
630
|
-
title = title[dot + 1:]
|
|
700
|
+
title = title[dot + 1 :]
|
|
631
701
|
return title, target
|
|
632
702
|
|
|
633
703
|
|
|
@@ -643,23 +713,29 @@ class CExprRole(SphinxRole):
|
|
|
643
713
|
|
|
644
714
|
def run(self) -> tuple[list[Node], list[system_message]]:
|
|
645
715
|
text = self.text.replace('\n', ' ')
|
|
646
|
-
parser = DefinitionParser(
|
|
647
|
-
|
|
716
|
+
parser = DefinitionParser(
|
|
717
|
+
text, location=self.get_location(), config=self.config
|
|
718
|
+
)
|
|
648
719
|
# attempt to mimic XRefRole classes, except that...
|
|
649
720
|
try:
|
|
650
721
|
ast = parser.parse_expression()
|
|
651
722
|
except DefinitionError as ex:
|
|
652
|
-
logger.warning(
|
|
653
|
-
|
|
723
|
+
logger.warning(
|
|
724
|
+
'Unparseable C expression: %r\n%s',
|
|
725
|
+
text,
|
|
726
|
+
ex,
|
|
727
|
+
location=self.get_location(),
|
|
728
|
+
)
|
|
654
729
|
# see below
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
730
|
+
node = addnodes.desc_inline('c', text, text, classes=[self.class_type])
|
|
731
|
+
return [node], []
|
|
732
|
+
parent_symbol = self.env.current_document.c_parent_symbol
|
|
733
|
+
if parent_symbol is None:
|
|
734
|
+
parent_symbol = self.env.domaindata['c']['root_symbol']
|
|
659
735
|
# ...most if not all of these classes should really apply to the individual references,
|
|
660
736
|
# not the container node
|
|
661
737
|
signode = addnodes.desc_inline('c', classes=[self.class_type])
|
|
662
|
-
ast.describe_signature(signode, 'markType', self.env,
|
|
738
|
+
ast.describe_signature(signode, 'markType', self.env, parent_symbol)
|
|
663
739
|
return [signode], []
|
|
664
740
|
|
|
665
741
|
|
|
@@ -671,16 +747,18 @@ class CDomain(Domain):
|
|
|
671
747
|
object_types = {
|
|
672
748
|
# 'identifier' is the one used for xrefs generated in signatures, not in roles
|
|
673
749
|
'member': ObjType(_('member'), 'var', 'member', 'data', 'identifier'),
|
|
674
|
-
'var': ObjType(_('variable'),
|
|
675
|
-
'function': ObjType(_('function'),
|
|
676
|
-
'macro': ObjType(_('macro'),
|
|
677
|
-
'struct': ObjType(_('struct'),
|
|
678
|
-
'union': ObjType(_('union'),
|
|
679
|
-
'enum': ObjType(_('enum'),
|
|
680
|
-
'enumerator': ObjType(_('enumerator'), 'enumerator',
|
|
681
|
-
'type': ObjType(_('type'),
|
|
750
|
+
'var': ObjType(_('variable'), 'var', 'member', 'data', 'identifier'),
|
|
751
|
+
'function': ObjType(_('function'), 'func', 'identifier', 'type'),
|
|
752
|
+
'macro': ObjType(_('macro'), 'macro', 'identifier'),
|
|
753
|
+
'struct': ObjType(_('struct'), 'struct', 'identifier', 'type'),
|
|
754
|
+
'union': ObjType(_('union'), 'union', 'identifier', 'type'),
|
|
755
|
+
'enum': ObjType(_('enum'), 'enum', 'identifier', 'type'),
|
|
756
|
+
'enumerator': ObjType(_('enumerator'), 'enumerator', 'identifier'),
|
|
757
|
+
'type': ObjType(_('type'), 'identifier', 'type'),
|
|
682
758
|
# generated object types
|
|
683
|
-
'functionParam': ObjType(
|
|
759
|
+
'functionParam': ObjType(
|
|
760
|
+
_('function parameter'), 'identifier', 'var', 'member', 'data'
|
|
761
|
+
),
|
|
684
762
|
}
|
|
685
763
|
|
|
686
764
|
directives = {
|
|
@@ -721,124 +799,167 @@ class CDomain(Domain):
|
|
|
721
799
|
|
|
722
800
|
def clear_doc(self, docname: str) -> None:
|
|
723
801
|
if Symbol.debug_show_tree:
|
|
724
|
-
logger.debug(
|
|
725
|
-
logger.debug(
|
|
802
|
+
logger.debug('clear_doc: %s', docname)
|
|
803
|
+
logger.debug('\tbefore:')
|
|
726
804
|
logger.debug(self.data['root_symbol'].dump(1))
|
|
727
|
-
logger.debug(
|
|
805
|
+
logger.debug('\tbefore end')
|
|
728
806
|
|
|
729
|
-
|
|
730
|
-
|
|
807
|
+
root_symbol = self.data['root_symbol']
|
|
808
|
+
root_symbol.clear_doc(docname)
|
|
731
809
|
|
|
732
810
|
if Symbol.debug_show_tree:
|
|
733
|
-
logger.debug(
|
|
811
|
+
logger.debug('\tafter:')
|
|
734
812
|
logger.debug(self.data['root_symbol'].dump(1))
|
|
735
|
-
logger.debug(
|
|
736
|
-
logger.debug(
|
|
813
|
+
logger.debug('\tafter end')
|
|
814
|
+
logger.debug('clear_doc end: %s', docname)
|
|
737
815
|
|
|
738
|
-
def process_doc(
|
|
739
|
-
|
|
816
|
+
def process_doc(
|
|
817
|
+
self, env: BuildEnvironment, docname: str, document: nodes.document
|
|
818
|
+
) -> None:
|
|
740
819
|
if Symbol.debug_show_tree:
|
|
741
|
-
logger.debug(
|
|
820
|
+
logger.debug('process_doc: %s', docname)
|
|
742
821
|
logger.debug(self.data['root_symbol'].dump(0))
|
|
743
|
-
logger.debug(
|
|
822
|
+
logger.debug('process_doc end: %s', docname)
|
|
744
823
|
|
|
745
824
|
def process_field_xref(self, pnode: pending_xref) -> None:
|
|
746
825
|
pnode.attributes.update(self.env.ref_context)
|
|
747
826
|
|
|
748
827
|
def merge_domaindata(self, docnames: Set[str], otherdata: dict[str, Any]) -> None:
|
|
749
828
|
if Symbol.debug_show_tree:
|
|
750
|
-
logger.debug(
|
|
751
|
-
logger.debug(
|
|
829
|
+
logger.debug('merge_domaindata:')
|
|
830
|
+
logger.debug('\tself:')
|
|
752
831
|
logger.debug(self.data['root_symbol'].dump(1))
|
|
753
|
-
logger.debug(
|
|
754
|
-
logger.debug(
|
|
832
|
+
logger.debug('\tself end')
|
|
833
|
+
logger.debug('\tother:')
|
|
755
834
|
logger.debug(otherdata['root_symbol'].dump(1))
|
|
756
|
-
logger.debug(
|
|
757
|
-
logger.debug(
|
|
835
|
+
logger.debug('\tother end')
|
|
836
|
+
logger.debug('merge_domaindata end')
|
|
758
837
|
|
|
759
|
-
self.data['root_symbol'].merge_with(
|
|
760
|
-
|
|
761
|
-
|
|
838
|
+
self.data['root_symbol'].merge_with(
|
|
839
|
+
otherdata['root_symbol'], docnames, self.env
|
|
840
|
+
)
|
|
841
|
+
our_objects = self.data['objects']
|
|
762
842
|
for fullname, (fn, id_, objtype) in otherdata['objects'].items():
|
|
763
843
|
if fn in docnames:
|
|
764
|
-
if fullname not in
|
|
765
|
-
|
|
844
|
+
if fullname not in our_objects:
|
|
845
|
+
our_objects[fullname] = (fn, id_, objtype)
|
|
766
846
|
# no need to warn on duplicates, the symbol merge already does that
|
|
767
847
|
|
|
768
|
-
def _resolve_xref_inner(
|
|
769
|
-
|
|
770
|
-
|
|
848
|
+
def _resolve_xref_inner(
|
|
849
|
+
self,
|
|
850
|
+
env: BuildEnvironment,
|
|
851
|
+
fromdocname: str,
|
|
852
|
+
builder: Builder,
|
|
853
|
+
typ: str,
|
|
854
|
+
target: str,
|
|
855
|
+
node: pending_xref,
|
|
856
|
+
contnode: Element,
|
|
857
|
+
) -> tuple[nodes.reference, str] | tuple[None, None]:
|
|
771
858
|
parser = DefinitionParser(target, location=node, config=env.config)
|
|
772
859
|
try:
|
|
773
860
|
name = parser.parse_xref_object()
|
|
774
861
|
except DefinitionError as e:
|
|
775
|
-
logger.warning(
|
|
776
|
-
|
|
862
|
+
logger.warning(
|
|
863
|
+
'Unparseable C cross-reference: %r\n%s', target, e, location=node
|
|
864
|
+
)
|
|
777
865
|
return None, None
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
if
|
|
781
|
-
|
|
782
|
-
if not
|
|
783
|
-
logger.debug(
|
|
784
|
-
logger.debug(
|
|
785
|
-
logger.debug(
|
|
786
|
-
assert
|
|
866
|
+
parent_key: LookupKey | None = node.get('c:parent_key', None)
|
|
867
|
+
root_symbol = self.data['root_symbol']
|
|
868
|
+
if parent_key:
|
|
869
|
+
parent_symbol: Symbol = root_symbol.direct_lookup(parent_key)
|
|
870
|
+
if not parent_symbol:
|
|
871
|
+
logger.debug('Target: %s', target)
|
|
872
|
+
logger.debug('ParentKey: %s', parent_key)
|
|
873
|
+
logger.debug(root_symbol.dump(1))
|
|
874
|
+
assert parent_symbol # should be there
|
|
787
875
|
else:
|
|
788
|
-
|
|
789
|
-
s =
|
|
790
|
-
|
|
876
|
+
parent_symbol = root_symbol
|
|
877
|
+
s = parent_symbol.find_declaration(
|
|
878
|
+
name, typ, matchSelf=True, recurseInAnon=True
|
|
879
|
+
)
|
|
791
880
|
if s is None or s.declaration is None:
|
|
792
881
|
return None, None
|
|
793
882
|
|
|
794
883
|
# TODO: check role type vs. object type
|
|
795
884
|
|
|
796
885
|
declaration = s.declaration
|
|
797
|
-
|
|
886
|
+
display_name = name.get_display_string()
|
|
798
887
|
docname = s.docname
|
|
799
888
|
assert docname
|
|
800
889
|
|
|
801
|
-
return make_refnode(
|
|
802
|
-
|
|
803
|
-
|
|
890
|
+
return make_refnode(
|
|
891
|
+
builder,
|
|
892
|
+
fromdocname,
|
|
893
|
+
docname,
|
|
894
|
+
declaration.get_newest_id(),
|
|
895
|
+
contnode,
|
|
896
|
+
display_name,
|
|
897
|
+
), declaration.objectType
|
|
804
898
|
|
|
805
|
-
def resolve_xref(
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
899
|
+
def resolve_xref(
|
|
900
|
+
self,
|
|
901
|
+
env: BuildEnvironment,
|
|
902
|
+
fromdocname: str,
|
|
903
|
+
builder: Builder,
|
|
904
|
+
typ: str,
|
|
905
|
+
target: str,
|
|
906
|
+
node: pending_xref,
|
|
907
|
+
contnode: Element,
|
|
908
|
+
) -> nodes.reference | None:
|
|
909
|
+
return self._resolve_xref_inner(
|
|
910
|
+
env, fromdocname, builder, typ, target, node, contnode
|
|
911
|
+
)[0]
|
|
912
|
+
|
|
913
|
+
def resolve_any_xref(
|
|
914
|
+
self,
|
|
915
|
+
env: BuildEnvironment,
|
|
916
|
+
fromdocname: str,
|
|
917
|
+
builder: Builder,
|
|
918
|
+
target: str,
|
|
919
|
+
node: pending_xref,
|
|
920
|
+
contnode: Element,
|
|
921
|
+
) -> list[tuple[str, nodes.reference]]:
|
|
814
922
|
with logging.suppress_logging():
|
|
815
|
-
retnode, objtype = self._resolve_xref_inner(
|
|
816
|
-
|
|
923
|
+
retnode, objtype = self._resolve_xref_inner(
|
|
924
|
+
env, fromdocname, builder, 'any', target, node, contnode
|
|
925
|
+
)
|
|
817
926
|
if retnode:
|
|
818
927
|
return [('c:' + self.role_for_objtype(objtype), retnode)]
|
|
819
928
|
return []
|
|
820
929
|
|
|
821
930
|
def get_objects(self) -> Iterator[tuple[str, str, str, str, str, int]]:
|
|
822
|
-
|
|
823
|
-
for symbol in
|
|
931
|
+
root_symbol = self.data['root_symbol']
|
|
932
|
+
for symbol in root_symbol.get_all_symbols():
|
|
824
933
|
if symbol.declaration is None:
|
|
825
934
|
continue
|
|
826
935
|
assert symbol.docname
|
|
827
|
-
|
|
828
|
-
name = str(
|
|
829
|
-
dispname =
|
|
830
|
-
|
|
936
|
+
full_nested_name = symbol.get_full_nested_name()
|
|
937
|
+
name = str(full_nested_name).lstrip('.')
|
|
938
|
+
dispname = full_nested_name.get_display_string().lstrip('.')
|
|
939
|
+
object_type = symbol.declaration.objectType
|
|
831
940
|
docname = symbol.docname
|
|
832
|
-
|
|
833
|
-
yield
|
|
941
|
+
newest_id = symbol.declaration.get_newest_id()
|
|
942
|
+
yield name, dispname, object_type, docname, newest_id, 1
|
|
834
943
|
|
|
835
944
|
|
|
836
945
|
def setup(app: Sphinx) -> ExtensionMetadata:
|
|
837
946
|
app.add_domain(CDomain)
|
|
838
|
-
app.add_config_value(
|
|
839
|
-
app.add_config_value(
|
|
840
|
-
|
|
841
|
-
|
|
947
|
+
app.add_config_value('c_id_attributes', [], 'env', types=frozenset({list, tuple}))
|
|
948
|
+
app.add_config_value(
|
|
949
|
+
'c_paren_attributes', [], 'env', types=frozenset({list, tuple})
|
|
950
|
+
)
|
|
951
|
+
app.add_config_value(
|
|
952
|
+
'c_extra_keywords',
|
|
953
|
+
_macro_keywords,
|
|
954
|
+
'env',
|
|
955
|
+
types=frozenset({frozenset, list, set, tuple}),
|
|
956
|
+
)
|
|
957
|
+
app.add_config_value(
|
|
958
|
+
'c_maximum_signature_line_length',
|
|
959
|
+
None,
|
|
960
|
+
'env',
|
|
961
|
+
types=frozenset({int, NoneType}),
|
|
962
|
+
)
|
|
842
963
|
app.add_post_transform(AliasTransform)
|
|
843
964
|
|
|
844
965
|
return {
|