B
    +d?                 @   s   d dl mZmZ d dlmZmZmZmZ d dlm	Z	 de
ddddZG d	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ZG dd deZG dd deZdS )    )abstractmethodabstractproperty)ListOptionalTupleUnion)split_lines
NodeOrLeafzOptional[BaseNode])node
node_typesreturnc             G   s,   | j }x |dk	r&|j|kr|S |j }qW dS )an  
    Recursively looks at the parents of a node and returns the first found node
    that matches ``node_types``. Returns ``None`` if no matching node is found.

    This function is deprecated, use :meth:`NodeOrLeaf.search_ancestor` instead.

    :param node: The ancestors of this node will be checked.
    :param node_types: type names that are searched for.
    N)parenttype)r
   r   n r   W/work/yifan.wang/ringdown/master-ringdown-env/lib/python3.7/site-packages/parso/tree.pysearch_ancestor   s    



r   c               @   s   e Zd ZU dZdZeed< ded< dd Zdd	 Zd
d Z	dd Z
dd Zeeeef dddZeeeef dddZedd Zedd Zedd Zed'ddZedddd Zd!d"eeeef  ed#d$d%Zd&S )(r	   z.
    The base class for nodes and leaves.
    )r   r   zOptional[BaseNode]r   c             C   s   | }x|j dk	r|j }qW |S )z
        Returns the root node of a parser tree. The returned node doesn't have
        a parent node like all the other nodes/leaves.
        N)r   )selfscoper   r   r   get_root_node(   s    
zNodeOrLeaf.get_root_nodec          	   C   s\   | j }|dkrdS xDt|jD ]6\}}|| kry| j j|d  S  tk
rR   dS X qW dS )z
        Returns the node immediately following this node in this parent's
        children list. If this node does not have a next sibling, it is None
        N   )r   	enumeratechildren
IndexError)r   r   ichildr   r   r   get_next_sibling2   s    zNodeOrLeaf.get_next_siblingc             C   sR   | j }|dkrdS x:t|jD ],\}}|| kr|dkr:dS | j j|d  S qW dS )z
        Returns the node immediately preceding this node in this parent's
        children list. If this node does not have a previous sibling, it is
        None.
        Nr   r   )r   r   r   )r   r   r   r   r   r   r   get_previous_siblingC   s    zNodeOrLeaf.get_previous_siblingc             C   s   | j dkrdS | }xB|j j}||}|dkrD|j }|j dkrRdS q||d  }P qW x(y|jd }W qX tk
rz   |S X qXW dS )z
        Returns the previous leaf in the parser tree.
        Returns `None` if this is the first element in the parser tree.
        Nr   r   )r   r   indexAttributeError)r   r
   cr   r   r   r   get_previous_leafT   s"    


zNodeOrLeaf.get_previous_leafc             C   s   | j dkrdS | }xJ|j j}||}|t|d krL|j }|j dkrZdS q||d  }P qW x(y|jd }W q` tk
r   |S X q`W dS )z
        Returns the next leaf in the parser tree.
        Returns None if this is the last element in the parser tree.
        Nr   r   )r   r   r   lenr    )r   r
   r!   r   r   r   r   get_next_leafn   s"    


zNodeOrLeaf.get_next_leaf)r   c             C   s   dS )z
        Returns the starting position of the prefix as a tuple, e.g. `(3, 4)`.

        :return tuple of int: (line, column)
        Nr   )r   r   r   r   	start_pos   s    zNodeOrLeaf.start_posc             C   s   dS )z
        Returns the end position of the prefix as a tuple, e.g. `(3, 4)`.

        :return tuple of int: (line, column)
        Nr   )r   r   r   r   end_pos   s    zNodeOrLeaf.end_posc             C   s   dS )a-  
        Returns the start_pos of the prefix. This means basically it returns
        the end_pos of the last prefix. The `get_start_pos_of_prefix()` of the
        prefix `+` in `2 + 1` would be `(1, 1)`, while the start_pos is
        `(1, 2)`.

        :return tuple of int: (line, column)
        Nr   )r   r   r   r   get_start_pos_of_prefix   s    	z"NodeOrLeaf.get_start_pos_of_prefixc             C   s   dS )zO
        Returns the first leaf of a node or itself if this is a leaf.
        Nr   )r   r   r   r   get_first_leaf   s    zNodeOrLeaf.get_first_leafc             C   s   dS )zN
        Returns the last leaf of a node or itself if this is a leaf.
        Nr   )r   r   r   r   get_last_leaf   s    zNodeOrLeaf.get_last_leafTc             C   s   dS )z
        Returns the code that was the input for the parser for this node.

        :param include_prefix: Removes the prefix (whitespace and comments) of
            e.g. a statement.
        Nr   )r   include_prefixr   r   r   get_code   s    zNodeOrLeaf.get_code)r   r   c             G   s,   | j }x |dk	r&|j|kr|S |j }qW dS )a  
        Recursively looks at the parents of this node or leaf and returns the
        first found node that matches ``node_types``. Returns ``None`` if no
        matching node is found.

        :param node_types: type names that are searched for.
        N)r   r   )r   r   r
   r   r   r   r      s    


zNodeOrLeaf.search_ancestor   )indent)r-   r   c               sr   |dkrddn:t |tr*dd| n"t |tr>d|ntd|d
ttttd fdd	  | S )a  
        Returns a formatted dump of the parser tree rooted at this node or leaf. This is
        mainly useful for debugging purposes.

        The ``indent`` parameter is interpreted in a similar way as :py:func:`ast.dump`.
        If ``indent`` is a non-negative integer or string, then the tree will be
        pretty-printed with that indent level. An indent level of 0, negative, or ``""``
        will only insert newlines. ``None`` selects the single line representation.
        Using a positive integer indent indents that many spaces per level. If
        ``indent`` is a string (such as ``"\t"``), that string is used to indent each
        level.

        :param indent: Indentation style as described above. The default indentation is
            4 spaces, which yields a pretty-printed dump.

        >>> import parso
        >>> print(parso.parse("lambda x, y: x + y").dump())
        Module([
            Lambda([
                Keyword('lambda', (1, 0)),
                Param([
                    Name('x', (1, 7), prefix=' '),
                    Operator(',', (1, 8)),
                ]),
                Param([
                    Name('y', (1, 10), prefix=' '),
                ]),
                Operator(':', (1, 11)),
                PythonNode('arith_expr', [
                    Name('x', (1, 13), prefix=' '),
                    Operator('+', (1, 15), prefix=' '),
                    Name('y', (1, 17), prefix=' '),
                ]),
            ]),
            EndMarker('', (1, 18)),
        ])
        NF T z,expect 'indent' to be int, str or None, got )r
   r-   	top_levelr   c                sH  d}t | j}t| tr|| | d7 }t| trF|| jd7 }nt| tr`|| j d7 }|| jd| j7 }| j	r|d| j	7 }|d7 }nt| t
r|| | d7 }t| tr|| j d7 }|d7 }r|d7 }x$| jD ]}| || dd	7 }qW || d
7 }ntd| |sDr<|d7 }n|d7 }|S )Nr.   (z, z	, prefix=)[
F)r-   r0   z])zunsupported node encountered: z,
)r   __name__
isinstanceLeaf	ErrorLeaf
token_type	TypedLeafvaluer%   prefixBaseNodeNoder   	TypeError)r
   r-   r0   resultZ	node_typer   )_format_dumpindent_stringnewliner   r   rA      s8    






z%NodeOrLeaf.dump.<locals>._format_dump)r.   T)r6   intstrr?   r	   bool)r   r-   r   )rA   rB   rC   r   dump   s    &


$zNodeOrLeaf.dumpN)T)r5   
__module____qualname____doc__	__slots__rE   __annotations__r   r   r   r"   r$   r   r   rD   r%   r&   r   r'   r(   r)   r+   r   r   r   rG   r   r   r   r   r	      s(   

c               @   s   e Zd ZU dZdZeed< deeeef eddddZ	e
eeef d	d
dZejeeef ddddZdd Zdd Zdd ZdddZe
eeef d	ddZdd ZdS )r7   z
    Leafs are basically tokens with a better API. Leafs exactly know where they
    were defined and what text preceeds them.
    )r;   linecolumnr<   r<   r.   N)r;   r%   r<   r   c             C   s   || _ || _|| _d | _d S )N)r;   r%   r<   r   )r   r;   r%   r<   r   r   r   __init__(  s
    zLeaf.__init__)r   c             C   s   | j | jfS )N)rM   rN   )r   r   r   r   r%   8  s    zLeaf.start_pos)r;   r   c             C   s   |d | _ |d | _d S )Nr   r   )rM   rN   )r   r;   r   r   r   r%   <  s    
c             C   s6   |   }|d kr0t| j}| jt| d dfS |jS )Nr   r   )r"   r   r<   rM   r#   r&   )r   Zprevious_leaflinesr   r   r   r'   A  s
    
zLeaf.get_start_pos_of_prefixc             C   s   | S )Nr   )r   r   r   r   r(   I  s    zLeaf.get_first_leafc             C   s   | S )Nr   )r   r   r   r   r)   L  s    zLeaf.get_last_leafTc             C   s   |r| j | j S | jS d S )N)r<   r;   )r   r*   r   r   r   r+   O  s    zLeaf.get_codec             C   sN   t | j}| jt| d }| j|kr:| jt|d  }nt|d }||fS )Nr   r   )r   r;   rM   r#   rN   )r   rP   Zend_pos_lineZend_pos_columnr   r   r   r&   U  s    

zLeaf.end_posc             C   s"   | j }|s| j}dt| j|f S )Nz<%s: %s>)r;   r   r5   )r   r;   r   r   r   __repr__`  s    zLeaf.__repr__)r.   )T)r5   rH   rI   rJ   rK   rE   rL   r   rD   rO   propertyr%   setterr'   r(   r)   r+   r&   rQ   r   r   r   r   r7      s   


r7   c                   s"   e Zd ZdZd fdd	Z  ZS )r:   )r   r.   c                s   t  ||| || _d S )N)superrO   r   )r   r   r;   r%   r<   )	__class__r   r   rO   j  s    zTypedLeaf.__init__)r.   )r5   rH   rI   rK   rO   __classcell__r   r   )rU   r   r:   g  s   r:   c               @   s   e Zd ZdZdZee ddddZee	e
e
f ddd	Zd
d Zee	e
e
f dddZdd ZdddZdddZdd Zdd Zdd ZdS )r=   zd
    The super class for all nodes.
    A node has children, a type and possibly a parent node.
    )r   N)r   r   c             C   s$   || _ d | _x|D ]
}| |_qW d S )N)r   r   )r   r   r   r   r   r   rO   v  s    
zBaseNode.__init__)r   c             C   s   | j d jS )Nr   )r   r%   )r   r   r   r   r%     s    zBaseNode.start_posc             C   s   | j d  S )Nr   )r   r'   )r   r   r   r   r'     s    z BaseNode.get_start_pos_of_prefixc             C   s   | j d jS )Nr   )r   r&   )r   r   r   r   r&     s    zBaseNode.end_posc             C   sL   |rd dd |D S |d jdd}|d dd |dd  D  S d S )	Nr.   c             s   s   | ]}|  V  qd S )N)r+   ).0r!   r   r   r   	<genexpr>  s    z2BaseNode._get_code_for_children.<locals>.<genexpr>r   F)r*   c             s   s   | ]}|  V  qd S )N)r+   )rW   r!   r   r   r   rX     s    r   )joinr+   )r   r   r*   firstr   r   r   _get_code_for_children  s    zBaseNode._get_code_for_childrenTc             C   s   |  | j|S )N)r[   r   )r   r*   r   r   r   r+     s    zBaseNode.get_codeFc                sL    fdd d  kr.j d jks8n td dtj d S )ax  
        Get the :py:class:`parso.tree.Leaf` at ``position``

        :param tuple position: A position tuple, row, column. Rows start from 1
        :param bool include_prefixes: If ``False``, ``None`` will be returned if ``position`` falls
            on whitespace or comments before a leaf
        :return: :py:class:`parso.tree.Leaf` at ``position``, or ``None``
        c                s   | |krFj |  }s$|jk r$d S y|S  tk
rD   |S X t| | d }j | }|jkrt | |S  |d |S d S )N   r   )r   r%   get_leaf_for_positionr    rD   r&   )lowerupperelementr   )binary_searchinclude_prefixespositionr   r   r   ra     s    



z5BaseNode.get_leaf_for_position.<locals>.binary_search)r   r   r   z7Please provide a position that exists within this node.r   r   )r   r&   
ValueErrorr#   )r   rc   rb   r   )ra   rb   rc   r   r   r]     s    	zBaseNode.get_leaf_for_positionc             C   s   | j d  S )Nr   )r   r(   )r   r   r   r   r(     s    zBaseNode.get_first_leafc             C   s   | j d  S )Nr   )r   r)   )r   r   r   r   r)     s    zBaseNode.get_last_leafc             C   s>   |   dddd }dt| j|| jd | jd f S )Nr4   r/   z<%s: %s@%s,%s>r   r   )r+   replacestripr   r5   r%   )r   coder   r   r   rQ     s    zBaseNode.__repr__)T)F)r5   rH   rI   rJ   rK   r   r	   rO   rR   r   rD   r%   r'   r&   r[   r+   r]   r(   r)   rQ   r   r   r   r   r=   o  s   

 r=   c                   s,   e Zd ZdZdZ fddZdd Z  ZS )r>   z+Concrete implementation for interior nodes.)r   c                s   t  | || _d S )N)rT   rO   r   )r   r   r   )rU   r   r   rO     s    zNode.__init__c             C   s   d| j j| j| jf S )Nz
%s(%s, %r))rU   r5   r   r   )r   r   r   r   rQ     s    zNode.__repr__)r5   rH   rI   rJ   rK   rO   rQ   rV   r   r   )rU   r   r>     s   r>   c               @   s   e Zd ZdZdZdZdS )	ErrorNodez
    A node that contains valid nodes/leaves that we're follow by a token that
    was invalid. This basically means that the leaf after this node is where
    Python would mark a syntax error.
    r   Z
error_nodeN)r5   rH   rI   rJ   rK   r   r   r   r   r   ri     s   ri   c                   s2   e Zd ZdZdZdZd	 fdd	Zdd Z  ZS )
r8   z
    A leaf that is either completely invalid in a language (like `$` in Python)
    or is invalid at that position. Like the star in `1 +* 1`.
    )r9   Z
error_leafr.   c                s   t  ||| || _d S )N)rT   rO   r9   )r   r9   r;   r%   r<   )rU   r   r   rO     s    zErrorLeaf.__init__c             C   s    dt | j| jt| j| jf S )Nz<%s: %s:%s, %s>)r   r5   r9   reprr;   r%   )r   r   r   r   rQ     s    zErrorLeaf.__repr__)r.   )	r5   rH   rI   rJ   rK   r   rO   rQ   rV   r   r   )rU   r   r8     s
   r8   N)abcr   r   typingr   r   r   r   Zparso.utilsr   rE   r   r	   r7   r:   r=   r>   ri   r8   r   r   r   r   <module>   s     	GU
