o
    @aC                     @   sn   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G dd	 d	ejZG d
d deZdS )zu
ExpandGlobals replaces globals variables by function call.

It also turn globals assignment in function definition.
    )LocalNameDeclarations)Transformation)PythranSyntaxError)path_to_attr)metadataNc                   @   s    e Zd ZdZdd Zdd ZdS )GlobalTransformerz?
    Use assumptions on globals to improve code generation
    c                 C   s   |S N selfnoder	   r	   H/usr/lib/python3/dist-packages/pythran/transformations/expand_globals.py
visit_Call   s   zGlobalTransformer.visit_Callc                    s0   t tdt  fdd|jD t  gg S )N)builtinspythranZstatic_listc                    s   g | ]}  |qS r	   )visit).0eltr   r	   r   
<listcomp>   s    z0GlobalTransformer.visit_List.<locals>.<listcomp>)astCallr   ZTupleeltsLoadr
   r	   r   r   
visit_List   s   
zGlobalTransformer.visit_ListN)__name__
__module____qualname____doc__r   r   r	   r	   r	   r   r      s    r   c                       s0   e Zd ZdZ fddZdd Zdd Z  ZS )ExpandGlobalsa  
    Expands all builtins into full paths.

    >>> import gast as ast
    >>> from pythran import passmanager, backend
    >>> node = ast.parse('''
    ... a = 1
    ... def foo():
    ...     return a''')
    >>> pm = passmanager.PassManager("test")
    >>> _, node = pm.apply(ExpandGlobals, node)
    >>> print(pm.dump(backend.Python, node))
    def a():
        return 1
    def foo():
        return a()
    c                    s"   t  | _t  | _tt|   dS )z; Initialize local declaration and constant name to expand. N)set
local_decl	to_expandsuperr   __init__r   	__class__r	   r   r$   4   s   zExpandGlobals.__init__c           	         s  t  }t }|jD ]q}t|tjtjfr&|jD ]}|jp|j	}|
| qnt|tjr?|j	|v r9td|j	 ||
|j	 t|tjsFq	|jD ]0}t|tjsVtd||j jv rdtd|j |t|jtjrr|jj|v rrqI j
|j qIq	|jD ]o}t|tjrt fdd|jD r|| q~t  _t  |j}|jD ]3}t|tjsJ |t|jtg g dg g dg tj|dgg dd t
|d jd t  qq~ t| _| | q~  jt jO  _||_|S )	z@Turn globals assignment to functionDef and visit function defs. z$Multiple top-level definition of %s.z&Top-level assignment to an expression.c                 3   s(    | ]}t |tjo|j jvV  qd S r   )
isinstancer   Nameidr"   )r   tr   r	   r   	<genexpr>`   s     z-ExpandGlobals.visit_Module.<locals>.<genexpr>N)valuer   ) listr    bodyr'   r   ZImportZ
ImportFromnamesasnamenameaddZFunctionDefr   ZAssigntargetsr(   r)   r"   r,   allappendr!   r   r   Z	argumentsZReturnr   ZStaticReturnZgatherr   updatebool)	r   r   Zmodule_bodysymbolsZstmtaliasr2   targetZ	cst_valuer	   r   r   visit_Module:   s   






zExpandGlobals.visit_Modulec                 C   s@   t |jtjr|j| jvr|j| jv rd| _tj|g g dS |S )z
        Turn global variable used not shadows to function call.

        We check it is a name from an assignment as import or functions use
        should not be turn into call.
        T)funcargskeywords)	r'   ctxr   r   r)   r!   r"   r7   r   r
   r	   r	   r   
visit_Name{   s   

zExpandGlobals.visit_Name)r   r   r   r   r$   r<   rA   __classcell__r	   r	   r%   r   r       s
    Ar   )r   Zpythran.analysesr   Zpythran.passmanagerr   Zpythran.syntaxr   Zpythran.utilsr   r   r   Zgastr   ZNodeTransformerr   r   r	   r	   r	   r   <module>   s    