B
    t\&,                 @   s   d dl mZmZ d dlmZmZmZ d dlm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ZG dd deZG dd deZG dd deZdS )    )abstractmethodabstractproperty)	utf8_reprencoding
py_version)split_linesc             G   s&   x | j } | dks| j|kr| S qW dS )a;  
    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.

    :param node: The ancestors of this node will be checked.
    :param node_types: type names that are searched for.
    :type node_types: tuple of str
    N)parenttype)nodeZ
node_types r   )lib/python3.7/site-packages/parso/tree.pysearch_ancestor   s    	r   c               @   s   e Zd ZdZdZdZdd Zdd Zdd	 Zd
d Z	dd Z
edd Zedd Zedd Zedd Zedd ZedddZdS )
NodeOrLeafz.
    The base class for nodes and leaves.
    r   Nc             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   )selfZscoper   r   r   get_root_node    s    
zNodeOrLeaf.get_root_nodec          	   C   sL   xFt | jjD ]6\}}|| kry| jj|d  S  tk
rB   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)	enumerater   children
IndexError)r   ichildr   r   r   get_next_sibling*   s    zNodeOrLeaf.get_next_siblingc             C   sB   x<t | j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.
        r   Nr   )r   r   r   )r   r   r   r   r   r   get_previous_sibling7   s
    zNodeOrLeaf.get_previous_siblingc             C   sv   | }xB|j j}||}|dkr6|j }|j dkrDdS q||d  }P qW x(y|jd }W qJ tk
rl   |S X qJW dS )z
        Returns the previous leaf in the parser tree.
        Returns `None` if this is the first element in the parser tree.
        r   Nr   )r   r   indexAttributeError)r   r
   cr   r   r   r   get_previous_leafD   s    

zNodeOrLeaf.get_previous_leafc             C   s~   | }xJ|j j}||}|t|d kr>|j }|j dkrLdS q||d  }P qW x(y|jd }W qR tk
rt   |S X qRW dS )z
        Returns the next leaf in the parser tree.
        Returns None if this is the last element in the parser tree.
        r   Nr   )r   r   r   lenr   )r   r
   r   r   r   r   r   get_next_leaf[   s    

zNodeOrLeaf.get_next_leafc             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_posr   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_posz   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 input 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)T)__name__
__module____qualname____doc__	__slots__r	   r   r   r   r   r   r   r    r!   r   r"   r#   r$   r&   r   r   r   r   r      s   
r   c               @   sr   e Zd ZdZdZdddZedd Zejdd Zd	d
 Z	dd Z
dd ZdddZedd Zedd ZdS )Leafz
    Leafs are basically tokens with a better API. Leafs exactly know where they
    were defined and what text preceeds them.
    )valuer   linecolumnprefix c             C   s   || _ || _|| _d | _d S )N)r-   r    r0   r   )r   r-   r    r0   r   r   r   __init__   s
    zLeaf.__init__c             C   s   | j | jfS )N)r.   r/   )r   r   r   r   r       s    zLeaf.start_posc             C   s   |d | _ |d | _d S )Nr   r   )r.   r/   )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   r0   r.   r   r!   )r   Zprevious_leaflinesr   r   r   r"      s
    
zLeaf.get_start_pos_of_prefixc             C   s   | S )Nr   )r   r   r   r   r#      s    zLeaf.get_first_leafc             C   s   | S )Nr   )r   r   r   r   r$      s    zLeaf.get_last_leafTc             C   s   |r| j | j S | jS d S )N)r0   r-   )r   r%   r   r   r   r&      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-   r.   r   r/   )r   r3   Zend_pos_lineZend_pos_columnr   r   r   r!      s    

zLeaf.end_posc             C   s"   | j }|s| j}dt| j|f S )Nz<%s: %s>)r-   r	   r'   )r   r-   r   r   r   __repr__   s    zLeaf.__repr__N)r1   )T)r'   r(   r)   r*   r+   r2   propertyr    setterr"   r#   r$   r&   r!   r   r4   r   r   r   r   r,      s   

r,   c                   s"   e Zd ZdZd fdd	Z  ZS )	TypedLeaf)r	   r1   c                s   t t| ||| || _d S )N)superr7   r2   r	   )r   r	   r-   r    r0   )	__class__r   r   r2      s    zTypedLeaf.__init__)r1   )r'   r(   r)   r+   r2   __classcell__r   r   )r9   r   r7      s   r7   c               @   sx   e Zd ZdZdZdZdd Zedd Zdd	 Z	ed
d Z
dd ZdddZdddZdd Zdd Zedd ZdS )BaseNodezd
    The super class for all nodes.
    A node has children, a type and possibly a parent node.
    )r   r   Nc             C   s   || _ d | _d S )N)r   r   )r   r   r   r   r   r2      s    zBaseNode.__init__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 )	Nr1   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&   )r<   r   r   r   r   r=     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   intr!   )lowerupperelementr   )binary_searchinclude_prefixespositionr   r   r   rG   #  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   rI   rH   r   )rG   rH   rI   r   r   rB     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   sR   |   dddd }tdks0|td}dt| j|| jd | jd f S )	N
    replacez<%s: %s@%s,%s>r   r   )	r&   rO   stripr   encoder   r	   r'   r    )r   coder   r   r   r4   A  s
    zBaseNode.__repr__)T)F)r'   r(   r)   r*   r+   r	   r2   r5   r    r"   r!   r@   r&   rB   r#   r$   r   r4   r   r   r   r   r;      s   

!r;   c                   s,   e Zd ZdZdZ fddZdd Z  ZS )Nodez+Concrete implementation for interior nodes.)r	   c                s   t t| | || _d S )N)r8   rS   r2   r	   )r   r	   r   )r9   r   r   r2   N  s    zNode.__init__c             C   s   d| j j| j| jf S )Nz
%s(%s, %r))r9   r'   r	   r   )r   r   r   r   r4   R  s    zNode.__repr__)r'   r(   r)   r*   r+   r2   r4   r:   r   r   )r9   r   rS   J  s   rS   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)r'   r(   r)   r*   r+   r	   r   r   r   r   rT   V  s   rT   c                   s2   e Zd ZdZdZdZd	 fdd	Zdd Z  ZS )
	ErrorLeafz
    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`.
    )
token_typeZ
error_leafr1   c                s   t t| ||| || _d S )N)r8   rU   r2   rV   )r   rV   r-   r    r0   )r9   r   r   r2   h  s    zErrorLeaf.__init__c             C   s    dt | j| jt| j| jf S )Nz<%s: %s:%s, %s>)r	   r'   rV   reprr-   r    )r   r   r   r   r4   l  s    zErrorLeaf.__repr__)r1   )	r'   r(   r)   r*   r+   r	   r2   r4   r:   r   r   )r9   r   rU   `  s
   rU   N)abcr   r   Zparso._compatibilityr   r   r   Zparso.utilsr   r   objectr   r,   r7   r;   rS   rT   rU   r   r   r   r   <module>   s    GX
