U
    nuf                     @   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mZ dd	lmZ dd
lmZ ddlmZmZ ddlmZ ddlmZ dZdd Zejedd Zeddedd Zdd Zdd Zdd Z dS )a  
One of the really important features of |jedi| is to have an option to
understand code like this::

    def foo(bar):
        bar. # completion here
    foo(1)

There's no doubt wheter bar is an ``int`` or not, but if there's also a call
like ``foo('str')``, what would happen? Well, we'll just show both. Because
that's what a human would expect.

It works as follows:

- |Jedi| sees a param
- search for function calls named ``foo``
- execute these calls and check the input.
    )settings)debug)get_parent_scope)inference_state_method_cache)TreeArguments)get_executed_param_names)is_stdlib_path)to_list)instance)ValueSet	NO_VALUES)#get_module_contexts_containing_name)	recursion   c                    s    fdd}|S )Nc              
      sn   | j }t|| jP}|rT| jd7  _z | |W W  5 Q R  S | jd8  _X tW  5 Q R  S Q R X d S )N   )inference_stater   Zexecution_allowed	tree_nodedynamic_params_depthr   )function_valueparam_indexinfallowedfunc A/tmp/pip-unpacked-wheel-ol4ehs9f/jedi/inference/dynamic_params.pywrapper&   s    z"_avoid_recursions.<locals>.wrapperr   )r   r   r   r   r   _avoid_recursions%   s    r   c                    s    j jstS  j}   }|dk	r2t|r2tS |jdkrRt|}|dkrZtS n|j	j
}tjd|dd   }t|||}t fdd|D }tjddd |S )	a:  
    A dynamic search for param values. If you try to complete a type:

    >>> def func(foo):
    ...     foo
    >>> func(1)
    >>> func("")

    It is not known what the type ``foo`` without analysing the whole code. You
    have to look for all calls to ``func`` to find out what ``foo`` possibly
    is.
    NZlambdefzDynamic param search in %s.MAGENTA)colorc                 3   s    | ]}t  |  V  qd S )N)r   infer).0	argumentsr   r   r   r   	<genexpr>\   s    z'dynamic_param_lookup.<locals>.<genexpr>zDynamic param result finished)r   Zdo_dynamic_params_searchr   r   get_root_contextZ
py__file__r   type_get_lambda_namenamevaluer   Zdbg_search_function_argumentsr   Z	from_sets)r   r   funcdefpathstring_namemodule_contextZarguments_listvaluesr   r#   r   dynamic_param_lookup6   s&    
r0   N)defaultc                 c   s   |}|dkr*t |}|jdkr*|jj}|}d}d}| j}tjrRt|| g|dd}n| g}|D ]j}	t|	|D ]P\}
}|d7 }||j	 t
kr  dS |	|
}t||||
|D ]}d	}|V  qqj|r\ dS q\dS )
z(
    Returns a list of param names.
    __init__classdefFr      )Zlimit_reductionr   NT)r   r&   r(   r)   r   r   Z dynamic_params_for_other_modulesr   _get_potential_nodesr   MAX_PARAM_SEARCHEScreate_context_check_name_for_execution)r.   r+   r-   compare_nodeclsZfound_argumentsir   Zmodule_contextsZfor_mod_contextr(   trailerrandom_contextr"   r   r   r   r*   f   sD    
  
    
r*   c                 C   sD   | j }|jdkr@t| d }|dkr@|jd }|jdkr@|jS d S )NZ	expr_stmt=r   r(   )parentr&   nextZyield_operatorschildrenr)   )nodeZstmtZfirst_operatorfirstr   r   r   r'      s    


r'   c                 c   sb   z| j  | }W n tk
r(   Y d S X |D ].}| }|j}|jdkr.|dkr.||fV  q.d S )Nr<   ()r   Zget_used_namesKeyErrorZget_next_leafr?   r&   )Zmodule_valueZfunc_string_namenamesr(   Zbracketr<   r   r   r   r5      s    r5   c                 #   s  ddl m}  fdd} |D ]}|j}||krF||V  q(t|j|r(|jdkr(|j }	t|	dkrtq(|	d  }
dd |
D |gkr( 	 }|
||}t||	d j}|D ]F\}|j|j  k r|jk rn q||}t|||E d H  qq(d S )	Nr   )BaseFunctionExecutionContextc                    st   j d }|dkrd }t |}ddlm} | jjdkrXt| j| |}|||S | 	 rl|| j|}|S d S )Nr   )r   )InstanceArgumentsr3   )
rA   r   Zjedi.inference.value.instancerI   r   r&   r
   ZTreeInstanceparent_contextZis_bound_method)r)   ZarglistargsrI   Zcreated_instancecontextr   r<   r   r   create_args   s     

z._check_name_for_execution.<locals>.create_argsr+   r   c                 S   s   g | ]
}|j qS r   )r   )r!   vr   r   r   
<listcomp>   s     z-_check_name_for_execution.<locals>.<listcomp>)Zjedi.inference.value.functionrG   r    r   
isinstancerJ   r&   Zget_param_nameslenr%   Z
as_contextr5   r-   Z	start_posZend_posr7   r8   )r   rM   r9   r(   r<   rG   rN   r)   Z
value_nodeZparam_namesr/   r.   Zexecution_contextZpotential_nodesr=   r   rL   r   r8      s6    

r8   )!__doc__Zjedir   r   Zjedi.parser_utilsr   Zjedi.inference.cacher   Zjedi.inference.argumentsr   Zjedi.inference.paramr   Zjedi.inference.helpersr   Zjedi.inference.utilsr	   Zjedi.inference.valuer
   Zjedi.inference.base_valuer   r   Zjedi.inference.referencesr   Zjedi.inferencer   r6   r   Zincrease_indentr0   r*   r'   r5   r8   r   r   r   r   <module>   s.   ..