diff options
author | Takeshi KOMIYA <i.tkomiya@gmail.com> | 2020-08-14 14:37:19 +0900 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-08-14 14:37:19 +0900 |
commit | d3912121018f5c33390e1243af730b9ad48ab292 (patch) | |
tree | 11616bdcc65dc6a419270d1b9e0d5b9caacfbfcd | |
parent | 611fff975e9c1b3972fd9e2dfd7a96d3d8d8cdb7 (diff) | |
parent | 90e9b31a16a2679889ef75db6040b55ab51bb536 (diff) | |
download | sphinx-git-d3912121018f5c33390e1243af730b9ad48ab292.tar.gz |
Merge branch '3.2.x' into 8099_NameError_for_TYPE_CHECKING
-rw-r--r-- | CHANGES | 2 | ||||
-rw-r--r-- | sphinx/domains/c.py | 21 | ||||
-rw-r--r-- | sphinx/domains/cpp.py | 20 | ||||
-rw-r--r-- | sphinx/util/cfamily.py | 2 | ||||
-rw-r--r-- | tests/test_domain_c.py | 9 | ||||
-rw-r--r-- | tests/test_domain_cpp.py | 7 |
6 files changed, 47 insertions, 14 deletions
@@ -36,6 +36,7 @@ Features added * #8095: napoleon: Add :confval:`napoleon_preprocess_types` to enable the type preprocessor for numpy style docstrings +* #8114: C and C++, parse function attributes after parameters and qualifiers. Bugs fixed ---------- @@ -48,6 +49,7 @@ Bugs fixed * #8091: autodoc: AttributeError is raised on documenting an attribute on Python 3.5.2 * #8099: autodoc: NameError is raised when target code uses ``TYPE_CHECKING`` +* C++, fix parsing of template template paramters, broken by the fix of #7944 Testing -------- diff --git a/sphinx/domains/c.py b/sphinx/domains/c.py index 65786b5de..d8ccc2e3d 100644 --- a/sphinx/domains/c.py +++ b/sphinx/domains/c.py @@ -32,7 +32,7 @@ from sphinx.transforms import SphinxTransform from sphinx.transforms.post_transforms import ReferencesResolver from sphinx.util import logging from sphinx.util.cfamily import ( - NoOldIdError, ASTBaseBase, ASTBaseParenExprList, + NoOldIdError, ASTBaseBase, ASTAttribute, ASTBaseParenExprList, verify_description_mode, StringifyTransform, BaseParser, DefinitionError, UnsupportedMultiCharacterCharLiteral, identifier_re, anon_identifier_re, integer_literal_re, octal_literal_re, @@ -652,8 +652,9 @@ class ASTFunctionParameter(ASTBase): class ASTParameters(ASTBase): - def __init__(self, args: List[ASTFunctionParameter]) -> None: + def __init__(self, args: List[ASTFunctionParameter], attrs: List[ASTAttribute]) -> None: self.args = args + self.attrs = attrs @property def function_params(self) -> List[ASTFunctionParameter]: @@ -669,6 +670,9 @@ class ASTParameters(ASTBase): first = False res.append(str(a)) res.append(')') + for attr in self.attrs: + res.append(' ') + res.append(transform(attr)) return ''.join(res) def describe_signature(self, signode: TextElement, mode: str, @@ -683,6 +687,9 @@ class ASTParameters(ASTBase): arg.describe_signature(param, 'markType', env, symbol=symbol) paramlist += param signode += paramlist + for attr in self.attrs: + signode += nodes.Text(' ') + attr.describe_signature(signode) class ASTDeclSpecsSimple(ASTBaseBase): @@ -2572,7 +2579,15 @@ class DefinitionParser(BaseParser): self.fail( 'Expecting "," or ")" in parameters, ' 'got "%s".' % self.current_char) - return ASTParameters(args) + + attrs = [] + while True: + attr = self._parse_attribute() + if attr is None: + break + attrs.append(attr) + + return ASTParameters(args, attrs) def _parse_decl_specs_simple(self, outer: str, typed: bool) -> ASTDeclSpecsSimple: """Just parse the simple ones.""" diff --git a/sphinx/domains/cpp.py b/sphinx/domains/cpp.py index 46708b846..92d578427 100644 --- a/sphinx/domains/cpp.py +++ b/sphinx/domains/cpp.py @@ -1879,7 +1879,8 @@ class ASTNoexceptSpec(ASTBase): class ASTParametersQualifiers(ASTBase): def __init__(self, args: List[ASTFunctionParameter], volatile: bool, const: bool, refQual: str, exceptionSpec: ASTNoexceptSpec, trailingReturn: "ASTType", - override: bool, final: bool, initializer: str) -> None: + override: bool, final: bool, attrs: List[ASTAttribute], + initializer: str) -> None: self.args = args self.volatile = volatile self.const = const @@ -1888,6 +1889,7 @@ class ASTParametersQualifiers(ASTBase): self.trailingReturn = trailingReturn self.override = override self.final = final + self.attrs = attrs self.initializer = initializer @property @@ -1947,6 +1949,9 @@ class ASTParametersQualifiers(ASTBase): res.append(' final') if self.override: res.append(' override') + for attr in self.attrs: + res.append(' ') + res.append(transform(attr)) if self.initializer: res.append(' = ') res.append(self.initializer) @@ -1988,6 +1993,9 @@ class ASTParametersQualifiers(ASTBase): _add_anno(signode, 'final') if self.override: _add_anno(signode, 'override') + for attr in self.attrs: + signode += nodes.Text(' ') + attr.describe_signature(signode) if self.initializer: _add_text(signode, '= ' + str(self.initializer)) @@ -5709,6 +5717,13 @@ class DefinitionParser(BaseParser): override = self.skip_word_and_ws( 'override') # they can be permuted + attrs = [] + while True: + attr = self._parse_attribute() + if attr is None: + break + attrs.append(attr) + self.skip_ws() initializer = None if self.skip_string('='): @@ -5725,7 +5740,7 @@ class DefinitionParser(BaseParser): return ASTParametersQualifiers( args, volatile, const, refQual, exceptionSpec, trailingReturn, - override, final, initializer) + override, final, attrs, initializer) def _parse_decl_specs_simple(self, outer: str, typed: bool) -> ASTDeclSpecsSimple: """Just parse the simple ones.""" @@ -6251,6 +6266,7 @@ class DefinitionParser(BaseParser): # ========================================================================== def _parse_template_paramter(self) -> ASTTemplateParam: + self.skip_ws() if self.skip_word('template'): # declare a tenplate template parameter nestedParams = self._parse_template_parameter_list() diff --git a/sphinx/util/cfamily.py b/sphinx/util/cfamily.py index a67b2a0ad..0edea128c 100644 --- a/sphinx/util/cfamily.py +++ b/sphinx/util/cfamily.py @@ -391,7 +391,7 @@ class BaseParser: % startPos) return self.definition[startPos:self.pos] - def _parse_attribute(self) -> ASTAttribute: + def _parse_attribute(self) -> Optional[ASTAttribute]: self.skip_ws() # try C++11 style startPos = self.pos diff --git a/tests/test_domain_c.py b/tests/test_domain_c.py index 71bf251e9..b6f72287e 100644 --- a/tests/test_domain_c.py +++ b/tests/test_domain_c.py @@ -497,17 +497,16 @@ def test_attributes(): parse('member', 'paren_attr({]}) int f') # position: decl specs - check('function', 'static inline __attribute__(()) void f()', - {1: 'f'}, + check('function', 'static inline __attribute__(()) void f()', {1: 'f'}, output='__attribute__(()) static inline void f()') - check('function', '[[attr1]] [[attr2]] void f()', - {1: 'f'}, - output='[[attr1]] [[attr2]] void f()') + check('function', '[[attr1]] [[attr2]] void f()', {1: 'f'}) # position: declarator check('member', 'int *[[attr]] i', {1: 'i'}) check('member', 'int *const [[attr]] volatile i', {1: 'i'}, output='int *[[attr]] volatile const i') check('member', 'int *[[attr]] *i', {1: 'i'}) + # position: parameters + check('function', 'void f() [[attr1]] [[attr2]]', {1: 'f'}) # issue michaeljones/breathe#500 check('function', 'LIGHTGBM_C_EXPORT int LGBM_BoosterFree(int handle)', diff --git a/tests/test_domain_cpp.py b/tests/test_domain_cpp.py index 118227cd7..558d69911 100644 --- a/tests/test_domain_cpp.py +++ b/tests/test_domain_cpp.py @@ -764,6 +764,7 @@ def test_templates(): check('class', "template<template<typename> typename> {key}A", {2: "II0E0E1A"}) check('class', "template<template<typename> typename ...T> {key}A", {2: "II0EDpE1A"}) check('class', "template<template<typename> typename...> {key}A", {2: "II0EDpE1A"}) + check('class', "template<typename T, template<typename> typename...> {key}A", {2: "I0I0EDpE1A"}) check('class', "template<int> {key}A", {2: "I_iE1A"}) check('class', "template<int T> {key}A", {2: "I_iE1A"}) @@ -937,15 +938,15 @@ def test_attributes(): check('function', 'static inline __attribute__(()) void f()', {1: 'f', 2: '1fv'}, output='__attribute__(()) static inline void f()') - check('function', '[[attr1]] [[attr2]] void f()', - {1: 'f', 2: '1fv'}, - output='[[attr1]] [[attr2]] void f()') + check('function', '[[attr1]] [[attr2]] void f()', {1: 'f', 2: '1fv'}) # position: declarator check('member', 'int *[[attr]] i', {1: 'i__iP', 2: '1i'}) check('member', 'int *const [[attr]] volatile i', {1: 'i__iPVC', 2: '1i'}, output='int *[[attr]] volatile const i') check('member', 'int &[[attr]] i', {1: 'i__iR', 2: '1i'}) check('member', 'int *[[attr]] *i', {1: 'i__iPP', 2: '1i'}) + # position: parameters and qualifiers + check('function', 'void f() [[attr1]] [[attr2]]', {1: 'f', 2: '1fv'}) def test_xref_parsing(): |