C++, add support for parameterized noexcept specifier in function declarations

This commit is contained in:
Jan Babst 2020-04-15 00:10:13 +02:00
parent 2fac698e76
commit 95e9204438
3 changed files with 41 additions and 14 deletions

1
.gitignore vendored
View File

@ -9,6 +9,7 @@
.mypy_cache/
.pytest_cache/
.ropeproject/
.vscode/
TAGS
.tags
.tox/

View File

@ -10,7 +10,7 @@
import re
from typing import (
Any, Callable, Dict, Generator, Iterator, List, Tuple, Type, TypeVar, Union
Any, Callable, Dict, Generator, Iterator, List, Tuple, Type, TypeVar, Union, Optional
)
from docutils import nodes
@ -1266,7 +1266,7 @@ class ASTNoexceptExpr(ASTExpression):
self.expr = expr
def _stringify(self, transform: StringifyTransform) -> str:
return "noexcept(" + transform(self.expr) + ")"
return 'noexcept(' + transform(self.expr) + ')'
def get_id(self, version: int) -> str:
return 'nx' + self.expr.get_id(version)
@ -1812,10 +1812,28 @@ class ASTFunctionParameter(ASTBase):
self.arg.describe_signature(signode, mode, env, symbol=symbol)
class ASTNoexceptSpec(ASTBase):
def __init__(self, expr: Optional[ASTExpression]):
self.expr = expr
def _stringify(self, transform: StringifyTransform) -> str:
if self.expr:
return 'noexcept(' + transform(self.expr) + ')'
return 'noexcept'
def describe_signature(self, signode: TextElement, mode: str,
env: "BuildEnvironment", symbol: "Symbol") -> None:
signode += addnodes.desc_annotation('noexcept', 'noexcept')
if self.expr:
signode.append(nodes.Text('('))
self.expr.describe_signature(signode, mode, env, symbol)
signode.append(nodes.Text(')'))
class ASTParametersQualifiers(ASTBase):
def __init__(self, args: List[ASTFunctionParameter],
volatile: bool, const: bool, refQual: str,
exceptionSpec: str, override: bool, final: bool, initializer: str) -> None:
def __init__(self, args: List[ASTFunctionParameter], volatile: bool, const: bool,
refQual: str, exceptionSpec: ASTNoexceptSpec, override: bool, final: bool,
initializer: str) -> None:
self.args = args
self.volatile = volatile
self.const = const
@ -1874,7 +1892,7 @@ class ASTParametersQualifiers(ASTBase):
res.append(self.refQual)
if self.exceptionSpec:
res.append(' ')
res.append(str(self.exceptionSpec))
res.append(transform(self.exceptionSpec))
if self.final:
res.append(' final')
if self.override:
@ -1911,7 +1929,8 @@ class ASTParametersQualifiers(ASTBase):
if self.refQual:
_add_text(signode, self.refQual)
if self.exceptionSpec:
_add_anno(signode, str(self.exceptionSpec))
signode += nodes.Text(' ')
self.exceptionSpec.describe_signature(signode, mode, env, symbol)
if self.final:
_add_anno(signode, 'final')
if self.override:
@ -5495,11 +5514,14 @@ class DefinitionParser(BaseParser):
initializer = None
self.skip_ws()
if self.skip_string('noexcept'):
exceptionSpec = 'noexcept'
self.skip_ws()
if self.skip_string('('):
self.fail('Parameterised "noexcept" not yet implemented.')
if self.skip_string_and_ws('('):
expr = self._parse_constant_expression(False)
self.skip_ws()
if not self.skip_string(')'):
self.fail("Expecting ')' to end 'noexcept'.")
exceptionSpec = ASTNoexceptSpec(expr)
else:
exceptionSpec = ASTNoexceptSpec(None)
self.skip_ws()
override = self.skip_word_and_ws('override')
final = self.skip_word_and_ws('final')

View File

@ -393,7 +393,7 @@ def test_function_definitions():
x = 'std::vector<std::pair<std::string, int>> &module::test(register int ' \
'foo, bar, std::string baz = "foobar, blah, bleh") const = 0'
check('function', x, {1: "module::test__i.bar.ssC",
2: "NK6module4testEi3barNSt6stringE"})
2: "NK6module4testEi3barNSt6stringE"})
check('function', 'void f(std::pair<A, B>)',
{1: "f__std::pair:A.B:", 2: "1fNSt4pairI1A1BEE"})
check('function', 'explicit module::myclass::foo::foo()',
@ -427,6 +427,10 @@ def test_function_definitions():
{1: "get_valueCE", 2: "9get_valuev"})
check('function', 'int get_value() const noexcept',
{1: "get_valueC", 2: "NK9get_valueEv"})
check('function', 'int get_value() const noexcept(std::is_nothrow_move_constructible<T>::value)',
{1: "get_valueC", 2: "NK9get_valueEv"})
check('function', 'int get_value() const noexcept("see below")',
{1: "get_valueC", 2: "NK9get_valueEv"})
check('function', 'int get_value() const noexcept = delete',
{1: "get_valueC", 2: "NK9get_valueEv"})
check('function', 'int get_value() volatile const',
@ -868,7 +872,7 @@ def test_xref_parsing():
def filter_warnings(warning, file):
lines = warning.getvalue().split("\n");
lines = warning.getvalue().split("\n")
res = [l for l in lines if "domain-cpp" 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))