mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
1
CHANGES
1
CHANGES
@@ -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
|
||||
----------
|
||||
|
||||
@@ -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."""
|
||||
|
||||
@@ -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."""
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)',
|
||||
|
||||
@@ -938,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():
|
||||
|
||||
Reference in New Issue
Block a user