Skip to content

Commit 345e37f

Browse files
committed
C, intersphinx delegation
1 parent 72a828d commit 345e37f

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

4344
logger = logging.getLogger(__name__)
@@ -46,6 +47,7 @@
4647
DeclarationType = Union[
4748
"ASTStruct", "ASTUnion", "ASTEnum", "ASTEnumerator",
4849
"ASTType", "ASTTypeWithInit", "ASTMacro",
50+
"ASTIntersphinx_v2",
4951
]
5052

5153
# https://en.cppreference.com/w/c/keyword
@@ -1341,6 +1343,28 @@ def describe_signature(self, signode: TextElement, mode: str,
13411343
self.init.describe_signature(signode, 'markType', env, symbol)
13421344

13431345

1346+
class ASTIntersphinx_v2(ASTBaseBase):
1347+
def __init__(self, name: ASTNestedName, data: InventoryItemSet):
1348+
self.name = name
1349+
self.data = data
1350+
1351+
def _stringify(self, transform: StringifyTransform) -> str:
1352+
return transform(self.name) + " (has data)"
1353+
1354+
def get_id(self, version: int, objectType: str, symbol: "Symbol") -> str:
1355+
return symbol.get_full_nested_name().get_id(version)
1356+
1357+
def describe_signature(self, signode: TextElement, mode: str,
1358+
env: "BuildEnvironment", symbol: "Symbol") -> None:
1359+
assert False # Should not happen
1360+
1361+
@property
1362+
def function_params(self):
1363+
# the v2 data does not contain actual declarations, but just names
1364+
# so return nothing here
1365+
return None
1366+
1367+
13441368
class ASTDeclaration(ASTBaseBase):
13451369
def __init__(self, objectType: str, directiveType: str,
13461370
declaration: Union[DeclarationType, ASTFunctionParameter],
@@ -3726,6 +3750,10 @@ class CDomain(Domain):
37263750
'objects': {}, # fullname -> docname, node_id, objtype
37273751
} # type: Dict[str, Union[Symbol, Dict[str, Tuple[str, str, str]]]]
37283752

3753+
initial_intersphinx_inventory = {
3754+
'root_symbol': Symbol(None, None, None, None, None),
3755+
}
3756+
37293757
def clear_doc(self, docname: str) -> None:
37303758
if Symbol.debug_show_tree:
37313759
print("clear_doc:", docname)
@@ -3772,9 +3800,10 @@ def merge_domaindata(self, docnames: List[str], otherdata: Dict) -> None:
37723800
ourObjects[fullname] = (fn, id_, objtype)
37733801
# no need to warn on duplicates, the symbol merge already does that
37743802

3775-
def _resolve_xref_inner(self, env: BuildEnvironment, fromdocname: str, builder: Builder,
3776-
typ: str, target: str, node: pending_xref,
3777-
contnode: Element) -> Tuple[Element, str]:
3803+
def _resolve_xref_in_tree(self, env: BuildEnvironment, root: Symbol,
3804+
softParent: bool,
3805+
typ: str, target: str, node: pending_xref,
3806+
contnode: Element) -> Tuple[Symbol, ASTNestedName]:
37783807
parser = DefinitionParser(target, location=node, config=env.config)
37793808
try:
37803809
name = parser.parse_xref_object()
@@ -3783,20 +3812,34 @@ def _resolve_xref_inner(self, env: BuildEnvironment, fromdocname: str, builder:
37833812
location=node)
37843813
return None, None
37853814
parentKey = node.get("c:parent_key", None) # type: LookupKey
3786-
rootSymbol = self.data['root_symbol']
37873815
if parentKey:
3788-
parentSymbol = rootSymbol.direct_lookup(parentKey) # type: Symbol
3816+
parentSymbol = root.direct_lookup(parentKey) # type: Symbol
37893817
if not parentSymbol:
3790-
print("Target: ", target)
3791-
print("ParentKey: ", parentKey)
3792-
print(rootSymbol.dump(1))
3793-
assert parentSymbol # should be there
3818+
if softParent:
3819+
parentSymbol = root
3820+
else:
3821+
print("Target: ", target)
3822+
print("ParentKey: ", parentKey)
3823+
print(root.dump(1))
3824+
assert False
37943825
else:
3795-
parentSymbol = rootSymbol
3826+
parentSymbol = root
37963827
s = parentSymbol.find_declaration(name, typ,
37973828
matchSelf=True, recurseInAnon=True)
37983829
if s is None or s.declaration is None:
37993830
return None, None
3831+
# TODO: conditionally warn about xrefs with incorrect tagging?
3832+
return s, name
3833+
3834+
def _resolve_xref_inner(self, env: BuildEnvironment, fromdocname: str, builder: Builder,
3835+
typ: str, target: str, node: pending_xref,
3836+
contnode: Element) -> Tuple[Element, str]:
3837+
if Symbol.debug_lookup:
3838+
print("C._resolve_xref_inner(type={}, target={})".format(typ, target))
3839+
s, name = self._resolve_xref_in_tree(env, self.data['root_symbol'],
3840+
False, typ, target, node, contnode)
3841+
if s is None:
3842+
return None, None
38003843

38013844
# TODO: check role type vs. object type
38023845

@@ -3839,6 +3882,47 @@ def get_objects(self) -> Iterator[Tuple[str, str, str, str, str, int]]:
38393882
newestId = symbol.declaration.get_newest_id()
38403883
yield (name, dispname, objectType, docname, newestId, 1)
38413884

3885+
def intersphinx_add_entries_v2(self, store: Dict,
3886+
data: Dict[Tuple[str, str], InventoryItemSet]) -> None:
3887+
root = store['root_symbol'] # type: Symbol
3888+
for k, v in data.items():
3889+
object_name, object_type = k
3890+
parser = DefinitionParser(
3891+
object_name, location=('intersphinx', 0), config=self.env.config)
3892+
try:
3893+
ast = parser._parse_nested_name()
3894+
except DefinitionError as e:
3895+
logger.warning("Error in C entry in intersphinx inventory:\n" + str(e))
3896+
continue
3897+
decl = ASTDeclaration(object_type, 'intersphinx', ASTIntersphinx_v2(ast, v))
3898+
root.add_declaration(decl, docname="$FakeIntersphinxDoc", line=0)
3899+
3900+
def _intersphinx_resolve_xref_inner(self, env: "BuildEnvironment", store: Dict,
3901+
target: str,
3902+
node: pending_xref, contnode: TextElement,
3903+
typ: str) -> Optional[Element]:
3904+
if Symbol.debug_lookup:
3905+
print("C._intersphinx_resolve_xref_inner(type={}, target={})".format(typ, target))
3906+
s, name = self._resolve_xref_in_tree(env, store['root_symbol'],
3907+
True, typ, target, node, contnode)
3908+
if s is None:
3909+
return None
3910+
assert s.declaration is not None
3911+
decl = cast(ASTIntersphinx_v2, s.declaration.declaration)
3912+
return decl.data.make_refnode(self.name, target, node, contnode)
3913+
3914+
def intersphinx_resolve_xref(self, env: "BuildEnvironment", store: Dict,
3915+
typ: str, target: str, node: pending_xref,
3916+
contnode: TextElement) -> Optional[Element]:
3917+
return self._intersphinx_resolve_xref_inner(env, store, target, node, contnode, typ)
3918+
3919+
def intersphinx_resolve_any_xref(self, env: "BuildEnvironment", store: Dict,
3920+
target: str, node: pending_xref,
3921+
contnode: TextElement) -> Optional[Element]:
3922+
with logging.suppress_logging():
3923+
return self._intersphinx_resolve_xref_inner(
3924+
env, store, target, node, contnode, 'any')
3925+
38423926

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

0 commit comments

Comments
 (0)