U
    nufm6                     @   s
  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mZ dZe
d	  Zd
d Zdd Zdd Zd1ddZdd Zdd Zdd Zdd Zdd Zdd Zdd  Zd!d" Zd#d$ Zd%d& Z d'd( Z!d)d* Z"d+d, Z#d-d. Z$d/d0 Z%dS )2    )dedent)split_lines)debug)RefactoringError)RefactoringEXPRESSION_PARTS)indent_block)function_is_classmethodfunction_is_staticmethodZsuite
file_inputz_atom testlist_star_expr testlist test lambdef lambdef_nocond keyword name number string fstringc                 C   s\   t |||}td| t|\}}|s0t||d t| }	|t|||	|i}
t| |
S )NzExtracting nodes: %s = )_find_nodesr   Zdbg_is_expression_with_errorr   _expression_nodes_to_string_replacer   )inference_statepathmodule_nodenamepos	until_posnodesis_expressionmessageZgenerated_codefile_to_node_changes r   @/tmp/pip-unpacked-wheel-ol4ehs9f/jedi/api/refactoring/extract.pyextract_variable   s    r   c                 C   s:   t dd | D rdS | d jtkr6dd| d j fS dS )z8
    Returns a tuple (is_expression, error_string).
    c                 s   s    | ]}|j d ko| V  qdS )r   N)typeis_definition).0noder   r   r   	<genexpr>#   s     z,_is_expression_with_error.<locals>.<genexpr>)Fz,Cannot extract a name that defines somethingr   FzCannot extract a "%s")T )anyr   _VARIABLE_EXCTRACTABLEr   r   r   r   r      s
    r   c                 C   s*  | j |dd}|dkr||jdkr>| }|dk	r>|j|kr>|}t|rL|j}|jjdkr`|jj}|jjtkrt|j}q`|g}n|j|kr| }|dk	r|}t|r|j}| j |dd}|j|kr| }|dkrt	d|}|j|jk r|j}qt
|||}t|dkr&|jdkr&|d	 jd gS |S )
zd
    Looks up a module and tries to find the appropriate amount of nodes that
    are in there.
    T)Zinclude_prefixesNoperatortrailerz!Cannot extract anything from that   )return_stmtZ
yield_exprr   )Zget_leaf_for_positionr   get_next_leaf	start_pos_is_not_extractable_syntaxparentr   end_posZget_previous_leafr   !_remove_unwanted_expression_nodeslenchildren)r   r   r   Z
start_nodeZ	next_leafr   Zend_leafparent_noder   r   r   r   +   s>    


r   Nc                 C   s   t | d }|d kr| }| d  }t|jdd}||krR|d k	rR||d d< t||d d g|dd< d|}	i }
||kr|	| |
| d < n>|d kr|j}n|t| d  }|| |
| d < |	|j |
|< | dd  D ]}d|
|< q|
S )Nr   Tkeepends
r$   r*   )_get_parent_definitionget_first_leafr   prefixr   join_get_indentationvalue)r   Zexpression_replacementZ	extractedr   insert_before_leafremaining_prefixZ
definitionZfirst_node_leaflinesZextracted_prefixreplacement_dctpr"   r   r   r   r   a   s*    

r   c                 C   s   d dd t| D S )Nr$   c                 s   s"   | ]\}}|j |d kdV  qdS )r   Zinclude_prefixNget_code)r!   inr   r   r   r#      s     z._expression_nodes_to_string.<locals>.<genexpr>)r<   	enumerater'   r   r   r   r      s    r   c                 C   sV   | d }t | |d d \}}||jdd ddd | dd  D  }||fS )Nr   r*   FrD   r$   c                 s   s   | ]}|  V  qd S )NrE   )r!   rH   r   r   r   r#      s     z)_suite_nodes_to_string.<locals>.<genexpr>)_split_prefix_atr:   rF   r<   )r   r   rH   r;   Zpart_of_codecoder   r   r   _suite_nodes_to_string   s    rL   c                 C   sD   | j d | }t| jdd}d|d|  d|| d fS )zU
    Returns a tuple of the leaf's prefix, split at the until_line
    position.
    r   Tr5   r$   N)r-   r   r;   r<   )ZleafZ
until_lineZsecond_line_countrA   r   r   r   rJ      s    rJ   c                 C   s   t |  jd S )Nr7   )r   r:   r;   r"   r   r   r   r=      s    r=   c                 C   s,   | dk	r | j jtkr| S | j } q tddS )z8
    Returns the statement where a node is defined.
    NzWe should never even get here)r/   r   _DEFINITION_SCOPESNotImplementedErrorrM   r   r   r   r9      s
    r9   c                 C   s  | j }|dk}|tks|r| j}t|D ],\}}|j|kr*|}|j dkrR|d8 } qXq*ttt|D ]T\}}|j|k rh|}	|j dkr|	d7 }	||d D ]}
t|
r|	d7 }	q qq qqh|||	d  }|st	|d |||dd< t	|d |||dd< |S | gS )z~
    This function makes it so for `1 * 2 + 3` you can extract `2 + 3`, even
    though it is not part of the expression.
    r   r(   r*   Nr   r7   )
r   r   r3   rI   r0   reversedlistr-   r.   r1   )r4   r   r   typZis_suite_partr   rG   rH   start_indexZ	end_indexZn2r   r   r   r1      s4    




r1   c                 C   s   | j dkp| j dko| jdkS )Nr(   keyword)NoneTrueFalse)r   r>   rM   r   r   r   r.      s    
r.   c                    sj  t |j||}t|stt|\}}||d }	|	 }
tt||	|\}}|		 r^d }nt
|	j|
}| }|rdt| d }d }d}nt|d }|s|rtt|	|d j|d j|p|d gng }t||\}}|d  }t||d \}}||7 }t|}|s,d|}|d| d 7 }t|r@|d d n| d}d  |
rt|	js|	  }t|r|d j  fdd	|D }t|	jrd
}n|d7 }d||d d kr|n g| t|f }d d krdn d | d|f }|r|}n$|r"d| d }n|d | d }t||||||}|sX||j ||< ||i}t| |S )Nr   zreturn r8   Fr7   z, r$   c                    s   g | ]}| kr|qS r   r   )r!   rC   Z
self_paramr   r   
<listcomp>  s      z$extract_function.<locals>.<listcomp>z@classmethod
z%sdef %s(%s):
%sz%s(%s).r   ) r   Z	tree_noder2   AssertionErrorr   Zcreate_contextis_bound_methodrQ   _find_inputs_and_outputs	is_module_get_code_insertion_noder:   r   _is_node_ending_return_stmt_find_needed_output_variablesr/   r0   rL   r,   rJ   r   r<   _check_for_non_extractablesr
   	get_valueZget_param_namesZstring_namer	   r   r   r>   r   )r   r   module_contextr   r   r   r   r   _contextr\   paramsreturn_variablesr?   r"   Z
code_blockr@   Zhas_ending_return_stmtZ
after_leaffirstsecondZoutput_var_str	decoratorZfunction_param_namesZfunction_codeZfunction_callreplacementrB   r   r   rX   r   extract_function   s    	



 rm   c              	   C   sZ   | D ]P}z
|j }W n8 tk
rJ   |jdkr4td|jdkrFtdY qX t| qd S )Nreturnz:Can only extract return statements if they are at the end.yieldz Cannot extract yield statements.)r3   AttributeErrorr>   r   rb   )r   rH   r3   r   r   r   rb   (  s    


rb   c                 C   s\   |D ]R}|j dks|j s| | k	r. dS |jd ksP||j  krN|k sn  dS qdS )NparamTF)Zapi_typeZparent_contextr^   Zget_root_contextr-   )rd   namesri   lastr   r   r   r   _is_name_input6  s    "rt   c           	      C   s   |d j }|d j}g }g }t|D ]X}| rF||kr|||j q$|j|kr$|||j }|rpt| |||r$||j q$||fS )Nr   r7   )r-   r0   _find_non_global_namesr    appendr>   gotort   )	rd   rf   r   ri   rs   inputsoutputsr   Zname_definitionsr   r   r   r]   @  s    


r]   c              	   c   sf   | D ]\}z
|j }W n$ tk
r6   |jdkr2|V  Y qX |jdkrR|j d dkrRqt|E d H  qd S )Nr   r)   r   rZ   )r3   rp   r   ru   )r   r"   r3   r   r   r   ru   U  s    

ru   c                 C   s8   |rt | r | jjdkr | j} q| jjdkr4| j} q | S )Nr   )Zasync_funcdefZ	decoratedZ
async_stmt)r
   r/   r   )r"   r\   r   r   r   r_   d  s    r_   c                 c   sZ   |j D ]N}|j|k rqt|}t|gD ]*}| s(|j|kr(||j |jV  q(qdS )z
    Searches everything after at_least_pos in a node and checks if any of the
    return_variables are used in there and returns those.
    N)r3   r-   setru   r    r>   remove)rf   Zsearch_nodeZat_least_posrh   r"   r   r   r   r   ra   n  s    

ra   c                 C   s$   | j }|dkrt| jd S |dkS )NZsimple_stmtr   r+   )r   r`   r3   )r"   tr   r   r   r`   ~  s    r`   )NN)&textwrapr   Zparsor   Zjedir   Zjedi.api.exceptionsr   Zjedi.api.refactoringr   r   Zjedi.commonr   Zjedi.parser_utilsr	   r
   rN   splitr&   r   r   r   r   r   rL   rJ   r=   r9   r1   r.   rm   rb   rt   r]   ru   r_   ra   r`   r   r   r   r   <module>   s>   7   
!$W

