o
    @a                     @   s   d 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
 ddlmZ ddlZdd	lmZ G d
d deZi Zdd Ze D ]Zee qBG dd deZdS )z5 ArgumentEffects computes write effect on arguments.     )Aliases)GlobalDeclarations)ModuleAnalysis)MODULES)DiGraph)	intrinsicN)reducec                   @   s   e Zd Zdd ZdS )FunctionEffectsc                 C   s|   || _ t|tjrdgt|jj | _d S t|tjr&dd |j	D | _d S t|tj
r1g | _d S t|tjr<g | _d S t)NFc                 S   s   g | ]}t |tjqS  )
isinstancer   ZUpdateEffect).0xr
   r
   C/usr/lib/python3/dist-packages/pythran/analyses/argument_effects.py
<listcomp>   s    z,FunctionEffects.__init__.<locals>.<listcomp>)funcr   astZFunctionDeflenargsupdate_effectsr   Z	IntrinsicZargument_effectsaliasClassNotImplementedErrorselfnoder
   r
   r   __init__   s   

zFunctionEffects.__init__N)__name__
__module____qualname__r   r
   r
   r
   r   r	      s    r	   c                 C   sL   |   D ]}t|trt| qt|}|t|< t|tjr#t|j qdS )z: Recursively save function effect for pythonic functions. N)	valuesr   dictsave_function_effectr	   IntrinsicArgumentEffectsr   r   Zfields)moduleZintrfer
   r
   r   r!   #   s   


r!   c                       sh   e Zd ZdZ fddZ fddZ fddZdd	 Zd
d Zdd Z	dd Z
dd Zdd Z  ZS )ArgumentEffectsz7Gathers inter-procedural effects on function arguments.c                    sB   t  | _t | _t D ]}| j| qtt| 	t
t d S )N)r   resultr"   copynode_to_functioneffectr   add_nodesuperr%   r   r   r   )r   r$   	__class__r
   r   r   7   s
   
zArgumentEffects.__init__c                    sB   t t| | | j D ]}t|}|| j|< | j| qdS )z
        Initialise arguments effects as this analyse is inter-procedural.

        Initialisation done for Pythonic functions and default value set for
        user defined functions.
        N)	r*   r%   prepareglobal_declarationsr   r	   r(   r&   r)   )r   r   nr$   r+   r
   r   r-   >   s   
zArgumentEffects.preparec                    s   t t| |}t|}|rX| }t|jD ]>}|\}}|s q||D ]/}|j||f }	t|	d D ]}
|
\}}|	d | }||krS|j| sSd|j|< |	| q4q%q|sdd |D | _
| j
S )Nformal_parameterseffective_parametersTc                 S   s   i | ]}|j |jqS r
   )r   r   )r   fr
   r
   r   
<dictcomp>`   s    z'ArgumentEffects.run.<locals>.<dictcomp>)r*   r%   runsetpop	enumerater   predecessorsedgesaddr&   )r   r   r&   Z
candidatesfunctionZueZupdate_effect_idxZupdate_effectZprededgefpiZformal_parameter_idxZith_effectivr+   r
   r   r4   K   s0   

zArgumentEffects.runc                 C   s   t |tjr|j}t |tjs| j| D ])}t |tjr%|j}t |tjs|| jv r1| j|   S || jv r=| j|   S qdS )N)r   r   	Subscriptvaluealiasescurrent_argumentscurrent_subscripted_arguments)r   r   Z
node_aliasr
   r
   r   argument_indexc   s   

zArgumentEffects.argument_indexc                 C   sJ   | j | | _dd t|jjD | _t | _| j| jv sJ | | d S )Nc                 S   s   i | ]\}}||qS r
   r
   )r   r>   argr
   r
   r   r3   q   s    
z5ArgumentEffects.visit_FunctionDef.<locals>.<dictcomp>)	r(   current_functionr7   r   rC   r    rD   r&   generic_visitr   r
   r
   r   visit_FunctionDefo   s   
z!ArgumentEffects.visit_FunctionDefc                 C   s.   |  |j}|dkr|| j|j< | | d S Nr   )rE   iterrD   targetrH   )r   r   Zair
   r
   r   	visit_Forx      zArgumentEffects.visit_Forc                 C   s.   |  |j}|dkrd| jj|< | | d S Nr   T)rE   rL   rG   r   rH   )r   r   r/   r
   r
   r   visit_AugAssign~   rN   zArgumentEffects.visit_AugAssignc                 C   sD   |j D ]}t|tjr| |}|dkrd| jj|< q| | d S rO   )targetsr   r   r@   rE   rG   r   rH   )r   r   tr/   r
   r
   r   visit_Assign   s   

zArgumentEffects.visit_Assignc                    sf  t |jD ]\}} |}|dkr j|j }|d u r#d jj|< qt fdd|t }|D ]z}t	|t
jrC|jd j} j| }|tju rIq0| jvrOq0|td d u rx j|jd  } j| }	t|dkrwtt|}
 j|
|	}	n j| }	 j|	} j|vr jj j|	g g d  jj j|	f }|d	 | |d
 | q0q | d S )Nr   Tc                    s4   | t |tjr |dkrt j  S |g S rJ   )r   r   NamerE   listr(   keys)r   yr   r
   r   <lambda>   s    
z,ArgumentEffects.visit_Call.<locals>.<lambda>	functoolspartial   )r1   r0   r1   r0   )r7   r   rE   rB   r   rG   r   r   rU   r   r   ZCallidr.   r   ZUnboundValuer(   r   r   nextrK   getr&   r8   Zadd_edger9   appendrH   )r   r   r>   rF   r/   Zfunc_aliasesZ
func_aliasZ
bound_nameZbase_func_aliasesr$   Zbase_func_aliasr8   r<   r
   rX   r   
visit_Call   sX   








zArgumentEffects.visit_Call)r   r   r   __doc__r   r-   r4   rE   rI   rM   rP   rS   ra   __classcell__r
   r
   r+   r   r%   3   s    	r%   )rb   Zpythran.analyses.aliasesr   Z$pythran.analyses.global_declarationsr   Zpythran.passmanagerr   Zpythran.tablesr   Zpythran.graphr   Zpythranr   Zgastr   rZ   r   objectr	   r"   r!   r   r#   r%   r
   r
   r
   r   <module>   s    
