o
    @a`                     @   sP   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	Z
G dd deZdS )	z"
Scope computes scope information
    )AncestorsWithBody)DefUseChains)FunctionAnalysis)defaultdictNc                       s0   e Zd ZdZ fddZdd Zdd Z  ZS )ScopeaN  
    Associate each variable declaration with the node that defines it

    Whenever possible, associate the variable declaration to an assignment,
    otherwise to a node that defines a bloc (e.g. a For)
    This takes OpenMP information into accounts!
    The result is a dictionary with nodes as key and set of names as values
    c                    s<   t t| _tjtjtjtjtjt	f| _
tt| tt d S N)r   setresultastZFunctionDefZForZexcepthandlerZWhileZIftupledecl_holderssuperr   __init__r   r   self	__class__ 8/usr/lib/python3/dist-packages/pythran/analyses/scope.pyr      s   

zScope.__init__c                 C   s>   |j D ]}||jv rqt|tjr| j|jg | qd S r   )	ZdepsZprivate_deps
isinstancer
   Nameopenmp_deps
setdefaultidappend)r   nodeZdepr   r   r   visit_OMPDirective   s   

zScope.visit_OMPDirectivec                    s   j  _t  _ | t } jj| D ]}|| g 	| q|
 D ]\}}dd |D dd |D  }| fdd j|g D   fdd|D }dd t| D }|d d	 }	t|	 jrd
d |D }| j|g  t }
|D ]"}|} j| d |	ur j| d } j| d |	us|
| q|	|
vrt|	tr|	n|	j}|D ]}||
v rt|tjr|}	 nq j|	 | q(d S )Nc                 S      g | ]}|j qS r   r   .0dr   r   r   
<listcomp>4       z+Scope.visit_FunctionDef.<locals>.<listcomp>c                 S   s    g | ]}|  D ]}|jqqS r   )Zusersr   )r    r!   ur   r   r   r"   4   s
    c                 3   s    | ]
} j | d  V  qdS )N	ancestorsr   r   r   r   	<genexpr>7   s    z*Scope.visit_FunctionDef.<locals>.<genexpr>c                    s   g | ]} j | qS r   r&   )r    refr   r   r   r"   :   s    c                 S   s    g | ]}t t|d kr|qS )   )lenr   )r    pr   r   r   r"   <   s     r   c                 S   r   r   r   r   r   r   r   r"   C   r#   )Zancestors_with_bodyr'   dictr   Zgeneric_visitZdef_use_chainslocalsr   namer   itemsextendgetzipr   r   r   addr   bodyr
   ZAssignr	   )r   r   Zname_to_defsZdef_r0   ZdefsZrefsr'   prefixescommonZprefsrZancestorr6   cr   r   r   visit_FunctionDef%   sH   
zScope.visit_FunctionDef)__name__
__module____qualname____doc__r   r   r;   __classcell__r   r   r   r   r      s
    	r   )r?   Zpythran.analyses.ancestorsr   Zpythran.analyses.use_def_chainr   Zpythran.passmanagerr   collectionsr   Zgastr
   r   r   r   r   r   <module>   s    