Skip to content

Commit af5828f

Browse files
committed
C, intersphinx delegation
1 parent bd6aee0 commit af5828f

File tree

2 files changed

+100
-16
lines changed

2 files changed

+100
-16
lines changed

sphinx/domains/__init__.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@
1111

1212
import copy
1313
from abc import ABC, abstractmethod
14-
from typing import (TYPE_CHECKING, Any, Callable, Dict, Iterable, List, NamedTuple,
15-
Optional, Tuple, Type, Union, cast)
14+
from typing import (TYPE_CHECKING, Any, Callable, Dict, Iterable, List, NamedTuple, Optional,
15+
Tuple, Type, Union, cast)
1616

1717
from docutils import nodes
1818
from docutils.nodes import Element, Node, TextElement, system_message
@@ -409,7 +409,7 @@ def get_full_qualified_name(self, node: Element) -> str:
409409
"""Return full qualified name for given node."""
410410
return None
411411

412-
def intersphinx_add_entries_v2(self, store: Any,
412+
def intersphinx_add_entries_v2(self, store: Dict,
413413
data: Dict[Tuple[str, str], InventoryItemSet]) -> None:
414414
"""Store the given *data* for later intersphinx reference resolution.
415415
@@ -512,7 +512,7 @@ def intersphinx_resolve_xref(self, env: "BuildEnvironment", store: Any,
512512
return None
513513
return self._intersphinx_resolve_xref_1(store, target, node, contnode, objtypes)
514514

515-
def intersphinx_resolve_any_xref(self, env: "BuildEnvironment", store: Any,
515+
def intersphinx_resolve_any_xref(self, env: "BuildEnvironment", store: Dict,
516516
target: str, node: pending_xref,
517517
contnode: TextElement) -> Optional[Element]:
518518
"""Resolve the pending_xref *node* with the given *typ* and *target* via intersphinx.

sphinx/domains/c.py

Lines changed: 96 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@
99
"""
1010

1111
import re
12-
from typing import (Any, Callable, Dict, Generator, Iterator, List, Tuple, Type, TypeVar,
13-
Union, cast)
12+
from typing import (Any, Callable, Dict, Generator, Iterator, List, Optional, Tuple, Type,
13+
TypeVar, Union, cast)
1414

1515
from docutils import nodes
1616
from docutils.nodes import Element, Node, TextElement, system_message
@@ -38,6 +38,7 @@
3838
octal_literal_re, verify_description_mode)
3939
from sphinx.util.docfields import Field, TypedField
4040
from sphinx.util.docutils import SphinxDirective
41+
from sphinx.util.inventory import InventoryItemSet
4142
from sphinx.util.nodes import make_refnode
4243
from sphinx.util.typing import OptionSpec
4344

@@ -47,6 +48,7 @@
4748
DeclarationType = Union[
4849
"ASTStruct", "ASTUnion", "ASTEnum", "ASTEnumerator",
4950
"ASTType", "ASTTypeWithInit", "ASTMacro",
51+
"ASTIntersphinx_v2",
5052
]
5153

5254
# https://en.cppreference.com/w/c/keyword
@@ -1360,6 +1362,28 @@ def describe_signature(self, signode: TextElement, mode: str,
13601362
self.init.describe_signature(signode, 'markType', env, symbol)
13611363

13621364

1365+
class ASTIntersphinx_v2(ASTBaseBase):
1366+
def __init__(self, name: ASTNestedName, data: InventoryItemSet):
1367+
self.name = name
1368+
self.data = data
1369+
1370+
def _stringify(self, transform: StringifyTransform) -> str:
1371+
return transform(self.name) + " (has data)"
1372+
1373+
def get_id(self, version: int, objectType: str, symbol: "Symbol") -> str:
1374+
return symbol.get_full_nested_name().get_id(version)
1375+
1376+
def describe_signature(self, signode: TextElement, mode: str,
1377+
env: "BuildEnvironment", symbol: "Symbol") -> None:
1378+
assert False # Should not happen
1379+
1380+
@property
1381+
def function_params(self):
1382+
# the v2 data does not contain actual declarations, but just names
1383+
# so return nothing here
1384+
return None
1385+
1386+
13631387
class ASTDeclaration(ASTBaseBase):
13641388
def __init__(self, objectType: str, directiveType: str,
13651389
declaration: Union[DeclarationType, ASTFunctionParameter],
@@ -3745,6 +3769,10 @@ class CDomain(Domain):
37453769
'objects': {}, # fullname -> docname, node_id, objtype
37463770
}
37473771

3772+
initial_intersphinx_inventory = {
3773+
'root_symbol': Symbol(None, None, None, None, None),
3774+
}
3775+
37483776
def clear_doc(self, docname: str) -> None:
37493777
if Symbol.debug_show_tree:
37503778
print("clear_doc:", docname)
@@ -3791,9 +3819,10 @@ def merge_domaindata(self, docnames: List[str], otherdata: Dict) -> None:
37913819
ourObjects[fullname] = (fn, id_, objtype)
37923820
# no need to warn on duplicates, the symbol merge already does that
37933821

3794-
def _resolve_xref_inner(self, env: BuildEnvironment, fromdocname: str, builder: Builder,
3795-
typ: str, target: str, node: pending_xref,
3796-
contnode: Element) -> Tuple[Element, str]:
3822+
def _resolve_xref_in_tree(self, env: BuildEnvironment, root: Symbol,
3823+
softParent: bool,
3824+
typ: str, target: str, node: pending_xref,
3825+
contnode: Element) -> Tuple[Symbol, ASTNestedName]:
37973826
parser = DefinitionParser(target, location=node, config=env.config)
37983827
try:
37993828
name = parser.parse_xref_object()
@@ -3802,20 +3831,34 @@ def _resolve_xref_inner(self, env: BuildEnvironment, fromdocname: str, builder:
38023831
location=node)
38033832
return None, None
38043833
parentKey: LookupKey = node.get("c:parent_key", None)
3805-
rootSymbol = self.data['root_symbol']
38063834
if parentKey:
3807-
parentSymbol: Symbol = rootSymbol.direct_lookup(parentKey)
3835+
parentSymbol: Symbol = root.direct_lookup(parentKey)
38083836
if not parentSymbol:
3809-
print("Target: ", target)
3810-
print("ParentKey: ", parentKey)
3811-
print(rootSymbol.dump(1))
3812-
assert parentSymbol # should be there
3837+
if softParent:
3838+
parentSymbol = root
3839+
else:
3840+
print("Target: ", target)
3841+
print("ParentKey: ", parentKey)
3842+
print(root.dump(1))
3843+
assert False
38133844
else:
3814-
parentSymbol = rootSymbol
3845+
parentSymbol = root
38153846
s = parentSymbol.find_declaration(name, typ,
38163847
matchSelf=True, recurseInAnon=True)
38173848
if s is None or s.declaration is None:
38183849
return None, None
3850+
# TODO: conditionally warn about xrefs with incorrect tagging?
3851+
return s, name
3852+
3853+
def _resolve_xref_inner(self, env: BuildEnvironment, fromdocname: str, builder: Builder,
3854+
typ: str, target: str, node: pending_xref,
3855+
contnode: Element) -> Tuple[Element, str]:
3856+
if Symbol.debug_lookup:
3857+
print("C._resolve_xref_inner(type={}, target={})".format(typ, target))
3858+
s, name = self._resolve_xref_in_tree(env, self.data['root_symbol'],
3859+
False, typ, target, node, contnode)
3860+
if s is None:
3861+
return None, None
38193862

38203863
# TODO: check role type vs. object type
38213864

@@ -3858,6 +3901,47 @@ def get_objects(self) -> Iterator[Tuple[str, str, str, str, str, int]]:
38583901
newestId = symbol.declaration.get_newest_id()
38593902
yield (name, dispname, objectType, docname, newestId, 1)
38603903

3904+
def intersphinx_add_entries_v2(self, store: Dict,
3905+
data: Dict[Tuple[str, str], InventoryItemSet]) -> None:
3906+
root = store['root_symbol'] # type: Symbol
3907+
for k, v in data.items():
3908+
object_name, object_type = k
3909+
parser = DefinitionParser(
3910+
object_name, location=('intersphinx', 0), config=self.env.config)
3911+
try:
3912+
ast = parser._parse_nested_name()
3913+
except DefinitionError as e:
3914+
logger.warning("Error in C entry in intersphinx inventory:\n" + str(e))
3915+
continue
3916+
decl = ASTDeclaration(object_type, 'intersphinx', ASTIntersphinx_v2(ast, v))
3917+
root.add_declaration(decl, docname="$FakeIntersphinxDoc", line=0)
3918+
3919+
def _intersphinx_resolve_xref_inner(self, env: "BuildEnvironment", store: Dict,
3920+
target: str,
3921+
node: pending_xref, contnode: TextElement,
3922+
typ: str) -> Optional[Element]:
3923+
if Symbol.debug_lookup:
3924+
print("C._intersphinx_resolve_xref_inner(type={}, target={})".format(typ, target))
3925+
s, name = self._resolve_xref_in_tree(env, store['root_symbol'],
3926+
True, typ, target, node, contnode)
3927+
if s is None:
3928+
return None
3929+
assert s.declaration is not None
3930+
decl = cast(ASTIntersphinx_v2, s.declaration.declaration)
3931+
return decl.data.make_refnode(self.name, target, node, contnode)
3932+
3933+
def intersphinx_resolve_xref(self, env: "BuildEnvironment", store: Dict,
3934+
typ: str, target: str, node: pending_xref,
3935+
contnode: TextElement) -> Optional[Element]:
3936+
return self._intersphinx_resolve_xref_inner(env, store, target, node, contnode, typ)
3937+
3938+
def intersphinx_resolve_any_xref(self, env: "BuildEnvironment", store: Dict,
3939+
target: str, node: pending_xref,
3940+
contnode: TextElement) -> Optional[Element]:
3941+
with logging.suppress_logging():
3942+
return self._intersphinx_resolve_xref_inner(
3943+
env, store, target, node, contnode, 'any')
3944+
38613945

38623946
def setup(app: Sphinx) -> Dict[str, Any]:
38633947
app.add_domain(CDomain)

0 commit comments

Comments
 (0)