B
    œúðbÎ  ã               @   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
„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ ZdS )a°  
Searching for names with given scope and name. This is very central in Jedi and
Python. The name resolution is quite complicated with descripter,
``__getattribute__``, ``__getattr__``, ``global``, etc.

If you want to understand name resolution, please read the first few chapters
in http://blog.ionelmc.ro/2015/02/09/understanding-python-metaclasses/.

Flow checks
+++++++++++

Flow checks are not really mature. There's only a check for ``isinstance``.  It
would check whether a flow has the form of ``if isinstance(a, type_or_tuple)``.
Unfortunately every other thing is being ignored (e.g. a == '' would be easy to
check for -> a is a string). There's big potential in these checks.
é    )Úsearch_ancestor)ÚName)Úsettings)ÚTreeArguments)Úiterable)Ú	NO_VALUES)Úis_scopec             C   sB   t |tƒr|jn|}g }x| D ]}| |¡}|rP qW tt|ƒƒS )zh
    Searches names that are defined in a scope (the different
    ``filters``), until a name fits.
    )Ú
isinstancer   ÚvalueÚgetÚlistÚ_remove_del_stmt)ÚfiltersZname_or_strZstring_nameÚnamesÚfilter© r   ú4lib/python3.7/site-packages/jedi/inference/finder.pyÚfilter_name   s    

r   c             c   s@   x:| D ]2}|j d k	r2|j  ¡ }|d k	r2|jdkr2q|V  qW d S )NZdel_stmt)Z	tree_nameZget_definitionÚtype)r   ÚnameZ
definitionr   r   r   r   +   s    


r   c                sê   t js
dS d}tˆ ƒr˜ˆ  ¡ }y| ¡ |j }W n tk
rD   dS X t‡ ‡fdd„|D ƒƒ}x8|D ]0}t|dƒ}|dk	rdt	| |j
|ƒ}|dk	rd|S qdW ˆ jdkrædd„ ˆ jddd… D ƒ}	x(t|	ƒD ]}
|j|
jkrÆt	| |
|ƒS qÆW |S )	zÿ Try to find out the type of a variable just with the information that
    is given by the flows: e.g. It is also responsible for assert checks.::

        if isinstance(k, str):
            k.  # <- completion here

    ensures that `k` is a string.
    Nc                s2   g | ]*}ˆ j |j   kr&ˆp ˆ jk rn q|‘qS r   )Ú	start_posÚend_pos)Ú.0Ún)ÚflowÚposr   r   ú
<listcomp>J   s    z*check_flow_information.<locals>.<listcomp>Zassert_stmt)Zif_stmtZ
while_stmtc             S   s   g | ]}|d kr|‘qS )ú:r   )r   Úcr   r   r   r   V   s    é   é   )r   Zdynamic_flow_informationr   Zget_root_nodeZget_used_namesr
   ÚKeyErrorÚreversedr   Ú_check_isinstance_typeZ	assertionr   Úchildrenr   r   )r
   r   Úsearch_namer   ÚresultZmodule_noder   r   ZassZpotential_ifsZif_testr   )r   r   r   Úcheck_flow_information5   s.    	


r'   c             C   sV   | j dkrRt| jƒdkrR| j\}}|j dkrR|jdkrR|j dkrR|jd dkrR|S d S )N)ZpowerÚ	atom_expré   r   r	   Útrailerr   ú()r   Úlenr$   r
   )ÚnodeÚfirstr*   r   r   r   Ú_get_isinstance_trailer_arglist]   s    
r/   c             C   s  d }t |ƒ}|d k	r¤t|jƒdkr¤|jd }t| j| ||ƒ}t| ¡ ƒ}t|ƒdkr¤t|jƒdkr¤|\\}}	\}
}|d kr¤|
d kr¤t|ƒ}t|jd ƒ}||kr¤|}|d kr°d S t}xV| 	¡ D ]J}t
|tjƒrü|jdkrüx.| ¡ D ]}|| 	¡  ¡ O }qâW q¾|| ¡ O }q¾W |S )Né   r   r)   r   Útuple)r/   r,   r$   r   Zinference_stater   ÚunpackÚ_get_call_stringr   Zinferr	   r   ÚSequenceZ
array_typeZ
py__iter__Zexecute_with_values)r
   r-   r%   Zlazy_clsr*   ZarglistÚargsZ
param_listZkey1Ú_Zkey2Zlazy_value_clsZcallZis_instance_callZ	value_setZ
cls_or_tupZ
lazy_valuer   r   r   r#   g   s,    
r#   c             C   sR   | j jdkrt| j ƒS d}|  ¡ }|  ¡ j}x |j|k rL||j7 }| ¡ }q.W |S )Nr(   Ú )	Úparentr   r3   Zget_first_leafZget_last_leafr   r   r
   Zget_next_leaf)r-   ÚcodeZleafÚendr   r   r   r3   ˆ   s    


r3   N)Ú__doc__Z
parso.treer   Zparso.python.treer   Zjedir   Zjedi.inference.argumentsr   Zjedi.inference.valuer   Zjedi.inference.base_valuer   Zjedi.parser_utilsr   r   r   r'   r/   r#   r3   r   r   r   r   Ú<module>   s   
(
!