mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
2
CHANGES
2
CHANGES
@@ -77,6 +77,8 @@ Bugs fixed
|
||||
with size explicitly set in pixels) (fixed for ``'pdflatex'/'lualatex'`` only)
|
||||
* #8911: C++: remove the longest matching prefix in
|
||||
:confval:`cpp_index_common_prefix` instead of the first that matches.
|
||||
* C, properly reject function declarations when a keyword is used
|
||||
as parameter name.
|
||||
|
||||
Testing
|
||||
--------
|
||||
|
||||
@@ -387,19 +387,6 @@ class ASTPostfixDec(ASTPostfixOp):
|
||||
signode.append(nodes.Text('--'))
|
||||
|
||||
|
||||
class ASTPostfixMember(ASTPostfixOp):
|
||||
def __init__(self, name):
|
||||
self.name = name
|
||||
|
||||
def _stringify(self, transform: StringifyTransform) -> str:
|
||||
return '.' + transform(self.name)
|
||||
|
||||
def describe_signature(self, signode: TextElement, mode: str,
|
||||
env: "BuildEnvironment", symbol: "Symbol") -> None:
|
||||
signode.append(nodes.Text('.'))
|
||||
self.name.describe_signature(signode, 'noneIsName', env, symbol)
|
||||
|
||||
|
||||
class ASTPostfixMemberOfPointer(ASTPostfixOp):
|
||||
def __init__(self, name):
|
||||
self.name = name
|
||||
@@ -2256,7 +2243,7 @@ class DefinitionParser(BaseParser):
|
||||
# | postfix "[" expression "]"
|
||||
# | postfix "[" braced-init-list [opt] "]"
|
||||
# | postfix "(" expression-list [opt] ")"
|
||||
# | postfix "." id-expression
|
||||
# | postfix "." id-expression // taken care of in primary by nested name
|
||||
# | postfix "->" id-expression
|
||||
# | postfix "++"
|
||||
# | postfix "--"
|
||||
@@ -2274,17 +2261,6 @@ class DefinitionParser(BaseParser):
|
||||
self.fail("Expected ']' in end of postfix expression.")
|
||||
postFixes.append(ASTPostfixArray(expr))
|
||||
continue
|
||||
if self.skip_string('.'):
|
||||
if self.skip_string('*'):
|
||||
# don't steal the dot
|
||||
self.pos -= 2
|
||||
elif self.skip_string('..'):
|
||||
# don't steal the dot
|
||||
self.pos -= 3
|
||||
else:
|
||||
name = self._parse_nested_name()
|
||||
postFixes.append(ASTPostfixMember(name))
|
||||
continue
|
||||
if self.skip_string('->'):
|
||||
if self.skip_string('*'):
|
||||
# don't steal the arrow
|
||||
@@ -2693,16 +2669,13 @@ class DefinitionParser(BaseParser):
|
||||
def _parse_declarator_name_suffix(
|
||||
self, named: Union[bool, str], paramMode: str, typed: bool
|
||||
) -> ASTDeclarator:
|
||||
assert named in (True, False, 'single')
|
||||
# now we should parse the name, and then suffixes
|
||||
if named == 'maybe':
|
||||
pos = self.pos
|
||||
try:
|
||||
declId = self._parse_nested_name()
|
||||
except DefinitionError:
|
||||
self.pos = pos
|
||||
declId = None
|
||||
elif named == 'single':
|
||||
if named == 'single':
|
||||
if self.match(identifier_re):
|
||||
if self.matched_text in _keywords:
|
||||
self.fail("Expected identifier, "
|
||||
"got keyword: %s" % self.matched_text)
|
||||
identifier = ASTIdentifier(self.matched_text)
|
||||
declId = ASTNestedName([identifier], rooted=False)
|
||||
else:
|
||||
@@ -2880,8 +2853,8 @@ class DefinitionParser(BaseParser):
|
||||
|
||||
def _parse_type(self, named: Union[bool, str], outer: str = None) -> ASTType:
|
||||
"""
|
||||
named=False|'maybe'|True: 'maybe' is e.g., for function objects which
|
||||
doesn't need to name the arguments
|
||||
named=False|'single'|True: 'single' is e.g., for function objects which
|
||||
doesn't need to name the arguments, but otherwise is a single name
|
||||
"""
|
||||
if outer: # always named
|
||||
if outer not in ('type', 'member', 'function'):
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
.. c:namespace:: anon_dup_decl_ns
|
||||
|
||||
.. c:struct:: anon_dup_decl
|
||||
|
||||
.. c:struct:: @a.A
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
.. c:namespace:: function_param_target
|
||||
|
||||
.. c:function:: void f(int i)
|
||||
|
||||
- :c:var:`i`
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
.. c:namespace:: index
|
||||
|
||||
test-domain-c
|
||||
=============
|
||||
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
.. c:member:: int member;
|
||||
.. c:var:: int var;
|
||||
.. c:function:: void f();
|
||||
.. .. c:macro:: NO_SEMICOLON;
|
||||
.. c:struct:: Struct;
|
||||
.. c:union:: Union;
|
||||
.. c:enum:: Enum;
|
||||
.. c:enumerator:: Enumerator;
|
||||
.. c:type:: Type;
|
||||
.. c:type:: int TypeDef;
|
||||
@@ -417,6 +417,9 @@ def test_function_definitions():
|
||||
check('function', 'void f(int arr[const static volatile 42])', {1: 'f'},
|
||||
output='void f(int arr[static volatile const 42])')
|
||||
|
||||
with pytest.raises(DefinitionError):
|
||||
parse('function', 'void f(int for)')
|
||||
|
||||
|
||||
def test_nested_name():
|
||||
check('struct', '{key}.A', {1: "A"})
|
||||
@@ -523,8 +526,15 @@ def test_attributes():
|
||||
# raise DefinitionError("")
|
||||
|
||||
|
||||
def split_warnigns(warning):
|
||||
ws = warning.getvalue().split("\n")
|
||||
assert len(ws) >= 1
|
||||
assert ws[-1] == ""
|
||||
return ws[:-1]
|
||||
|
||||
|
||||
def filter_warnings(warning, file):
|
||||
lines = warning.getvalue().split("\n")
|
||||
lines = split_warnigns(warning)
|
||||
res = [l for l in lines if "domain-c" in l and "{}.rst".format(file) in l and
|
||||
"WARNING: document isn't included in any toctree" not in l]
|
||||
print("Filtered warnings for file '{}':".format(file))
|
||||
@@ -578,10 +588,22 @@ def test_build_domain_c_anon_dup_decl(app, status, warning):
|
||||
assert "WARNING: c:identifier reference target not found: @b" in ws[1]
|
||||
|
||||
|
||||
@pytest.mark.sphinx(testroot='domain-c', confoverrides={'nitpicky': True})
|
||||
def test_build_domain_c_semicolon(app, status, warning):
|
||||
app.builder.build_all()
|
||||
ws = filter_warnings(warning, "semicolon")
|
||||
@pytest.mark.sphinx(confoverrides={'nitpicky': True})
|
||||
def test_build_domain_c_semicolon(app, warning):
|
||||
text = """
|
||||
.. c:member:: int member;
|
||||
.. c:var:: int var;
|
||||
.. c:function:: void f();
|
||||
.. .. c:macro:: NO_SEMICOLON;
|
||||
.. c:struct:: Struct;
|
||||
.. c:union:: Union;
|
||||
.. c:enum:: Enum;
|
||||
.. c:enumerator:: Enumerator;
|
||||
.. c:type:: Type;
|
||||
.. c:type:: int TypeDef;
|
||||
"""
|
||||
restructuredtext.parse(app, text)
|
||||
ws = split_warnigns(warning)
|
||||
assert len(ws) == 0
|
||||
|
||||
|
||||
@@ -593,8 +615,8 @@ def test_build_function_param_target(app, warning):
|
||||
assert len(ws) == 0
|
||||
entries = extract_role_links(app, "function_param_target.html")
|
||||
assert entries == [
|
||||
('c.f', 'i', 'i'),
|
||||
('c.f', 'f.i', 'f.i'),
|
||||
('c.function_param_target.f', 'i', 'i'),
|
||||
('c.function_param_target.f', 'f.i', 'f.i'),
|
||||
]
|
||||
|
||||
|
||||
@@ -656,6 +678,8 @@ def test_noindexentry(app):
|
||||
|
||||
@pytest.mark.sphinx(testroot='domain-c-intersphinx', confoverrides={'nitpicky': True})
|
||||
def test_intersphinx(tempdir, app, status, warning):
|
||||
# a splitting of test_ids_vs_tags0 into the primary directives in a remote project,
|
||||
# and then the references in the test project
|
||||
origSource = """\
|
||||
.. c:member:: int _member
|
||||
.. c:var:: int _var
|
||||
|
||||
Reference in New Issue
Block a user