
    `N`p*                        d Z ddlZddlmZ ddlmZ ddlmZ ddlmZ ddlmZ  e	g d          Z
 e	h d	          Z e	h d
          Z G d de          Zd Zd Zd Zej                                        Zej        d= ej                                        Zej        d= d Zd Zd Zd Zd#dZdZd Zd$dZd Z d Z!d Z"d Z#d Z$d  Z%d! Z&d" Z'dS )%a  pytree-related utilities.

This module collects various utilities related to the parse trees produced by
the lib2to3 library.

  NodeName(): produces a string name for pytree nodes.
  ParseCodeToTree(): convenience wrapper around lib2to3 interfaces to parse
                     a given string with code to a pytree.
  InsertNodeBefore(): insert a node before another in a pytree.
  InsertNodeAfter(): insert a node after another in a pytree.
  {Get,Set}NodeAnnotation(): manage custom annotations on pytree nodes.
    N)pygram)pytree)driver)parse)token)DEDENTINDENTNEWLINE	ENDMARKER>   ([{>   )]}c                   &    e Zd ZdZdZdZdZdZdZdS )
Annotationz)Annotation names associated with pytrees.child_indentnewlines
must_splitsplit_penaltysubtypeN)	__name__
__module____qualname____doc__CHILD_INDENTNEWLINES
MUST_SPLITSPLIT_PENALTYSUBTYPE     9lib/python3.11/site-packages/yapf/yapflib/pytree_utils.pyr   r   -   s-        11,(*!-'''r#   r   c                 ~    | j         dk     rt          j        | j                  S t          j        j        | j                  S )zProduce a string name for a given node.

  For a Leaf this is the token name, and for a Node this is the type.

  Arguments:
    node: a tree node

  Returns:
    Name as a string.
     )typer   tok_namer   python_grammarnumber2symbolnodes    r$   NodeNamer-   6   s1     
Y__>$)$$ .ty99r#   c                 n    t          | t          j                  r| S t          | j        d                   S )Nr   )
isinstancer   LeafFirstLeafNodechildrenr+   s    r$   r1   r1   H   s0    fk"" K	t}Q'	(	((r#   c                 n    t          | t          j                  r| S t          | j        d                   S )N)r/   r   r0   LastLeafNoder2   r+   s    r$   r5   r5   N   s0    fk"" K	dmB'	(	((r#   execnonlocalc                    	 t          j        t          t          j                  }|                    | d          }n# t          j        $ r~ 	 t          j        t          t          j                  }|                    | d          }n=# t          j        $ r+ 	 t          j        |             # t          $ r}|d}~ww xY ww xY wY nw xY wt          |          S )a  Parse the given code to a lib2to3 pytree.

  Arguments:
    code: a string with the code to parse.

  Raises:
    SyntaxError if the code is invalid syntax.
    parse.ParseError if some other parsing failure.

  Returns:
    The root node of the parsed tree.
  )convertF)debugN)r   Driver_GRAMMAR_FOR_PY3r   r9   parse_stringr   
ParseError_GRAMMAR_FOR_PY2astSyntaxError_WrapEndMarker)codeparser_drivertreees       r$   ParseCodeToTreerG   `   s     M"2FNKKKM%%d%%88DD		   
m$4fnMMMm''E'::dd   	$ 	    	 d 
		sK   <? C<BCCB10C1
C;B==CCCCc                     t          | t          j                  r:| j        t          j        k    r%t          j        t          j        j	        | g          S | S )aS  Wrap a single ENDMARKER token in a "file_input" node.

  Arguments:
    tree: (pytree.Node) The root node of the parsed tree.

  Returns:
    The root node of the parsed tree. If the tree is a single ENDMARKER node,
    then that node is wrapped in a "file_input" node. That will ensure we don't
    skip comments attached to that node.
  )
r/   r   r0   r'   r   r   Noder   python_symbols
file_input)rE   s    r$   rB   rB      sF     fk"" AtyEO'C'C;v,7$@@@	+r#   c                 4    | D ]}t          ||d           dS )aT  Insert new_nodes before the given target location in the tree.

  Arguments:
    new_nodes: a sequence of new nodes to insert (the nodes should not be in the
      tree).
    target: the target node before which the new node node will be inserted.

  Raises:
    RuntimeError: if the tree is corrupted, or the insertion would corrupt it.
  FafterN)_InsertNodeAt	new_nodestargetr,   s      r$   InsertNodesBeforerS      s5      - -d$e,,,,,- -r#   c                 N    t          |           D ]}t          ||d           dS )aR  Insert new_nodes after the given target location in the tree.

  Arguments:
    new_nodes: a sequence of new nodes to insert (the nodes should not be in the
      tree).
    target: the target node after which the new node node will be inserted.

  Raises:
    RuntimeError: if the tree is corrupted, or the insertion would corrupt it.
  TrM   N)reversedrO   rP   s      r$   InsertNodesAfterrV      s=     y!! , ,d$d+++++, ,r#   Fc                    | j         t          d| | j         f          |j         }|t          d|f          t          |j                  D ]+\  }}||u r"|r|dz   n|}|                    ||             dS ,t          d|f          )a|  Underlying implementation for node insertion.

  Arguments:
    new_node: a new node to insert (this node should not be in the tree).
    target: the target node.
    after: if True, new_node is inserted after target. Otherwise, it's inserted
      before target.

  Returns:
    nothing

  Raises:
    RuntimeError: if the tree is corrupted, or the insertion would corrupt it.
  Nz)inserting node which already has a parentz%expected target node to have a parent   z.unable to find insertion point for target node)parentRuntimeError	enumerater2   insert_child)new_noderR   rN   parent_of_targetichildinsertion_indexs          r$   rO   rO      s    " _ 
B (/24 4 4 ]
>	
J
JJ,566  ha!&-AAo##OX>>>ff 
 	EY	  	   r#   _yapf_annotation_c           
          t          |           D ]<}|                    t                    r t          ||t	          | |d                     =dS )zCopy all YAPF annotations from the source node to the destination node.

  Arguments:
    src: the source node.
    dst: the destination node.
  N)dir
startswith_NODE_ANNOTATION_PREFIXsetattrgetattr)srcdst
annotations      r$   CopyYapfAnnotationsrl      sY     HH ? ?j455 ?c:wsJ==>>>? ?r#   c                 4    t          | t          |z   |          S )aC  Get annotation value from a node.

  Arguments:
    node: the node.
    annotation: annotation name - a string.
    default: the default value to return if there's no annotation.

  Returns:
    Value of the annotation in the given node. If the node doesn't have this
    particular annotation name yet, returns default.
  rh   rf   )r,   rk   defaults      r$   GetNodeAnnotationrp      s     
.;W	E	EEr#   c                 8    t          | t          |z   |           dS )zSet annotation value on a node.

  Arguments:
    node: the node.
    annotation: annotation name - a string.
    value: annotation value to set.
  Nrg   rf   )r,   rk   values      r$   SetNodeAnnotationrt      s"     
$'*4e<<<<<r#   c                     t          | |t                                }|                    |           t          | ||           dS )zAppends an annotation value to a list of annotations on the node.

  Arguments:
    node: the node.
    annotation: annotation name - a string.
    value: annotation value to set.
  N)rp   setaddrt   )r,   rk   rs   attrs       r$   AppendNodeAnnotationry     s@     
4SUU	3	3$((5///D*d+++++r#   c                     t          | t          j                  }|r6||v r4|                    |           t	          | t          j        |           dS dS dS )zRemoves an annotation value from the subtype annotations on the node.

  Arguments:
    node: the node.
    value: annotation value to remove.
  N)rp   r   r!   removert   )r,   rs   rx   s      r$   RemoveSubtypeAnnotationr|     sa     
4!3	4	4$	 6etmmKKdJ.555556 6mmr#   c                 4    t          | t          dz   d          S )zGet opening bracket value from a node.

  Arguments:
    node: the node.

  Returns:
    The opening bracket node or None if it couldn't find one.
  container_bracketNrn   r+   s    r$   GetOpeningBracketr     s     
.1DDd	K	KKr#   c                 8    t          | t          dz   |           dS )zoSet opening bracket value for a node.

  Arguments:
    node: the node.
    bracket: opening bracket to set.
  r~   Nrr   )r,   brackets     r$   SetOpeningBracketr   *  s#     
$'*==wGGGGGr#   c                    t          | t          j                  rld}|                    t	          |           t          |           | j        | j        t          | j	                  t          | t          j        d                    S d}|                    t	          |           t          | j                  t          | t          j                            S )zDump a string representation of the given node. For debugging.

  Arguments:
    node: the node.

  Returns:
    The string representation.
  zV{name}({value}) [lineno={lineno}, column={column}, prefix={prefix}, penalty={penalty}]N)namers   linenocolumnprefixpenaltyz1{node} [{len} children] [child_indent="{indent}"])r,   lenindent)r/   r   r0   formatr-   _PytreeNodeReprr   r   reprr   rp   r   r    r   r2   r   )r,   fmts     r$   DumpNodeToStringr   4  s     fk"" A1C::d^^d##{{DK  !$
(@$GG  I I I >C::d^^ z'>??  A A Ar#   c                    t          | t          j                  r1| j        j        dt          |           dd | j        D             dS t          | t          j                  r'| j        j        dt          |           d| j        dS dS )zCLike pytree.Node.__repr__, but names instead of numbers for tokens.r   z, c                 ,    g | ]}t          |          S r"   )r   ).0cs     r$   
<listcomp>z#_PytreeNodeRepr.<locals>.<listcomp>S  s     FFF1OA..FFFr#   r   N)	r/   r   rI   	__class__r   r-   r2   r0   rs   r+   s    r$   r   r   O  s    fk"" H>222HTNNNNFFFFFFFH Hfk"" P>222HTNNNNDJJJOOP Pr#   c                 h    t          |           dk    o| j        d         j        t          j        k    S )Nsimple_stmtr   )r-   r2   r'   r   COMMENTr+   s    r$   IsCommentStatementr   X  s.    
4..M
) 1
-

5=
02r#   )F)N)(r   r@   lib2to3r   r   lib2to3.pgen2r   r   r   	frozensetNONSEMANTIC_TOKENSOPENING_BRACKETSCLOSING_BRACKETSobjectr   r-   r1   r5   !python_grammar_no_print_statementcopyr<   keywordsr)   r?   rG   rB   rS   rV   rO   rf   rl   rp   rt   ry   r|   r   r   r   r   r   r"   r#   r$   <module>r      s]    


                                     YKKKLL 9___-- 9___--        : : :$) ) )) ) ) ;@@BB f%(--// j)" " "J   - - -, , ,!  !  !  ! P . 	? 	? 	?F F F F= = =
, 
, 
,
6 
6 
6	L 	L 	LH H HA A A6P P P2 2 2 2 2r#   