B
    7r\!                 @   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 ddlmZmZ ddlmZmZ ddlmZ dZG dd deZej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.
    )tree)settings)debug)evaluator_function_cache)imports)TreeArguments)create_default_params)is_stdlib_path)to_list)get_parent_scope)ModuleContextinstance)
ContextSetNO_CONTEXTS)	recursion   c               @   s    e Zd ZdZdd Zdd ZdS )DynamicExecutedParamszP
    Simulates being a parameter while actually just being multiple params.
    c             C   s   || _ || _d S )N)	evaluator_executed_params)selfr   executed_params r   4lib/python3.7/site-packages/jedi/evaluate/dynamic.py__init__+   s    zDynamicExecutedParams.__init__c          	   C   s8   t | j|  }|r*tdd | jD S tS Q R X d S )Nc             s   s   | ]}|  V  qd S )N)infer).0pr   r   r   	<genexpr>5   s    z.DynamicExecutedParams.infer.<locals>.<genexpr>)r   Zexecution_allowedr   r   Z	from_setsr   r   )r   Zallowedr   r   r   r   /   s    zDynamicExecutedParams.inferN)__name__
__module____qualname____doc__r   r   r   r   r   r   r   &   s   r   c       	   
      s  t jst||S   jd7  _z|  }|dk	rFt|rFt||S |jdkrlt|}|dkrtt||S n|j	j
}tjd|dd zT| }t |||d}|rttdd	 |D  } fd
d|D }n
t||S W dtjddd X |S   jd8  _X 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.ZMAGENTA)Zcolor)string_namec             s   s   | ]}|  V  qd S )N)get_executed_params)r   function_executionr   r   r   r   f   s   z search_params.<locals>.<genexpr>c                s   g | ]}t  |qS r   )r   )r   r   )r   r   r   
<listcomp>i   s    z!search_params.<locals>.<listcomp>zDynamic param result finished)r   Zdynamic_paramsr   dynamic_params_depthget_root_contextZ
py__file__r	   type_get_lambda_namenamevaluer   Zdbg_search_function_executionsziplist)	r   execution_contextfuncdefpathr#   module_contextZfunction_executionsZzipped_paramsparamsr   )r   r   search_params9   s:    


r5   N)defaultc             c   s   |}|dkr,t |}t|tjr,|jj}|}d}d}xt| |g|D ]|}t|tsXdS x`t	||D ]R\}	}
|d7 }|| j
 tkrdS | ||	}x"t| |||	|
D ]}d}|V  qW qdW |rFdS qFW dS )z(
    Returns a list of param names.
    r   Fr   Nr"   T)r   
isinstancer   ZClassr+   r,   r   Zget_modules_containing_namer   _get_possible_nodesr'   MAX_PARAM_SEARCHEScreate_context_check_name_for_execution)r   r3   r1   r#   compare_nodeclsZfound_executionsiZfor_mod_contextr+   trailerrandom_contextr%   r   r   r   r-   t   s.    
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,   )ZnodeZstmtZfirst_operatorfirstr   r   r   r*      s    


r*   c             c   sd   y| j  | }W n tk
r&   d S X x6|D ].}| }|j}|jdkr.|dkr.||fV  q.W d S )Nr?   ()	tree_nodeZget_used_namesKeyErrorZget_next_leafrB   r)   )r3   Zfunc_string_namenamesr+   Zbracketr?   r   r   r   r8      s    
r8   c             #   s6  ddl m}  fdd}x |D  ]j|kr\x| D ]
}|V  qLW q0tj|r0|jdkr0j }t|dkrq0|d 	 }	dd |	D }
|
|gkr0 
 }t| }xlt||d jD ]X\}j|j  k rjk rn q҈||}t|||}x|D ]}|V  qW qW q0W d S )	Nr   )FunctionExecutionContextc              3   sj   j d } | dkrd } t | }jdkrZtj|}x$| D ]
}|V  qJW n|V  d S )Nr"   )Zclassdef)rD   r   r)   r   ZTreeInstanceparent_contextZcreate_init_executionsZget_function_execution)ZarglistargsZcreated_instanceZ	execution)contextr   r?   r,   
value_noder   r   create_func_excs   s    

z3_check_name_for_execution.<locals>.create_func_excsr1   r"   c             S   s   g | ]
}|j qS r   )rG   )r   vr   r   r   r&      s    z-_check_name_for_execution.<locals>.<listcomp>)Zjedi.evaluate.context.functionrJ   Zgoto_definitionsrG   r7   rL   r)   r$   lenr   r(   rC   r8   r#   Z	start_posZend_posr:   r;   )r   rN   r<   r+   r?   rJ   rP   Zfunc_executionr4   valuesZnodesr3   r0   r@   iteratorr%   r   )rN   r   r?   r,   rO   r   r;      s8    




r;   )$r!   Zparso.pythonr   Zjedir   r   Zjedi.evaluate.cacher   Zjedi.evaluater   Zjedi.evaluate.argumentsr   Zjedi.evaluate.paramr   Zjedi.evaluate.helpersr	   Zjedi.evaluate.utilsr
   Zjedi.parser_utilsr   Zjedi.evaluate.contextr   r   Zjedi.evaluate.base_contextr   r   r   r9   objectr   Zincrease_indentr5   r-   r*   r8   r;   r   r   r   r   <module>   s*   ;'