B
    öÀ„\kD  ã               @   s<  d Z ddlZddlZddlZddlZddlZddlZddlmZm	Z	m
Z
mZmZmZmZ ddlmZmZ ddlmZmZ e d¡Ze d¡Ze d¡Zejd	kr®ejejfZnejZd
d„ Zdd„ Zddd„Zdd„ ZG dd„ de ƒZ!G dd„ de ƒZ"G dd„ de"ƒZ#G dd„ dej$ƒZ%G dd„ de"ƒZ&G dd„ de ƒZ'dS )z×
    sphinx.pycode.parser
    ~~~~~~~~~~~~~~~~~~~~

    Utilities parsing and analyzing Python code.

    :copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
    :license: BSD, see LICENSE for details.
é    N)ÚNAMEÚNEWLINEÚINDENTÚDEDENTÚNUMBERÚOPÚSTRING)ÚCOMMENTÚNL)ÚPY2Ú	text_typez^\s*#: ?(.*)?
?$z^\s*$z^\s*(#.*)?$)é   é   c             C   s   |   dd¡S )Núú )Úreplace)Úcode© r   ú3lib/python3.7/site-packages/sphinx/pycode/parser.pyÚfilter_whitespace%   s    r   c             C   s   t | tjƒr| jS | jgS dS )z3Get list of targets from Assign and AnnAssign node.N)Ú
isinstanceÚastÚAssignÚtargetsÚtarget)Únoder   r   r   Úget_assign_targets*   s    r   c          	   C   s2  |rt r|j}n|j}| jj}|dkr6td|  ƒ‚ nø|dkrf|dksP| j|krX| jgS td|  ƒ‚nÈ|dkr°g }x8| jD ].}y| t||ƒ¡ W qz tk
r¦   Y qzX qzW |S |dk rü| j	jjdkrî|rî| j	j|krîdt| j
|ƒd	  gS td|  ƒ‚n2|d
kr| gS |dkr"t| j	|ƒS td| ƒ‚dS )zÆConvert assignment-AST to variable names.

    This raises `TypeError` if the assignment does not create new variable::

        ary[0] = 'foo'
        dic["bar"] = 'baz'
        # => TypeError
    )ZIndexZNumZSliceÚStrZ	Subscriptz%r does not create new variableÚNameNz*The assignment %r is not instance variable)ZTupleZListZ	Attributez%sr   ÚstrZStarredzUnexpected node name %r)r   ÚidÚargÚ	__class__Ú__name__Ú	TypeErrorZeltsÚextendÚget_lvar_namesÚvalueÚattrÚNotImplementedError)r   ÚselfZself_idZ	node_nameÚmembersZeltr   r   r   r&   3   s8    




r&   c             C   s(   dd„ }| |_ t |¡}| d¡ d¡S )z1Remove common leading indentation from docstring.c               S   s   d S )Nr   r   r   r   r   Údummyd   s    zdedent_docstring.<locals>.dummyz
)Ú__doc__ÚinspectZgetdocÚlstripÚrstrip)Úsr,   Ú	docstringr   r   r   Údedent_docstringa   s    
r3   c               @   s8   e Zd ZdZdd„ Zdd„ Zdd„ Zdd	„ Zd
d„ ZdS )ÚTokenz)Better token wrapper for tokenize module.c             C   s"   || _ || _|| _|| _|| _d S )N)Úkindr'   ÚstartÚendÚsource)r*   r5   r'   r6   r7   r8   r   r   r   Ú__init__q   s
    zToken.__init__c             C   sf   t |tƒr| j|kS t |tƒr(| j|kS t |ttfƒrJ| j| jgt|ƒkS |d krVdS td| ƒ‚d S )NFzUnknown value: %r)r   Úintr5   r   r'   ÚlistÚtupleÚ
ValueError)r*   Úotherr   r   r   Ú__eq__y   s    



zToken.__eq__c             C   s
   | |k S )Nr   )r*   r>   r   r   r   Ú__ne__†   s    zToken.__ne__c                s   t ‡ fdd„|D ƒƒS )Nc             3   s   | ]}ˆ |kV  qd S )Nr   )Ú.0Ú	candidate)r*   r   r   ú	<genexpr>Œ   s    zToken.match.<locals>.<genexpr>)Úany)r*   Z
conditionsr   )r*   r   ÚmatchŠ   s    zToken.matchc             C   s   dt j| j | j ¡ f S )Nz<Token kind=%r value=%r>)ÚtokenizeÚtok_namer5   r'   Ústrip)r*   r   r   r   Ú__repr__Ž   s    zToken.__repr__N)	r#   Ú
__module__Ú__qualname__r-   r9   r?   r@   rE   rI   r   r   r   r   r4   n   s   r4   c               @   s,   e Zd Zdd„ Zdd„ Zdd„ Zdd„ Zd	S )
ÚTokenProcessorc                s2   t |ƒ‰ || _t ‡ fdd„¡| _d | _d | _d S )Nc                  s   t ˆ ƒS )N)Únextr   )Úlinesr   r   Ú<lambda>™   s    z)TokenProcessor.__init__.<locals>.<lambda>)ÚiterÚbuffersrF   Úgenerate_tokensÚtokensÚcurrentÚprevious)r*   rQ   r   )rN   r   r9   •   s
    zTokenProcessor.__init__c             C   s   | j |d  S )zReturns specified line.é   )rQ   )r*   Úlinenor   r   r   Úget_line   s    zTokenProcessor.get_linec             C   s>   y| j | _tt| jƒŽ | _ W n tk
r6   d| _ Y nX | j S )z^Fetch a next token from source code.

        Returns ``False`` if sequence finished.
        N)rT   rU   r4   rM   rS   ÚStopIteration)r*   r   r   r   Úfetch_token¢   s    zTokenProcessor.fetch_tokenc             C   s”   g }xŠ|   ¡ rŽ| | j¡ | j|kr(P q| jtdgkrJ||  tdg¡7 }q| jtdgkrl||  tdg¡7 }q| jtdgkr||  tdg¡7 }qW |S )zlFetch tokens until specified token appeared.

        .. note:: This also handles parenthesis well.
        ú(ú)Ú{Ú}ú[ú])rZ   ÚappendrT   r   Úfetch_until)r*   Z	conditionrS   r   r   r   rb   °   s    

zTokenProcessor.fetch_untilN)r#   rJ   rK   r9   rX   rZ   rb   r   r   r   r   rL   ”   s   rL   c                   s0   e Zd ZdZ‡ fdd„Zdd„ Zdd„ Z‡  ZS )ÚAfterCommentParserz¿Python source code parser to pick up comment after assignment.

    This parser takes a python code starts with assignment statement,
    and returns the comments for variable if exists.
    c                s   t t| ƒ |¡ d | _d S )N)Úsuperrc   r9   Úcomment)r*   rN   )r"   r   r   r9   Ì   s    zAfterCommentParser.__init__c             C   sÊ   g }xÀ|   ¡ rÄ| | j¡ | jtdgkr<||  tdg¡7 }q| jtdgkr^||  tdg¡7 }q| jtdgkr€||  tdg¡7 }q| jtkrš||  t¡7 }q| jtdgkr¬P q| jjttt	t
fkrP qW |S )z%Fetch right-hand value of assignment.r[   r\   r]   r^   r_   r`   ú;)rZ   ra   rT   r   rb   r   r   r5   r   r   r   )r*   rS   r   r   r   Úfetch_rvalueÑ   s     

zAfterCommentParser.fetch_rvaluec             C   sT   x$|   ¡  tdgtt¡s$| jst‚qW | jtdgkr<|  ¡  | jtkrP| jj| _	dS )z3Parse the code and obtain comment after assignment.ú=N)
rZ   rE   r   r   r	   rT   ÚAssertionErrorrg   r'   re   )r*   r   r   r   Úparseæ   s    
zAfterCommentParser.parse)r#   rJ   rK   r-   r9   rg   rj   Ú__classcell__r   r   )r"   r   rc   Å   s   rc   c                   st   e Zd ZdZ‡ fdd„Zdd„ Zdd„ Zdd	„ Zd
d„ Z‡ fdd„Z	dd„ Z
dd„ Zdd„ Zdd„ Zdd„ Z‡  ZS )ÚVariableCommentPickerz7Python source code parser to pick up variable comments.c                sL   t  ¡ | _|| _|| _g | _g | _d | _i | _d | _	i | _
tt| ƒ ¡  d S )N)Ú	itertoolsÚcountÚcounterrQ   ÚencodingÚcontextÚcurrent_classesÚcurrent_functionÚcommentsrU   Ú	defordersrd   rl   r9   )r*   rQ   rp   )r"   r   r   r9   ø   s    
zVariableCommentPicker.__init__c             C   s\   | j r6| jr0| jd dkr0| jd d… |g }qBd S n| j|g }t| jƒ| jd |¡< d S )Néÿÿÿÿr9   Ú.)rs   rr   rq   rM   ro   ru   Újoin)r*   ÚnameÚ
definitionr   r   r   Ú	add_entry  s    zVariableCommentPicker.add_entryc             C   sT   | j r6| jr0| jd dkr0d | jd d… ¡}qBd S nd | j¡}|| j||f< d S )Nrv   r9   rw   )rs   rr   rq   rx   rt   )r*   ry   re   rq   r   r   r   Úadd_variable_comment  s    z*VariableCommentPicker.add_variable_commentc             C   s&   | j r| j jjr| j jjd S dS dS )z2Returns the name of first argument if in function.r   N)rs   Úargs)r*   r   r   r   Úget_self  s    zVariableCommentPicker.get_selfc             C   s   | j |d  S )zReturns specified line.rV   )rQ   )r*   rW   r   r   r   rX   '  s    zVariableCommentPicker.get_linec                s   t t| ƒ |¡ || _dS )zUpdates self.previous to .N)rd   rl   ÚvisitrU   )r*   r   )r"   r   r   r   ,  s    zVariableCommentPicker.visitc                s~  y0t |ƒ}t‡ fdd„|D ƒg ƒ}ˆ  |j¡}W n tk
rD   dS X t||jd… gˆ j|jd…  ƒ}| ¡  |j	r¶t
 |j	¡r¶x,|D ]$}ˆ  |t
 d|j	¡¡ ˆ  |¡ qŠW dS t |d|j… ¡r`g }xLt|jd ƒD ]:}ˆ  |jd | ¡}	t
 |	¡r| t
 d|	¡¡ qàP qàW |r`td t|ƒ¡ƒ}
x$|D ]}ˆ  ||
¡ ˆ  |¡ q<W dS x|D ]}ˆ  |¡ qfW dS )z3Handles Assign node and pick up a variable comment.c                s   g | ]}t |ˆ  ¡ d ‘qS ))r*   )r&   r~   )rA   Út)r*   r   r   ú
<listcomp>7  s    z6VariableCommentPicker.visit_Assign.<locals>.<listcomp>Nz\1rV   Ú
)r   ÚsumrX   rW   r$   rc   Ú
col_offsetrQ   rj   re   Ú
comment_rerE   r|   Úsubr{   Ú	indent_reÚrangera   r3   rx   Úreversed)r*   r   r   ÚvarnamesZcurrent_lineÚparserÚvarnameZcomment_linesÚiZbefore_linere   r   )r*   r   Úvisit_Assign2  s:    


z"VariableCommentPicker.visit_Assignc             C   s   |   |¡ dS )z6Handles AnnAssign node and pick up a variable comment.N)rŽ   )r*   r   r   r   r   Úvisit_AnnAssign[  s    z%VariableCommentPicker.visit_AnnAssignc             C   s¨   t | jtƒr¤t |jtjƒr¤ytt| jƒ}t|d |  ¡ ƒ}xR|D ]J}t |jj	t
ƒrZ|jj	}n|jj	 | jpjd¡}|  |t|ƒ¡ |  |¡ q>W W n tk
r¢   Y nX dS )z2Handles Expr node and pick up a comment if string.r   zutf-8N)r   rU   ÚASSIGN_NODESr'   r   r   r   r&   r~   r1   r   Údecoderp   r|   r3   r{   r$   )r*   r   r   rŠ   rŒ   r2   r   r   r   Ú
visit_Expr`  s    


z VariableCommentPicker.visit_Exprc             C   s`   | j  |j¡ |  |j¡ | j |j¡ || _x|jD ]}|  |¡ q6W | j ¡  | j  ¡  dS )z&Handles ClassDef node and set context.N)	rr   ra   ry   r{   rq   rU   Úbodyr   Úpop)r*   r   Úchildr   r   r   Úvisit_ClassDefr  s    
z$VariableCommentPicker.visit_ClassDefc             C   sX   | j dkrT|  |j¡ | j |j¡ || _ x|jD ]}|  |¡ q2W | j ¡  d| _ dS )z)Handles FunctionDef node and set context.N)rs   r{   ry   rq   ra   r“   r   r”   )r*   r   r•   r   r   r   Úvisit_FunctionDef~  s    

z'VariableCommentPicker.visit_FunctionDef)r#   rJ   rK   r-   r9   r{   r|   r~   rX   r   rŽ   r   r’   r–   r—   rk   r   r   )r"   r   rl   õ   s   )rl   c                   s<   e Zd Z‡ fdd„Zdd„ Zdd„ Zdd„ Zd	d
„ Z‡  ZS )ÚDefinitionFinderc                s,   t t| ƒ |¡ d | _g | _g | _i | _d S )N)rd   r˜   r9   Ú	decoratorrq   ÚindentsÚdefinitions)r*   rN   )r"   r   r   r9   Œ  s
    zDefinitionFinder.__init__c             C   s4   | j r&| j d d dkr&|d dkr&n
|| j|< d S )Nrv   r   Údef)rš   r›   )r*   ry   Úentryr   r   r   Úadd_definition”  s    $zDefinitionFinder.add_definitionc             C   s¼   x¶|   ¡ }|d krP q|tkr q|tdgkrZ| jd ksH| j tttt¡rZ| j	d kr´|| _	q| t
dg¡rt|  d¡ q| t
dg¡rŽ|  d¡ q|tkr¤| j d¡ q|tkr|  ¡  qW d S )Nú@Úclassrœ   )r>   NN)rZ   r	   r   rU   rE   r   r
   r   r   r™   r   Úparse_definitionrš   ra   Úfinalize_block)r*   Útokenr   r   r   rj   œ  s$    
zDefinitionFinder.parsec             C   s¨   |   ¡ }| j |j¡ d | j¡}| jr<| jjd }d | _n
|jd }|  tdg¡ |   ¡  	t
t¡r‚|  t¡ | j |||f¡ n"|  ||||jd f¡ | j ¡  d S )Nrw   r   ú:)rZ   rq   ra   r'   rx   r™   r6   rb   r   rE   r	   r   r   rš   rž   r7   r”   )r*   Útypry   ÚfuncnameÚ	start_posr   r   r   r¡   ±  s    

z!DefinitionFinder.parse_definitionc             C   sn   | j  ¡ }|d dkrj|\}}}| jjd d }xt |  |¡¡rL|d8 }q2W |  ||||f¡ | j ¡  d S )Nr   r>   rV   )	rš   r”   rT   r7   Úemptyline_rerE   rX   rž   rq   )r*   rz   r¥   r¦   r§   Zend_posr   r   r   r¢   Æ  s    

zDefinitionFinder.finalize_block)	r#   rJ   rK   r9   rž   rj   r¡   r¢   rk   r   r   )r"   r   r˜   ‹  s
   r˜   c               @   s2   e Zd ZdZddd„Zdd„ Zdd„ Zd	d
„ ZdS )ÚParserzyPython source code parser to pick up variable comments.

    This is a better wrapper for ``VariableCommentPicker``.
    úutf-8c             C   s&   t |ƒ| _|| _i | _i | _i | _d S )N)r   r   rp   rt   ru   r›   )r*   r   rp   r   r   r   r9   Ù  s
    
zParser.__init__c             C   s   |   ¡  |  ¡  dS )zParse the source code.N)Úparse_commentsr¡   )r*   r   r   r   rj   á  s    zParser.parsec             C   sD   t  | j d¡¡}t| j d¡| jƒ}| |¡ |j| _|j	| _	dS )z$Parse the code and pick up comments.zutf-8TN)
r   rj   r   Úencoderl   Ú
splitlinesrp   r   rt   ru   )r*   ZtreeZpickerr   r   r   r«   ç  s
    
zParser.parse_commentsc             C   s$   t | j d¡ƒ}| ¡  |j| _dS )z0Parse the location of definitions from the code.TN)r˜   r   r­   rj   r›   )r*   r‹   r   r   r   r¡   ð  s    zParser.parse_definitionN)rª   )r#   rJ   rK   r-   r9   rj   r«   r¡   r   r   r   r   r©   Ó  s
   
	r©   )N)(r-   r   r.   rm   ÚreÚsysrF   r£   r   r   r   r   r   r   r   r	   r
   Zsixr   r   Úcompiler…   r‡   r¨   Úversion_infor   Z	AnnAssignr   r   r   r&   r3   Úobjectr4   rL   rc   ZNodeVisitorrl   r˜   r©   r   r   r   r   Ú<module>
   s4   $



	
.&10 H