diff options
author | Takeshi KOMIYA <i.tkomiya@gmail.com> | 2021-04-10 00:32:26 +0900 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-04-10 00:32:26 +0900 |
commit | fe6d95e4294f47d61f1a04a1f8c6567c9802f504 (patch) | |
tree | 33a7143bf1dcf60830c2e1fcd4b396175af45e64 /sphinx/domains/cpp.py | |
parent | 7327e56dff865d4766c43d46405ae827e10fd6c3 (diff) | |
parent | ce5d66e618c111b115a9bb7b1401a26483fcfa8f (diff) | |
download | sphinx-git-fe6d95e4294f47d61f1a04a1f8c6567c9802f504.tar.gz |
Merge branch 'master' into patch-1
Diffstat (limited to 'sphinx/domains/cpp.py')
-rw-r--r-- | sphinx/domains/cpp.py | 163 |
1 files changed, 93 insertions, 70 deletions
diff --git a/sphinx/domains/cpp.py b/sphinx/domains/cpp.py index 7ee023d1d..abe961791 100644 --- a/sphinx/domains/cpp.py +++ b/sphinx/domains/cpp.py @@ -39,6 +39,7 @@ from sphinx.util.cfamily import (ASTAttribute, ASTBaseBase, ASTBaseParenExprList from sphinx.util.docfields import Field, GroupedField from sphinx.util.docutils import SphinxDirective from sphinx.util.nodes import make_refnode +from sphinx.util.typing import OptionSpec logger = logging.getLogger(__name__) T = TypeVar('T') @@ -179,7 +180,6 @@ T = TypeVar('T') declarator -> ptr-declarator | noptr-declarator parameters-and-qualifiers trailing-return-type - (TODO: for now we don't support trailing-eturn-type) ptr-declarator -> noptr-declarator | ptr-operator ptr-declarator @@ -306,6 +306,7 @@ _operator_re = re.compile(r'''(?x) | \+\+ | -- | ->\*? | \, | (<<|>>)=? | && | \|\| + | <=> | [!<>=/*%+|&^~-]=? | (\b(and|and_eq|bitand|bitor|compl|not|not_eq|or|or_eq|xor|xor_eq)\b) ''') @@ -494,6 +495,7 @@ _id_operator_v2 = { '>': 'gt', '<=': 'le', '>=': 'ge', + '<=>': 'ss', '!': 'nt', 'not': 'nt', '&&': 'aa', 'and': 'aa', '||': 'oo', 'or': 'oo', @@ -516,10 +518,10 @@ _id_operator_unary_v2 = { '!': 'nt', 'not': 'nt', '~': 'co', 'compl': 'co' } -_id_char_from_prefix = { +_id_char_from_prefix: Dict[Optional[str], str] = { None: 'c', 'u8': 'c', 'u': 'Ds', 'U': 'Di', 'L': 'w' -} # type: Dict[Any, str] +} # these are ordered by preceedence _expression_bin_ops = [ ['||', 'or'], @@ -528,7 +530,7 @@ _expression_bin_ops = [ ['^', 'xor'], ['&', 'bitand'], ['==', '!=', 'not_eq'], - ['<=', '>=', '<', '>'], + ['<=>', '<=', '>=', '<', '>'], ['<<', '>>'], ['+', '-'], ['*', '/', '%'], @@ -716,8 +718,7 @@ class ASTNestedName(ASTBase): res.append('') for i in range(len(self.names)): n = self.names[i] - t = self.templates[i] - if t: + if self.templates[i]: res.append("template " + transform(n)) else: res.append(transform(n)) @@ -728,16 +729,29 @@ class ASTNestedName(ASTBase): verify_description_mode(mode) # just print the name part, with template args, not template params if mode == 'noneIsName': - signode += nodes.Text(str(self)) + if self.rooted: + signode += nodes.Text('::') + for i in range(len(self.names)): + if i != 0: + signode += nodes.Text('::') + n = self.names[i] + if self.templates[i]: + signode += nodes.Text("template") + signode += nodes.Text(" ") + n.describe_signature(signode, mode, env, '', symbol) elif mode == 'param': - name = str(self) - signode += nodes.emphasis(name, name) + assert not self.rooted, str(self) + assert len(self.names) == 1 + assert not self.templates[0] + node = nodes.emphasis() + self.names[0].describe_signature(node, 'noneIsName', env, '', symbol) + signode += node elif mode == 'markType' or mode == 'lastIsName' or mode == 'markName': # Each element should be a pending xref targeting the complete # prefix. however, only the identifier part should be a link, such # that template args can be a link as well. # For 'lastIsName' we should also prepend template parameter lists. - templateParams = [] # type: List[Any] + templateParams: List[Any] = [] if mode == 'lastIsName': assert symbol is not None if symbol.declaration.templatePrefix is not None: @@ -1248,7 +1262,7 @@ class ASTSizeofParamPack(ASTExpression): def describe_signature(self, signode: TextElement, mode: str, env: "BuildEnvironment", symbol: "Symbol") -> None: signode.append(nodes.Text('sizeof...(')) - self.identifier.describe_signature(signode, mode, env, + self.identifier.describe_signature(signode, 'markType', env, symbol=symbol, prefix="", templateArgs="") signode.append(nodes.Text(')')) @@ -1965,15 +1979,23 @@ class ASTParametersQualifiers(ASTBase): def describe_signature(self, signode: TextElement, mode: str, env: "BuildEnvironment", symbol: "Symbol") -> None: verify_description_mode(mode) - paramlist = addnodes.desc_parameterlist() - for arg in self.args: - param = addnodes.desc_parameter('', '', noemph=True) - if mode == 'lastIsName': # i.e., outer-function params + # only use the desc_parameterlist for the outer list, not for inner lists + if mode == 'lastIsName': + paramlist = addnodes.desc_parameterlist() + for arg in self.args: + param = addnodes.desc_parameter('', '', noemph=True) arg.describe_signature(param, 'param', env, symbol=symbol) - else: - arg.describe_signature(param, 'markType', env, symbol=symbol) - paramlist += param - signode += paramlist + paramlist += param + signode += paramlist + else: + signode += nodes.Text('(', '(') + first = True + for arg in self.args: + if not first: + signode += nodes.Text(', ', ', ') + first = False + arg.describe_signature(signode, 'markType', env, symbol=symbol) + signode += nodes.Text(')', ')') def _add_anno(signode: TextElement, text: str) -> None: signode += nodes.Text(' ') @@ -2035,7 +2057,7 @@ class ASTDeclSpecsSimple(ASTBase): self.attrs + other.attrs) def _stringify(self, transform: StringifyTransform) -> str: - res = [] # type: List[str] + res: List[str] = [] res.extend(transform(attr) for attr in self.attrs) if self.storage: res.append(self.storage) @@ -2122,7 +2144,7 @@ class ASTDeclSpecs(ASTBase): return ''.join(res) def _stringify(self, transform: StringifyTransform) -> str: - res = [] # type: List[str] + res: List[str] = [] l = transform(self.leftSpecs) if len(l) > 0: res.append(l) @@ -2189,7 +2211,7 @@ class ASTArray(ASTBase): verify_description_mode(mode) signode.append(nodes.Text("[")) if self.size: - self.size.describe_signature(signode, mode, env, symbol) + self.size.describe_signature(signode, 'markType', env, symbol) signode.append(nodes.Text("]")) @@ -2657,7 +2679,7 @@ class ASTDeclaratorMemPtr(ASTDeclarator): def describe_signature(self, signode: TextElement, mode: str, env: "BuildEnvironment", symbol: "Symbol") -> None: verify_description_mode(mode) - self.className.describe_signature(signode, mode, env, symbol) + self.className.describe_signature(signode, 'markType', env, symbol) signode += nodes.Text('::*') def _add_anno(signode: TextElement, text: str) -> None: @@ -3613,9 +3635,9 @@ class ASTDeclaration(ASTBase): self.trailingRequiresClause = trailingRequiresClause self.semicolon = semicolon - self.symbol = None # type: Symbol + self.symbol: Symbol = None # set by CPPObject._add_enumerator_to_parent - self.enumeratorScopedSymbol = None # type: Symbol + self.enumeratorScopedSymbol: Symbol = None def clone(self) -> "ASTDeclaration": templatePrefixClone = self.templatePrefix.clone() if self.templatePrefix else None @@ -3835,8 +3857,8 @@ class Symbol: docname: str, line: int) -> None: self.parent = parent # declarations in a single directive are linked together - self.siblingAbove = None # type: Symbol - self.siblingBelow = None # type: Symbol + self.siblingAbove: Symbol = None + self.siblingBelow: Symbol = None self.identOrOp = identOrOp self.templateParams = templateParams # template<templateParams> self.templateArgs = templateArgs # identifier<templateArgs> @@ -3847,8 +3869,8 @@ class Symbol: self._assert_invariants() # Remember to modify Symbol.remove if modifications to the parent change. - self._children = [] # type: List[Symbol] - self._anonChildren = [] # type: List[Symbol] + self._children: List[Symbol] = [] + self._anonChildren: List[Symbol] = [] # note: _children includes _anonChildren if self.parent: self.parent._children.append(self) @@ -3918,7 +3940,7 @@ class Symbol: self.parent = None def clear_doc(self, docname: str) -> None: - newChildren = [] # type: List[Symbol] + newChildren: List[Symbol] = [] for sChild in self._children: sChild.clear_doc(docname) if sChild.declaration and sChild.docname == docname: @@ -4950,7 +4972,7 @@ class DefinitionParser(BaseParser): # fold-expression # id-expression -> we parse this with _parse_nested_name self.skip_ws() - res = self._parse_literal() # type: ASTExpression + res: ASTExpression = self._parse_literal() if res is not None: return res self.skip_ws() @@ -4978,7 +5000,7 @@ class DefinitionParser(BaseParser): if self.skip_string(close): return [], False - exprs = [] # type: List[Union[ASTExpression, ASTBracedInitList]] + exprs: List[Union[ASTExpression, ASTBracedInitList]] = [] trailingComma = False while True: self.skip_ws() @@ -5057,7 +5079,7 @@ class DefinitionParser(BaseParser): # | "typeid" "(" type-id ")" prefixType = None - prefix = None # type: Any + prefix: Any = None self.skip_ws() cast = None @@ -5140,7 +5162,7 @@ class DefinitionParser(BaseParser): raise self._make_multi_error(errors, header) from eInner # and now parse postfixes - postFixes = [] # type: List[ASTPostfixOp] + postFixes: List[ASTPostfixOp] = [] while True: self.skip_ws() if prefixType in ['expr', 'cast', 'typeid']: @@ -5309,7 +5331,7 @@ class DefinitionParser(BaseParser): # exclusive-or = and ^ # and = equality & # equality = relational ==, != - # relational = shift <, >, <=, >= + # relational = shift <, >, <=, >=, <=> # shift = additive <<, >> # additive = multiplicative +, - # multiplicative = pm *, /, % @@ -5370,7 +5392,7 @@ class DefinitionParser(BaseParser): # logical-or-expression # | logical-or-expression "?" expression ":" assignment-expression # | logical-or-expression assignment-operator initializer-clause - exprs = [] # type: List[Union[ASTExpression, ASTBracedInitList]] + exprs: List[Union[ASTExpression, ASTBracedInitList]] = [] ops = [] orExpr = self._parse_logical_or_expression(inTemplate=inTemplate) exprs.append(orExpr) @@ -5443,7 +5465,7 @@ class DefinitionParser(BaseParser): else: # TODO: add handling of more bracket-like things, and quote handling brackets = {'(': ')', '{': '}', '[': ']', '<': '>'} - symbols = [] # type: List[str] + symbols: List[str] = [] while not self.eof: if (len(symbols) == 0 and self.current_char in end): break @@ -5506,7 +5528,7 @@ class DefinitionParser(BaseParser): if self.skip_string('>'): return ASTTemplateArgs([], False) prevErrors = [] - templateArgs = [] # type: List[Union[ASTType, ASTTemplateArgConstant]] + templateArgs: List[Union[ASTType, ASTTemplateArgConstant]] = [] packExpansion = False while 1: pos = self.pos @@ -5558,8 +5580,8 @@ class DefinitionParser(BaseParser): return ASTTemplateArgs(templateArgs, packExpansion) def _parse_nested_name(self, memberPointer: bool = False) -> ASTNestedName: - names = [] # type: List[ASTNestedNameElement] - templates = [] # type: List[bool] + names: List[ASTNestedNameElement] = [] + templates: List[bool] = [] self.skip_ws() rooted = False @@ -5572,7 +5594,7 @@ class DefinitionParser(BaseParser): else: template = False templates.append(template) - identOrOp = None # type: Union[ASTIdentifier, ASTOperator] + identOrOp: Union[ASTIdentifier, ASTOperator] = None if self.skip_word_and_ws('operator'): identOrOp = self._parse_operator() else: @@ -6075,7 +6097,7 @@ class DefinitionParser(BaseParser): return ASTInitializer(bracedInit) if outer == 'member': - fallbackEnd = [] # type: List[str] + fallbackEnd: List[str] = [] elif outer == 'templateParam': fallbackEnd = [',', '>'] elif outer is None: # function parameter @@ -6161,7 +6183,7 @@ class DefinitionParser(BaseParser): typed=typed) else: paramMode = 'type' - if outer == 'member': # i.e., member + if outer == 'member': named = True elif outer == 'operatorCast': paramMode = 'operatorCast' @@ -6354,7 +6376,7 @@ class DefinitionParser(BaseParser): def _parse_template_parameter_list(self) -> ASTTemplateParams: # only: '<' parameter-list '>' # we assume that 'template' has just been parsed - templateParams = [] # type: List[ASTTemplateParam] + templateParams: List[ASTTemplateParam] = [] self.skip_ws() if not self.skip_string("<"): self.fail("Expected '<' after 'template'") @@ -6477,11 +6499,11 @@ class DefinitionParser(BaseParser): def _parse_template_declaration_prefix(self, objectType: str ) -> Optional[ASTTemplateDeclarationPrefix]: - templates = [] # type: List[Union[ASTTemplateParams, ASTTemplateIntroduction]] + templates: List[Union[ASTTemplateParams, ASTTemplateIntroduction]] = [] while 1: self.skip_ws() # the saved position is only used to provide a better error message - params = None # type: Union[ASTTemplateParams, ASTTemplateIntroduction] + params: Union[ASTTemplateParams, ASTTemplateIntroduction] = None pos = self.pos if self.skip_word("template"): try: @@ -6537,7 +6559,7 @@ class DefinitionParser(BaseParser): msg += str(nestedName) self.warn(msg) - newTemplates = [] # type: List[Union[ASTTemplateParams, ASTTemplateIntroduction]] + newTemplates: List[Union[ASTTemplateParams, ASTTemplateIntroduction]] = [] for i in range(numExtra): newTemplates.append(ASTTemplateParams([])) if templatePrefix and not isMemberInstantiation: @@ -6557,7 +6579,7 @@ class DefinitionParser(BaseParser): templatePrefix = None requiresClause = None trailingRequiresClause = None - declaration = None # type: Any + declaration: Any = None self.skip_ws() if self.match(_visibility_re): @@ -6697,7 +6719,7 @@ class CPPObject(ObjectDescription[ASTDeclaration]): names=('returns', 'return')), ] - option_spec = { + option_spec: OptionSpec = { 'noindexentry': directives.flag, 'tparam-line-spec': directives.flag, } @@ -6856,7 +6878,7 @@ class CPPObject(ObjectDescription[ASTDeclaration]): return super().run() def handle_signature(self, sig: str, signode: desc_signature) -> ASTDeclaration: - parentSymbol = self.env.temp_data['cpp:parent_symbol'] # type: Symbol + parentSymbol: Symbol = self.env.temp_data['cpp:parent_symbol'] parser = DefinitionParser(sig, location=signode, config=self.env.config) try: @@ -6903,10 +6925,10 @@ class CPPObject(ObjectDescription[ASTDeclaration]): return ast def before_content(self) -> None: - lastSymbol = self.env.temp_data['cpp:last_symbol'] # type: Symbol + lastSymbol: Symbol = self.env.temp_data['cpp:last_symbol'] assert lastSymbol self.oldParentSymbol = self.env.temp_data['cpp:parent_symbol'] - self.oldParentKey = self.env.ref_context['cpp:parent_key'] # type: LookupKey + self.oldParentKey: LookupKey = self.env.ref_context['cpp:parent_key'] self.env.temp_data['cpp:parent_symbol'] = lastSymbol self.env.ref_context['cpp:parent_key'] = lastSymbol.get_lookup_key() @@ -6963,13 +6985,13 @@ class CPPNamespaceObject(SphinxDirective): required_arguments = 1 optional_arguments = 0 final_argument_whitespace = True - option_spec = {} # type: Dict + option_spec: OptionSpec = {} def run(self) -> List[Node]: rootSymbol = self.env.domaindata['cpp']['root_symbol'] if self.arguments[0].strip() in ('NULL', '0', 'nullptr'): symbol = rootSymbol - stack = [] # type: List[Symbol] + stack: List[Symbol] = [] else: parser = DefinitionParser(self.arguments[0], location=self.get_source_info(), @@ -6994,7 +7016,7 @@ class CPPNamespacePushObject(SphinxDirective): required_arguments = 1 optional_arguments = 0 final_argument_whitespace = True - option_spec = {} # type: Dict + option_spec: OptionSpec = {} def run(self) -> List[Node]: if self.arguments[0].strip() in ('NULL', '0', 'nullptr'): @@ -7026,7 +7048,7 @@ class CPPNamespacePopObject(SphinxDirective): required_arguments = 0 optional_arguments = 0 final_argument_whitespace = True - option_spec = {} # type: Dict + option_spec: OptionSpec = {} def run(self) -> List[Node]: stack = self.env.temp_data.get('cpp:namespace_stack', None) @@ -7081,7 +7103,7 @@ class AliasTransform(SphinxTransform): maxdepth -= 1 recurse = True - nodes = [] # type: List[Node] + nodes: List[Node] = [] if not skipThis: signode = addnodes.desc_signature('', '') nodes.append(signode) @@ -7089,7 +7111,7 @@ class AliasTransform(SphinxTransform): if recurse: if skipThis: - childContainer = nodes # type: Union[List[Node], addnodes.desc] + childContainer: Union[List[Node], addnodes.desc] = nodes else: content = addnodes.desc_content() desc = addnodes.desc() @@ -7138,15 +7160,15 @@ class AliasTransform(SphinxTransform): node.replace_self(signode) continue - rootSymbol = self.env.domains['cpp'].data['root_symbol'] # type: Symbol - parentSymbol = rootSymbol.direct_lookup(parentKey) # type: Symbol + rootSymbol: Symbol = self.env.domains['cpp'].data['root_symbol'] + parentSymbol: Symbol = rootSymbol.direct_lookup(parentKey) if not parentSymbol: print("Target: ", sig) print("ParentKey: ", parentKey) print(rootSymbol.dump(1)) assert parentSymbol # should be there - symbols = [] # type: List[Symbol] + symbols: List[Symbol] = [] if isShorthand: assert isinstance(ast, ASTNamespace) ns = ast @@ -7203,10 +7225,10 @@ class AliasTransform(SphinxTransform): class CPPAliasObject(ObjectDescription): - option_spec = { + option_spec: OptionSpec = { 'maxdepth': directives.nonnegative_int, 'noroot': directives.flag, - } # type: Dict + } def run(self) -> List[Node]: """ @@ -7225,7 +7247,7 @@ class CPPAliasObject(ObjectDescription): # 'desctype' is a backwards compatible attribute node['objtype'] = node['desctype'] = self.objtype - self.names = [] # type: List[str] + self.names: List[str] = [] aliasOptions = { 'maxdepth': self.options.get('maxdepth', 1), 'noroot': 'noroot' in self.options, @@ -7285,7 +7307,7 @@ class CPPExprRole(SphinxRole): if asCode: # render the expression as inline code self.class_type = 'cpp-expr' - self.node_type = nodes.literal # type: Type[TextElement] + self.node_type: Type[TextElement] = nodes.literal else: # render the expression as inline text self.class_type = 'cpp-texpr' @@ -7466,10 +7488,10 @@ class CPPDomain(Domain): logger.warning('Unparseable C++ cross-reference: %r\n%s', t, ex, location=node) return None, None - parentKey = node.get("cpp:parent_key", None) # type: LookupKey + parentKey: LookupKey = node.get("cpp:parent_key", None) rootSymbol = self.data['root_symbol'] if parentKey: - parentSymbol = rootSymbol.direct_lookup(parentKey) # type: Symbol + parentSymbol: Symbol = rootSymbol.direct_lookup(parentKey) if not parentSymbol: print("Target: ", target) print("ParentKey: ", parentKey.data) @@ -7623,7 +7645,7 @@ class CPPDomain(Domain): target = node.get('reftarget', None) if target is None: return None - parentKey = node.get("cpp:parent_key", None) # type: LookupKey + parentKey: LookupKey = node.get("cpp:parent_key", None) if parentKey is None or len(parentKey.data) <= 0: return None @@ -7644,10 +7666,11 @@ def setup(app: Sphinx) -> Dict[str, Any]: app.add_config_value("cpp_debug_lookup", False, '') app.add_config_value("cpp_debug_show_tree", False, '') - def setDebugFlags(app): + def initStuff(app): Symbol.debug_lookup = app.config.cpp_debug_lookup Symbol.debug_show_tree = app.config.cpp_debug_show_tree - app.connect("builder-inited", setDebugFlags) + app.config.cpp_index_common_prefix.sort(reverse=True) + app.connect("builder-inited", initStuff) return { 'version': 'builtin', |