3
%^1                 @   s&   d dl Z d dlmZ G dd dZdS )    N)	lru_cachec               @   sZ   e Zd ZdZdZdd Zeeddd Zdd	 Zd
d Z	dddZ
dddZdd ZdS )TransformVisitorzA visitor for handling transforms.

    The standard approach of using it is to call
    :meth:`~visit` with an *astroid* module and the class
    will take care of the rest, walking the tree and running the
    transforms for each encountered node.
    i'  c             C   s   t jt| _d S )N)collectionsdefaultdictlist
transforms)self r	   5/tmp/pip-build-8app2_gc/astroid/astroid/transforms.py__init__   s    zTransformVisitor.__init__)maxsizec             C   sd   |j }|| jkr|S | j| }x@|D ]8\}}|dks<||r$||}|dk	rP|}|j |kr$P q$W |S )zdCall matching transforms for the given node if any and return the
        transformed node.
        N)	__class__r   )r   nodeclsr   Ztransform_func	predicateretr	   r	   r
   
_transform   s    


zTransformVisitor._transformc             C   sL   t |drBx6|jD ],}t||}| j|}||krt||| qW | j|S )N_astroid_fields)hasattrr   getattr_visit_genericsetattrr   )r   r   namevaluevisitedr	   r	   r
   _visit2   s    


zTransformVisitor._visitc                sZ   t |tr fdd|D S t |tr<t fdd|D S | sLt |trP|S  j|S )Nc                s   g | ]} j |qS r	   )r   ).0child)r   r	   r
   
<listcomp>=   s    z3TransformVisitor._visit_generic.<locals>.<listcomp>c             3   s   | ]} j |V  qd S )N)r   )r   r   )r   r	   r
   	<genexpr>?   s    z2TransformVisitor._visit_generic.<locals>.<genexpr>)
isinstancer   tuplestrr   )r   r   r	   )r   r
   r   ;   s    

zTransformVisitor._visit_genericNc             C   s   | j | j||f dS )a7  Register `transform(node)` function to be applied on the given
        astroid's `node_class` if `predicate` is None or returns true
        when called with the node as argument.

        The transform function may return a value which is then used to
        substitute the original node in the tree.
        N)r   append)r   
node_class	transformr   r	   r	   r
   register_transformE   s    z#TransformVisitor.register_transformc             C   s   | j | j||f dS )zUnregister the given transform.N)r   remove)r   r$   r%   r   r	   r	   r
   unregister_transformO   s    z%TransformVisitor.unregister_transformc                s     fdd|j D |_  j|S )zWalk the given astroid *tree* and transform each encountered node

        Only the nodes which have transforms registered will actually
        be replaced or changed.
        c                s   g | ]} j |qS r	   )r   )r   r   )r   r	   r
   r   Y   s    z*TransformVisitor.visit.<locals>.<listcomp>)bodyr   )r   moduler	   )r   r
   visitS   s    zTransformVisitor.visit)N)N)__name__
__module____qualname____doc__ZTRANSFORM_MAX_CACHE_SIZEr   r   r   r   r   r&   r(   r+   r	   r	   r	   r
   r      s   	



r   )r   	functoolsr   r   r	   r	   r	   r
   <module>	   s   