diff options
author | Takeshi KOMIYA <i.tkomiya@gmail.com> | 2016-11-07 23:58:40 +0900 |
---|---|---|
committer | Takeshi KOMIYA <i.tkomiya@gmail.com> | 2016-11-16 12:06:22 +0900 |
commit | 8a06a42c311c58dcab1116e06b3afbc2541f49f1 (patch) | |
tree | b149bc5cc24a8881ed28b89551bacc2c6e17f0e1 | |
parent | 2bdaf5c8a0b0ee07bea0724b1ef38420cf219111 (diff) | |
download | sphinx-git-8a06a42c311c58dcab1116e06b3afbc2541f49f1.tar.gz |
Add type-check annotations to sphinx.domains
-rw-r--r-- | sphinx/domains/__init__.py | 62 | ||||
-rw-r--r-- | sphinx/domains/c.py | 35 | ||||
-rw-r--r-- | sphinx/domains/cpp.py | 546 | ||||
-rw-r--r-- | sphinx/domains/javascript.py | 23 | ||||
-rw-r--r-- | sphinx/domains/python.py | 72 | ||||
-rw-r--r-- | sphinx/domains/rst.py | 23 | ||||
-rw-r--r-- | sphinx/domains/std.py | 84 |
7 files changed, 710 insertions, 135 deletions
diff --git a/sphinx/domains/__init__.py b/sphinx/domains/__init__.py index da7e5d9ae..a90ee84aa 100644 --- a/sphinx/domains/__init__.py +++ b/sphinx/domains/__init__.py @@ -17,6 +17,13 @@ from six import iteritems from sphinx.errors import SphinxError from sphinx.locale import _ +if False: + # For type annotation + from typing import Any, Callable, Iterable, Tuple, Type, Union # NOQA + from docutils import nodes # NOQA + from sphinx.builders import Builder # NOQA + from sphinx.environment import BuildEnvironment # NOQA + class ObjType(object): """ @@ -38,9 +45,10 @@ class ObjType(object): } def __init__(self, lname, *roles, **attrs): - self.lname = lname - self.roles = roles - self.attrs = self.known_attrs.copy() + # type: (unicode, Any, Any) -> None + self.lname = lname # type: unicode + self.roles = roles # type: Tuple + self.attrs = self.known_attrs.copy() # type: Dict self.attrs.update(attrs) @@ -59,17 +67,19 @@ class Index(object): domains using :meth:`~sphinx.application.Sphinx.add_index_to_domain()`. """ - name = None - localname = None - shortname = None + name = None # type: unicode + localname = None # type: unicode + shortname = None # type: unicode def __init__(self, domain): + # type: (Domain) -> None if self.name is None or self.localname is None: raise SphinxError('Index subclass %s has no valid name or localname' % self.__class__.__name__) self.domain = domain def generate(self, docnames=None): + # type: (List[unicode]) -> Tuple[List[Tuple[unicode, List[List[Union[unicode, int]]]]], bool] # NOQA """Return entries for the index given by *name*. If *docnames* is given, restrict to entries referring to these docnames. @@ -128,23 +138,26 @@ class Domain(object): #: domain label: longer, more descriptive (used in messages) label = '' #: type (usually directive) name -> ObjType instance - object_types = {} + object_types = {} # type: Dict[unicode, Any] #: directive name -> directive class - directives = {} + directives = {} # type: Dict[unicode, Any] #: role name -> role callable - roles = {} + roles = {} # type: Dict[unicode, Callable] #: a list of Index subclasses - indices = [] + indices = [] # type: List[Type[Index]] #: role name -> a warning message if reference is missing - dangling_warnings = {} + dangling_warnings = {} # type: Dict[unicode, unicode] #: data value for a fresh environment - initial_data = {} + initial_data = {} # type: Dict + #: data value + data = None # type: Dict #: data version, bump this when the format of `self.data` changes data_version = 0 def __init__(self, env): - self.env = env + # type: (BuildEnvironment) -> None + self.env = env # type: BuildEnvironment if self.name not in env.domaindata: assert isinstance(self.initial_data, dict) new_data = copy.deepcopy(self.initial_data) @@ -154,18 +167,19 @@ class Domain(object): self.data = env.domaindata[self.name] if self.data['version'] != self.data_version: raise IOError('data of %r domain out of date' % self.label) - self._role_cache = {} - self._directive_cache = {} - self._role2type = {} - self._type2role = {} + self._role_cache = {} # type: Dict[unicode, Callable] + self._directive_cache = {} # type: Dict[unicode, Callable] + self._role2type = {} # type: Dict[unicode, List[unicode]] + self._type2role = {} # type: Dict[unicode, unicode] for name, obj in iteritems(self.object_types): for rolename in obj.roles: self._role2type.setdefault(rolename, []).append(name) self._type2role[name] = obj.roles[0] if obj.roles else '' - self.objtypes_for_role = self._role2type.get - self.role_for_objtype = self._type2role.get + self.objtypes_for_role = self._role2type.get # type: Callable[[unicode], List[unicode]] # NOQA + self.role_for_objtype = self._type2role.get # type: Callable[[unicode], unicode] def role(self, name): + # type: (unicode) -> Callable """Return a role adapter function that always gives the registered role its full name ('domain:name') as the first argument. """ @@ -183,6 +197,7 @@ class Domain(object): return role_adapter def directive(self, name): + # type: (unicode) -> Callable """Return a directive adapter class that always gives the registered directive its full name ('domain:name') as ``self.name``. """ @@ -193,7 +208,7 @@ class Domain(object): fullname = '%s:%s' % (self.name, name) BaseDirective = self.directives[name] - class DirectiveAdapter(BaseDirective): + class DirectiveAdapter(BaseDirective): # type: ignore def run(self): self.name = fullname return BaseDirective.run(self) @@ -203,10 +218,12 @@ class Domain(object): # methods that should be overwritten def clear_doc(self, docname): + # type: (unicode) -> None """Remove traces of a document in the domain-specific inventories.""" pass def merge_domaindata(self, docnames, otherdata): + # type: (List[unicode], Dict) -> None """Merge in data regarding *docnames* from a different domaindata inventory (coming from a subprocess in parallel builds). """ @@ -215,11 +232,13 @@ class Domain(object): self.__class__) def process_doc(self, env, docname, document): + # type: (BuildEnvironment, unicode, nodes.Node) -> None """Process a document after it is read by the environment.""" pass def resolve_xref(self, env, fromdocname, builder, typ, target, node, contnode): + # type: (BuildEnvironment, unicode, Builder, unicode, unicode, nodes.Node, nodes.Node) -> nodes.Node # NOQA """Resolve the pending_xref *node* with the given *typ* and *target*. This method should return a new node, to replace the xref node, @@ -236,6 +255,7 @@ class Domain(object): pass def resolve_any_xref(self, env, fromdocname, builder, target, node, contnode): + # type: (BuildEnvironment, unicode, Builder, unicode, nodes.Node, nodes.Node) -> List[Tuple[unicode, nodes.Node]] # NOQA """Resolve the pending_xref *node* with the given *target*. The reference comes from an "any" or similar role, which means that we @@ -252,6 +272,7 @@ class Domain(object): raise NotImplementedError def get_objects(self): + # type: () -> Iterable[Tuple[unicode, unicode, unicode, unicode, unicode, int]] """Return an iterable of "object descriptions", which are tuples with five items: @@ -271,6 +292,7 @@ class Domain(object): return [] def get_type_name(self, type, primary=False): + # type: (ObjType, bool) -> unicode """Return full name for given ObjType.""" if primary: return type.lname diff --git a/sphinx/domains/c.py b/sphinx/domains/c.py index 43e869dbc..cf4c23d5d 100644 --- a/sphinx/domains/c.py +++ b/sphinx/domains/c.py @@ -22,6 +22,13 @@ from sphinx.directives import ObjectDescription from sphinx.util.nodes import make_refnode from sphinx.util.docfields import Field, TypedField +if False: + # For type annotation + from typing import Any, Iterator, Tuple # NOQA + from sphinx.application import Sphinx # NOQA + from sphinx.builders import Builder # NOQA + from sphinx.environment import BuildEnvironment # NOQA + # RE to split at word boundaries wsplit_re = re.compile(r'(\W+)') @@ -74,8 +81,9 @@ class CObject(ObjectDescription): )) def _parse_type(self, node, ctype): + # type: (nodes.Node, unicode) -> None # add cross-ref nodes for all words - for part in [_f for _f in wsplit_re.split(ctype) if _f]: + for part in [_f for _f in wsplit_re.split(ctype) if _f]: # type: ignore tnode = nodes.Text(part, part) if part[0] in string.ascii_letters+'_' and \ part not in self.stopwords: @@ -88,11 +96,12 @@ class CObject(ObjectDescription): node += tnode def _parse_arglist(self, arglist): + # type: (unicode) -> Iterator[unicode] while True: - m = c_funcptr_arg_sig_re.match(arglist) + m = c_funcptr_arg_sig_re.match(arglist) # type: ignore if m: yield m.group() - arglist = c_funcptr_arg_sig_re.sub('', arglist) + arglist = c_funcptr_arg_sig_re.sub('', arglist) # type: ignore if ',' in arglist: _, arglist = arglist.split(',', 1) else: @@ -106,11 +115,12 @@ class CObject(ObjectDescription): break def handle_signature(self, sig, signode): + # type: (unicode, addnodes.desc_signature) -> unicode """Transform a C signature into RST nodes.""" # first try the function pointer signature regex, it's more specific - m = c_funcptr_sig_re.match(sig) + m = c_funcptr_sig_re.match(sig) # type: ignore if m is None: - m = c_sig_re.match(sig) + m = c_sig_re.match(sig) # type: ignore if m is None: raise ValueError('no match') rettype, name, arglist, const = m.groups() @@ -151,7 +161,7 @@ class CObject(ObjectDescription): arg = arg.strip() param = addnodes.desc_parameter('', '', noemph=True) try: - m = c_funcptr_arg_sig_re.match(arg) + m = c_funcptr_arg_sig_re.match(arg) # type: ignore if m: self._parse_type(param, m.group(1) + '(') param += nodes.emphasis(m.group(2), m.group(2)) @@ -173,6 +183,7 @@ class CObject(ObjectDescription): return fullname def get_index_text(self, name): + # type: (unicode) -> unicode if self.objtype == 'function': return _('%s (C function)') % name elif self.objtype == 'member': @@ -187,6 +198,7 @@ class CObject(ObjectDescription): return '' def add_target_and_index(self, name, sig, signode): + # type: (unicode, unicode, addnodes.desc_signature) -> None # for C API items we add a prefix since names are usually not qualified # by a module name and so easily clash with e.g. section titles targetname = 'c.' + name @@ -209,6 +221,7 @@ class CObject(ObjectDescription): targetname, '', None)) def before_content(self): + # type: () -> None self.typename_set = False if self.name == 'c:type': if self.names: @@ -216,12 +229,14 @@ class CObject(ObjectDescription): self.typename_set = True def after_content(self): + # type: () -> None if self.typename_set: self.env.ref_context.pop('c:type', None) class CXRefRole(XRefRole): def process_link(self, env, refnode, has_explicit_title, title, target): + # type: (BuildEnvironment, nodes.Node, bool, unicode, unicode) -> Tuple[unicode, unicode] # NOQA if not has_explicit_title: target = target.lstrip('~') # only has a meaning for the title # if the first character is a tilde, don't display the module/class @@ -262,14 +277,16 @@ class CDomain(Domain): } initial_data = { 'objects': {}, # fullname -> docname, objtype - } + } # type: Dict[unicode, Dict[unicode, Tuple[unicode, Any]]] def clear_doc(self, docname): + # type: (unicode) -> None for fullname, (fn, _l) in list(self.data['objects'].items()): if fn == docname: del self.data['objects'][fullname] def merge_domaindata(self, docnames, otherdata): + # type: (List[unicode], Dict) -> None # XXX check duplicates for fullname, (fn, objtype) in otherdata['objects'].items(): if fn in docnames: @@ -277,6 +294,7 @@ class CDomain(Domain): def resolve_xref(self, env, fromdocname, builder, typ, target, node, contnode): + # type: (BuildEnvironment, unicode, Builder, unicode, unicode, nodes.Node, nodes.Node) -> nodes.Node # NOQA # strip pointer asterisk target = target.rstrip(' *') # becase TypedField can generate xrefs @@ -290,6 +308,7 @@ class CDomain(Domain): def resolve_any_xref(self, env, fromdocname, builder, target, node, contnode): + # type: (BuildEnvironment, unicode, Builder, unicode, nodes.Node, nodes.Node) -> List[Tuple[unicode, nodes.Node]] # NOQA # strip pointer asterisk target = target.rstrip(' *') if target not in self.data['objects']: @@ -300,9 +319,11 @@ class CDomain(Domain): contnode, target))] def get_objects(self): + # type: () -> Iterator[Tuple[unicode, unicode, unicode, unicode, unicode, int]] for refname, (docname, type) in list(self.data['objects'].items()): yield (refname, refname, type, docname, 'c.' + refname, 1) def setup(app): + # type: (Sphinx) -> None app.add_domain(CDomain) diff --git a/sphinx/domains/cpp.py b/sphinx/domains/cpp.py index 6c12d6aca..5eeabcb11 100644 --- a/sphinx/domains/cpp.py +++ b/sphinx/domains/cpp.py @@ -13,6 +13,7 @@ import re from copy import deepcopy from six import iteritems, text_type + from docutils import nodes from sphinx import addnodes @@ -25,6 +26,14 @@ from sphinx.util.compat import Directive from sphinx.util.pycompat import UnicodeMixin from sphinx.util.docfields import Field, GroupedField +if False: + # For type annotation + from typing import Any, Iterator, Match, Pattern, Tuple, Union # NOQA + from sphinx.application import Sphinx # NOQA + from sphinx.builders import Builder # NOQA + from sphinx.config import Config # NOQA + from sphinx.environment import BuildEnvironment # NOQA + """ Important note on ids ---------------------------------------------------------------------------- @@ -317,7 +326,7 @@ _id_fundamental_v1 = { 'signed long': 'l', 'unsigned long': 'L', 'bool': 'b' -} +} # type: Dict[unicode, unicode] _id_shorthands_v1 = { 'std::string': 'ss', 'std::ostream': 'os', @@ -325,7 +334,7 @@ _id_shorthands_v1 = { 'std::iostream': 'ios', 'std::vector': 'v', 'std::map': 'm' -} +} # type: Dict[unicode, unicode] _id_operator_v1 = { 'new': 'new-operator', 'new[]': 'new-array-operator', @@ -374,7 +383,7 @@ _id_operator_v1 = { '->': 'pointer-operator', '()': 'call-operator', '[]': 'subscript-operator' -} +} # type: Dict[unicode, unicode] # ------------------------------------------------------------------------------ # Id v2 constants @@ -420,7 +429,7 @@ _id_fundamental_v2 = { 'auto': 'Da', 'decltype(auto)': 'Dc', 'std::nullptr_t': 'Dn' -} +} # type: Dict[unicode, unicode] _id_operator_v2 = { 'new': 'nw', 'new[]': 'na', @@ -469,43 +478,50 @@ _id_operator_v2 = { '->': 'pt', '()': 'cl', '[]': 'ix' -} +} # type: Dict[unicode, unicode] class NoOldIdError(UnicodeMixin, Exception): # Used to avoid implementing unneeded id generation for old id schmes. def __init__(self, description=""): + # type: (unicode) -> None self.description = description def __unicode__(self): + # type: () -> unicode return self.description class DefinitionError(UnicodeMixin, Exception): def __init__(self, description): + # type: (unicode) -> None self.description = description def __unicode__(self): + # type: () -> unicode return self.description class _DuplicateSymbolError(UnicodeMixin, Exception): def __init__(self, symbol, candSymbol): + # type: (Symbol, Symbol) -> None assert symbol assert candSymbol self.symbol = symbol self.candSymbol = candSymbol def __unicode__(self): + # type: () -> unicode return "Internal C++ duplicate symbol error:\n%s" % self.symbol.dump(0) class ASTBase(UnicodeMixin): def __eq__(self, other): + # type: (Any) -> bool if type(self) is not type(other): return False try: - for key, value in iteritems(self.__dict__): + for key, value in iteritems(self.__dict__): # type: ignore if value != getattr(other, key): return False except AttributeError: @@ -513,23 +529,28 @@ class ASTBase(UnicodeMixin): return True def __ne__(self, other): + # type: (Any) -> bool return not self.__eq__(other) - __hash__ = None + __hash__ = None # type: None def clone(self): + # type: () -> ASTBase """Clone a definition expression node.""" return deepcopy(self) def get_id_v1(self): + # type: () -> unicode """Return the v1 id for the node.""" raise NotImplementedError(repr(self)) def get_id_v2(self): + # type: () -> unicode """Return the v2 id for the node.""" raise NotImplementedError(repr(self)) def get_name(self): + # type: () -> unicode """Return the name. Returns either `None` or a node with a name you might call @@ -538,10 +559,12 @@ class ASTBase(UnicodeMixin): raise NotImplementedError(repr(self)) def prefix_nested_name(self, prefix): + # type: (unicode) -> unicode """Prefix a name node (a node returned by :meth:`get_name`).""" raise NotImplementedError(repr(self)) def __unicode__(self): + # type: () -> unicode raise NotImplementedError(repr(self)) def __repr__(self): @@ -549,29 +572,35 @@ class ASTBase(UnicodeMixin): def _verify_description_mode(mode): + # type: (unicode) -> None if mode not in ('lastIsName', 'noneIsName', 'markType', 'param'): raise Exception("Description mode '%s' is invalid." % mode) class ASTCPPAttribute(ASTBase): def __init__(self, arg): + # type: (unicode) -> None self.arg = arg def __unicode__(self): + # type: () -> unicode return "[[" + self.arg + "]]" def describe_signature(self, signode): + # type: (addnodes.desc_signature) -> None txt = text_type(self) signode.append(nodes.Text(txt, txt)) class ASTGnuAttribute(ASTBase): def __init__(self, name, args): + # type: (unicode, Any) -> None self.name = name self.args = args def __unicode__(self): - res = [self.name] + # type: () -> unicode + res = [self.name] # type: List[unicode] if self.args: res.append('(') res.append(text_type(self.args)) @@ -581,10 +610,12 @@ class ASTGnuAttribute(ASTBase): class ASTGnuAttributeList(ASTBase): def __init__(self, attrs): + # type: (List[Any]) -> None self.attrs = attrs def __unicode__(self): - res = ['__attribute__(('] + # type: () -> unicode + res = ['__attribute__(('] # type: List[unicode] first = True for attr in self.attrs: if not first: @@ -595,6 +626,7 @@ class ASTGnuAttributeList(ASTBase): return ''.join(res) def describe_signature(self, signode): + # type: (addnodes.desc_signature) -> None txt = text_type(self) signode.append(nodes.Text(txt, txt)) @@ -603,12 +635,15 @@ class ASTIdAttribute(ASTBase): """For simple attributes defined by the user.""" def __init__(self, id): + # type: (unicode) -> None self.id = id def __unicode__(self): + # type: () -> unicode return self.id def describe_signature(self, signode): + # type: (addnodes.desc_signature) -> None signode.append(nodes.Text(self.id, self.id)) @@ -616,29 +651,35 @@ class ASTParenAttribute(ASTBase): """For paren attributes defined by the user.""" def __init__(self, id, arg): + # type: (unicode, unicode) -> None self.id = id self.arg = arg def __unicode__(self): + # type: () -> unicode return self.id + '(' + self.arg + ')' def describe_signature(self, signode): + # type: (addnodes.desc_signature) -> None txt = text_type(self) signode.append(nodes.Text(txt, txt)) class ASTIdentifier(ASTBase): def __init__(self, identifier): + # type: (unicode) -> None assert identifier is not None self.identifier = identifier def get_id_v1(self): + # type: () -> unicode if self.identifier == 'size_t': return 's' else: return self.identifier def get_id_v2(self): + # type: () -> unicode if self.identifier == "std": return 'St' elif self.identifier[0] == "~": @@ -648,9 +689,11 @@ class ASTIdentifier(ASTBase): return text_type(len(self.identifier)) + self.identifier def __unicode__(self): + # type: () -> unicode return self.identifier def describe_signature(self, signode, mode, env, prefix, symbol): + # type: (addnodes.desc_signature, unicode, BuildEnvironment, unicode, Symbol) -> None _verify_description_mode(mode) if mode == 'markType': targetText = prefix + self.identifier @@ -673,6 +716,7 @@ class ASTIdentifier(ASTBase): class ASTTemplateKeyParamPackIdDefault(ASTBase): def __init__(self, key, identifier, parameterPack, default): + # type: (unicode, Any, bool, Any) -> None assert key if parameterPack: assert default is None @@ -682,9 +726,11 @@ class ASTTemplateKeyParamPackIdDefault(ASTBase): self.default = default def get_identifier(self): + # type: () -> unicode return self.identifier def get_id_v2(self): + # type: () -> unicode # this is not part of the normal name mangling in C++ res = [] if self.parameterPack: @@ -694,7 +740,8 @@ class ASTTemplateKeyParamPackIdDefault(ASTBase): return ''.join(res) def __unicode__(self): - res = [self.key] + # type: () -> unicode + res = [self.key] # type: List[unicode] if self.parameterPack: if self.identifier: res.append(' ') @@ -709,6 +756,7 @@ class ASTTemplateKeyParamPackIdDefault(ASTBase): return ''.join(res) def describe_signature(self, signode, mode, env, symbol): + # type: (addnodes.desc_signature, unicode, BuildEnvironment, Symbol) -> None signode += nodes.Text(self.key) if self.parameterPack: if self.identifier: @@ -725,18 +773,22 @@ class ASTTemplateKeyParamPackIdDefault(ASTBase): class ASTTemplateParamType(ASTBase): def __init__(self, data): + # type: (Any) -> None assert data self.data = data @property def name(self): + # type: () -> ASTNestedName id = self.get_identifier() return ASTNestedName([ASTNestedNameElement(id, None)], rooted=False) def get_identifier(self): + # type: () -> unicode return self.data.get_identifier() def get_id_v2(self, objectType=None, symbol=None): + # type: (unicode, Symbol) -> unicode # this is not part of the normal name mangling in C++ if symbol: # the anchor will be our parent @@ -745,14 +797,17 @@ class ASTTemplateParamType(ASTBase): return self.data.get_id_v2() def __unicode__(self): + # type: () -> unicode return text_type(self.data) def describe_signature(self, signode, mode, env, symbol): + # type: (addnodes.desc_signature, unicode, BuildEnvironment, Symbol) -> None self.data.describe_signature(signode, mode, env, symbol) class ASTTemplateParamTemplateType(ASTBase): def __init__(self, nestedParams, data): + # type: (Any, Any) -> None assert nestedParams assert data self.nestedParams = nestedParams @@ -760,13 +815,16 @@ class ASTTemplateParamTemplateType(ASTBase): @property def name(self): + # type: () -> ASTNestedName id = self.get_identifier() return ASTNestedName([ASTNestedNameElement(id, None)], rooted=False) def get_identifier(self): + # type: () -> unicode return self.data.get_identifier() def get_id_v2(self, objectType=None, symbol=None): + # type: (unicode, Symbol) -> unicode # this is not part of the normal name mangling in C++ if symbol: # the anchor will be our parent @@ -775,9 +833,11 @@ class ASTTemplateParamTemplateType(ASTBase): return self.nestedParams.get_id_v2() + self.data.get_id_v2() def __unicode__(self): + # type: () -> unicode return text_type(self.nestedParams) + text_type(self.data) def describe_signature(self, signode, mode, env, symbol): + # type: (addnodes.desc_signature, unicode, BuildEnvironment, Symbol) -> None self.nestedParams.describe_signature(signode, 'noneIsName', env, symbol) signode += nodes.Text(' ') self.data.describe_signature(signode, mode, env, symbol) @@ -785,15 +845,18 @@ class ASTTemplateParamTemplateType(ASTBase): class ASTTemplateParamNonType(ASTBase): def __init__(self, param): + # type: (Any) -> None assert param self.param = param @property def name(self): + # type: () -> ASTNestedName id = self.get_identifier() return ASTNestedName([ASTNestedNameElement(id, None)], rooted=False) def get_identifier(self): + # type: () -> unicode name = self.param.name if name: assert len(name.names) == 1 @@ -804,6 +867,7 @@ class ASTTemplateParamNonType(ASTBase): return None def get_id_v2(self, objectType=None, symbol=None): + # type: (unicode, Symbol) -> unicode # this is not part of the normal name mangling in C++ if symbol: # the anchor will be our parent @@ -812,18 +876,22 @@ class ASTTemplateParamNonType(ASTBase): return '_' + self.param.get_id_v2() def __unicode__(self): + # type: () -> unicode return text_type(self.param) def describe_signature(self, signode, mode, env, symbol): + # type: (addnodes.desc_signature, unicode, BuildEnvironment, Symbol) -> None self.param.describe_signature(signode, mode, env, symbol) class ASTTemplateParams(ASTBase): def __init__(self, params): + # type: (Any) -> None assert params is not None self.params = params def get_id_v2(self): + # type: () -> unicode res = [] res.append("I") for param in self.params: @@ -832,6 +900,7 @@ class ASTTemplateParams(ASTBase): return ''.join(res) def __unicode__(self): + # type: () -> unicode res = [] res.append(u"template<") res.append(u", ".join(text_type(a) for a in self.params)) @@ -839,6 +908,7 @@ class ASTTemplateParams(ASTBase): return ''.join(res) def describe_signature(self, signode, mode, env, symbol): + # type: (addnodes.desc_signature, unicode, BuildEnvironment, Symbol) -> None signode.sphinx_cpp_tagname = 'templateParams' signode += nodes.Text("template<") first = True @@ -852,13 +922,16 @@ class ASTTemplateParams(ASTBase): class ASTTemplateIntroductionParameter(ASTBase): def __init__(self, identifier, parameterPack): + # type: (Any, Any) -> None self.identifier = identifier self.parameterPack = parameterPack def get_identifier(self): + # type: () -> unicode return self.identifier def get_id_v2(self, objectType=None, symbol=None): + # type: (unicode, Symbol) -> unicode # this is not part of the normal name mangling in C++ if symbol: # the anchor will be our parent @@ -870,6 +943,7 @@ class ASTTemplateIntroductionParameter(ASTBase): return '0' # we need to put something def get_id_v2_as_arg(self): + # type: () -> unicode # used for the implicit requires clause res = self.identifier.get_id_v2() if self.parameterPack: @@ -878,13 +952,15 @@ class ASTTemplateIntroductionParameter(ASTBase): return res def __unicode__(self): - res = [] + # type: () -> unicode + res = [] # type: List[unicode] if self.parameterPack: res.append('...') res.append(text_type(self.identifier)) return ''.join(res) def describe_signature(self, signode, mode, env, symbol): + # type: (addnodes.desc_signature, unicode, BuildEnvironment, Symbol) -> None if self.parameterPack: signode += nodes.Text('...') self.identifier.describe_signature(signode, mode, env, '', symbol) @@ -892,6 +968,7 @@ class ASTTemplateIntroductionParameter(ASTBase): class ASTTemplateIntroduction(ASTBase): def __init__(self, concept, params): + # type: (Any, List[Any]) -> None assert len(params) > 0 self.concept = concept self.params = params @@ -899,6 +976,7 @@ class ASTTemplateIntroduction(ASTBase): # id_v1 does not exist def get_id_v2(self): + # type: () -> unicode # first do the same as a normal template parameter list res = [] res.append("I") @@ -916,6 +994,7 @@ class ASTTemplateIntroduction(ASTBase): return ''.join(res) def __unicode__(self): + # type: () -> unicode res = [] res.append(text_type(self.concept)) res.append('{') @@ -924,6 +1003,7 @@ class ASTTemplateIntroduction(ASTBase): return ''.join(res) def describe_signature(self, signode, mode, env, symbol): + # type: (addnodes.desc_signature, unicode, BuildEnvironment, Symbol) -> None signode.sphinx_cpp_tagname = 'templateIntroduction' self.concept.describe_signature(signode, 'markType', env, symbol) signode += nodes.Text('{') @@ -938,6 +1018,7 @@ class ASTTemplateIntroduction(ASTBase): class ASTTemplateDeclarationPrefix(ASTBase): def __init__(self, templates): + # type: (List[Any]) -> None assert templates is not None assert len(templates) > 0 self.templates = templates @@ -945,6 +1026,7 @@ class ASTTemplateDeclarationPrefix(ASTBase): # id_v1 does not exist def get_id_v2(self): + # type: () -> unicode # this is not part of a normal name mangling system res = [] for t in self.templates: @@ -952,12 +1034,14 @@ class ASTTemplateDeclarationPrefix(ASTBase): return u''.join(res) def __unicode__(self): + # type: () -> unicode res = [] for t in self.templates: res.append(text_type(t)) return u''.join(res) def describe_signature(self, signode, mode, env, symbol): + # type: (addnodes.desc_signature, unicode, BuildEnvironment, Symbol) -> None _verify_description_mode(mode) for t in self.templates: templateNode = addnodes.desc_signature_line() @@ -967,30 +1051,36 @@ class ASTTemplateDeclarationPrefix(ASTBase): class ASTOperatorBuildIn(ASTBase): def __init__(self, op): + # type: (unicode) -> None self.op = op def is_operator(self): + # type: () -> bool return True def get_id_v1(self): + # type: () -> unicode if self.op not in _id_operator_v1: raise Exception('Internal error: Build-in operator "%s" can not ' 'be mapped to an id.' % self.op) return _id_operator_v1[self.op] def get_id_v2(self): + # type: () -> unicode if self.op not in _id_operator_v2: raise Exception('Internal error: Build-in operator "%s" can not ' 'be mapped to an id.' % self.op) return _id_operator_v2[self.op] def __unicode__(self): + # type: () -> unicode if self.op in ('new', 'new[]', 'delete', 'delete[]'): return u'operator ' + self.op else: return u'operator' + self.op def describe_signature(self, signode, mode, env, prefix, symbol): + # type: (addnodes.desc_signature, unicode, BuildEnvironment, unicode, Symbol) -> None _verify_description_mode(mode) identifier = text_type(self) if mode == 'lastIsName': @@ -1001,24 +1091,31 @@ class ASTOperatorBuildIn(ASTBase): class ASTOperatorType(ASTBase): def __init__(self, type): + # type: (Any) -> None self.type = type def is_operator(self): + # type: () -> bool return True def get_id_v1(self): + # type: () -> unicode return u'castto-%s-operator' % self.type.get_id_v1() def get_id_v2(self): + # type: () -> unicode return u'cv' + self.type.get_id_v2() def __unicode__(self): + # type: () -> unicode return u''.join(['operator ', text_type(self.type)]) def get_name_no_template(self): + # type: () -> unicode return text_type(self) def describe_signature(self, signode, mode, env, prefix, symbol): + # type: (addnodes.desc_signature, unicode, BuildEnvironment, unicode, Symbol) -> None _verify_description_mode(mode) identifier = text_type(self) if mode == 'lastIsName': @@ -1029,21 +1126,27 @@ class ASTOperatorType(ASTBase): class ASTOperatorLiteral(ASTBase): def __init__(self, identifier): + # type: (Any) -> None self.identifier = identifier def is_operator(self): + # type: () -> bool return True def get_id_v1(self): + # type: () -> unicode raise NoOldIdError() def get_id_v2(self): + # type: () -> unicode return u'li' + self.identifier.get_id_v2() def __unicode__(self): + # type: () -> unicode return u'operator""' + text_type(self.identifier) def describe_signature(self, signode, mode, env, prefix, symbol): + # type: (addnodes.desc_signature, unicode, BuildEnvironment, unicode, Symbol) -> None _verify_description_mode(mode) identifier = text_type(self) if mode == 'lastIsName': @@ -1054,38 +1157,46 @@ class ASTOperatorLiteral(ASTBase): class ASTTemplateArgConstant(ASTBase): def __init__(self, value): + # type: (Any) -> None self.value = value def __unicode__(self): + # type: () -> unicode return text_type(self.value) def get_id_v1(self): + # type: () -> unicode return text_type(self).replace(u' ', u'-') def get_id_v2(self): + # type: () -> unicode # TODO: doing this properly needs parsing of expressions, let's just # juse it verbatim for now return u'X' + text_type(self) + u'E' def describe_signature(self, signode, mode, env, symbol): + # type: (addnodes.desc_signature, unicode, BuildEnvironment, Symbol) -> None _verify_description_mode(mode) signode += nodes.Text(text_type(self)) class ASTTemplateArgs(ASTBase): def __init__(self, args): + # type: (List[Any]) -> None assert args is not None assert len(args) > 0 self.args = args def get_id_v1(self): - res = [] + # type: () -> unicode + res = [] # type: List[unicode] res.append(':') res.append(u'.'.join(a.get_id_v1() for a in self.args)) res.append(':') return u''.join(res) def get_id_v2(self): + # type: () -> unicode res = [] res.append('I') for a in self.args: @@ -1094,10 +1205,12 @@ class ASTTemplateArgs(ASTBase): return u''.join(res) def __unicode__(self): + # type: () -> unicode res = ', '.join(text_type(a) for a in self.args) return '<' + res + '>' def describe_signature(self, signode, mode, env, symbol): + # type: (addnodes.desc_signature, unicode, BuildEnvironment, Symbol) -> None _verify_description_mode(mode) signode += nodes.Text('<') first = True @@ -1111,31 +1224,37 @@ class ASTTemplateArgs(ASTBase): class ASTNestedNameElement(ASTBase): def __init__(self, identifier, templateArgs): + # type: (Any, Any) -> None self.identifier = identifier self.templateArgs = templateArgs def is_operator(self): + # type: () -> bool return False def get_id_v1(self): + # type: () -> unicode res = self.identifier.get_id_v1() if self.templateArgs: res += self.templateArgs.get_id_v1() return res def get_id_v2(self): + # type: () -> unicode res = self.identifier.get_id_v2() if self.templateArgs: res += self.templateArgs.get_id_v2() return res def __unicode__(self): + # type: () -> unicode res = text_type(self.identifier) if self.templateArgs: res += text_type(self.templateArgs) return res def describe_signature(self, signode, mode, env, prefix, symbol): + # type: (addnodes.desc_signature, unicode, BuildEnvironment, unicode, Symbol) -> None self.identifier.describe_signature(signode, mode, env, prefix, symbol) if self.templateArgs: self.templateArgs.describe_signature(signode, mode, env, symbol) @@ -1143,15 +1262,18 @@ class ASTNestedNameElement(ASTBase): class ASTNestedName(ASTBase): def __init__(self, names, rooted): + # type: (List[Any], bool) -> None assert len(names) > 0 self.names = names self.rooted = rooted @property def name(self): + # type: () -> ASTNestedName return self def num_templates(self): + # type: () -> int count = 0 for n in self.names: if n.is_operator(): @@ -1161,6 +1283,7 @@ class ASTNestedName(ASTBase): return count def get_id_v1(self): + # type: () -> unicode tt = text_type(self) if tt in _id_shorthands_v1: return _id_shorthands_v1[tt] @@ -1168,7 +1291,8 @@ class ASTNestedName(ASTBase): return u'::'.join(n.get_id_v1() for n in self.names) def get_id_v2(self, modifiers=""): - res = [] + # type: (unicode) -> unicode + res = [] # type: List[unicode] if len(self.names) > 1 or len(modifiers) > 0: res.append('N') res.append(modifiers) @@ -1179,7 +1303,8 @@ class ASTNestedName(ASTBase): return u''.join(res) def __unicode__(self): - res = [] + # type: () -> unicode + res = [] # type: List[unicode] if self.rooted: res.append('') for n in self.names: @@ -1187,15 +1312,16 @@ class ASTNestedName(ASTBase): return '::'.join(res) def describe_signature(self, signode, mode, env, symbol): + # type: (addnodes.desc_signature, unicode, BuildEnvironment, Symbol) -> None _verify_description_mode(mode) # just print the name part, with template args, not template params if mode == 'lastIsName': - addname = [] + addname = [] # type: List[unicode] if self.rooted: addname.append('') for n in self.names[:-1]: addname.append(text_type(n)) - addname = '::'.join(addname) + addname = '::'.join(addname) # type: ignore if len(self.names) > 1: addname += '::' signode += addnodes.desc_addname(addname, addname) @@ -1209,7 +1335,7 @@ class ASTNestedName(ASTBase): # 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. - prefix = '' + prefix = '' # type: unicode first = True for name in self.names: if not first: @@ -1217,7 +1343,7 @@ class ASTNestedName(ASTBase): prefix += '::' first = False if name != '': - name.describe_signature(signode, mode, env, prefix, symbol) + name.describe_signature(signode, mode, env, prefix, symbol) # type: ignore prefix += text_type(name) else: raise Exception('Unknown description mode: %s' % mode) @@ -1225,12 +1351,15 @@ class ASTNestedName(ASTBase): class ASTTrailingTypeSpecFundamental(ASTBase): def __init__(self, name): + # type: (unicode) -> None self.name = name def __unicode__(self): + # type: () -> unicode return self.name def get_id_v1(self): + # type: () -> unicode res = [] for a in self.name.split(' '): if a in _id_fundamental_v1: @@ -1240,6 +1369,7 @@ class ASTTrailingTypeSpecFundamental(ASTBase): return u'-'.join(res) def get_id_v2(self): + # type: () -> unicode if self.name not in _id_fundamental_v2: raise Exception( 'Semi-internal error: Fundamental type "%s" can not be mapped ' @@ -1248,26 +1378,32 @@ class ASTTrailingTypeSpecFundamental(ASTBase): return _id_fundamental_v2[self.name] def describe_signature(self, signode, mode, env, symbol): + # type: (addnodes.desc_signature, unicode, BuildEnvironment, Symbol) -> None signode += nodes.Text(text_type(self.name)) class ASTTrailingTypeSpecName(ASTBase): def __init__(self, prefix, nestedName): + # type: (unicode, Any) -> None self.prefix = prefix self.nestedName = nestedName @property def name(self): + # type: () -> Any return self.nestedName def get_id_v1(self): + # type: () -> unicode return self.nestedName.get_id_v1() def get_id_v2(self): + # type: () -> unicode return self.nestedName.get_id_v2() def __unicode__(self): - res = [] + # type: () -> unicode + res = [] # type: List[unicode] if self.prefix: res.append(self.prefix) res.append(' ') @@ -1275,6 +1411,7 @@ class ASTTrailingTypeSpecName(ASTBase): return u''.join(res) def describe_signature(self, signode, mode, env, symbol): + # type: (addnodes.desc_signature, unicode, BuildEnvironment, Symbol) -> None if self.prefix: signode += addnodes.desc_annotation(self.prefix, self.prefix) signode += nodes.Text(' ') @@ -1283,28 +1420,33 @@ class ASTTrailingTypeSpecName(ASTBase): class ASTFunctinoParameter(ASTBase): def __init__(self, arg, ellipsis=False): + # type: (Any, bool) -> None self.arg = arg self.ellipsis = ellipsis def get_id_v1(self): + # type: () -> unicode if self.ellipsis: return 'z' else: return self.arg.get_id_v1() def get_id_v2(self): + # type: () -> unicode if self.ellipsis: return 'z' else: return self.arg.get_id_v2() def __unicode__(self): + # type: () -> unicode if self.ellipsis: return '...' else: return text_type(self.arg) def describe_signature(self, signode, mode, env, symbol): + # type: (addnodes.desc_signature, unicode, BuildEnvironment, Symbol) -> None _verify_description_mode(mode) if self.ellipsis: signode += nodes.Text('...') @@ -1315,6 +1457,7 @@ class ASTFunctinoParameter(ASTBase): class ASTParametersQualifiers(ASTBase): def __init__(self, args, volatile, const, refQual, exceptionSpec, override, final, initializer): + # type: (List[Any], bool, bool, unicode, unicode, bool, bool, unicode) -> None self.args = args self.volatile = volatile self.const = const @@ -1327,6 +1470,7 @@ class ASTParametersQualifiers(ASTBase): # Id v1 ------------------------------------------------------------------ def get_modifiers_id_v1(self): + # type: () -> unicode res = [] if self.volatile: res.append('V') @@ -1339,6 +1483,7 @@ class ASTParametersQualifiers(ASTBase): return u''.join(res) def get_param_id_v1(self): + # type: () -> unicode if len(self.args) == 0: return '' else: @@ -1347,6 +1492,7 @@ class ASTParametersQualifiers(ASTBase): # Id v2 ------------------------------------------------------------------ def get_modifiers_id_v2(self): + # type: () -> unicode res = [] if self.volatile: res.append('V') @@ -1359,13 +1505,15 @@ class ASTParametersQualifiers(ASTBase): return u''.join(res) def get_param_id_v2(self): + # type: () -> unicode if len(self.args) == 0: return 'v' else: return u''.join(a.get_id_v2() for a in self.args) def __unicode__(self): - res = [] + # type: () -> unicode + res = [] # type: List[unicode] res.append('(') first = True for a in self.args: @@ -1394,6 +1542,7 @@ class ASTParametersQualifiers(ASTBase): return u''.join(res) def describe_signature(self, signode, mode, env, symbol): + # type: (addnodes.desc_signature, unicode, BuildEnvironment, Symbol) -> None _verify_description_mode(mode) paramlist = addnodes.desc_parameterlist() for arg in self.args: @@ -1431,6 +1580,7 @@ class ASTParametersQualifiers(ASTBase): class ASTDeclSpecsSimple(ASTBase): def __init__(self, storage, threadLocal, inline, virtual, explicit, constexpr, volatile, const, friend, attrs): + # type: (unicode, bool, bool, bool, bool, bool, bool, bool, bool, List[Any]) -> None self.storage = storage self.threadLocal = threadLocal self.inline = inline @@ -1443,6 +1593,7 @@ class ASTDeclSpecsSimple(ASTBase): self.attrs = attrs def mergeWith(self, other): + # type: (ASTDeclSpecsSimple) -> ASTDeclSpecsSimple if not other: return self return ASTDeclSpecsSimple(self.storage or other.storage, @@ -1457,7 +1608,8 @@ class ASTDeclSpecsSimple(ASTBase): self.attrs + other.attrs) def __unicode__(self): - res = [] + # type: () -> unicode + res = [] # type: List[unicode] res.extend(text_type(attr) for attr in self.attrs) if self.storage: res.append(self.storage) @@ -1480,6 +1632,7 @@ class ASTDeclSpecsSimple(ASTBase): return u' '.join(res) def describe_signature(self, modifiers): + # type: (List[nodes.Node]) -> None def _add(modifiers, text): if len(modifiers) > 0: modifiers.append(nodes.Text(' ')) @@ -1520,9 +1673,11 @@ class ASTDeclSpecs(ASTBase): @property def name(self): + # type: () -> unicode return self.trailingTypeSpec.name def get_id_v1(self): + # type: () -> unicode res = [] res.append(self.trailingTypeSpec.get_id_v1()) if self.allSpecs.volatile: @@ -1532,6 +1687,7 @@ class ASTDeclSpecs(ASTBase): return u''.join(res) def get_id_v2(self): + # type: () -> unicode res = [] if self.leftSpecs.volatile or self.rightSpecs.volatile: res.append('V') @@ -1541,7 +1697,8 @@ class ASTDeclSpecs(ASTBase): return u''.join(res) def __unicode__(self): - res = [] + # type: () -> unicode + res = [] # type: List[unicode] l = text_type(self.leftSpecs) if len(l) > 0: if len(res) > 0: @@ -1559,8 +1716,9 @@ class ASTDeclSpecs(ASTBase): return "".join(res) def describe_signature(self, signode, mode, env, symbol): + # type: (addnodes.desc_signature, unicode, BuildEnvironment, Symbol) -> None _verify_description_mode(mode) - modifiers = [] + modifiers = [] # type: List[nodes.Node] def _add(modifiers, text): if len(modifiers) > 0: @@ -1586,15 +1744,19 @@ class ASTDeclSpecs(ASTBase): class ASTArray(ASTBase): def __init__(self, size): + # type: (unicode) -> None self.size = size def __unicode__(self): + # type: () -> unicode return u''.join(['[', text_type(self.size), ']']) def get_id_v1(self): + # type: () -> unicode return u'A' def get_id_v2(self): + # type: () -> unicode # TODO: this should maybe be done differently return u'A' + text_type(self.size) + u'_' @@ -1605,6 +1767,7 @@ class ASTArray(ASTBase): class ASTDeclaratorPtr(ASTBase): def __init__(self, next, volatile, const): + # type: (Any, bool, bool) -> None assert next self.next = next self.volatile = volatile @@ -1612,14 +1775,17 @@ class ASTDeclaratorPtr(ASTBase): @property def name(self): + # type: () -> unicode return self.next.name def require_space_after_declSpecs(self): + # type: () -> bool # TODO: if has paramPack, then False ? return True def __unicode__(self): - res = ['*'] + # type: () -> unicode + res = ['*'] # type: List[unicode] if self.volatile: res.append('volatile') if self.const: @@ -1635,12 +1801,15 @@ class ASTDeclaratorPtr(ASTBase): # Id v1 ------------------------------------------------------------------ def get_modifiers_id_v1(self): + # type: () -> unicode return self.next.get_modifiers_id_v1() def get_param_id_v1(self): + # type: () -> unicode return self.next.get_param_id_v1() def get_ptr_suffix_id_v1(self): + # type: () -> unicode res = 'P' if self.volatile: res += 'V' @@ -1651,13 +1820,16 @@ class ASTDeclaratorPtr(ASTBase): # Id v2 ------------------------------------------------------------------ def get_modifiers_id_v2(self): + # type: () -> unicode return self.next.get_modifiers_id_v2() def get_param_id_v2(self): + # type: () -> unicode return self.next.get_param_id_v2() def get_ptr_suffix_id_v2(self): - res = [self.next.get_ptr_suffix_id_v2()] + # type: () -> unicode + res = [self.next.get_ptr_suffix_id_v2()] # type: List[unicode] res.append('P') if self.volatile: res.append('V') @@ -1666,8 +1838,9 @@ class ASTDeclaratorPtr(ASTBase): return u''.join(res) def get_type_id_v2(self, returnTypeId): + # type: (unicode) -> unicode # ReturnType *next, so we are part of the return type of 'next - res = ['P'] + res = ['P'] # type: List[unicode] if self.volatile: res.append('V') if self.const: @@ -1678,9 +1851,11 @@ class ASTDeclaratorPtr(ASTBase): # ------------------------------------------------------------------------ def is_function_type(self): + # type: () -> bool return self.next.is_function_type() def describe_signature(self, signode, mode, env, symbol): + # type: (addnodes.desc_signature, unicode, BuildEnvironment, Symbol) -> None _verify_description_mode(mode) signode += nodes.Text("*") @@ -1700,51 +1875,64 @@ class ASTDeclaratorPtr(ASTBase): class ASTDeclaratorRef(ASTBase): def __init__(self, next): + # type: (Any) -> None assert next self.next = next @property def name(self): + # type: () -> unicode return self.next.name def require_space_after_declSpecs(self): + # type: () -> bool return self.next.require_space_after_declSpecs() def __unicode__(self): + # type: () -> unicode return '&' + text_type(self.next) # Id v1 ------------------------------------------------------------------ def get_modifiers_id_v1(self): + # type: () -> unicode return self.next.get_modifiers_id_v1() def get_param_id_v1(self): # only the parameters (if any) + # type: () -> unicode return self.next.get_param_id_v1() def get_ptr_suffix_id_v1(self): + # type: () -> unicode return u'R' + self.next.get_ptr_suffix_id_v1() # Id v2 ------------------------------------------------------------------ def get_modifiers_id_v2(self): + # type: () -> unicode return self.next.get_modifiers_id_v2() def get_param_id_v2(self): # only the parameters (if any) + # type: () -> unicode return self.next.get_param_id_v2() def get_ptr_suffix_id_v2(self): + # type: () -> unicode return self.next.get_ptr_suffix_id_v2() + u'R' def get_type_id_v2(self, returnTypeId): + # type: (unicode) -> unicode # ReturnType &next, so we are part of the return type of 'next return self.next.get_type_id_v2(returnTypeId=u'R' + returnTypeId) # ------------------------------------------------------------------------ def is_function_type(self): + # type: () -> bool return self.next.is_function_type() def describe_signature(self, signode, mode, env, symbol): + # type: (addnodes.desc_signature, unicode, BuildEnvironment, Symbol) -> None _verify_description_mode(mode) signode += nodes.Text("&") self.next.describe_signature(signode, mode, env, symbol) @@ -1752,17 +1940,21 @@ class ASTDeclaratorRef(ASTBase): class ASTDeclaratorParamPack(ASTBase): def __init__(self, next): + # type: (Any) -> None assert next self.next = next @property def name(self): + # type: () -> unicode return self.next.name def require_space_after_declSpecs(self): + # type: () -> bool return False def __unicode__(self): + # type: () -> unicode res = text_type(self.next) if self.next.name: res = ' ' + res @@ -1771,35 +1963,43 @@ class ASTDeclaratorParamPack(ASTBase): # Id v1 ------------------------------------------------------------------ def get_modifiers_id_v1(self): + # type: () -> unicode return self.next.get_modifiers_id_v1() def get_param_id_v1(self): # only the parameters (if any) + # type: () -> unicode return self.next.get_param_id_v1() def get_ptr_suffix_id_v1(self): + # type: () -> unicode return 'Dp' + self.next.get_ptr_suffix_id_v2() # Id v2 ------------------------------------------------------------------ def get_modifiers_id_v2(self): + # type: () -> unicode return self.next.get_modifiers_id_v2() def get_param_id_v2(self): # only the parameters (if any) return self.next.get_param_id_v2() def get_ptr_suffix_id_v2(self): + # type: () -> unicode return self.next.get_ptr_suffix_id_v2() + u'Dp' def get_type_id_v2(self, returnTypeId): + # type: (unicode) -> unicode # ReturnType... next, so we are part of the return type of 'next return self.next.get_type_id_v2(returnTypeId=u'Dp' + returnTypeId) # ------------------------------------------------------------------------ def is_function_type(self): + # type: () -> bool return self.next.is_function_type() def describe_signature(self, signode, mode, env, symbol): + # type: (addnodes.desc_signature, unicode, BuildEnvironment, Symbol) -> None _verify_description_mode(mode) signode += nodes.Text("...") if self.next.name: @@ -1809,6 +2009,7 @@ class ASTDeclaratorParamPack(ASTBase): class ASTDeclaratorMemPtr(ASTBase): def __init__(self, className, const, volatile, next): + # type: (Any, bool, bool, Any) -> None assert className assert next self.className = className @@ -1818,12 +2019,15 @@ class ASTDeclaratorMemPtr(ASTBase): @property def name(self): + # type: () -> unicode return self.next.name def require_space_after_declSpecs(self): + # type: () -> bool return True def __unicode__(self): + # type: () -> unicode res = [] res.append(text_type(self.className)) res.append('::*') @@ -1839,29 +2043,36 @@ class ASTDeclaratorMemPtr(ASTBase): # Id v1 ------------------------------------------------------------------ def get_modifiers_id_v1(self): + # type: () -> unicode raise NoOldIdError() def get_param_id_v1(self): # only the parameters (if any) + # type: () -> unicode raise NoOldIdError() def get_ptr_suffix_id_v1(self): + # type: () -> unicode raise NoOldIdError() # Id v2 ------------------------------------------------------------------ def get_modifiers_id_v2(self): + # type: () -> unicode return self.next.get_modifiers_id_v2() def get_param_id_v2(self): # only the parameters (if any) + # type: () -> unicode return self.next.get_param_id_v2() def get_ptr_suffix_id_v2(self): + # type: () -> unicode raise NotImplementedError() return self.next.get_ptr_suffix_id_v2() + u'Dp' def get_type_id_v2(self, returnTypeId): + # type: (unicode) -> unicode # ReturnType name::* next, so we are part of the return type of next - nextReturnTypeId = '' + nextReturnTypeId = '' # type: unicode if self.volatile: nextReturnTypeId += 'V' if self.const: @@ -1874,9 +2085,11 @@ class ASTDeclaratorMemPtr(ASTBase): # ------------------------------------------------------------------------ def is_function_type(self): + # type: () -> bool return self.next.is_function_type() def describe_signature(self, signode, mode, env, symbol): + # type: (addnodes.desc_signature, unicode, BuildEnvironment, Symbol) -> None _verify_description_mode(mode) self.className.describe_signature(signode, mode, env, symbol) signode += nodes.Text('::*') @@ -1897,6 +2110,7 @@ class ASTDeclaratorMemPtr(ASTBase): class ASTDeclaratorParen(ASTBase): def __init__(self, inner, next): + # type: (Any, Any) -> None assert inner assert next self.inner = inner @@ -1905,13 +2119,16 @@ class ASTDeclaratorParen(ASTBase): @property def name(self): + # type: () -> unicode return self.inner.name def require_space_after_declSpecs(self): + # type: () -> bool return True def __unicode__(self): - res = ['('] + # type: () -> unicode + res = ['('] # type: List[unicode] res.append(text_type(self.inner)) res.append(')') res.append(text_type(self.next)) @@ -1920,12 +2137,15 @@ class ASTDeclaratorParen(ASTBase): # Id v1 ------------------------------------------------------------------ def get_modifiers_id_v1(self): + # type: () -> unicode return self.inner.get_modifiers_id_v1() def get_param_id_v1(self): # only the parameters (if any) + # type: () -> unicode return self.inner.get_param_id_v1() def get_ptr_suffix_id_v1(self): + # type: () -> unicode raise NoOldIdError() # TODO: was this implemented before? return self.next.get_ptr_suffix_id_v2() + \ self.inner.get_ptr_suffix_id_v2() @@ -1933,16 +2153,20 @@ class ASTDeclaratorParen(ASTBase): # Id v2 ------------------------------------------------------------------ def get_modifiers_id_v2(self): + # type: () -> unicode return self.inner.get_modifiers_id_v2() def get_param_id_v2(self): # only the parameters (if any) + # type: () -> unicode return self.inner.get_param_id_v2() def get_ptr_suffix_id_v2(self): + # type: () -> unicode return self.inner.get_ptr_suffix_id_v2() + \ self.next.get_ptr_suffix_id_v2() def get_type_id_v2(self, returnTypeId): + # type: (unicode) -> unicode # ReturnType (inner)next, so 'inner' returns everything outside nextId = self.next.get_type_id_v2(returnTypeId) return self.inner.get_type_id_v2(returnTypeId=nextId) @@ -1950,9 +2174,11 @@ class ASTDeclaratorParen(ASTBase): # ------------------------------------------------------------------------ def is_function_type(self): + # type: () -> bool return self.inner.is_function_type() def describe_signature(self, signode, mode, env, symbol): + # type: (addnodes.desc_signature, unicode, BuildEnvironment, Symbol) -> None _verify_description_mode(mode) signode += nodes.Text('(') self.inner.describe_signature(signode, mode, env, symbol) @@ -1962,17 +2188,20 @@ class ASTDeclaratorParen(ASTBase): class ASTDecleratorNameParamQual(ASTBase): def __init__(self, declId, arrayOps, paramQual): + # type: (Any, List[Any], Any) -> None self.declId = declId self.arrayOps = arrayOps self.paramQual = paramQual @property def name(self): + # type: () -> unicode return self.declId # Id v1 ------------------------------------------------------------------ def get_modifiers_id_v1(self): # only the modifiers for a function, e.g., + # type: () -> unicode # cv-qualifiers if self.paramQual: return self.paramQual.get_modifiers_id_v1() @@ -1980,17 +2209,20 @@ class ASTDecleratorNameParamQual(ASTBase): "This should only be called on a function: %s" % text_type(self)) def get_param_id_v1(self): # only the parameters (if any) + # type: () -> unicode if self.paramQual: return self.paramQual.get_param_id_v1() else: return '' def get_ptr_suffix_id_v1(self): # only the array specifiers + # type: () -> unicode return u''.join(a.get_id_v1() for a in self.arrayOps) # Id v2 ------------------------------------------------------------------ def get_modifiers_id_v2(self): # only the modifiers for a function, e.g., + # type: () -> unicode # cv-qualifiers if self.paramQual: return self.paramQual.get_modifiers_id_v2() @@ -1998,15 +2230,18 @@ class ASTDecleratorNameParamQual(ASTBase): "This should only be called on a function: %s" % text_type(self)) def get_param_id_v2(self): # only the parameters (if any) + # type: () -> unicode if self.paramQual: return self.paramQual.get_param_id_v2() else: return '' def get_ptr_suffix_id_v2(self): # only the array specifiers + # type: () -> unicode return u''.join(a.get_id_v2() for a in self.arrayOps) def get_type_id_v2(self, returnTypeId): + # type: (unicode) -> unicode res = [] # TOOD: can we actually have both array ops and paramQual? res.append(self.get_ptr_suffix_id_v2()) @@ -2023,12 +2258,15 @@ class ASTDecleratorNameParamQual(ASTBase): # ------------------------------------------------------------------------ def require_space_after_declSpecs(self): + # type: () -> bool return self.declId is not None def is_function_type(self): + # type: () -> bool return self.paramQual is not None def __unicode__(self): + # type: () -> unicode res = [] if self.declId: res.append(text_type(self.declId)) @@ -2039,6 +2277,7 @@ class ASTDecleratorNameParamQual(ASTBase): return u''.join(res) def describe_signature(self, signode, mode, env, symbol): + # type: (addnodes.desc_signature, unicode, BuildEnvironment, Symbol) -> None _verify_description_mode(mode) if self.declId: self.declId.describe_signature(signode, mode, env, symbol) @@ -2050,18 +2289,22 @@ class ASTDecleratorNameParamQual(ASTBase): class ASTInitializer(ASTBase): def __init__(self, value): + # type: (unicode) -> None self.value = value def __unicode__(self): + # type: () -> unicode return u''.join([' = ', text_type(self.value)]) def describe_signature(self, signode, mode): + # type: (addnodes.desc_signature, unicode) -> None _verify_description_mode(mode) signode += nodes.Text(text_type(self)) class ASTType(ASTBase): def __init__(self, declSpecs, decl): + # type: (Any, Any) -> None assert declSpecs assert decl self.declSpecs = declSpecs @@ -2069,10 +2312,12 @@ class ASTType(ASTBase): @property def name(self): + # type: () -> unicode name = self.decl.name return name def get_id_v1(self, objectType=None, symbol=None): + # type: (unicode, Symbol) -> unicode res = [] if objectType: # needs the name if objectType == 'function': # also modifiers @@ -2097,6 +2342,7 @@ class ASTType(ASTBase): return u''.join(res) def get_id_v2(self, objectType=None, symbol=None): + # type: (unicode, Symbol) -> unicode res = [] if objectType: # needs the name if objectType == 'function': # also modifiers @@ -2117,6 +2363,7 @@ class ASTType(ASTBase): return u''.join(res) def __unicode__(self): + # type: () -> unicode res = [] declSpecs = text_type(self.declSpecs) res.append(declSpecs) @@ -2126,12 +2373,14 @@ class ASTType(ASTBase): return u''.join(res) def get_type_declaration_prefix(self): + # type: () -> unicode if self.declSpecs.trailingTypeSpec: return 'typedef' else: return 'type' def describe_signature(self, signode, mode, env, symbol): + # type: (addnodes.desc_signature, unicode, BuildEnvironment, Symbol) -> None _verify_description_mode(mode) self.declSpecs.describe_signature(signode, 'markType', env, symbol) if (self.decl.require_space_after_declSpecs() and @@ -2142,14 +2391,17 @@ class ASTType(ASTBase): class ASTTypeWithInit(ASTBase): def __init__(self, type, init): + # type: (Any, Any) -> None self.type = type self.init = init @property def name(self): + # type: () -> unicode return self.type.name def get_id_v1(self, objectType=None, symbol=None): + # type: (unicode, Symbol) -> unicode if objectType == 'member': return symbol.get_full_nested_name().get_id_v1() + u'__' \ + self.type.get_id_v1() @@ -2157,12 +2409,14 @@ class ASTTypeWithInit(ASTBase): return self.type.get_id_v1(objectType) def get_id_v2(self, objectType=None, symbol=None): + # type: (unicode, Symbol) -> unicode if objectType == 'member': return symbol.get_full_nested_name().get_id_v2() else: return self.type.get_id_v2() def __unicode__(self): + # type: () -> unicode res = [] res.append(text_type(self.type)) if self.init: @@ -2170,6 +2424,7 @@ class ASTTypeWithInit(ASTBase): return u''.join(res) def describe_signature(self, signode, mode, env, symbol): + # type: (addnodes.desc_signature, unicode, BuildEnvironment, Symbol) -> None _verify_description_mode(mode) self.type.describe_signature(signode, mode, env, symbol=symbol) if self.init: @@ -2178,16 +2433,20 @@ class ASTTypeWithInit(ASTBase): class ASTTypeUsing(ASTBase): def __init__(self, name, type): + # type: (Any, Any) -> None self.name = name self.type = type def get_id_v1(self, objectType=None, symbol=None): + # type: (unicode, Symbol) -> unicode raise NoOldIdError() def get_id_v2(self, objectType=None, symbol=None): + # type: (unicode, Symbol) -> unicode return symbol.get_full_nested_name().get_id_v2() def __unicode__(self): + # type: () -> unicode res = [] res.append(text_type(self.name)) if self.type: @@ -2196,9 +2455,11 @@ class ASTTypeUsing(ASTBase): return u''.join(res) def get_type_declaration_prefix(self): + # type: () -> unicode return 'using' def describe_signature(self, signode, mode, env, symbol): + # type: (addnodes.desc_signature, unicode, BuildEnvironment, Symbol) -> None _verify_description_mode(mode) self.name.describe_signature(signode, mode, env, symbol=symbol) if self.type: @@ -2208,21 +2469,26 @@ class ASTTypeUsing(ASTBase): class ASTConcept(ASTBase): def __init__(self, nestedName, isFunction, initializer): + # type: (Any, bool, Any) -> None self.nestedName = nestedName self.isFunction = isFunction # otherwise it's a variable concept self.initializer = initializer @property def name(self): + # type: () -> unicode return self.nestedName def get_id_v1(self, objectType=None, symbol=None): + # type: (unicode, Symbol) -> unicode raise NoOldIdError() - def get_id_v2(self, objectType, symbol): + def get_id_v2(self, objectType, symbol): # type: ignore + # type: (unicode, Symbol) -> unicode return symbol.get_full_nested_name().get_id_v2() def __unicode__(self): + # type: () -> unicode res = text_type(self.nestedName) if self.isFunction: res += "()" @@ -2231,6 +2497,7 @@ class ASTConcept(ASTBase): return res def describe_signature(self, signode, mode, env, symbol): + # type: (addnodes.desc_signature, unicode, BuildEnvironment, Symbol) -> None signode += nodes.Text(text_type("bool ")) self.nestedName.describe_signature(signode, mode, env, symbol) if self.isFunction: @@ -2241,13 +2508,15 @@ class ASTConcept(ASTBase): class ASTBaseClass(ASTBase): def __init__(self, name, visibility, virtual, pack): + # type: (Any, unicode, bool, bool) -> None self.name = name self.visibility = visibility self.virtual = virtual self.pack = pack def __unicode__(self): - res = [] + # type: () -> unicode + res = [] # type: List[unicode] if self.visibility != 'private': res.append(self.visibility) res.append(' ') @@ -2259,6 +2528,7 @@ class ASTBaseClass(ASTBase): return u''.join(res) def describe_signature(self, signode, mode, env, symbol): + # type: (addnodes.desc_signature, unicode, BuildEnvironment, Symbol) -> None _verify_description_mode(mode) if self.visibility != 'private': signode += addnodes.desc_annotation(self.visibility, @@ -2274,17 +2544,21 @@ class ASTBaseClass(ASTBase): class ASTClass(ASTBase): def __init__(self, name, final, bases): + # type: (Any, bool, List[Any]) -> None self.name = name self.final = final self.bases = bases - def get_id_v1(self, objectType, symbol): + def get_id_v1(self, objectType, symbol): # type: ignore + # type: (unicode, Symbol) -> unicode return symbol.get_full_nested_name().get_id_v1() - def get_id_v2(self, objectType, symbol): + def get_id_v2(self, objectType, symbol): # type: ignore + # type: (unicode, Symbol) -> unicode return symbol.get_full_nested_name().get_id_v2() def __unicode__(self): + # type: () -> unicode res = [] res.append(text_type(self.name)) if self.final: @@ -2300,6 +2574,7 @@ class ASTClass(ASTBase): return u''.join(res) def describe_signature(self, signode, mode, env, symbol): + # type: (addnodes.desc_signature, unicode, BuildEnvironment, Symbol) -> None _verify_description_mode(mode) self.name.describe_signature(signode, mode, env, symbol=symbol) if self.final: @@ -2315,18 +2590,22 @@ class ASTClass(ASTBase): class ASTEnum(ASTBase): def __init__(self, name, scoped, underlyingType): + # type: (Any, unicode, Any) -> None self.name = name self.scoped = scoped self.underlyingType = underlyingType - def get_id_v1(self, objectType, symbol): + def get_id_v1(self, objectType, symbol): # type: ignore + # type: (unicode, Symbol) -> unicode raise NoOldIdError() - def get_id_v2(self, objectType, symbol): + def get_id_v2(self, objectType, symbol): # type: ignore + # type: (unicode, Symbol) -> unicode return symbol.get_full_nested_name().get_id_v2() def __unicode__(self): - res = [] + # type: () -> unicode + res = [] # type: List[unicode] if self.scoped: res.append(self.scoped) res.append(' ') @@ -2337,6 +2616,7 @@ class ASTEnum(ASTBase): return u''.join(res) def describe_signature(self, signode, mode, env, symbol): + # type: (addnodes.desc_signature, unicode, BuildEnvironment, Symbol) -> None _verify_description_mode(mode) # self.scoped has been done by the CPPEnumObject self.name.describe_signature(signode, mode, env, symbol=symbol) @@ -2348,16 +2628,20 @@ class ASTEnum(ASTBase): class ASTEnumerator(ASTBase): def __init__(self, name, init): + # type: (Any, Any) -> None self.name = name self.init = init - def get_id_v1(self, objectType, symbol): + def get_id_v1(self, objectType, symbol): # type: ignore + # type: (unicode, Symbol) -> unicode raise NoOldIdError() - def get_id_v2(self, objectType, symbol): + def get_id_v2(self, objectType, symbol): # type: ignore + # type: (unicode, Symbol) -> unicode return symbol.get_full_nested_name().get_id_v2() def __unicode__(self): + # type: () -> unicode res = [] res.append(text_type(self.name)) if self.init: @@ -2365,6 +2649,7 @@ class ASTEnumerator(ASTBase): return u''.join(res) def describe_signature(self, signode, mode, env, symbol): + # type: (addnodes.desc_signature, unicode, BuildEnvironment, Symbol) -> None _verify_description_mode(mode) self.name.describe_signature(signode, mode, env, symbol=symbol) if self.init: @@ -2373,16 +2658,18 @@ class ASTEnumerator(ASTBase): class ASTDeclaration(ASTBase): def __init__(self, objectType, visibility, templatePrefix, declaration): + # type: (unicode, unicode, Any, Any) -> None self.objectType = objectType self.visibility = visibility self.templatePrefix = templatePrefix self.declaration = declaration - self.symbol = None + self.symbol = None # type: Symbol # set by CPPObject._add_enumerator_to_parent - self.enumeratorScopedSymbol = None + self.enumeratorScopedSymbol = None # type: Any def clone(self): + # type: () -> ASTDeclaration if self.templatePrefix: templatePrefixClone = self.templatePrefix.clone() else: @@ -2393,9 +2680,11 @@ class ASTDeclaration(ASTBase): @property def name(self): + # type: () -> unicode return self.declaration.name def get_id_v1(self): + # type: () -> unicode if self.templatePrefix: raise NoOldIdError() if self.objectType == 'enumerator' and self.enumeratorScopedSymbol: @@ -2403,6 +2692,7 @@ class ASTDeclaration(ASTBase): return self.declaration.get_id_v1(self.objectType, self.symbol) def get_id_v2(self, prefixed=True): + # type: (bool) -> unicode if self.objectType == 'enumerator' and self.enumeratorScopedSymbol: return self.enumeratorScopedSymbol.declaration.get_id_v2(prefixed) if prefixed: @@ -2415,10 +2705,12 @@ class ASTDeclaration(ASTBase): return u''.join(res) def get_newest_id(self): + # type: () -> unicode return self.get_id_v2() def __unicode__(self): - res = [] + # type: () -> unicode + res = [] # type: List[unicode] if self.visibility and self.visibility != "public": res.append(self.visibility) res.append(u' ') @@ -2428,6 +2720,7 @@ class ASTDeclaration(ASTBase): return u''.join(res) def describe_signature(self, signode, mode, env): + # type: (addnodes.desc_signature, unicode, BuildEnvironment) -> None _verify_description_mode(mode) # The caller of the domain added a desc_signature node. # Always enable multiline: @@ -2459,8 +2752,8 @@ class ASTDeclaration(ASTBase): mainDeclNode += addnodes.desc_annotation('class ', 'class ') elif self.objectType == 'enum': prefix = 'enum ' - if self.scoped: - prefix += self.scoped + if self.scoped: # type: ignore + prefix += self.scoped # type: ignore prefix += ' ' mainDeclNode += addnodes.desc_annotation(prefix, prefix) elif self.objectType == 'enumerator': @@ -2473,12 +2766,14 @@ class ASTDeclaration(ASTBase): class ASTNamespace(ASTBase): def __init__(self, nestedName, templatePrefix): + # type: (Any, Any) -> None self.nestedName = nestedName self.templatePrefix = templatePrefix class Symbol(object): def _assert_invariants(self): + # type: () -> None if not self.parent: # parent == None means global scope, so declaration means a parent assert not self.identifier @@ -2495,6 +2790,7 @@ class Symbol(object): def __init__(self, parent, identifier, templateParams, templateArgs, declaration, docname): + # type: (Any, Any, Any, Any, Any, unicode) -> None self.parent = parent self.identifier = identifier self.templateParams = templateParams # template<templateParams> @@ -2503,7 +2799,7 @@ class Symbol(object): self.docname = docname self._assert_invariants() - self.children = [] + self.children = [] # type: List[Any] if self.parent: self.parent.children.append(self) if self.declaration: @@ -2524,6 +2820,7 @@ class Symbol(object): self._add_symbols(nn, [], decl, docname) def _fill_empty(self, declaration, docname): + # type: (Any, unicode) -> None self._assert_invariants() assert not self.declaration assert not self.docname @@ -2535,6 +2832,7 @@ class Symbol(object): self._assert_invariants() def clear_doc(self, docname): + # type: (unicode) -> None newChildren = [] for sChild in self.children: sChild.clear_doc(docname) @@ -2550,12 +2848,14 @@ class Symbol(object): self.children = newChildren def get_all_symbols(self): + # type: () -> Iterator[Any] yield self for sChild in self.children: for s in sChild.get_all_symbols(): yield s def get_lookup_key(self): + # type: () -> List[Tuple[ASTNestedNameElement, Any]] if not self.parent: # specialise for the root return None @@ -2576,6 +2876,7 @@ class Symbol(object): return key def get_full_nested_name(self): + # type: () -> ASTNestedName names = [] for nne, templateParams in self.get_lookup_key(): names.append(nne) @@ -2584,6 +2885,7 @@ class Symbol(object): def _find_named_symbol(self, identifier, templateParams, templateArgs, operator, templateShorthand, matchSelf): + # type: (Any, Any, Any, Any, Any, bool) -> Symbol assert (identifier is None) != (operator is None) def matches(s): @@ -2624,6 +2926,7 @@ class Symbol(object): return None def _add_symbols(self, nestedName, templateDecls, declaration, docname): + # type: (Any, List[Any], Any, unicode) -> Symbol # This condition should be checked at the parser level. # Each template argument list must have a template parameter list. # But to declare a template there must be an additional template parameter list. @@ -2722,6 +3025,7 @@ class Symbol(object): return symbol def merge_with(self, other, docnames, env): + # type: (Any, List[unicode], BuildEnvironment) -> None assert other is not None for otherChild in other.children: if not otherChild.identifier: @@ -2765,6 +3069,7 @@ class Symbol(object): ourChild.merge_with(otherChild, docnames, env) def add_name(self, nestedName, templatePrefix=None): + # type: (unicode, Any) -> Symbol if templatePrefix: templateDecls = templatePrefix.templates else: @@ -2773,6 +3078,7 @@ class Symbol(object): declaration=None, docname=None) def add_declaration(self, declaration, docname): + # type: (Any, unicode) -> Symbol assert declaration assert docname nestedName = declaration.name @@ -2783,6 +3089,7 @@ class Symbol(object): return self._add_symbols(nestedName, templateDecls, declaration, docname) def find_identifier(self, identifier, matchSelf): + # type: (Any, bool) -> Symbol if matchSelf and self.identifier and self.identifier == identifier: return self for s in self.children: @@ -2791,6 +3098,7 @@ class Symbol(object): return None def direct_lookup(self, key): + # type: (List[Tuple[Any, Any]]) -> Symbol s = self for name, templateParams in key: if name.is_operator(): @@ -2810,6 +3118,7 @@ class Symbol(object): return s def find_name(self, nestedName, templateDecls, templateShorthand, matchSelf): + # type: (Any, Any, Any, bool) -> Symbol # templateShorthand: missing template parameter lists for templates is ok # TODO: unify this with the _add_symbols @@ -2885,7 +3194,8 @@ class Symbol(object): assert False # should have returned in the loop def to_string(self, indent): - res = ['\t'*indent] + # type: (int) -> unicode + res = ['\t'*indent] # type: List[unicode] if not self.parent: res.append('::') else: @@ -2910,6 +3220,7 @@ class Symbol(object): return ''.join(res) def dump(self, indent): + # type: (int) -> unicode res = [self.to_string(indent)] for c in self.children: res.append(c.dump(indent + 1)) @@ -2927,16 +3238,18 @@ class DefinitionParser(object): _prefix_keys = ('class', 'struct', 'enum', 'union', 'typename') def __init__(self, definition, warnEnv, config): + # type: (Any, Any, Config) -> None self.definition = definition.strip() self.pos = 0 self.end = len(self.definition) - self.last_match = None - self._previous_state = (0, None) + self.last_match = None # type: Match + self._previous_state = (0, None) # type: Tuple[int, Match] self.warnEnv = warnEnv self.config = config def _make_multi_error(self, errors, header): + # type: (List[Any], unicode) -> DefinitionError if len(errors) == 1: return DefinitionError(header + '\n' + errors[0][0].description) result = [header, '\n'] @@ -2956,23 +3269,27 @@ class DefinitionParser(object): return DefinitionError(''.join(result)) def status(self, msg): + # type: (unicode) -> unicode # for debugging indicator = '-' * self.pos + '^' print("%s\n%s\n%s" % (msg, self.definition, indicator)) def fail(self, msg): + # type: (unicode) -> None indicator = '-' * self.pos + '^' raise DefinitionError( 'Invalid definition: %s [error at %d]\n %s\n %s' % (msg, self.pos, self.definition, indicator)) def warn(self, msg): + # type: (unicode) -> None if self.warnEnv: self.warnEnv.warn(msg) else: print("Warning: %s" % msg) def match(self, regex): + # type: (Pattern) -> bool match = regex.match(self.definition, self.pos) if match is not None: self._previous_state = (self.pos, self.last_match) @@ -2982,9 +3299,11 @@ class DefinitionParser(object): return False def backout(self): + # type: () -> None self.pos, self.last_match = self._previous_state def skip_string(self, string): + # type: (unicode) -> bool strlen = len(string) if self.definition[self.pos:self.pos + strlen] == string: self.pos += strlen @@ -2992,18 +3311,22 @@ class DefinitionParser(object): return False def skip_word(self, word): + # type: (unicode) -> bool return self.match(re.compile(r'\b%s\b' % re.escape(word))) def skip_ws(self): + # type: (unicode) -> bool return self.match(_whitespace_re) def skip_word_and_ws(self, word): + # type: (unicode) -> bool if self.skip_word(word): self.skip_ws() return True return False def skip_string_and_ws(self, string): + # type: (unicode) -> bool if self.skip_string(string): self.skip_ws() return True @@ -3011,10 +3334,12 @@ class DefinitionParser(object): @property def eof(self): + # type: () -> bool return self.pos >= self.end @property def current_char(self): + # type: () -> unicode try: return self.definition[self.pos] except IndexError: @@ -3022,24 +3347,28 @@ class DefinitionParser(object): @property def matched_text(self): + # type: () -> unicode if self.last_match is not None: return self.last_match.group() def read_rest(self): + # type: () -> unicode rv = self.definition[self.pos:] self.pos = self.end return rv def assert_end(self): + # type: () -> None self.skip_ws() if not self.eof: self.fail('Expected end of definition.') def _parse_balanced_token_seq(self, end): + # type: (List[unicode]) -> unicode # TODO: add handling of string literals and similar - brackets = {'(': ')', '[': ']', '{': '}'} + brackets = {'(': ')', '[': ']', '{': '}'} # type: Dict[unicode, unicode] startPos = self.pos - symbols = [] + symbols = [] # type: List[unicode] while not self.eof: if len(symbols) == 0 and self.current_char in end: break @@ -3056,6 +3385,7 @@ class DefinitionParser(object): return self.definition[startPos:self.pos] def _parse_attribute(self): + # type: () -> Any self.skip_ws() # try C++11 style startPos = self.pos @@ -3115,6 +3445,7 @@ class DefinitionParser(object): return None def _parse_expression(self, end): + # type: (List[unicode]) -> unicode # Stupidly "parse" an expression. # 'end' should be a list of characters which ends the expression. assert end @@ -3124,8 +3455,8 @@ class DefinitionParser(object): value = self.matched_text else: # TODO: add handling of more bracket-like things, and quote handling - brackets = {'(': ')', '[': ']'} - symbols = [] + brackets = {'(': ')', '[': ']'} # type: Dict[unicode, unicode] + symbols = [] # type: List[unicode] while not self.eof: if (len(symbols) == 0 and self.current_char in end): break @@ -3141,6 +3472,7 @@ class DefinitionParser(object): return value.strip() def _parse_operator(self): + # type: () -> Any self.skip_ws() # adapted from the old code # thank god, a regular operator definition @@ -3173,11 +3505,12 @@ class DefinitionParser(object): return ASTOperatorType(type) def _parse_template_argument_list(self): + # type: () -> ASTTemplateArgs self.skip_ws() if not self.skip_string('<'): return None prevErrors = [] - templateArgs = [] + templateArgs = [] # type: List while 1: pos = self.pos parsedComma = False @@ -3216,6 +3549,7 @@ class DefinitionParser(object): return ASTTemplateArgs(templateArgs) def _parse_nested_name(self, memberPointer=False): + # type: (bool) -> ASTNestedName names = [] self.skip_ws() @@ -3240,7 +3574,7 @@ class DefinitionParser(object): self.fail("Expected identifier in nested name, " "got keyword: %s" % identifier) templateArgs = self._parse_template_argument_list() - identifier = ASTIdentifier(identifier) + identifier = ASTIdentifier(identifier) # type: ignore names.append(ASTNestedNameElement(identifier, templateArgs)) self.skip_ws() @@ -3251,6 +3585,7 @@ class DefinitionParser(object): return ASTNestedName(names, rooted) def _parse_trailing_type_spec(self): + # type: () -> Any # fundemental types self.skip_ws() for t in self._simple_fundemental_types: @@ -3296,6 +3631,7 @@ class DefinitionParser(object): return ASTTrailingTypeSpecName(prefix, nestedName) def _parse_parameters_and_qualifiers(self, paramMode): + # type: (unicode) -> ASTParametersQualifiers self.skip_ws() if not self.skip_string('('): if paramMode == 'function': @@ -3385,6 +3721,7 @@ class DefinitionParser(object): initializer) def _parse_decl_specs_simple(self, outer, typed): + # type: (unicode, bool) -> ASTDeclSpecsSimple """Just parse the simple ones.""" storage = None threadLocal = None @@ -3459,6 +3796,7 @@ class DefinitionParser(object): friend, attrs) def _parse_decl_specs(self, outer, typed=True): + # type: (unicode, bool) -> ASTDeclSpecs if outer: if outer not in ('type', 'member', 'function', 'templateParam'): raise Exception('Internal error, unknown outer "%s".' % outer) @@ -3486,6 +3824,7 @@ class DefinitionParser(object): return ASTDeclSpecs(outer, leftSpecs, rightSpecs, trailing) def _parse_declarator_name_param_qual(self, named, paramMode, typed): + # type: (Union[bool, unicode], unicode, bool) -> ASTDecleratorNameParamQual # now we should parse the name, and then suffixes if named == 'maybe': pos = self.pos @@ -3525,6 +3864,7 @@ class DefinitionParser(object): paramQual=paramQual) def _parse_declerator(self, named, paramMode, typed=True): + # type: (Union[bool, unicode], unicode, bool) -> Any # 'typed' here means 'parse return type stuff' if paramMode not in ('type', 'function', 'operatorCast'): raise Exception( @@ -3625,13 +3965,14 @@ class DefinitionParser(object): raise self._make_multi_error(prevErrors, header) def _parse_initializer(self, outer=None): + # type: (unicode) -> ASTInitializer self.skip_ws() # TODO: support paren and brace initialization for memberObject if not self.skip_string('='): return None else: if outer == 'member': - value = self.read_rest().strip() + value = self.read_rest().strip() # type: unicode elif outer == 'templateParam': value = self._parse_expression(end=[',', '>']) elif outer is None: # function parameter @@ -3642,6 +3983,7 @@ class DefinitionParser(object): return ASTInitializer(value) def _parse_type(self, named, outer=None): + # type: (Union[bool, unicode], unicode) -> ASTType """ named=False|'maybe'|True: 'maybe' is e.g., for function objects which doesn't need to name the arguments @@ -3725,6 +4067,7 @@ class DefinitionParser(object): return ASTType(declSpecs, decl) def _parse_type_with_init(self, named, outer): + # type: (Union[bool, unicode], unicode) -> ASTTypeWithInit if outer: assert outer in ('type', 'member', 'function', 'templateParam') type = self._parse_type(outer=outer, named=named) @@ -3732,6 +4075,7 @@ class DefinitionParser(object): return ASTTypeWithInit(type, init) def _parse_type_using(self): + # type: () -> ASTTypeUsing name = self._parse_nested_name() self.skip_ws() if not self.skip_string('='): @@ -3740,6 +4084,7 @@ class DefinitionParser(object): return ASTTypeUsing(name, type) def _parse_concept(self): + # type: () -> ASTConcept nestedName = self._parse_nested_name() isFunction = False @@ -3757,6 +4102,7 @@ class DefinitionParser(object): return ASTConcept(nestedName, isFunction, initializer) def _parse_class(self): + # type: () -> ASTClass name = self._parse_nested_name() self.skip_ws() final = self.skip_word_and_ws('final') @@ -3765,7 +4111,7 @@ class DefinitionParser(object): if self.skip_string(':'): while 1: self.skip_ws() - visibility = 'private' + visibility = 'private' # type: unicode virtual = False pack = False if self.skip_word_and_ws('virtual'): @@ -3787,7 +4133,8 @@ class DefinitionParser(object): return ASTClass(name, final, bases) def _parse_enum(self): - scoped = None # is set by CPPEnumObject + # type: () -> ASTEnum + scoped = None # type: unicode # is set by CPPEnumObject self.skip_ws() name = self._parse_nested_name() self.skip_ws() @@ -3797,6 +4144,7 @@ class DefinitionParser(object): return ASTEnum(name, scoped, underlyingType) def _parse_enumerator(self): + # type: () -> ASTEnumerator name = self._parse_nested_name() self.skip_ws() init = None @@ -3806,9 +4154,10 @@ class DefinitionParser(object): return ASTEnumerator(name, init) def _parse_template_parameter_list(self): + # type: () -> ASTTemplateParams # only: '<' parameter-list '>' # we assume that 'template' has just been parsed - templateParams = [] + templateParams = [] # type: List self.skip_ws() if not self.skip_string("<"): self.fail("Expected '<' after 'template'") @@ -3847,7 +4196,7 @@ class DefinitionParser(object): parameterPack, default) if nestedParams: # template type - param = ASTTemplateParamTemplateType(nestedParams, data) + param = ASTTemplateParamTemplateType(nestedParams, data) # type: Any else: # type param = ASTTemplateParamType(data) @@ -3875,6 +4224,7 @@ class DefinitionParser(object): raise self._make_multi_error(prevErrors, header) def _parse_template_introduction(self): + # type: () -> ASTTemplateIntroduction pos = self.pos try: concept = self._parse_nested_name() @@ -3899,7 +4249,7 @@ class DefinitionParser(object): if identifier in _keywords: self.fail("Expected identifier in template introduction list, " "got keyword: %s" % identifier) - identifier = ASTIdentifier(identifier) + identifier = ASTIdentifier(identifier) # type: ignore params.append(ASTTemplateIntroductionParameter(identifier, parameterPack)) self.skip_ws() @@ -3913,13 +4263,14 @@ class DefinitionParser(object): return ASTTemplateIntroduction(concept, params) def _parse_template_declaration_prefix(self, objectType): - templates = [] + # type: (unicode) -> ASTTemplateDeclarationPrefix + templates = [] # type: List while 1: self.skip_ws() # the saved position is only used to provide a better error message pos = self.pos if self.skip_word("template"): - params = self._parse_template_parameter_list() + params = self._parse_template_parameter_list() # type: Any else: params = self._parse_template_introduction() if not params: @@ -3937,6 +4288,7 @@ class DefinitionParser(object): def _check_template_consistency(self, nestedName, templatePrefix, fullSpecShorthand): + # type: (Any, Any, bool) -> ASTTemplateDeclarationPrefix numArgs = nestedName.num_templates() if not templatePrefix: numParams = 0 @@ -3952,7 +4304,7 @@ class DefinitionParser(object): msg = "Too many template argument lists compared to parameter" \ " lists. Argument lists: %d, Parameter lists: %d," \ " Extra empty parameters lists prepended: %d." \ - % (numArgs, numParams, numExtra) + % (numArgs, numParams, numExtra) # type: unicode msg += " Declaration:\n\t" if templatePrefix: msg += "%s\n\t" % text_type(templatePrefix) @@ -3968,12 +4320,13 @@ class DefinitionParser(object): return templatePrefix def parse_declaration(self, objectType): + # type: (unicode) -> ASTDeclaration if objectType not in ('type', 'concept', 'member', 'function', 'class', 'enum', 'enumerator'): raise Exception('Internal error, unknown objectType "%s".' % objectType) visibility = None templatePrefix = None - declaration = None + declaration = None # type: Any self.skip_ws() if self.match(_visibility_re): @@ -4021,6 +4374,7 @@ class DefinitionParser(object): templatePrefix, declaration) def parse_namespace_object(self): + # type: () -> ASTNamespace templatePrefix = self._parse_template_declaration_prefix(objectType="namespace") name = self._parse_nested_name() templatePrefix = self._check_template_consistency(name, templatePrefix, @@ -4030,6 +4384,7 @@ class DefinitionParser(object): return res def parse_xref_object(self): + # type: () -> ASTNamespace templatePrefix = self._parse_template_declaration_prefix(objectType="xref") name = self._parse_nested_name() templatePrefix = self._check_template_consistency(name, templatePrefix, @@ -4040,6 +4395,7 @@ class DefinitionParser(object): def _make_phony_error_name(): + # type: () -> ASTNestedName nne = ASTNestedNameElement(ASTIdentifier("PhonyNameDueToError"), None) return ASTNestedName([nne], rooted=False) @@ -4062,9 +4418,11 @@ class CPPObject(ObjectDescription): ] def warn(self, msg): + # type: (unicode) -> None self.state_machine.reporter.warning(msg, line=self.lineno) def _add_enumerator_to_parent(self, ast): + # type: (Any) -> None assert ast.objectType == 'enumerator' # find the parent, if it exists && is an enum # && it's unscoped, @@ -4106,6 +4464,7 @@ class CPPObject(ObjectDescription): docname=self.env.docname) def add_target_and_index(self, ast, sig, signode): + # type: (Any, unicode, addnodes.desc_signature) -> None # general note: name must be lstrip(':')'ed, to remove "::" try: id_v1 = ast.get_id_v1() @@ -4152,12 +4511,15 @@ class CPPObject(ObjectDescription): self.state.document.note_explicit_target(signode) def parse_definition(self, parser): + # type: (Any) -> Any raise NotImplementedError() def describe_signature(self, signode, ast, parentScope): + # type: (addnodes.desc_signature, Any, Any) -> None raise NotImplementedError() def handle_signature(self, sig, signode): + # type: (unicode, addnodes.desc_signature) -> Any if 'cpp:parent_symbol' not in self.env.ref_context: root = self.env.domaindata['cpp']['root_symbol'] self.env.ref_context['cpp:parent_symbol'] = root @@ -4191,75 +4553,94 @@ class CPPObject(ObjectDescription): return ast def before_content(self): + # type: () -> None lastSymbol = self.env.ref_context['cpp:last_symbol'] assert lastSymbol self.oldParentSymbol = self.env.ref_context['cpp:parent_symbol'] self.env.ref_context['cpp:parent_symbol'] = lastSymbol def after_content(self): + # type: () -> None self.env.ref_context['cpp:parent_symbol'] = self.oldParentSymbol class CPPTypeObject(CPPObject): def get_index_text(self, name): + # type: (unicode) -> unicode return _('%s (C++ type)') % name def parse_definition(self, parser): + # type: (Any) -> Any return parser.parse_declaration("type") - def describe_signature(self, signode, ast): + def describe_signature(self, signode, ast): # type: ignore + # type: (addnodes.desc_signature, Any) -> None ast.describe_signature(signode, 'lastIsName', self.env) class CPPConceptObject(CPPObject): def get_index_text(self, name): + # type: (unicode) -> unicode return _('%s (C++ concept)') % name def parse_definition(self, parser): + # type: (Any) -> Any return parser.parse_declaration("concept") - def describe_signature(self, signode, ast): + def describe_signature(self, signode, ast): # type: ignore + # type: (addnodes.desc_signature, Any) -> None ast.describe_signature(signode, 'lastIsName', self.env) class CPPMemberObject(CPPObject): def get_index_text(self, name): + # type: (unicode) -> unicode return _('%s (C++ member)') % name def parse_definition(self, parser): + # type: (Any) -> Any return parser.parse_declaration("member") - def describe_signature(self, signode, ast): + def describe_signature(self, signode, ast): # type: ignore + # type: (addnodes.desc_signature, Any) -> None ast.describe_signature(signode, 'lastIsName', self.env) class CPPFunctionObject(CPPObject): def get_index_text(self, name): + # type: (unicode) -> unicode return _('%s (C++ function)') % name def parse_definition(self, parser): + # type: (Any) -> Any return parser.parse_declaration("function") - def describe_signature(self, signode, ast): + def describe_signature(self, signode, ast): # type: ignore + # type: (addnodes.desc_signature, Any) -> None ast.describe_signature(signode, 'lastIsName', self.env) class CPPClassObject(CPPObject): def get_index_text(self, name): + # type: (unicode) -> unicode return _('%s (C++ class)') % name def parse_definition(self, parser): + # type: (Any) -> Any return parser.parse_declaration("class") - def describe_signature(self, signode, ast): + def describe_signature(self, signode, ast): # type: ignore + # type: (addnodes.desc_signature, Any) -> None ast.describe_signature(signode, 'lastIsName', self.env) class CPPEnumObject(CPPObject): def get_index_text(self, name): + # type: (unicode) -> unicode return _('%s (C++ enum)') % name def parse_definition(self, parser): + # type: (Any) -> Any ast = parser.parse_declaration("enum") # self.objtype is set by ObjectDescription in run() if self.objtype == "enum": @@ -4272,18 +4653,22 @@ class CPPEnumObject(CPPObject): assert False return ast - def describe_signature(self, signode, ast): + def describe_signature(self, signode, ast): # type: ignore + # type: (addnodes.desc_signature, Any) -> None ast.describe_signature(signode, 'lastIsName', self.env) class CPPEnumeratorObject(CPPObject): def get_index_text(self, name): + # type: (unicode) -> unicode return _('%s (C++ enumerator)') % name def parse_definition(self, parser): + # type: (Any) -> Any return parser.parse_declaration("enumerator") - def describe_signature(self, signode, ast): + def describe_signature(self, signode, ast): # type: ignore + # type: (addnodes.desc_signature, Any) -> None ast.describe_signature(signode, 'lastIsName', self.env) @@ -4297,17 +4682,19 @@ class CPPNamespaceObject(Directive): required_arguments = 1 optional_arguments = 0 final_argument_whitespace = True - option_spec = {} + option_spec = {} # type: Dict def warn(self, msg): + # type: (unicode) -> None self.state_machine.reporter.warning(msg, line=self.lineno) def run(self): + # type: () -> List[nodes.Node] env = self.state.document.settings.env rootSymbol = env.domaindata['cpp']['root_symbol'] if self.arguments[0].strip() in ('NULL', '0', 'nullptr'): symbol = rootSymbol - stack = [] + stack = [] # type: List[Symbol] else: parser = DefinitionParser(self.arguments[0], self, env.config) try: @@ -4329,12 +4716,14 @@ class CPPNamespacePushObject(Directive): required_arguments = 1 optional_arguments = 0 final_argument_whitespace = True - option_spec = {} + option_spec = {} # type: Dict def warn(self, msg): + # type: (unicode) -> None self.state_machine.reporter.warning(msg, line=self.lineno) def run(self): + # type: () -> List[nodes.Node] env = self.state.document.settings.env if self.arguments[0].strip() in ('NULL', '0', 'nullptr'): return @@ -4362,12 +4751,14 @@ class CPPNamespacePopObject(Directive): required_arguments = 0 optional_arguments = 0 final_argument_whitespace = True - option_spec = {} + option_spec = {} # type: Dict def warn(self, msg): + # type: (unicode) -> None self.state_machine.reporter.warning(msg, line=self.lineno) def run(self): + # type: () -> List[nodes.Node] env = self.state.document.settings.env stack = env.temp_data.get('cpp:namespace_stack', None) if not stack or len(stack) == 0: @@ -4386,6 +4777,7 @@ class CPPNamespacePopObject(Directive): class CPPXRefRole(XRefRole): def process_link(self, env, refnode, has_explicit_title, title, target): + # type: (BuildEnvironment, nodes.Node, bool, unicode, unicode) -> Tuple[unicode, unicode] # NOQA parent = env.ref_context.get('cpp:parent_symbol', None) if parent: refnode['cpp:parent_key'] = parent.get_lookup_key() @@ -4455,6 +4847,7 @@ class CPPDomain(Domain): } def clear_doc(self, docname): + # type: (unicode) -> None rootSymbol = self.data['root_symbol'] rootSymbol.clear_doc(docname) for name, nDocname in list(self.data['names'].items()): @@ -4462,12 +4855,14 @@ class CPPDomain(Domain): del self.data['names'][name] def process_doc(self, env, docname, document): + # type: (BuildEnvironment, unicode, nodes.Node) -> None # just for debugging # print(docname) # print(self.data['root_symbol'].dump(0)) pass def merge_domaindata(self, docnames, otherdata): + # type: (List[unicode], Dict) -> None self.data['root_symbol'].merge_with(otherdata['root_symbol'], docnames, self.env) ourNames = self.data['names'] @@ -4483,6 +4878,7 @@ class CPPDomain(Domain): def _resolve_xref_inner(self, env, fromdocname, builder, typ, target, node, contnode, emitWarnings=True): + # type: (BuildEnvironment, unicode, Builder, unicode, unicode, nodes.Node, nodes.Node, bool) -> nodes.Node # NOQA class Warner(object): def warn(self, msg): if emitWarnings: @@ -4562,11 +4958,13 @@ class CPPDomain(Domain): def resolve_xref(self, env, fromdocname, builder, typ, target, node, contnode): + # type: (BuildEnvironment, unicode, Builder, unicode, unicode, nodes.Node, nodes.Node) -> nodes.Node # NOQA return self._resolve_xref_inner(env, fromdocname, builder, typ, target, node, contnode)[0] def resolve_any_xref(self, env, fromdocname, builder, target, node, contnode): + # type: (BuildEnvironment, unicode, Builder, unicode, nodes.Node, nodes.Node) -> List[Tuple[unicode, nodes.Node]] # NOQA node, objtype = self._resolve_xref_inner(env, fromdocname, builder, 'any', target, node, contnode, emitWarnings=False) @@ -4575,6 +4973,7 @@ class CPPDomain(Domain): return [] def get_objects(self): + # type: () -> Iterator[Tuple[unicode, unicode, unicode, unicode, unicode, int]] rootSymbol = self.data['root_symbol'] for symbol in rootSymbol.get_all_symbols(): if symbol.declaration is None: @@ -4588,6 +4987,7 @@ class CPPDomain(Domain): def setup(app): + # type: (Sphinx) -> None app.add_domain(CPPDomain) app.add_config_value("cpp_index_common_prefix", [], 'env') app.add_config_value("cpp_id_attributes", [], 'env') diff --git a/sphinx/domains/javascript.py b/sphinx/domains/javascript.py index ade6e4224..5c2eead01 100644 --- a/sphinx/domains/javascript.py +++ b/sphinx/domains/javascript.py @@ -18,6 +18,14 @@ from sphinx.domains.python import _pseudo_parse_arglist from sphinx.util.nodes import make_refnode from sphinx.util.docfields import Field, GroupedField, TypedField +if False: + # For type annotation + from typing import Iterator, Tuple # NOQA + from docutils import nodes # NOQA + from sphinx.application import Sphinx # NOQA + from sphinx.builders import Builder # NOQA + from sphinx.environment import BuildEnvironment # NOQA + class JSObject(ObjectDescription): """ @@ -28,9 +36,10 @@ class JSObject(ObjectDescription): has_arguments = False #: what is displayed right before the documentation entry - display_prefix = None + display_prefix = None # type: unicode def handle_signature(self, sig, signode): + # type: (unicode, addnodes.desc_signature) -> Tuple[unicode, unicode] sig = sig.strip() if '(' in sig and sig[-1:] == ')': prefix, arglist = sig.split('(', 1) @@ -76,6 +85,7 @@ class JSObject(ObjectDescription): return fullname, nameprefix def add_target_and_index(self, name_obj, sig, signode): + # type: (Tuple[unicode, unicode], unicode, addnodes.desc_signature) -> None objectname = self.options.get( 'object', self.env.ref_context.get('js:object')) fullname = name_obj[0] @@ -100,6 +110,7 @@ class JSObject(ObjectDescription): '', None)) def get_index_text(self, objectname, name_obj): + # type: (unicode, Tuple[unicode, unicode]) -> unicode name, obj = name_obj if self.objtype == 'function': if not obj: @@ -139,6 +150,7 @@ class JSConstructor(JSCallable): class JSXRefRole(XRefRole): def process_link(self, env, refnode, has_explicit_title, title, target): + # type: (BuildEnvironment, nodes.Node, bool, unicode, unicode) -> Tuple[unicode, unicode] # NOQA # basically what sphinx.domains.python.PyXRefRole does refnode['js:object'] = env.ref_context.get('js:object') if not has_explicit_title: @@ -180,20 +192,23 @@ class JavaScriptDomain(Domain): } initial_data = { 'objects': {}, # fullname -> docname, objtype - } + } # type: Dict[unicode, Dict[unicode, Tuple[unicode, unicode]]] def clear_doc(self, docname): + # type: (unicode) -> None for fullname, (fn, _l) in list(self.data['objects'].items()): if fn == docname: del self.data['objects'][fullname] def merge_domaindata(self, docnames, otherdata): + # type: (List[unicode], Dict) -> None # XXX check duplicates for fullname, (fn, objtype) in otherdata['objects'].items(): if fn in docnames: self.data['objects'][fullname] = (fn, objtype) def find_obj(self, env, obj, name, typ, searchorder=0): + # type: (BuildEnvironment, unicode, unicode, unicode, int) -> Tuple[unicode, Tuple[unicode, unicode]] # NOQA if name[-2:] == '()': name = name[:-2] objects = self.data['objects'] @@ -212,6 +227,7 @@ class JavaScriptDomain(Domain): def resolve_xref(self, env, fromdocname, builder, typ, target, node, contnode): + # type: (BuildEnvironment, unicode, Builder, unicode, unicode, nodes.Node, nodes.Node) -> nodes.Node # NOQA objectname = node.get('js:object') searchorder = node.hasattr('refspecific') and 1 or 0 name, obj = self.find_obj(env, objectname, target, typ, searchorder) @@ -222,6 +238,7 @@ class JavaScriptDomain(Domain): def resolve_any_xref(self, env, fromdocname, builder, target, node, contnode): + # type: (BuildEnvironment, unicode, Builder, unicode, nodes.Node, nodes.Node) -> List[Tuple[unicode, nodes.Node]] # NOQA objectname = node.get('js:object') name, obj = self.find_obj(env, objectname, target, None, 1) if not obj: @@ -231,10 +248,12 @@ class JavaScriptDomain(Domain): name.replace('$', '_S_'), contnode, name))] def get_objects(self): + # type: () -> Iterator[Tuple[unicode, unicode, unicode, unicode, unicode, int]] for refname, (docname, type) in list(self.data['objects'].items()): yield refname, refname, type, docname, \ refname.replace('$', '_S_'), 1 def setup(app): + # type: (Sphinx) -> None app.add_domain(JavaScriptDomain) diff --git a/sphinx/domains/python.py b/sphinx/domains/python.py index d37e55fa3..4f0d0f1ae 100644 --- a/sphinx/domains/python.py +++ b/sphinx/domains/python.py @@ -12,6 +12,7 @@ import re from six import iteritems + from docutils import nodes from docutils.parsers.rst import directives @@ -24,6 +25,13 @@ from sphinx.util.nodes import make_refnode from sphinx.util.compat import Directive from sphinx.util.docfields import Field, GroupedField, TypedField +if False: + # For type annotation + from typing import Any, Iterator, Tuple, Union # NOQA + from sphinx.application import Sphinx # NOQA + from sphinx.builders import Builder # NOQA + from sphinx.environment import BuildEnvironment # NOQA + # REs for Python signatures py_sig_re = re.compile( @@ -36,6 +44,7 @@ py_sig_re = re.compile( def _pseudo_parse_arglist(signode, arglist): + # type: (addnodes.desc_signature, unicode) -> None """"Parse" a list of arguments separated by commas. Arguments can have "optional" annotations given by enclosing them in @@ -87,7 +96,8 @@ def _pseudo_parse_arglist(signode, arglist): class PyXrefMixin(object): def make_xref(self, rolename, domain, target, innernode=nodes.emphasis, contnode=None): - result = super(PyXrefMixin, self).make_xref(rolename, domain, target, + # type: (unicode, unicode, unicode, nodes.Node, nodes.Node) -> nodes.Node + result = super(PyXrefMixin, self).make_xref(rolename, domain, target, # type: ignore innernode, contnode) result['refspecific'] = True if target.startswith(('.', '~')): @@ -103,6 +113,7 @@ class PyXrefMixin(object): def make_xrefs(self, rolename, domain, target, innernode=nodes.emphasis, contnode=None): + # type: (unicode, unicode, unicode, nodes.Node, nodes.Node) -> List[nodes.Node] delims = '(\s*[\[\]\(\),](?:\s*or\s)?\s*|\s+or\s+)' delims_re = re.compile(delims) sub_targets = re.split(delims, target) @@ -114,7 +125,7 @@ class PyXrefMixin(object): if split_contnode: contnode = nodes.Text(sub_target) - if delims_re.match(sub_target): + if delims_re.match(sub_target): # type: ignore results.append(contnode or innernode(sub_target, sub_target)) else: results.append(self.make_xref(rolename, domain, sub_target, @@ -165,18 +176,21 @@ class PyObject(ObjectDescription): ] def get_signature_prefix(self, sig): + # type: (unicode) -> unicode """May return a prefix to put before the object name in the signature. """ return '' def needs_arglist(self): + # type: () -> bool """May return true if an empty argument list is to be generated even if the document contains none. """ return False - def handle_signature(self, sig, signode): + def handle_signature(self, sig, signode): # type: ignore + # type: (unicode, addnodes.desc_signature) -> Tuple[unicode, unicode] """Transform a Python signature into RST nodes. Return (fully qualified name of the thing, classname if any). @@ -185,7 +199,7 @@ class PyObject(ObjectDescription): * it is stripped from the displayed name if present * it is added to the full name (return value) if not present """ - m = py_sig_re.match(sig) + m = py_sig_re.match(sig) # type: ignore if m is None: raise ValueError name_prefix, name, arglist, retann = m.groups() @@ -256,10 +270,12 @@ class PyObject(ObjectDescription): return fullname, name_prefix def get_index_text(self, modname, name): + # type: (unicode, unicode) -> unicode """Return the text for the index entry of the object.""" raise NotImplementedError('must be implemented in subclasses') def add_target_and_index(self, name_cls, sig, signode): + # type: (unicode, unicode, addnodes.desc_signature) -> None modname = self.options.get( 'module', self.env.ref_context.get('py:module')) fullname = (modname and modname + '.' or '') + name_cls[0] @@ -285,10 +301,12 @@ class PyObject(ObjectDescription): fullname, '', None)) def before_content(self): + # type: () -> None # needed for automatic qualification of members (reset in subclasses) self.clsname_set = False def after_content(self): + # type: () -> None if self.clsname_set: self.env.ref_context.pop('py:class', None) @@ -299,9 +317,11 @@ class PyModulelevel(PyObject): """ def needs_arglist(self): + # type: () -> bool return self.objtype == 'function' def get_index_text(self, modname, name_cls): + # type: (unicode, unicode) -> unicode if self.objtype == 'function': if not modname: return _('%s() (built-in function)') % name_cls[0] @@ -320,9 +340,11 @@ class PyClasslike(PyObject): """ def get_signature_prefix(self, sig): + # type: (unicode) -> unicode return self.objtype + ' ' def get_index_text(self, modname, name_cls): + # type: (unicode, unicode) -> unicode if self.objtype == 'class': if not modname: return _('%s (built-in class)') % name_cls[0] @@ -333,6 +355,7 @@ class PyClasslike(PyObject): return '' def before_content(self): + # type: () -> None PyObject.before_content(self) if self.names: self.env.ref_context['py:class'] = self.names[0][0] @@ -345,9 +368,11 @@ class PyClassmember(PyObject): """ def needs_arglist(self): + # type: () -> bool return self.objtype.endswith('method') def get_signature_prefix(self, sig): + # type: (unicode) -> unicode if self.objtype == 'staticmethod': return 'static ' elif self.objtype == 'classmethod': @@ -355,6 +380,7 @@ class PyClassmember(PyObject): return '' def get_index_text(self, modname, name_cls): + # type: (unicode, unicode) -> unicode name, cls = name_cls add_modules = self.env.config.add_module_names if self.objtype == 'method': @@ -411,6 +437,7 @@ class PyClassmember(PyObject): return '' def before_content(self): + # type: () -> None PyObject.before_content(self) lastname = self.names and self.names[-1][1] if lastname and not self.env.ref_context.get('py:class'): @@ -423,11 +450,13 @@ class PyDecoratorMixin(object): Mixin for decorator directives. """ def handle_signature(self, sig, signode): - ret = super(PyDecoratorMixin, self).handle_signature(sig, signode) + # type: (unicode, addnodes.desc_signature) -> Tuple[unicode, unicode] + ret = super(PyDecoratorMixin, self).handle_signature(sig, signode) # type: ignore signode.insert(0, addnodes.desc_addname('@', '@')) return ret def needs_arglist(self): + # type: () -> bool return False @@ -436,6 +465,7 @@ class PyDecoratorFunction(PyDecoratorMixin, PyModulelevel): Directive to mark functions meant to be used as decorators. """ def run(self): + # type: () -> List[nodes.Node] # a decorator function is a function after all self.name = 'py:function' return PyModulelevel.run(self) @@ -446,6 +476,7 @@ class PyDecoratorMethod(PyDecoratorMixin, PyClassmember): Directive to mark methods meant to be used as decorators. """ def run(self): + # type: () -> List[nodes.Node] self.name = 'py:method' return PyClassmember.run(self) @@ -467,6 +498,7 @@ class PyModule(Directive): } def run(self): + # type: () -> List[nodes.Node] env = self.state.document.settings.env modname = self.arguments[0].strip() noindex = 'noindex' in self.options @@ -502,9 +534,10 @@ class PyCurrentModule(Directive): required_arguments = 1 optional_arguments = 0 final_argument_whitespace = False - option_spec = {} + option_spec = {} # type: Dict def run(self): + # type: () -> List[nodes.Node] env = self.state.document.settings.env modname = self.arguments[0].strip() if modname == 'None': @@ -516,6 +549,7 @@ class PyCurrentModule(Directive): class PyXRefRole(XRefRole): def process_link(self, env, refnode, has_explicit_title, title, target): + # type: (BuildEnvironment, nodes.Node, bool, unicode, unicode) -> Tuple[unicode, unicode] # NOQA refnode['py:module'] = env.ref_context.get('py:module') refnode['py:class'] = env.ref_context.get('py:class') if not has_explicit_title: @@ -546,9 +580,11 @@ class PythonModuleIndex(Index): shortname = l_('modules') def generate(self, docnames=None): - content = {} + # type: (List[unicode]) -> Tuple[List[Tuple[unicode, List[List[Union[unicode, int]]]]], bool] # NOQA + content = {} # type: Dict[unicode, List] # list of prefixes to ignore - ignores = self.domain.env.config['modindex_common_prefix'] + ignores = None # type: List[unicode] + ignores = self.domain.env.config['modindex_common_prefix'] # type: ignore ignores = sorted(ignores, key=len, reverse=True) # list of all modules, sorted by module name modules = sorted(iteritems(self.domain.data['modules']), @@ -601,9 +637,9 @@ class PythonModuleIndex(Index): collapse = len(modules) - num_toplevels < num_toplevels # sort by first letter - content = sorted(iteritems(content)) + sorted_content = sorted(iteritems(content)) - return content, collapse + return sorted_content, collapse class PythonDomain(Domain): @@ -620,7 +656,7 @@ class PythonDomain(Domain): 'staticmethod': ObjType(l_('static method'), 'meth', 'obj'), 'attribute': ObjType(l_('attribute'), 'attr', 'obj'), 'module': ObjType(l_('module'), 'mod', 'obj'), - } + } # type: Dict[unicode, ObjType] directives = { 'function': PyModulelevel, @@ -650,12 +686,13 @@ class PythonDomain(Domain): initial_data = { 'objects': {}, # fullname -> docname, objtype 'modules': {}, # modname -> docname, synopsis, platform, deprecated - } + } # type: Dict[unicode, Dict[unicode, Tuple[Any]]] indices = [ PythonModuleIndex, ] def clear_doc(self, docname): + # type: (unicode) -> None for fullname, (fn, _l) in list(self.data['objects'].items()): if fn == docname: del self.data['objects'][fullname] @@ -664,6 +701,7 @@ class PythonDomain(Domain): del self.data['modules'][modname] def merge_domaindata(self, docnames, otherdata): + # type: (List[unicode], Dict) -> None # XXX check duplicates? for fullname, (fn, objtype) in otherdata['objects'].items(): if fn in docnames: @@ -673,6 +711,7 @@ class PythonDomain(Domain): self.data['modules'][modname] = data def find_obj(self, env, modname, classname, name, type, searchmode=0): + # type: (BuildEnvironment, unicode, unicode, unicode, unicode, int) -> List[Tuple[unicode, Any]] # NOQA """Find a Python object for "name", perhaps using the given module and/or classname. Returns a list of (name, object entry) tuples. """ @@ -684,7 +723,7 @@ class PythonDomain(Domain): return [] objects = self.data['objects'] - matches = [] + matches = [] # type: List[Tuple[unicode, Any]] newname = None if searchmode == 1: @@ -737,6 +776,7 @@ class PythonDomain(Domain): def resolve_xref(self, env, fromdocname, builder, type, target, node, contnode): + # type: (BuildEnvironment, unicode, Builder, unicode, unicode, nodes.Node, nodes.Node) -> nodes.Node # NOQA modname = node.get('py:module') clsname = node.get('py:class') searchmode = node.hasattr('refspecific') and 1 or 0 @@ -760,9 +800,10 @@ class PythonDomain(Domain): def resolve_any_xref(self, env, fromdocname, builder, target, node, contnode): + # type: (BuildEnvironment, unicode, Builder, unicode, nodes.Node, nodes.Node) -> List[Tuple[unicode, nodes.Node]] # NOQA modname = node.get('py:module') clsname = node.get('py:class') - results = [] + results = [] # type: List[Tuple[unicode, nodes.Node]] # always search in "refspecific" mode with the :any: role matches = self.find_obj(env, modname, clsname, target, None, 1) @@ -778,6 +819,7 @@ class PythonDomain(Domain): return results def _make_module_refnode(self, builder, fromdocname, name, contnode): + # type: (Builder, unicode, unicode, nodes.Node) -> nodes.Node # get additional info for modules docname, synopsis, platform, deprecated = self.data['modules'][name] title = name @@ -791,6 +833,7 @@ class PythonDomain(Domain): 'module-' + name, contnode, title) def get_objects(self): + # type: () -> Iterator[Tuple[unicode, unicode, unicode, unicode, unicode, int]] for modname, info in iteritems(self.data['modules']): yield (modname, modname, 'module', info[0], 'module-' + modname, 0) for refname, (docname, type) in iteritems(self.data['objects']): @@ -799,4 +842,5 @@ class PythonDomain(Domain): def setup(app): + # type: (Sphinx) -> None app.add_domain(PythonDomain) diff --git a/sphinx/domains/rst.py b/sphinx/domains/rst.py index 526ae18a7..fa3353aa6 100644 --- a/sphinx/domains/rst.py +++ b/sphinx/domains/rst.py @@ -20,6 +20,14 @@ from sphinx.directives import ObjectDescription from sphinx.roles import XRefRole from sphinx.util.nodes import make_refnode +if False: + # For type annotation + from typing import Iterator, Tuple # NOQA + from docutils import nodes # NOQA + from sphinx.application import Sphinx # NOQA + from sphinx.builders import Builder # NOQA + from sphinx.environment import BuildEnvironment # NOQA + dir_sig_re = re.compile(r'\.\. (.+?)::(.*)$') @@ -30,6 +38,7 @@ class ReSTMarkup(ObjectDescription): """ def add_target_and_index(self, name, sig, signode): + # type: (unicode, unicode, addnodes.desc_signature) -> None targetname = self.objtype + '-' + name if targetname not in self.state.document.ids: signode['names'].append(targetname) @@ -51,6 +60,7 @@ class ReSTMarkup(ObjectDescription): targetname, '', None)) def get_index_text(self, objectname, name): + # type: (unicode, unicode) -> unicode if self.objtype == 'directive': return _('%s (directive)') % name elif self.objtype == 'role': @@ -59,6 +69,7 @@ class ReSTMarkup(ObjectDescription): def parse_directive(d): + # type: (unicode) -> Tuple[unicode, unicode] """Parse a directive signature. Returns (directive, arguments) string tuple. If no arguments are given, @@ -68,7 +79,7 @@ def parse_directive(d): if not dir.startswith('.'): # Assume it is a directive without syntax return (dir, '') - m = dir_sig_re.match(dir) + m = dir_sig_re.match(dir) # type: ignore if not m: return (dir, '') parsed_dir, parsed_args = m.groups() @@ -80,6 +91,7 @@ class ReSTDirective(ReSTMarkup): Description of a reST directive. """ def handle_signature(self, sig, signode): + # type: (unicode, addnodes.desc_signature) -> unicode name, args = parse_directive(sig) desc_name = '.. %s::' % name signode += addnodes.desc_name(desc_name, desc_name) @@ -93,6 +105,7 @@ class ReSTRole(ReSTMarkup): Description of a reST role. """ def handle_signature(self, sig, signode): + # type: (unicode, addnodes.desc_signature) -> unicode signode += addnodes.desc_name(':%s:' % sig, ':%s:' % sig) return sig @@ -116,14 +129,16 @@ class ReSTDomain(Domain): } initial_data = { 'objects': {}, # fullname -> docname, objtype - } + } # type: Dict[unicode, Dict[unicode, Tuple[unicode, ObjType]]] def clear_doc(self, docname): + # type: (unicode) -> None for (typ, name), doc in list(self.data['objects'].items()): if doc == docname: del self.data['objects'][typ, name] def merge_domaindata(self, docnames, otherdata): + # type: (List[unicode], Dict) -> None # XXX check duplicates for (typ, name), doc in otherdata['objects'].items(): if doc in docnames: @@ -131,6 +146,7 @@ class ReSTDomain(Domain): def resolve_xref(self, env, fromdocname, builder, typ, target, node, contnode): + # type: (BuildEnvironment, unicode, Builder, unicode, unicode, nodes.Node, nodes.Node) -> nodes.Node # NOQA objects = self.data['objects'] objtypes = self.objtypes_for_role(typ) for objtype in objtypes: @@ -142,6 +158,7 @@ class ReSTDomain(Domain): def resolve_any_xref(self, env, fromdocname, builder, target, node, contnode): + # type: (BuildEnvironment, unicode, Builder, unicode, nodes.Node, nodes.Node) -> List[nodes.Node] # NOQA objects = self.data['objects'] results = [] for objtype in self.object_types: @@ -154,9 +171,11 @@ class ReSTDomain(Domain): return results def get_objects(self): + # type: () -> Iterator[Tuple[unicode, unicode, unicode, unicode, unicode, int]] for (typ, name), docname in iteritems(self.data['objects']): yield name, name, typ, docname, typ + '-' + name, 1 def setup(app): + # type: (Sphinx) -> None app.add_domain(ReSTDomain) diff --git a/sphinx/domains/std.py b/sphinx/domains/std.py index b7f2597d4..6044b5d59 100644 --- a/sphinx/domains/std.py +++ b/sphinx/domains/std.py @@ -12,7 +12,8 @@ import re import unicodedata -from six import iteritems +from six import PY3, iteritems + from docutils import nodes from docutils.parsers.rst import directives from docutils.statemachine import ViewList @@ -26,6 +27,21 @@ from sphinx.util import ws_re from sphinx.util.nodes import clean_astext, make_refnode from sphinx.util.compat import Directive +if False: + # For type annotation + from typing import Any, Callable, Dict, Iterator, List, Tuple, Type, Union # NOQA + from docutils.parsers.rst.states import Inliner # NOQA + from sphinx.application import Sphinx # NOQA + from sphinx.builders import Builder # NOQA + from sphinx.environment import BuildEnvironment # NOQA + from sphinx.util.typing import Role # NOQA + + if PY3: + unicode = str + + RoleFunction = Callable[[unicode, unicode, unicode, int, Inliner, Dict, List[unicode]], + Tuple[List[nodes.Node], List[nodes.Node]]] + # RE for option descriptions option_desc_re = re.compile(r'((?:/|--|-|\+)?[-\.?@#_a-zA-Z0-9]+)(=?\s*.*)') @@ -38,9 +54,10 @@ class GenericObject(ObjectDescription): A generic x-ref directive registered with Sphinx.add_object_type(). """ indextemplate = '' - parse_node = None + parse_node = None # type: Callable[[GenericObject, BuildEnvironment, unicode, addnodes.desc_signature], unicode] # NOQA def handle_signature(self, sig, signode): + # type: (unicode, addnodes.desc_signature) -> unicode if self.parse_node: name = self.parse_node(self.env, sig, signode) else: @@ -51,6 +68,7 @@ class GenericObject(ObjectDescription): return name def add_target_and_index(self, name, sig, signode): + # type: (unicode, unicode, addnodes.desc_signature) -> None targetname = '%s-%s' % (self.objtype, name) signode['ids'].append(targetname) self.state.document.note_explicit_target(signode) @@ -78,6 +96,7 @@ class EnvVarXRefRole(XRefRole): """ def result_nodes(self, document, env, node, is_ref): + # type: (nodes.Node, BuildEnvironment, nodes.Node, bool) -> Tuple[List[nodes.Node], List[nodes.Node]] # NOQA if not is_ref: return [node], [] varname = node['reftarget'] @@ -102,9 +121,10 @@ class Target(Directive): required_arguments = 1 optional_arguments = 0 final_argument_whitespace = True - option_spec = {} + option_spec = {} # type: Dict def run(self): + # type: () -> List[nodes.Node] env = self.state.document.settings.env # normalize whitespace in fullname like XRefRole does fullname = ws_re.sub(' ', self.arguments[0].strip()) @@ -136,12 +156,13 @@ class Cmdoption(ObjectDescription): """ def handle_signature(self, sig, signode): + # type: (unicode, addnodes.desc_signature) -> unicode """Transform an option description into RST nodes.""" count = 0 firstname = '' for potential_option in sig.split(', '): potential_option = potential_option.strip() - m = option_desc_re.match(potential_option) + m = option_desc_re.match(potential_option) # type: ignore if not m: self.env.warn( self.env.docname, @@ -166,6 +187,7 @@ class Cmdoption(ObjectDescription): return firstname def add_target_and_index(self, firstname, sig, signode): + # type: (unicode, unicode, addnodes.desc_signature) -> None currprogram = self.env.ref_context.get('std:program') for optname in signode.get('allnames', []): targetname = optname.replace('/', '-') @@ -197,9 +219,10 @@ class Program(Directive): required_arguments = 1 optional_arguments = 0 final_argument_whitespace = True - option_spec = {} + option_spec = {} # type: Dict def run(self): + # type: () -> List[nodes.Node] env = self.state.document.settings.env program = ws_re.sub('-', self.arguments[0].strip()) if program == 'None': @@ -211,17 +234,20 @@ class Program(Directive): class OptionXRefRole(XRefRole): def process_link(self, env, refnode, has_explicit_title, title, target): + # type: (BuildEnvironment, nodes.Node, bool, unicode, unicode) -> Tuple[unicode, unicode] # NOQA refnode['std:program'] = env.ref_context.get('std:program') return title, target def split_term_classifiers(line): + # type: (unicode) -> List[Union[unicode, None]] # split line into a term and classifiers. if no classifier, None is used.. parts = re.split(' +: +', line) + [None] return parts def make_glossary_term(env, textnodes, index_key, source, lineno, new_id=None): + # type: (BuildEnvironment, List[nodes.Node], unicode, unicode, int, unicode) -> nodes.term # get a text-only representation of the term and register it # as a cross-reference target term = nodes.term('', '', *textnodes) @@ -265,6 +291,7 @@ class Glossary(Directive): } def run(self): + # type: () -> List[nodes.Node] env = self.state.document.settings.env node = addnodes.glossary() node.document = self.state.document @@ -275,7 +302,7 @@ class Glossary(Directive): # be* a definition list. # first, collect single entries - entries = [] + entries = [] # type: List[Tuple[List[Tuple[unicode, unicode, int]], ViewList]] in_definition = True was_empty = True messages = [] @@ -329,7 +356,7 @@ class Glossary(Directive): for terms, definition in entries: termtexts = [] termnodes = [] - system_messages = [] + system_messages = [] # type: List[unicode] for line, source, lineno in terms: parts = split_term_classifiers(line) # parse the term with inline markup @@ -365,9 +392,10 @@ class Glossary(Directive): def token_xrefs(text): + # type: (unicode) -> List[nodes.Node] retnodes = [] pos = 0 - for m in token_re.finditer(text): + for m in token_re.finditer(text): # type: ignore if m.start() > pos: txt = text[pos:m.start()] retnodes.append(nodes.Text(txt, txt)) @@ -390,13 +418,14 @@ class ProductionList(Directive): required_arguments = 1 optional_arguments = 0 final_argument_whitespace = True - option_spec = {} + option_spec = {} # type: Dict def run(self): + # type: () -> List[nodes.Node] env = self.state.document.settings.env objects = env.domaindata['std']['objects'] node = addnodes.productionlist() - messages = [] + messages = [] # type: List[nodes.Node] i = 0 for rule in self.arguments[0].split('\n'): @@ -437,7 +466,7 @@ class StandardDomain(Domain): searchprio=-1), 'envvar': ObjType(l_('environment variable'), 'envvar'), 'cmdoption': ObjType(l_('program option'), 'option'), - } + } # type: Dict[unicode, ObjType] directives = { 'program': Program, @@ -446,7 +475,7 @@ class StandardDomain(Domain): 'envvar': EnvVar, 'glossary': Glossary, 'productionlist': ProductionList, - } + } # type: Dict[unicode, Type[Directive]] roles = { 'option': OptionXRefRole(warn_dangling=True), 'envvar': EnvVarXRefRole(), @@ -463,7 +492,7 @@ class StandardDomain(Domain): warn_dangling=True), # links to labels, without a different title 'keyword': XRefRole(warn_dangling=True), - } + } # type: Dict[unicode, Union[RoleFunction, XRefRole]] initial_data = { 'progoptions': {}, # (program, name) -> docname, labelid @@ -495,9 +524,10 @@ class StandardDomain(Domain): nodes.figure: ('figure', None), nodes.table: ('table', None), nodes.container: ('code-block', None), - } + } # type: Dict[nodes.Node, Tuple[unicode, Callable]] def clear_doc(self, docname): + # type: (unicode) -> None for key, (fn, _l) in list(self.data['progoptions'].items()): if fn == docname: del self.data['progoptions'][key] @@ -515,6 +545,7 @@ class StandardDomain(Domain): del self.data['anonlabels'][key] def merge_domaindata(self, docnames, otherdata): + # type: (List[unicode], Dict) -> None # XXX duplicates? for key, data in otherdata['progoptions'].items(): if data[0] in docnames: @@ -533,10 +564,12 @@ class StandardDomain(Domain): self.data['anonlabels'][key] = data def process_doc(self, env, docname, document): + # type: (BuildEnvironment, unicode, nodes.Node) -> None self.note_citations(env, docname, document) self.note_labels(env, docname, document) def note_citations(self, env, docname, document): + # type: (BuildEnvironment, unicode, nodes.Node) -> None for node in document.traverse(nodes.citation): label = node[0].astext() if label in self.data['citations']: @@ -546,6 +579,7 @@ class StandardDomain(Domain): self.data['citations'][label] = (docname, node['ids'][0]) def note_labels(self, env, docname, document): + # type: (BuildEnvironment, unicode, nodes.Node) -> None labels, anonlabels = self.data['labels'], self.data['anonlabels'] for name, explicit in iteritems(document.nametypes): if not explicit: @@ -585,6 +619,7 @@ class StandardDomain(Domain): def build_reference_node(self, fromdocname, builder, docname, labelid, sectname, rolename, **options): + # type: (unicode, Builder, unicode, unicode, unicode, unicode, Any) -> nodes.Node nodeclass = options.pop('nodeclass', nodes.reference) newnode = nodeclass('', '', internal=True, **options) innernode = nodes.inline(sectname, sectname) @@ -608,6 +643,7 @@ class StandardDomain(Domain): return newnode def resolve_xref(self, env, fromdocname, builder, typ, target, node, contnode): + # type: (BuildEnvironment, unicode, Builder, unicode, unicode, nodes.Node, nodes.Node) -> nodes.Node # NOQA if typ == 'ref': resolver = self._resolve_ref_xref elif typ == 'numref': @@ -624,6 +660,7 @@ class StandardDomain(Domain): return resolver(env, fromdocname, builder, typ, target, node, contnode) def _resolve_ref_xref(self, env, fromdocname, builder, typ, target, node, contnode): + # type: (BuildEnvironment, unicode, Builder, unicode, unicode, nodes.Node, nodes.Node) -> nodes.Node # NOQA if node['refexplicit']: # reference to anonymous label; the reference uses # the supplied link caption @@ -641,6 +678,7 @@ class StandardDomain(Domain): docname, labelid, sectname, 'ref') def _resolve_numref_xref(self, env, fromdocname, builder, typ, target, node, contnode): + # type: (BuildEnvironment, unicode, Builder, unicode, unicode, nodes.Node, nodes.Node) -> nodes.Node # NOQA if target in self.data['labels']: docname, labelid, figname = self.data['labels'].get(target, ('', '', '')) else: @@ -700,6 +738,7 @@ class StandardDomain(Domain): title=title) def _resolve_keyword_xref(self, env, fromdocname, builder, typ, target, node, contnode): + # type: (BuildEnvironment, unicode, Builder, unicode, unicode, nodes.Node, nodes.Node) -> nodes.Node # NOQA # keywords are oddballs: they are referenced by named labels docname, labelid, _ = self.data['labels'].get(target, ('', '', '')) if not docname: @@ -708,13 +747,14 @@ class StandardDomain(Domain): labelid, contnode) def _resolve_option_xref(self, env, fromdocname, builder, typ, target, node, contnode): + # type: (BuildEnvironment, unicode, Builder, unicode, unicode, nodes.Node, nodes.Node) -> nodes.Node # NOQA progname = node.get('std:program') target = target.strip() docname, labelid = self.data['progoptions'].get((progname, target), ('', '')) if not docname: commands = [] - while ws_re.search(target): - subcommand, target = ws_re.split(target, 1) + while ws_re.search(target): # type: ignore + subcommand, target = ws_re.split(target, 1) # type: ignore commands.append(subcommand) progname = "-".join(commands) @@ -729,6 +769,7 @@ class StandardDomain(Domain): labelid, contnode) def _resolve_citation_xref(self, env, fromdocname, builder, typ, target, node, contnode): + # type: (BuildEnvironment, unicode, Builder, unicode, unicode, nodes.Node, nodes.Node) -> nodes.Node # NOQA from sphinx.environment import NoUri docname, labelid = self.data['citations'].get(target, ('', '')) @@ -751,6 +792,7 @@ class StandardDomain(Domain): raise def _resolve_obj_xref(self, env, fromdocname, builder, typ, target, node, contnode): + # type: (BuildEnvironment, unicode, Builder, unicode, unicode, nodes.Node, nodes.Node) -> nodes.Node # NOQA objtypes = self.objtypes_for_role(typ) or [] for objtype in objtypes: if (objtype, target) in self.data['objects']: @@ -764,7 +806,8 @@ class StandardDomain(Domain): labelid, contnode) def resolve_any_xref(self, env, fromdocname, builder, target, node, contnode): - results = [] + # type: (BuildEnvironment, unicode, Builder, unicode, nodes.Node, nodes.Node) -> List[Tuple[unicode, nodes.Node]] # NOQA + results = [] # type: List[Tuple[unicode, nodes.Node]] ltarget = target.lower() # :ref: lowercases its target automatically for role in ('ref', 'option'): # do not try "keyword" res = self.resolve_xref(env, fromdocname, builder, role, @@ -785,6 +828,7 @@ class StandardDomain(Domain): return results def get_objects(self): + # type: () -> Iterator[Tuple[unicode, unicode, unicode, unicode, unicode, int]] # handle the special 'doc' reference here for doc in self.env.all_docs: yield (doc, clean_astext(self.env.titles[doc]), 'doc', doc, '', -1) @@ -802,13 +846,16 @@ class StandardDomain(Domain): yield (name, name, 'label', info[0], info[1], -1) def get_type_name(self, type, primary=False): + # type: (ObjType, bool) -> unicode # never prepend "Default" return type.lname def is_enumerable_node(self, node): + # type: (nodes.Node) -> bool return node.__class__ in self.enumerable_nodes def get_numfig_title(self, node): + # type: (nodes.Node) -> unicode """Get the title of enumerable nodes to refer them using its title""" if self.is_enumerable_node(node): _, title_getter = self.enumerable_nodes.get(node.__class__, (None, None)) @@ -822,6 +869,7 @@ class StandardDomain(Domain): return None def get_figtype(self, node): + # type: (nodes.Node) -> unicode """Get figure type of nodes.""" def has_child(node, cls): return any(isinstance(child, cls) for child in node) @@ -838,6 +886,7 @@ class StandardDomain(Domain): return figtype def get_fignumber(self, env, builder, figtype, docname, target_node): + # type: (BuildEnvironment, Builder, unicode, unicode, nodes.Node) -> Tuple[int, ...] if figtype == 'section': if builder.name == 'latex': return tuple() @@ -861,4 +910,5 @@ class StandardDomain(Domain): def setup(app): + # type: (Sphinx) -> None app.add_domain(StandardDomain) |