diff options
Diffstat (limited to 'doc/_extensions/autojsdoc/parser/jsdoc.py')
| -rw-r--r-- | doc/_extensions/autojsdoc/parser/jsdoc.py | 357 |
1 files changed, 0 insertions, 357 deletions
diff --git a/doc/_extensions/autojsdoc/parser/jsdoc.py b/doc/_extensions/autojsdoc/parser/jsdoc.py deleted file mode 100644 index 9e9b0ba441d..00000000000 --- a/doc/_extensions/autojsdoc/parser/jsdoc.py +++ /dev/null @@ -1,357 +0,0 @@ -# -*- coding: utf-8 -*- -import re - -import collections - -import pyjsdoc - -def strip_stars(doc_comment): - """ - Version of jsdoc.strip_stars which always removes 1 space after * if - one is available. - """ - return re.sub('\n\s*?\*[\t ]?', '\n', doc_comment[3:-2]).strip() - -class ParamDoc(pyjsdoc.ParamDoc): - """ - Replace ParamDoc because FunctionDoc doesn't properly handle optional - params or default values (TODO: or compounds) if guessed_params is used - - => augment paramdoc with "required" and "default" items to clean up name - """ - def __init__(self, text): - super(ParamDoc, self).__init__(text) - # param name and doc can be separated by - or :, strip it - self.doc = self.doc.strip().lstrip('-:').lstrip() - self.optional = False - self.default = None - # there may not be a space between the param name and the :, in which - # case the : gets attached to the name, strip *again* - # TODO: formal @param/@property parser to handle this crap properly once and for all - self.name = self.name.strip().rstrip(':') - if self.name.startswith('['): - self.name = self.name.strip('[]') - self.optional = True - if '=' in self.name: - self.name, self.default = self.name.rsplit('=', 1) - def to_dict(self): - d = super(ParamDoc, self).to_dict() - d['optional'] = self.optional - d['default'] = self.default - return d -pyjsdoc.ParamDoc = ParamDoc - -class CommentDoc(pyjsdoc.CommentDoc): - namekey = object() - is_constructor = False - - @property - def name(self): - return self[self.namekey] or self['name'] or self['guessed_name'] - def set_name(self, name): - # not great... - if name != '<exports>': - self.parsed['guessed_name'] = name - - @property - def is_private(self): - return 'private' in self.parsed - - def to_dict(self): - d = super(CommentDoc, self).to_dict() - d['name'] = self.name - return d - - # don't resolve already resolved docs (e.g. a literal dict being - # include-ed in two different classes because I don't even care anymore - def become(self, modules): - return self - -class PropertyDoc(CommentDoc): - @classmethod - def from_param(cls, s, sourcemodule=None): - parsed = ParamDoc(s).to_dict() - parsed['sourcemodule'] = sourcemodule - return cls(parsed) - - @property - def type(self): - return self['type'].strip('{}') - - def to_dict(self): - d = super(PropertyDoc, self).to_dict() - d['type'] = self.type - d['is_private'] = self.is_private - return d - -class InstanceDoc(CommentDoc): - @property - def cls(self): - return self['cls'] - - def to_dict(self): - return dict(super(InstanceDoc, self).to_dict(), cls=self.cls) - -class LiteralDoc(CommentDoc): - @property - def type(self): - if self['type']: - return self['type'] - valtype = type(self['value']) - if valtype is bool: - return 'Boolean' - elif valtype is float: - return 'Number' - elif valtype is type(u''): - return 'String' - return '' - - @property - def value(self): - return self['value'] - - def to_dict(self): - d = super(LiteralDoc, self).to_dict() - d['type'] = self.type - d['value'] = self.value - return d - -class FunctionDoc(CommentDoc): - type = 'Function' - namekey = 'function' - - @property - def is_constructor(self): - return self.name == 'init' - - @property - def params(self): - tag_texts = self.get_as_list('param') - # turns out guessed_params is *almost* (?) always set to a list, - # if empty list of guessed params fall back to @params - if not self['guessed_params']: - # only get "primary" params (no "." in name) - return [ - p for p in map(ParamDoc, tag_texts) - if '.' not in p.name - ] - else: - param_dict = {} - for text in tag_texts: - param = ParamDoc(text) - param_dict[param.name] = param - return [param_dict.get(name) or ParamDoc('{} ' + name) - for name in self.get('guessed_params')] - @property - def return_val(self): - ret = self.get('return') or self.get('returns') - type = self.get('type') - if '{' in ret and '}' in ret: - if not '} ' in ret: - # Ensure that name is empty - ret = re.sub(r'\}\s*', '} ', ret) - return ParamDoc(ret) - if ret and type: - return ParamDoc('{%s} %s' % (type, ret)) - return ParamDoc(ret) - - def to_dict(self): - d = super(FunctionDoc, self).to_dict() - d['name'] = self.name - d['params'] = [param.to_dict() for param in self.params] - d['return_val']= self.return_val.to_dict() - return d - -class NSDoc(CommentDoc): - namekey = 'namespace' - def __init__(self, parsed_comment): - super(NSDoc, self).__init__(parsed_comment) - self.members = collections.OrderedDict() - def add_member(self, name, member): - """ - :type name: str - :type member: CommentDoc - """ - member.set_name(name) - self.members[name] = member - - @property - def properties(self): - if self.get('property'): - return [ - (p.name, p) - for p in ( - PropertyDoc.from_param(p, self['sourcemodule']) - for p in self.get_as_list('property') - ) - ] - return list(self.members.items()) or self['_members'] or [] - - def has_property(self, name): - return self.get_property(name) is not None - - def get_property(self, name): - return next((p for n, p in self.properties if n == name), None) - - def to_dict(self): - d = super(NSDoc, self).to_dict() - d['properties'] = [(n, p.to_dict()) for n, p in self.properties] - return d - -class MixinDoc(NSDoc): - namekey = 'mixin' - -class ModuleDoc(NSDoc): - namekey = 'module' - def __init__(self, parsed_comment): - super(ModuleDoc, self).__init__(parsed_comment) - #: callbacks to run with the modules mapping once every module is resolved - self._post_process = [] - - def post_process(self, modules): - for callback in self._post_process: - callback(modules) - - @property - def module(self): - return self # lol - - @property - def dependencies(self): - """ - Returns the immediate dependencies of a module (only those explicitly - declared/used). - """ - return self.get('dependency', None) or set() - - @property - def exports(self): - """ - Returns the actual item exported from the AMD module, can be a - namespace, a class, a function, an instance, ... - """ - return self.get_property('<exports>') - - def to_dict(self): - vars = super(ModuleDoc, self).to_dict() - vars['dependencies'] = self.dependencies - vars['exports'] = self.exports - return vars - - def __str__(self): - s = super().__str__() - if self['sourcefile']: - s += " in file " + self['sourcefile'] - return s - -class ClassDoc(NSDoc): - namekey = 'class' - @property - def constructor(self): - return self.get_property('init') - - @property - def superclass(self): - return self['extends'] or self['base'] - - def get_property(self, method_name): - if method_name == 'extend': - return FunctionDoc({ - 'doc': 'Create subclass for %s' % self.name, - 'guessed_function': 'extend', - }) - # FIXME: should ideally be a proxy namespace - if method_name == 'prototype': - return self - return super(ClassDoc, self).get_property(method_name)\ - or (self.superclass and self.superclass.get_property(method_name)) - - @property - def mixins(self): - return self.get_as_list('mixes') - - def to_dict(self): - d = super(ClassDoc, self).to_dict() - d['mixins'] = self.mixins - return d - -DEFAULT = object() -class UnknownNS(NSDoc): - params = () # TODO: log warning when (somehow) trying to access / document an unknown object as ctor? - def get_property(self, name): - return super(UnknownNS, self).get_property(name) or \ - UnknownNS({'name': '{}.{}'.format(self.name, name)}) - - def __getitem__(self, item): - if self._probably_not_property(item): - return super().__getitem__(item) - return self.get_property(item) - - def _probably_not_property(self, item): - return ( - not isinstance(item, str) - or item in (self.namekey, 'name', 'params') - or item.startswith(('_', 'guessed_')) - or item in self.parsed - ) - -class Unknown(CommentDoc): - @classmethod - def from_(cls, source): - def builder(parsed): - inst = cls(parsed) - inst.parsed['source'] = source - return inst - return builder - - @property - def name(self): - return self['name'] + ' ' + self['source'] - - @property - def type(self): - return "Unknown" - - def get_property(self, p): - return Unknown(dict(self.parsed, source=self.name, name=p + '<')) - -def parse_comments(comments, doctype=None): - # find last comment which starts with a * - docstring = next(( - c['value'] - for c in reversed(comments or []) - if c['value'].startswith(u'*') - ), None) or u"" - - # \n prefix necessary otherwise parse_comment fails to take first - # block comment parser strips delimiters, but strip_stars fails without - # them - extract = '\n' + strip_stars('/*' + docstring + '\n*/') - parsed = pyjsdoc.parse_comment(extract, u'') - - if doctype == 'FunctionExpression': - doctype = FunctionDoc - elif doctype == 'ObjectExpression' or doctype is None: - doctype = guess - - if doctype is guess: - return doctype(parsed) - - # in case a specific doctype is given, allow overriding it anyway - return guess(parsed, default=doctype) - -def guess(parsed, default=UnknownNS): - if 'class' in parsed: - return ClassDoc(parsed) - if 'function' in parsed: - return FunctionDoc(parsed) - if 'mixin' in parsed: - return MixinDoc(parsed) - if 'namespace' in parsed: - return NSDoc(parsed) - if 'module' in parsed: - return ModuleDoc(parsed) - if 'type' in parsed: - return PropertyDoc(parsed) - - return default(parsed) |
