mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
C++, semicolon, move it entirely to ASTDeclaration
This commit is contained in:
parent
50ae1b04e8
commit
ef0c2bf83c
@ -109,6 +109,7 @@ T = TypeVar('T')
|
||||
simple-declaration ->
|
||||
attribute-specifier-seq[opt] decl-specifier-seq[opt]
|
||||
init-declarator-list[opt] ;
|
||||
# Make the semicolon optional.
|
||||
# For now: drop the attributes (TODO).
|
||||
# Use at most 1 init-declarator.
|
||||
-> decl-specifier-seq init-declarator
|
||||
@ -2690,13 +2691,11 @@ class ASTInitializer(ASTBase):
|
||||
|
||||
|
||||
class ASTType(ASTBase):
|
||||
def __init__(self, declSpecs: ASTDeclSpecs, decl: ASTDeclarator,
|
||||
semicolon: bool = False) -> None:
|
||||
def __init__(self, declSpecs: ASTDeclSpecs, decl: ASTDeclarator) -> None:
|
||||
assert declSpecs
|
||||
assert decl
|
||||
self.declSpecs = declSpecs
|
||||
self.decl = decl
|
||||
self.semicolon = semicolon
|
||||
|
||||
@property
|
||||
def name(self) -> ASTNestedName:
|
||||
@ -2770,8 +2769,6 @@ class ASTType(ASTBase):
|
||||
if self.decl.require_space_after_declSpecs() and len(declSpecs) > 0:
|
||||
res.append(' ')
|
||||
res.append(transform(self.decl))
|
||||
if self.semicolon:
|
||||
res.append(';')
|
||||
return ''.join(res)
|
||||
|
||||
def get_type_declaration_prefix(self) -> str:
|
||||
@ -2792,8 +2789,6 @@ class ASTType(ASTBase):
|
||||
if mode == 'markType':
|
||||
mode = 'noneIsName'
|
||||
self.decl.describe_signature(signode, mode, env, symbol)
|
||||
if self.semicolon:
|
||||
signode += nodes.Text(';')
|
||||
|
||||
|
||||
class ASTTemplateParamConstrainedTypeWithInit(ASTBase):
|
||||
@ -5876,7 +5871,6 @@ class DefinitionParser(BaseParser):
|
||||
raise Exception('Internal error, unknown outer "%s".' % outer)
|
||||
if outer != 'operatorCast':
|
||||
assert named
|
||||
semicolon = False
|
||||
if outer in ('type', 'function'):
|
||||
# We allow type objects to just be a name.
|
||||
# Some functions don't have normal return types: constructors,
|
||||
@ -5888,8 +5882,7 @@ class DefinitionParser(BaseParser):
|
||||
declSpecs = self._parse_decl_specs(outer=outer, typed=False)
|
||||
decl = self._parse_declarator(named=True, paramMode=outer,
|
||||
typed=False)
|
||||
semicolon = self.skip_string_and_ws(';')
|
||||
self.assert_end()
|
||||
self.assert_end(allowSemicolon=True)
|
||||
except DefinitionError as exUntyped:
|
||||
if outer == 'type':
|
||||
desc = "If just a name"
|
||||
@ -5944,7 +5937,7 @@ class DefinitionParser(BaseParser):
|
||||
named = 'single'
|
||||
declSpecs = self._parse_decl_specs(outer=outer)
|
||||
decl = self._parse_declarator(named=named, paramMode=paramMode)
|
||||
return ASTType(declSpecs, decl, semicolon)
|
||||
return ASTType(declSpecs, decl)
|
||||
|
||||
def _parse_type_with_init(
|
||||
self, named: Union[bool, str],
|
||||
@ -6300,7 +6293,8 @@ class DefinitionParser(BaseParser):
|
||||
templatePrefix,
|
||||
fullSpecShorthand=False,
|
||||
isMember=objectType == 'member')
|
||||
semicolon = self.skip_string_and_ws(';')
|
||||
self.skip_ws()
|
||||
semicolon = self.skip_string(';')
|
||||
return ASTDeclaration(objectType, directiveType, visibility,
|
||||
templatePrefix, declaration, semicolon)
|
||||
|
||||
|
@ -338,10 +338,14 @@ class BaseParser:
|
||||
self.pos = self.end
|
||||
return rv
|
||||
|
||||
def assert_end(self) -> None:
|
||||
def assert_end(self, *, allowSemicolon: bool = False) -> None:
|
||||
self.skip_ws()
|
||||
if not self.eof:
|
||||
self.fail('Expected end of definition.')
|
||||
if allowSemicolon:
|
||||
if not self.eof and self.definition[self.pos:] != ';':
|
||||
self.fail('Expected end of definition or ;.')
|
||||
else:
|
||||
if not self.eof:
|
||||
self.fail('Expected end of definition.')
|
||||
|
||||
################################################################################
|
||||
|
||||
|
14
tests/roots/test-domain-cpp/semicolon.rst
Normal file
14
tests/roots/test-domain-cpp/semicolon.rst
Normal file
@ -0,0 +1,14 @@
|
||||
.. cpp:class:: Class;
|
||||
.. cpp:struct:: Struct;
|
||||
.. cpp:union:: Union;
|
||||
.. cpp:function:: void f();
|
||||
.. cpp:member:: int member;
|
||||
.. cpp:var:: int var;
|
||||
.. cpp:type:: Type;
|
||||
.. cpp:type:: int TypeDef;
|
||||
.. cpp:type:: Alias = int;
|
||||
.. cpp:concept:: template<typename T> Concept;
|
||||
.. cpp:enum:: Enum;
|
||||
.. cpp:enum-struct:: EnumStruct;
|
||||
.. cpp:enum-class:: EnumClass;
|
||||
.. cpp:enumerator:: Enumerator;
|
@ -87,7 +87,7 @@ def check(name, input, idDict, output=None):
|
||||
# First, check without semicolon
|
||||
_check(name, input, idDict, output)
|
||||
# Second, check with semicolon
|
||||
_check(name, input + ';', idDict, output + ';')
|
||||
_check(name, input + ' ;', idDict, output + ';')
|
||||
|
||||
|
||||
def test_fundamental_types():
|
||||
@ -910,6 +910,13 @@ def test_build_domain_cpp_backslash_ok(app, status, warning):
|
||||
assert len(ws) == 0
|
||||
|
||||
|
||||
@pytest.mark.sphinx(testroot='domain-cpp', confoverrides={'nitpicky': True})
|
||||
def test_build_domain_cpp_semicolon(app, status, warning):
|
||||
app.builder.build_all()
|
||||
ws = filter_warnings(warning, "semicolon")
|
||||
assert len(ws) == 0
|
||||
|
||||
|
||||
@pytest.mark.sphinx(testroot='domain-cpp',
|
||||
confoverrides={'nitpicky': True, 'strip_signature_backslash': True})
|
||||
def test_build_domain_cpp_backslash_ok(app, status, warning):
|
||||
|
Loading…
Reference in New Issue
Block a user