o
    e                     @   sB   d Z ddlmZ G dd deZedefi ZG dd deZdS )a
  
Part of the astor library for Python AST manipulation.

License: 3-clause BSD

Copyright 2012 (c) Patrick Maupin
Copyright 2013 (c) Berker Peksag

This file contains a TreeWalk class that views a node tree
as a unified whole and allows several modes of traversal.

   )	iter_nodec                   @   s   e Zd ZdZdd ZdS )MetaFlattenzThis metaclass is used to flatten classes to remove
    class hierarchy.

    This makes it easier to manipulate classes (find
    attributes in a single dict, etc.)

    c                 C   s`   t f}i }t|D ]}||vr|t| q	|| |dd  |dd  t| |||S )N__dict____weakref__)objectreversedupdatevarspoptype__new__)ZclstypenamebasesZclsdictZnewbasesZnewdictbase r   ?D:\Projects\ConvertPro\env\Lib\site-packages\astor/tree_walk.pyr      s   
zMetaFlatten.__new__N)__name__
__module____qualname____doc__r   r   r   r   r   r      s    r   c                   @   sT   e Zd ZdZdddZdd Zdeeefdd	Z	e
d
d Ze
dd Zdd ZdS )TreeWalka  The TreeWalk class can be used as a superclass in order
    to walk an AST or similar tree.

    Unlike other treewalkers, this class can walk a tree either
    recursively or non-recursively.  Subclasses can define
    methods with the following signatures::

        def pre_xxx(self):
            pass

        def post_xxx(self):
            pass

        def init_xxx(self):
            pass

    Where 'xxx' is one of:

      - A class name
      - An attribute member name concatenated with '_name'
        For example, 'pre_targets_name' will process nodes
        that are referenced by the name 'targets' in their
        parent's node.
      - An attribute member name concatenated with '_item'
        For example, 'pre_targets_item'  will process nodes
        that are in a list that is the targets attribute
        of some node.

    pre_xxx will process a node before processing any of its subnodes.
    if the return value from pre_xxx evalates to true, then walk
    will not process any of the subnodes.  Those can be manually
    processed, if desired, by calling self.walk(node) on the subnodes
    before returning True.

    post_xxx will process a node after processing all its subnodes.

    init_xxx methods can decorate the class instance with subclass-specific
    information.  A single init_whatever method could be written, but to
    make it easy to keep initialization with use, any number of init_xxx
    methods can be written.  They will be called in alphabetical order.

    Nc                 C   s(   g | _ |   |d ur| | d S d S N)	nodestacksetupwalk)selfnoder   r   r   __init__W   s
   zTreeWalk.__init__c                 C   s   i  | _ }i  | _}ttt| D ]/}|dr t| |  q|dr1t| |||dd < q|drAt| |||dd < qdS )zYAll the node-specific handlers are setup at
        object initialization time.

        Zinit_Zpre_   NZpost_   )pre_handlerspost_handlerssortedr	   r   
startswithgetattr)r   r    r!   r   r   r   r   r   ]   s   




zTreeWalk.setup c                 C   s|  | j j}| jj}| j}||}	|j|j}
}|
|||t||d dg |||	kr|d \}}}}|||kru|||jpE||d }|du rN|  q%|| _|| _	|  |o\|d }|od|d |u }|rt|d ||d krt|  q%|d |d d< |dk r|||jp||d }|dur|| _|| _	| r|  n|| \}}|
|||t||d dg |||	ks+dS dS )zUWalk the tree starting at a given node.

        Maintain a stack of nodes.

        Z_item_nameN    r   )
r    getr!   r   appendr
   r   r   cur_nodeZcur_name)r   r   r   listlenr   r    r!   r   Z
emptystackr+   r
   ZsubnodesindexhandlercurrentZpopstackr   r   r   r   l   sJ   

zTreeWalk.walkc                 C   s"   | j }t|dk rdS |d d S )z+Return the parent node of the current node.   Nr)   r(   r   r.   r   r   r   r   r   parent   s   zTreeWalk.parentc                 C   s&   | j }t|dk rdS |d dd S )z Return the parent node and name.r2   Nr)   r3   r4   r   r   r   parent_name   s   zTreeWalk.parent_namec           
      C   s   | j }| j}| }|d }|d d }|d | \}}|d |  u r(|u s5n J |d ||d |f|d }	t|	trD||	|< dS t|	|| dS )z<Replace a node after first checking integrity of node stack.r&   r   r)   r(   N)r,   r   r
   
isinstancer-   setattr)
r   new_noder,   r   curprevr/   Zoldnoder   r5   r   r   r   replace   s   *
zTreeWalk.replacer   )r   r   r   r   r   r   r-   r.   r   r   propertyr5   r6   r<   r   r   r   r   r   +   s    
+)

r   N)r   Z	node_utilr   r   r   r   r   r   r   r   r   <module>   s
   