o
    @a#                     @   sh   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ZddlmZ G dd	 d	eZdS )
zG ArgumentReadOnce counts the usages of each argument of each function.     )Aliases)GlobalDeclarations)ModuleAnalysis)MODULESN)reducec                       s   e Zd ZdZG dd deZG dd deZG dd de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dd Zdd Zdd Zd d! Zd"d# Zd$d% Zd&d' Zd(d) Z  ZS )*ArgumentReadOncea  
    Counts the usages of each argument of each function.

    Attributes
    ----------
    result : {FunctionEffects}
        Number of use for each argument of each function.
    node_to_functioneffect : {???: ???}
        FunctionDef ast node to function effect binding.
    c                   @      e Zd Zdd ZdS )z ArgumentReadOnce.FunctionEffectsc                 C   sp   || _ dd | _t|tjrdgt|jj | _d S t|tj	r+dd |j
D | _d S t|tjr6g | _d S t)Nc                 S      dS Nr    ctxr   r   E/usr/lib/python3/dist-packages/pythran/analyses/argument_read_once.py<lambda>       z;ArgumentReadOnce.FunctionEffects.__init__.<locals>.<lambda>c                 S   s    g | ]}t |tjrd ndqS )      )
isinstance	intrinsicZReadOnceEffect).0xr   r   r   
<listcomp>!   s
    z=ArgumentReadOnce.FunctionEffects.__init__.<locals>.<listcomp>)funcdependenciesr   astZFunctionDeflenargsread_effectsr   Z	IntrinsicZargument_effectsaliasNotImplementedErrorselfnoder   r   r   __init__   s   

z)ArgumentReadOnce.FunctionEffects.__init__N__name__
__module____qualname__r$   r   r   r   r   FunctionEffects       r)   c                   @   r   )z#ArgumentReadOnce.ConstructorEffectsc                 C   s   || _ dd | _dg| _d S )Nc                 S   r	   r
   r   r   r   r   r   r   ,   r   z>ArgumentReadOnce.ConstructorEffects.__init__.<locals>.<lambda>r   )r   r   r   r!   r   r   r   r$   *   s   
z,ArgumentReadOnce.ConstructorEffects.__init__Nr%   r   r   r   r   ConstructorEffects)   r*   r+   c                   @   r   )zArgumentReadOnce.Contextc                 C   s   || _ || _|| _|| _d S N)functionindexpathglobal_dependencies)r"   r-   r.   r/   r0   r   r   r   r$   0   s   
z!ArgumentReadOnce.Context.__init__Nr%   r   r   r   r   Context/   r*   r1   c                    s&   t  | _t | _tt| tt dS )z) Basic initialiser for class attributes. N)	setresultdictnode_to_functioneffectsuperr   r$   r   r   r"   	__class__r   r   r$   6   s   zArgumentReadOnce.__init__c                    sh   t t| j D ]}t|}|j|< j| q fdd t	 D ]} | q+dS )z
        Initialise arguments effects as this analysis in inter-procedural.

        Initialisation done for Pythonic functions and default values set for
        user defined functions.
        c                    s\   |   D ]'}t|tr | qt|}|j|< j| t|tj	r+ |j
 qdS )z; Recursively save read once effect for Pythonic functions. N)valuesr   r4   r   r)   r5   r3   addr   ZClassZfields)moduleZintrfesave_effectr"   r   r   r?   K   s   




z-ArgumentReadOnce.prepare.<locals>.save_effectN)
r6   r   prepareglobal_declarationsr:   r)   r5   r3   r;   r   )r"   r#   nr=   r<   r8   r>   r   r@   <   s   


zArgumentReadOnce.preparec                    sT   t t| |}|D ]}tt|jD ]
}| ||t  qq
dd |D | _| jS )Nc                 S   s   i | ]}|j |jqS r   )r   r   )r   fr   r   r   
<dictcomp>_       z(ArgumentReadOnce.run.<locals>.<dictcomp>)	r6   r   runranger   r   recursive_weightr2   r3   )r"   r#   r3   Zfunir8   r   r   rF   Z   s   zArgumentReadOnce.runc              	   C   s~   t |j|kr	dS |j| dkr:||v }|| |r,d|t|||d |j|< n|t|||d|j|< |j| S )Nr   r   r   FT)r   r   r;   r   r   r1   )r"   r-   r.   Zpredecessorscycler   r   r   rH   b   s"   


z!ArgumentReadOnce.recursive_weightc              	   C   sf   t |tjr|j}t |tjs|| jv r1| j| D ]}z| jjjj|W   S  t	y0   Y qw dS )Nr   )
r   r   	Subscriptvaluealiasescurrent_functionr   r   r.   
ValueError)r"   r#   Zn_aliasr   r   r   argument_indext   s   
zArgumentReadOnce.argument_indexc                    s   |  | fddS )Nc                    s   | j kr S dS r
   )r.   r   effectr.   r   r   r      s    z/ArgumentReadOnce.local_effect.<locals>.<lambda>)rP   )r"   r#   rR   r   rQ   r   local_effect   s   
zArgumentReadOnce.local_effectc                    s$   fddt |D   fddS )Nc                       g | ]}  |qS r   visit)r   childr7   r   r   r      rE   z2ArgumentReadOnce.generic_visit.<locals>.<listcomp>c                    s   t  fddD S )Nc                 3       | ]}| V  qd S r,   r   r   lr   r   r   	<genexpr>       zCArgumentReadOnce.generic_visit.<locals>.<lambda>.<locals>.<genexpr>sumr   )lambdasr   r   r      rE   z0ArgumentReadOnce.generic_visit.<locals>.<lambda>)r   Ziter_child_nodesr!   r   )r_   r"   r   generic_visit   s   zArgumentReadOnce.generic_visitc                 C   s.   | j | | _| j| jv sJ | || j_d S r,   )r5   rN   r3   r`   r   r!   r   r   r   visit_FunctionDef   s   z"ArgumentReadOnce.visit_FunctionDefc                    s8   |  | t|jtjr| |jd fddS  S )Nr   c                        | |  S r,   r   r   deplocalr   r   r          z/ArgumentReadOnce.visit_Return.<locals>.<lambda>)r`   r   rL   r   NamerS   r!   r   rc   r   visit_Return   s
   
zArgumentReadOnce.visit_Returnc                    s,    | fdd|jD  fddS )Nc                    s$   g | ]}t |tjr |d qS )r   )r   r   rK   rS   )r   tr7   r   r   r      s    
z1ArgumentReadOnce.visit_Assign.<locals>.<listcomp>c                    s    t  fddD  S )Nc                 3   rX   r,   r   rY   r   r   r   r[      r\   zBArgumentReadOnce.visit_Assign.<locals>.<lambda>.<locals>.<genexpr>r]   r   rc   r   r   r      s    z/ArgumentReadOnce.visit_Assign.<locals>.<lambda>)r`   targetsr!   r   )rd   re   r"   r   visit_Assign   s   
zArgumentReadOnce.visit_Assignc                    &   |  | | |jd fddS )Nr   c                    rb   r,   r   r   rc   r   r   r      rf   z2ArgumentReadOnce.visit_AugAssign.<locals>.<lambda>)r`   rS   targetr!   r   rc   r   visit_AugAssign      
z ArgumentReadOnce.visit_AugAssignc                    sT    |jd|jfdd|jD  fdd|jD  fddS )Nr   c                    rT   r   rU   r   Zstmtr7   r   r   r      rE   z.ArgumentReadOnce.visit_For.<locals>.<listcomp>c                    rT   r   rU   rp   r7   r   r   r      rE   c                    s@      dt  fddD   t  fddD  S )Nr   c                 3   rX   r,   r   rY   r   r   r   r[          
z?ArgumentReadOnce.visit_For.<locals>.<lambda>.<locals>.<genexpr>c                 3   rX   r,   r   rY   r   r   r   r[      r\   r]   r   )	body_deps	else_deps	iter_deps
iter_localr   r   r      s
    
z,ArgumentReadOnce.visit_For.<locals>.<lambda>)rS   iterrV   bodyorelser!   r   )rr   rs   rt   ru   r"   r   	visit_For   s
   zArgumentReadOnce.visit_Forc                    D    |jfdd|jD  fdd|jD  fddS )Nc                    rT   r   rU   rp   r7   r   r   r      rE   z0ArgumentReadOnce.visit_While.<locals>.<listcomp>c                    rT   r   rU   rp   r7   r   r   r      rE   c                    s8    dt  fddD   t  fddD  S )Nr   c                 3   rX   r,   r   rY   r   r   r   r[      rq   zAArgumentReadOnce.visit_While.<locals>.<lambda>.<locals>.<genexpr>c                 3   rX   r,   r   rY   r   r   r   r[      r\   r]   r   rr   rs   	test_depsr   r   r      s
    
z.ArgumentReadOnce.visit_While.<locals>.<lambda>rV   testrw   rx   r!   r   rr   rs   r"   r|   r   visit_While      zArgumentReadOnce.visit_Whilec                    rz   )Nc                    rT   r   rU   rp   r7   r   r   r      rE   z-ArgumentReadOnce.visit_If.<locals>.<listcomp>c                    rT   r   rU   rp   r7   r   r   r      rE   c                    s6    t t fddD t fddD  S )Nc                 3   rX   r,   r   rY   r   r   r   r[      rq   z>ArgumentReadOnce.visit_If.<locals>.<lambda>.<locals>.<genexpr>c                 3   rX   r,   r   rY   r   r   r   r[      r\   )maxr^   r   r{   r   r   r      s
    z+ArgumentReadOnce.visit_If.<locals>.<lambda>r}   r!   r   r   r   visit_If   r   zArgumentReadOnce.visit_Ifc           	         s    |t d  t|jD ]I\}}|}|dkrXj|j }tfdd|t }|D ](}t	|t
jrB|jd j}j| }|tju rHq/|jvrNq/j|  ||< q/q fdd}|S )Nr   c                    s4   | t |tjr |dkrt j  S |g S r
   )r   r   rg   rP   listr5   keys)r   yr7   r   r   r      s    
z-ArgumentReadOnce.visit_Call.<locals>.<lambda>c                    sB   | }| j v r| jr | j  | j}|| S d}|| S r
   )r.   r0   rH   r/   )r   baseZrecr   Zindex_corresZl0r"   r   r   merger   s   z+ArgumentReadOnce.visit_Call.<locals>.merger)r`   r4   	enumerater   rP   rM   r   r   r   r   r   ZCallidrA   r   ZUnboundValuer5   )	r"   r#   rI   argrB   Zfunc_aliasesZ
func_aliasZ
bound_namer   r   r   r   
visit_Call   s2   








	zArgumentReadOnce.visit_Callc                    rl   )Nr   c                    rb   r,   r   r   rc   r   r   r      rf   z2ArgumentReadOnce.visit_Subscript.<locals>.<lambda>)r`   rS   rL   r!   r   rc   r   visit_Subscript   ro   z ArgumentReadOnce.visit_Subscriptc                    rl   )Nr   c                    rb   r,   r   r   rc   r   r   r      rf   z6ArgumentReadOnce.visit_comprehension.<locals>.<lambda>)r`   rS   rv   r!   r   rc   r   visit_comprehension   ro   z$ArgumentReadOnce.visit_comprehension)r&   r'   r(   __doc__objectr)   r+   r1   r$   r@   rF   rH   rP   rS   r`   ra   rh   rk   rn   ry   r   r   r   r   r   __classcell__r   r   r8   r   r      s,    .r   )r   Zpythran.analyses.aliasesr   Z$pythran.analyses.global_declarationsr   Zpythran.passmanagerr   Zpythran.tablesr   Zpythran.intrinsicr   Zgastr   	functoolsr   r   r   r   r   r   <module>   s    