diff options
Diffstat (limited to 'sphinx/domains/cpp.py')
-rw-r--r-- | sphinx/domains/cpp.py | 182 |
1 files changed, 10 insertions, 172 deletions
diff --git a/sphinx/domains/cpp.py b/sphinx/domains/cpp.py index 8180384da..79b6b9b03 100644 --- a/sphinx/domains/cpp.py +++ b/sphinx/domains/cpp.py @@ -21,7 +21,6 @@ from sphinx import addnodes from sphinx.addnodes import desc_signature, pending_xref from sphinx.application import Sphinx from sphinx.builders import Builder -from sphinx.config import Config from sphinx.directives import ObjectDescription from sphinx.domains import Domain, ObjType from sphinx.environment import BuildEnvironment @@ -32,7 +31,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, verify_description_mode, StringifyTransform, + NoOldIdError, ASTBaseBase, ASTAttribute, verify_description_mode, StringifyTransform, BaseParser, DefinitionError, UnsupportedMultiCharacterCharLiteral, identifier_re, anon_identifier_re, integer_literal_re, octal_literal_re, hex_literal_re, binary_literal_re, float_literal_re, @@ -770,89 +769,6 @@ class ASTNestedName(ASTBase): ################################################################################ -# Attributes -################################################################################ - -class ASTAttribute(ASTBase): - def describe_signature(self, signode: TextElement) -> None: - raise NotImplementedError(repr(self)) - - -class ASTCPPAttribute(ASTAttribute): - def __init__(self, arg: str) -> None: - self.arg = arg - - def _stringify(self, transform: StringifyTransform) -> str: - return "[[" + self.arg + "]]" - - def describe_signature(self, signode: TextElement) -> None: - txt = str(self) - signode.append(nodes.Text(txt, txt)) - - -class ASTGnuAttribute(ASTBase): - def __init__(self, name: str, args: Any) -> None: - self.name = name - self.args = args - - def _stringify(self, transform: StringifyTransform) -> str: - res = [self.name] - if self.args: - res.append('(') - res.append(transform(self.args)) - res.append(')') - return ''.join(res) - - -class ASTGnuAttributeList(ASTAttribute): - def __init__(self, attrs: List[ASTGnuAttribute]) -> None: - self.attrs = attrs - - def _stringify(self, transform: StringifyTransform) -> str: - res = ['__attribute__(('] - first = True - for attr in self.attrs: - if not first: - res.append(', ') - first = False - res.append(transform(attr)) - res.append('))') - return ''.join(res) - - def describe_signature(self, signode: TextElement) -> None: - txt = str(self) - signode.append(nodes.Text(txt, txt)) - - -class ASTIdAttribute(ASTAttribute): - """For simple attributes defined by the user.""" - - def __init__(self, id: str) -> None: - self.id = id - - def _stringify(self, transform: StringifyTransform) -> str: - return self.id - - def describe_signature(self, signode: TextElement) -> None: - signode.append(nodes.Text(self.id, self.id)) - - -class ASTParenAttribute(ASTAttribute): - """For paren attributes defined by the user.""" - - def __init__(self, id: str, arg: str) -> None: - self.id = id - self.arg = arg - - def _stringify(self, transform: StringifyTransform) -> str: - return self.id + '(' + self.arg + ')' - - def describe_signature(self, signode: TextElement) -> None: - txt = str(self) - signode.append(nodes.Text(txt, txt)) - - -################################################################################ # Expressions ################################################################################ @@ -4667,16 +4583,18 @@ class DefinitionParser(BaseParser): _prefix_keys = ('class', 'struct', 'enum', 'union', 'typename') - def __init__(self, definition: str, *, - location: Union[nodes.Node, Tuple[str, int]], - config: "Config") -> None: - super().__init__(definition, location=location) - self.config = config - @property def language(self) -> str: return 'C++' + @property + def id_attributes(self): + return self.config.cpp_id_attributes + + @property + def paren_attributes(self): + return self.config.cpp_paren_attributes + def _parse_string(self) -> str: if self.current_char != '"': return None @@ -4696,85 +4614,6 @@ class DefinitionParser(BaseParser): self.pos += 1 return self.definition[startPos:self.pos] - def _parse_balanced_token_seq(self, end: List[str]) -> str: - # TODO: add handling of string literals and similar - brackets = {'(': ')', '[': ']', '{': '}'} - startPos = self.pos - symbols = [] # type: List[str] - while not self.eof: - if len(symbols) == 0 and self.current_char in end: - break - if self.current_char in brackets.keys(): - symbols.append(brackets[self.current_char]) - elif len(symbols) > 0 and self.current_char == symbols[-1]: - symbols.pop() - elif self.current_char in ")]}": - self.fail("Unexpected '%s' in balanced-token-seq." % self.current_char) - self.pos += 1 - if self.eof: - self.fail("Could not find end of balanced-token-seq starting at %d." - % startPos) - return self.definition[startPos:self.pos] - - def _parse_attribute(self) -> ASTAttribute: - self.skip_ws() - # try C++11 style - startPos = self.pos - if self.skip_string_and_ws('['): - if not self.skip_string('['): - self.pos = startPos - else: - # TODO: actually implement the correct grammar - arg = self._parse_balanced_token_seq(end=[']']) - if not self.skip_string_and_ws(']'): - self.fail("Expected ']' in end of attribute.") - if not self.skip_string_and_ws(']'): - self.fail("Expected ']' in end of attribute after [[...]") - return ASTCPPAttribute(arg) - - # try GNU style - if self.skip_word_and_ws('__attribute__'): - if not self.skip_string_and_ws('('): - self.fail("Expected '(' after '__attribute__'.") - if not self.skip_string_and_ws('('): - self.fail("Expected '(' after '__attribute__('.") - attrs = [] - while 1: - if self.match(identifier_re): - name = self.matched_text - self.skip_ws() - if self.skip_string_and_ws('('): - self.fail('Parameterized GNU style attribute not yet supported.') - attrs.append(ASTGnuAttribute(name, None)) - # TODO: parse arguments for the attribute - if self.skip_string_and_ws(','): - continue - elif self.skip_string_and_ws(')'): - break - else: - self.fail("Expected identifier, ')', or ',' in __attribute__.") - if not self.skip_string_and_ws(')'): - self.fail("Expected ')' after '__attribute__((...)'") - return ASTGnuAttributeList(attrs) - - # try the simple id attributes defined by the user - for id in self.config.cpp_id_attributes: - if self.skip_word_and_ws(id): - return ASTIdAttribute(id) - - # try the paren attributes defined by the user - for id in self.config.cpp_paren_attributes: - if not self.skip_string_and_ws(id): - continue - if not self.skip_string('('): - self.fail("Expected '(' after user-defined paren-attribute.") - arg = self._parse_balanced_token_seq(end=[')']) - if not self.skip_string(')'): - self.fail("Expected ')' to end user-defined paren-attribute.") - return ASTParenAttribute(id, arg) - - return None - def _parse_literal(self) -> ASTLiteral: # -> integer-literal # | character-literal @@ -7200,8 +7039,7 @@ class CPPDomain(Domain): # add parens again for those that could be functions if typ == 'any' or typ == 'func': target += '()' - parser = DefinitionParser(target, location=node, - config=env.config) + parser = DefinitionParser(target, location=node, config=env.config) try: ast, isShorthand = parser.parse_xref_object() except DefinitionError as e: |