
    ?dY*                        d Z ddl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 G d	 d
e      Zd Zd Zd Zej"                  j%                         Zej(                  d= ej*                  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&y)"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	ENDMARKERc                   $    e Zd ZdZdZdZdZdZdZy)
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     :/usr/lib/python3/dist-packages/yapf/pytree/pytree_utils.pyr   r   +   s    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'   4   s=     
YY_>>$))$$  ..tyy99r   c                 j    t        | t        j                        r| S t        | j                  d         S )Nr   )
isinstancer   LeafFirstLeafNodechildrenr%   s    r   r+   r+   F   s)    fkk"K	t}}Q'	((r   c                 j    t        | t        j                        r| S t        | j                  d         S )N)r)   r   r*   LastLeafNoder,   r%   s    r   r/   r/   L   s)    fkk"K	dmmB'	((r   execnonlocalc                 :   | j                  t        j                        s| t        j                  z  } 	 t        j                  t
        t        j                        }|j                  | d      }t        |      S # t        j                  $ r 	 t        j                  t        t        j                        }|j                  | d      }nA# t        j                  $ r+ 	 t        j                  |         # t        $ r}|d}~ww xY ww xY wY t        |      S w xY w)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)endswithoslinesepr   Driver_GRAMMAR_FOR_PY3r   r3   parse_stringr   
ParseError_GRAMMAR_FOR_PY2astSyntaxError_WrapEndMarker)codeparser_drivertreees       r   ParseCodeToTreerD   ^   s     
rzz	"BJJD MM"2FNNKM%%d%%8D 
	 
		 
mm$4fnnMm''E':d 		$ 	  	  
	sM   <A; ;D<CDD
 C65D
6	D?DDD

DDc                     t        | t        j                        rL| 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   r*   r!   r   r   Noder   python_symbols
file_input)rB   s    r   r?   r?      sE     fkk"tyyEOO'C;;v,,77$@@	+r   c                 .    | D ]  }t        ||d        y)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   InsertNodesBeforerP      s      -d$e,-r   c                 @    t        |       D ]  }t        ||d        y)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.
  TrJ   N)reversedrL   rM   s      r   InsertNodesAfterrS      s$     y! ,d$d+,r   c                    | j                   t        d| | j                   f      |j                   }|t        d|f      t        |j                        D ]&  \  }}||u s|r|dz   n|}|j	                  ||         y 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	enumerater,   insert_child)new_noderO   rK   parent_of_targetichildinsertion_indexs          r   rL   rL      s    " __ 
B (//24 4 ]]
>	
JJ,556 ha!&AAo##OX>	 	EY	   r   _yapf_annotation_c           
          t        |       D ]0  }|j                  t              st        ||t	        | |d             2 y)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   CopyYapfAnnotationsri      s;     H ?j45c:wsJ=>?r   c                 *    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.
  re   rc   )r&   rh   defaults      r   GetNodeAnnotationrm      s     
.;W	EEr   c                 ,    t        | t        |z   |       y)zSet annotation value on a node.

  Arguments:
    node: the node.
    annotation: annotation name - a string.
    value: annotation value to set.
  Nrd   rc   )r&   rh   values      r   SetNodeAnnotationrq      s     
$'*4e<r   c                 j    t        | |t                     }|j                  |       t        | ||       y)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)rm   setaddrq   )r&   rh   rp   attrs       r   AppendNodeAnnotationrv     s+     
4SU	3$((5/D*d+r   c                     t        | t        j                        }|r2||v r-|j                  |       t	        | t        j                  |       yyy)zRemoves an annotation value from the subtype annotations on the node.

  Arguments:
    node: the node.
    value: annotation value to remove.
  N)rm   r   r   removerq   )r&   rp   ru   s      r   RemoveSubtypeAnnotationry     sD     
4!3!3	4$	etmKKdJ..5 Tr   c                 *    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_bracketNrk   r%   s    r   GetOpeningBracketr|     s     
.1DDd	KKr   c                 ,    t        | t        dz   |       y)zoSet opening bracket value for a node.

  Arguments:
    node: the node.
    bracket: opening bracket to set.
  r{   Nro   )r&   brackets     r   SetOpeningBracketr   +  s     
$'*==wGr   c                    t        | t        j                        rkd}|j                  t	        |       t        |       | j                  | j                  t        | j                        t        | t        j                  d            S d}|j                  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)namerp   linenocolumnprefixpenaltyz1{node} [{len} children] [child_indent="{indent}"])r&   lenindent)r)   r   r*   formatr'   _PytreeNodeReprr   r   reprr   rm   r   r   r   r,   r   )r&   fmts     r   DumpNodeToStringr   5  s     fkk"1C::d^d#{{{{DKK !$
(@(@$G  I I >C::d^ z'>'>?  A Ar   c           
      l   t        | t        j                        rI| j                  j                  dt        |       d| j                  D cg c]  }t        |       c}dS t        | t        j                        r2| j                  j                  dt        |       d| j                  dS yc c}w )zCLike pytree.Node.__repr__, but names instead of numbers for tokens.(z, )N)
r)   r   rF   	__class__r   r'   r,   r   r*   rp   )r&   cs     r   r   r   P  s~    fkk">>22HTN8<F1OA.FH Hfkk">>22HTNDJJOO # Gs   B1c                 v    t        |       dk(  xr* | j                  d   j                  t        j                  k(  S )Nsimple_stmtr   )r'   r,   r!   r   COMMENTr%   s    r   IsCommentStatementr   Y  s3    
4.M
) 1
--


5==
02r   )F)N)'r   r=   r6   lib2to3r   r   lib2to3.pgen2r   r   r   	frozensetNONSEMANTIC_TOKENSobjectr   r'   r+   r/   !python_grammar_no_print_statementcopyr9   keywordsr#   r<   rD   r?   rP   rS   rL   rc   ri   rm   rq   rv   ry   r|   r   r   r   r   r   r   r   <module>r      s     	       KL  :$)) ;;@@B f%((--/ j)%P -,! P . 	?F=
,
6	LHA6P2r   