| Index: third_party/cython/src/Cython/Compiler/AutoDocTransforms.py
|
| diff --git a/third_party/cython/src/Cython/Compiler/AutoDocTransforms.py b/third_party/cython/src/Cython/Compiler/AutoDocTransforms.py
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..408ce9abb176810ea6995d0e1aea1a4b87d6bcc1
|
| --- /dev/null
|
| +++ b/third_party/cython/src/Cython/Compiler/AutoDocTransforms.py
|
| @@ -0,0 +1,229 @@
|
| +from Cython.Compiler.Visitor import CythonTransform
|
| +from Cython.Compiler.StringEncoding import EncodedString
|
| +from Cython.Compiler import Options
|
| +from Cython.Compiler import PyrexTypes, ExprNodes
|
| +
|
| +class EmbedSignature(CythonTransform):
|
| +
|
| + def __init__(self, context):
|
| + super(EmbedSignature, self).__init__(context)
|
| + self.denv = None # XXX
|
| + self.class_name = None
|
| + self.class_node = None
|
| +
|
| + unop_precedence = 11
|
| + binop_precedence = {
|
| + 'or': 1,
|
| + 'and': 2,
|
| + 'not': 3,
|
| + 'in': 4, 'not in': 4, 'is': 4, 'is not': 4, '<': 4, '<=': 4, '>': 4, '>=': 4, '!=': 4, '==': 4,
|
| + '|': 5,
|
| + '^': 6,
|
| + '&': 7,
|
| + '<<': 8, '>>': 8,
|
| + '+': 9, '-': 9,
|
| + '*': 10, '/': 10, '//': 10, '%': 10,
|
| + # unary: '+': 11, '-': 11, '~': 11
|
| + '**': 12}
|
| +
|
| + def _fmt_expr_node(self, node, precedence=0):
|
| + if isinstance(node, ExprNodes.BinopNode) and not node.inplace:
|
| + new_prec = self.binop_precedence.get(node.operator, 0)
|
| + result = '%s %s %s' % (self._fmt_expr_node(node.operand1, new_prec),
|
| + node.operator,
|
| + self._fmt_expr_node(node.operand2, new_prec))
|
| + if precedence > new_prec:
|
| + result = '(%s)' % result
|
| + elif isinstance(node, ExprNodes.UnopNode):
|
| + result = '%s%s' % (node.operator,
|
| + self._fmt_expr_node(node.operand, self.unop_precedence))
|
| + if precedence > self.unop_precedence:
|
| + result = '(%s)' % result
|
| + elif isinstance(node, ExprNodes.AttributeNode):
|
| + result = '%s.%s' % (self._fmt_expr_node(node.obj), node.attribute)
|
| + else:
|
| + result = node.name
|
| + return result
|
| +
|
| + def _fmt_arg_defv(self, arg):
|
| + default_val = arg.default
|
| + if not default_val:
|
| + return None
|
| + try:
|
| + denv = self.denv # XXX
|
| + ctval = default_val.compile_time_value(self.denv)
|
| + repr_val = repr(ctval)
|
| + if isinstance(default_val, ExprNodes.UnicodeNode):
|
| + if repr_val[:1] != 'u':
|
| + return u'u%s' % repr_val
|
| + elif isinstance(default_val, ExprNodes.BytesNode):
|
| + if repr_val[:1] != 'b':
|
| + return u'b%s' % repr_val
|
| + elif isinstance(default_val, ExprNodes.StringNode):
|
| + if repr_val[:1] in 'ub':
|
| + return repr_val[1:]
|
| + return repr_val
|
| + except Exception:
|
| + try:
|
| + return self._fmt_expr_node(default_val)
|
| + except AttributeError, e:
|
| + return '<???>'
|
| +
|
| + def _fmt_arg(self, arg):
|
| + if arg.type is PyrexTypes.py_object_type or arg.is_self_arg:
|
| + doc = arg.name
|
| + else:
|
| + doc = arg.type.declaration_code(arg.name, for_display=1)
|
| + if arg.default:
|
| + arg_defv = self._fmt_arg_defv(arg)
|
| + if arg_defv:
|
| + doc = doc + ('=%s' % arg_defv)
|
| + return doc
|
| +
|
| + def _fmt_arglist(self, args,
|
| + npargs=0, pargs=None,
|
| + nkargs=0, kargs=None,
|
| + hide_self=False):
|
| + arglist = []
|
| + for arg in args:
|
| + if not hide_self or not arg.entry.is_self_arg:
|
| + arg_doc = self._fmt_arg(arg)
|
| + arglist.append(arg_doc)
|
| + if pargs:
|
| + arglist.insert(npargs, '*%s' % pargs.name)
|
| + elif nkargs:
|
| + arglist.insert(npargs, '*')
|
| + if kargs:
|
| + arglist.append('**%s' % kargs.name)
|
| + return arglist
|
| +
|
| + def _fmt_ret_type(self, ret):
|
| + if ret is PyrexTypes.py_object_type:
|
| + return None
|
| + else:
|
| + return ret.declaration_code("", for_display=1)
|
| +
|
| + def _fmt_signature(self, cls_name, func_name, args,
|
| + npargs=0, pargs=None,
|
| + nkargs=0, kargs=None,
|
| + return_type=None, hide_self=False):
|
| + arglist = self._fmt_arglist(args,
|
| + npargs, pargs,
|
| + nkargs, kargs,
|
| + hide_self=hide_self)
|
| + arglist_doc = ', '.join(arglist)
|
| + func_doc = '%s(%s)' % (func_name, arglist_doc)
|
| + if cls_name:
|
| + func_doc = '%s.%s' % (cls_name, func_doc)
|
| + if return_type:
|
| + ret_doc = self._fmt_ret_type(return_type)
|
| + if ret_doc:
|
| + func_doc = '%s -> %s' % (func_doc, ret_doc)
|
| + return func_doc
|
| +
|
| + def _embed_signature(self, signature, node_doc):
|
| + if node_doc:
|
| + return "%s\n%s" % (signature, node_doc)
|
| + else:
|
| + return signature
|
| +
|
| + def __call__(self, node):
|
| + if not Options.docstrings:
|
| + return node
|
| + else:
|
| + return super(EmbedSignature, self).__call__(node)
|
| +
|
| + def visit_ClassDefNode(self, node):
|
| + oldname = self.class_name
|
| + oldclass = self.class_node
|
| + self.class_node = node
|
| + try:
|
| + # PyClassDefNode
|
| + self.class_name = node.name
|
| + except AttributeError:
|
| + # CClassDefNode
|
| + self.class_name = node.class_name
|
| + self.visitchildren(node)
|
| + self.class_name = oldname
|
| + self.class_node = oldclass
|
| + return node
|
| +
|
| + def visit_DefNode(self, node):
|
| + if not self.current_directives['embedsignature']:
|
| + return node
|
| +
|
| + is_constructor = False
|
| + hide_self = False
|
| + if node.entry.is_special:
|
| + is_constructor = self.class_node and node.name == '__init__'
|
| + if not is_constructor:
|
| + return node
|
| + class_name, func_name = None, self.class_name
|
| + hide_self = True
|
| + else:
|
| + class_name, func_name = self.class_name, node.name
|
| +
|
| + nkargs = getattr(node, 'num_kwonly_args', 0)
|
| + npargs = len(node.args) - nkargs
|
| + signature = self._fmt_signature(
|
| + class_name, func_name, node.args,
|
| + npargs, node.star_arg,
|
| + nkargs, node.starstar_arg,
|
| + return_type=None, hide_self=hide_self)
|
| + if signature:
|
| + if is_constructor:
|
| + doc_holder = self.class_node.entry.type.scope
|
| + else:
|
| + doc_holder = node.entry
|
| +
|
| + if doc_holder.doc is not None:
|
| + old_doc = doc_holder.doc
|
| + elif not is_constructor and getattr(node, 'py_func', None) is not None:
|
| + old_doc = node.py_func.entry.doc
|
| + else:
|
| + old_doc = None
|
| + new_doc = self._embed_signature(signature, old_doc)
|
| + doc_holder.doc = EncodedString(new_doc)
|
| + if not is_constructor and getattr(node, 'py_func', None) is not None:
|
| + node.py_func.entry.doc = EncodedString(new_doc)
|
| + return node
|
| +
|
| + def visit_CFuncDefNode(self, node):
|
| + if not self.current_directives['embedsignature']:
|
| + return node
|
| + if not node.overridable: # not cpdef FOO(...):
|
| + return node
|
| +
|
| + signature = self._fmt_signature(
|
| + self.class_name, node.declarator.base.name,
|
| + node.declarator.args,
|
| + return_type=node.return_type)
|
| + if signature:
|
| + if node.entry.doc is not None:
|
| + old_doc = node.entry.doc
|
| + elif getattr(node, 'py_func', None) is not None:
|
| + old_doc = node.py_func.entry.doc
|
| + else:
|
| + old_doc = None
|
| + new_doc = self._embed_signature(signature, old_doc)
|
| + node.entry.doc = EncodedString(new_doc)
|
| + if hasattr(node, 'py_func') and node.py_func is not None:
|
| + node.py_func.entry.doc = EncodedString(new_doc)
|
| + return node
|
| +
|
| + def visit_PropertyNode(self, node):
|
| + if not self.current_directives['embedsignature']:
|
| + return node
|
| +
|
| + entry = node.entry
|
| + if entry.visibility == 'public':
|
| + # property synthesised from a cdef public attribute
|
| + type_name = entry.type.declaration_code("", for_display=1)
|
| + if not entry.type.is_pyobject:
|
| + type_name = "'%s'" % type_name
|
| + elif entry.type.is_extension_type:
|
| + type_name = entry.type.module_name + '.' + type_name
|
| + signature = '%s: %s' % (entry.name, type_name)
|
| + new_doc = self._embed_signature(signature, entry.doc)
|
| + entry.doc = EncodedString(new_doc)
|
| + return node
|
|
|