o
    jĎi>                     @   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dde
ddf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node
NodeOrLeaf
node_typesreturnOptional[BaseNode]c                 G   s
   | j | 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.
    )search_ancestor)r	   r    r   F/home/jeff/fluffinator/venv/lib/python3.10/site-packages/parso/tree.pyr      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deeef fddZedeeef fddZedd Zedd Zedd Zed'ddZdeddfdd Zd!d"d#eeeef  defd$d%Zd&S )(r
   z.
    The base class for nodes and leaves.
    parenttyper   r   c                 C   s"   | }|j dur|j }|j dus|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.
        Nr   )selfscoper   r   r   get_root_node#   s
   

zNodeOrLeaf.get_root_nodec              	   C   s`   | j }|du r	dS t|jD ]\}}|| u r-z| j j|d  W   S  ty,   Y  dS w q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_sibling-   s   zNodeOrLeaf.get_next_siblingc                 C   sT   | j }|du r	dS t|jD ]\}}|| u r'|dkr dS | j j|d    S q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   get_previous_sibling>   s   zNodeOrLeaf.get_previous_siblingc                 C   s~   | j du rdS | }	 |j j}||}|dkr"|j }|j du r!dS n||d  }nq
	 z|jd }W n ty=   | Y S w q+)z
        Returns the previous leaf in the parser tree.
        Returns `None` if this is the first element in the parser tree.
        NTr   r   )r   r   indexAttributeErrorr   r	   cr   r   r   r   get_previous_leafO   s*   


zNodeOrLeaf.get_previous_leafc                 C   s   | j du rdS | }	 |j j}||}|t|d kr&|j }|j du r%dS n||d  }nq
	 z|jd }W n tyA   | Y S w q/)z
        Returns the next leaf in the parser tree.
        Returns None if this is the last element in the parser tree.
        NTr   r   )r   r   r!   lenr"   r#   r   r   r   get_next_leafi   s*   


zNodeOrLeaf.get_next_leafr   c                 C      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       zNodeOrLeaf.start_posc                 C   r(   )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   r+   zNodeOrLeaf.end_posc                 C   r(   )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   r+   z"NodeOrLeaf.get_start_pos_of_prefixc                 C   r(   )zO
        Returns the first leaf of a node or itself if this is a leaf.
        Nr   r)   r   r   r   get_first_leaf   r+   zNodeOrLeaf.get_first_leafc                 C   r(   )zN
        Returns the last leaf of a node or itself if this is a leaf.
        Nr   r)   r   r   r   get_last_leaf   r+   zNodeOrLeaf.get_last_leafTc                 C   r(   )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   r+   zNodeOrLeaf.get_coder   c                 G   s.   | j }|dur|j|v r|S |j }|dus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   )indentr4   c             	      sx   |du r	ddnt |trdd| nt |trd|ntd|ddtdtd	td
tf 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	   r4   	top_levelr   c                    s@  d}t | j}t| trK|| | d7 }t| tr#|| jd7 }nt| tr0|| j d7 }|| jd| j7 }| j	rF|d| j	7 }|d7 }nEt| t
r|| | d7 }t| trf|| j d7 }|d7 }rp|d7 }| jD ]}| || dd	7 }qs|| d
7 }ntd| |sr|d7 }|S |d7 }|S )Nr5   (z, z	, prefix=)[
F)r4   r7   z])zunsupported node encountered: z,
)r   __name__
isinstanceLeaf	ErrorLeaf
token_type	TypedLeafvaluer*   prefixBaseNodeNoder   	TypeError)r	   r4   r7   result	node_typer   _format_dumpindent_stringnewliner   r   rJ      s:   







z%NodeOrLeaf.dump.<locals>._format_dump)r5   T)r=   intstrrF   r
   bool)r   r4   r   rI   r   dump   s   &


$$zNodeOrLeaf.dumpNT)r<   
__module____qualname____doc__	__slots__rN   __annotations__r   r   r   r%   r'   r   r   rM   r*   r,   r   r-   r.   r/   r2   r   r   r   rP   r   r   r   r   r
      s4   
 




(c                	   @   s   e Zd ZU dZdZeed< ddedeeef deddfd	d
Z	e
deeef fddZejdeeef ddfddZdd Zdd Zdd ZdddZe
deeef fddZdd ZdS )r>   z
    Leafs are basically tokens with a better API. Leafs exactly know where they
    were defined and what text preceeds them.
    )rB   linecolumnrC   rC   r5   rB   r*   r   Nc                 C   s    || _ 	 || _|| _	 d | _d S N)rB   r*   rC   r   )r   rB   r*   rC   r   r   r   __init__#  s   zLeaf.__init__c                 C   s   | j | jfS rY   rW   rX   r)   r   r   r   r*   3     zLeaf.start_posc                 C   s   |d | _ |d | _d S )Nr   r   r[   r   rB   r   r   r   r*   7  s   
c                 C   s6   |   }|d u rt| j}| jt| d dfS |jS )Nr   r   )r%   r   rC   rW   r&   r,   )r   previous_leaflinesr   r   r   r-   <  s
   
zLeaf.get_start_pos_of_prefixc                 C      | S rY   r   r)   r   r   r   r.   D     zLeaf.get_first_leafc                 C   r`   rY   r   r)   r   r   r   r/   G  ra   zLeaf.get_last_leafTc                 C   s   |r| j | j S | jS rY   )rC   rB   r0   r   r   r   r2   J  s   zLeaf.get_codec                 C   sT   t | j}| jt| d }| j|kr | jt|d  }||fS t|d }||fS )Nr   r    )r   rB   rW   r&   rX   )r   r_   end_pos_lineend_pos_columnr   r   r   r,   P  s   

zLeaf.end_posc                 C   s"   | j }|s| j}dt| j|f S )Nz<%s: %s>)rB   r   r<   r]   r   r   r   __repr__[  s   zLeaf.__repr__r5   rQ   )r<   rR   rS   rT   rU   rN   rV   r   rM   rZ   propertyr*   setterr-   r.   r/   r2   r,   rd   r   r   r   r   r>     s    
 $

r>   c                       s"   e Zd ZdZd fdd	Z  ZS )rA   r   r5   c                       t  ||| || _d S rY   superrZ   r   )r   r   rB   r*   rC   	__class__r   r   rZ   e     
zTypedLeaf.__init__re   )r<   rR   rS   rU   rZ   __classcell__r   r   rl   r   rA   b  s    rA   c                   @   s   e Zd ZdZdZdddZedeeef fddZ	d	d
 Z
edeeef f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 )rD   zd
    The super class for all nodes.
    A node has children, a type and possibly a parent node.
    )r   r   Nc                 C   s$   || _ 	 d | _	 |D ]}| |_q
d S rY   )r   r   )r   r   r   r   r   r   rZ   q  s   zBaseNode.__init__c                 C      | j d jS Nr   )r   r*   r)   r   r   r   r*   ~  r\   zBaseNode.start_posc                 C      | j d  S rq   )r   r-   r)   r   r   r   r-        z BaseNode.get_start_pos_of_prefixc                 C   rp   Nr    )r   r,   r)   r   r   r   r,     r\   zBaseNode.end_posc                 C   sH   |rd dd |D S |d jdd}|d dd |dd  D  S )	Nr5   c                 s       | ]}|  V  qd S rY   r2   .0r$   r   r   r   	<genexpr>      z2BaseNode._get_code_for_children.<locals>.<genexpr>r   F)r1   c                 s   ru   rY   rv   rw   r   r   r   ry     rz   r   )joinr2   )r   r   r1   firstr   r   r   _get_code_for_children  s    zBaseNode._get_code_for_childrenTc                 C   s   |  | j|S rY   )r}   r   r0   r   r   r   r2     rs   zBaseNode.get_codeFc                    sR    fdd d  krj d jkstd 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r%j |  }s|jk rd S z|W S  ty$   | Y S w t| | d }j | }|jkr< | |S  |d |S )N   r   )r   r*   get_leaf_for_positionr"   rM   r,   )lowerupperelementr!   binary_searchinclude_prefixespositionr   r   r   r     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   r   r   r   r   r   r     s   	zBaseNode.get_leaf_for_positionc                 C   rr   rq   )r   r.   r)   r   r   r   r.     rs   zBaseNode.get_first_leafc                 C   rr   rt   )r   r/   r)   r   r   r   r/     rs   zBaseNode.get_last_leafc                 C   s>   |   dddd }dt| j|| jd | jd f S )Nr;   r6   z<%s: %s@%s,%s>r   r   )r2   replacestripr   r<   r*   )r   coder   r   r   rd     s   zBaseNode.__repr__)r   NrQ   )F)r<   rR   rS   rT   rU   rZ   rf   r   rM   r*   r-   r,   r}   r2   r   r.   r/   rd   r   r   r   r   rD   j  s    


 rD   c                       s,   e Zd ZdZdZ fddZdd Z  ZS )rE   z+Concrete implementation for interior nodes.rh   c                    s   t  | || _d S rY   rj   )r   r   r   rl   r   r   rZ     s   
zNode.__init__c                 C   s   d| j j| j| jf S )Nz
%s(%s, %r))rm   r<   r   r   r)   r   r   r   rd     s   zNode.__repr__)r<   rR   rS   rT   rU   rZ   rd   ro   r   r   rl   r   rE     s
    rE   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   
error_nodeN)r<   rR   rS   rT   rU   r   r   r   r   r   r     s    r   c                       s2   e Zd ZdZdZdZd	 fdd	Zdd Z  ZS )
r?   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`.
    )r@   
error_leafr5   c                    ri   rY   )rk   rZ   r@   )r   r@   rB   r*   rC   rl   r   r   rZ     rn   zErrorLeaf.__init__c                 C   s    dt | j| jt| j| jf S )Nz<%s: %s:%s, %s>)r   r<   r@   reprrB   r*   r)   r   r   r   rd     s   zErrorLeaf.__repr__re   )	r<   rR   rS   rT   rU   r   rZ   rd   ro   r   r   rl   r   r?     s    r?   N)abcr   r   typingr   r   r   r   parso.utilsr   rN   r   r
   r>   rA   rD   rE   r   r?   r   r   r   r   <module>   s      	GU
