Skip to content

Commit 6f3426e

Browse files
committed
C, implicit tag lookup
1 parent 634028b commit 6f3426e

File tree

4 files changed

+42
-11
lines changed

4 files changed

+42
-11
lines changed

sphinx/domains/c.py

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -118,11 +118,6 @@ def __init__(self, identifier: str, tag: Optional[str]) -> None:
118118
self.identifier = identifier
119119
self.tag = tag
120120

121-
def __eq__(self, other: Any) -> bool:
122-
return type(other) is ASTIdentifier \
123-
and self.identifier == other.identifier \
124-
and self.tag == other.tag
125-
126121
def is_anon(self) -> bool:
127122
return self.identifier[0] == '@'
128123

@@ -135,6 +130,13 @@ def get_id(self, version: int) -> str:
135130
else:
136131
return self.identifier
137132

133+
def matches(self, other: "ASTIdentifier") -> bool:
134+
if self.identifier != other.identifier:
135+
return False
136+
if self.tag is None:
137+
return True
138+
return self.tag == other.tag
139+
138140
# and this is where we finally make a difference between __str__ and the display string
139141

140142
def __str__(self) -> str:
@@ -1685,7 +1687,7 @@ def candidates() -> Generator["Symbol", None, None]:
16851687
if Symbol.debug_lookup:
16861688
Symbol.debug_print("candidate:")
16871689
print(s.to_string(Symbol.debug_indent + 1), end="")
1688-
if s.ident == ident:
1690+
if s.ident and ident.matches(s.ident):
16891691
if Symbol.debug_lookup:
16901692
Symbol.debug_indent += 1
16911693
Symbol.debug_print("matches")
@@ -1997,11 +1999,11 @@ def find_identifier(self, ident: ASTIdentifier,
19971999
Symbol.debug_print("trying:")
19982000
print(current.to_string(Symbol.debug_indent + 1), end="")
19992001
Symbol.debug_indent -= 2
2000-
if matchSelf and current.ident == ident:
2002+
if matchSelf and ident.matches(current.ident):
20012003
return current
20022004
children = current.children_recurse_anon if recurseInAnon else current._children
20032005
for s in children:
2004-
if s.ident == ident:
2006+
if ident.matches(s.ident):
20052007
return s
20062008
if not searchInSiblings:
20072009
break
@@ -3764,10 +3766,20 @@ def _resolve_xref_inner(self, env: BuildEnvironment, fromdocname: str, builder:
37643766
assert parentSymbol # should be there
37653767
else:
37663768
parentSymbol = rootSymbol
3769+
37673770
s = parentSymbol.find_declaration(name, typ,
37683771
matchSelf=True, recurseInAnon=True)
37693772
if s is None or s.declaration is None:
3770-
return None, None
3773+
if typ == 'identifier':
3774+
# these are from within declarations and should be tagged correctly
3775+
return None, None
3776+
# but those from xref roles may not have correct tagging
3777+
name.setTagsToPattern()
3778+
s = parentSymbol.find_declaration(name, typ,
3779+
matchSelf=True, recurseInAnon=True)
3780+
if s is None or s.declaration is None:
3781+
return None, None
3782+
# TODO: conditionally warn about xrefs with incorrect tagging?
37713783

37723784
# TODO: check role type vs. object type
37733785

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
.. c:namespace:: @ids_vs_tags2
2+
3+
.. c:struct:: A
4+
5+
.. c:union:: @data
6+
7+
.. c:member:: int a
8+
9+
- :c:member:`struct A.union @data.a`
10+
- :c:member:`A.a`
11+
- :c:member:`[email protected]`
12+
- :c:member:`A.a`

tests/roots/test-domain-c/index.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ directives
88
99
:rtype: int
1010
11-
.. c:function:: MyStruct hello2(char *name)
11+
.. c:function:: struct MyStruct hello2(char *name)
1212
1313
:rtype: MyStruct
1414
@@ -46,7 +46,7 @@ directives
4646
- :c:expr:`unsigned int`
4747
- :c:texpr:`unsigned int`
4848
49-
.. c:var:: A a
49+
.. c:var:: struct A a
5050
5151
- :c:expr:`a->b`
5252
- :c:texpr:`a->b`

tests/test_domain_c.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -666,6 +666,13 @@ def test_ids_vs_tags(app, warning):
666666
assert entries == expected
667667

668668

669+
@pytest.mark.sphinx(testroot='domain-c', confoverrides={'nitpicky': True})
670+
def test_ids_vs_tags2(app, warning):
671+
app.builder.build_all()
672+
ws = filter_warnings(warning, "ids-vs-tags2")
673+
assert len(ws) == 0
674+
675+
669676
def test_build_domain_c_semicolon(app, warning):
670677
text = """
671678
.. c:member:: int member;

0 commit comments

Comments
 (0)