B
    7r\u                 @   s\   d Z ddlZddlmZmZ ddlmZ G dd deZdd Z	d	d
 Z
dd Zdd ZdS )a,  
THIS is not in active development, please check
https://github.com/davidhalter/jedi/issues/667 first before editing.

Introduce some basic refactoring functions to |jedi|. This module is still in a
very early development stage and needs much testing and improvement.

.. warning:: I won't do too much here, but if anyone wants to step in, please
             do. Refactoring is none of my priorities

It uses the |jedi| `API <api.html>`_ and supports currently the
following functions (sometimes bug-prone):

- rename
- extract variable
- inline variable
    N)python_bytes_to_unicodesplit_lines)helpersc               @   s,   e Zd Zdd Zdd Zdd Zdd Zd	S )
Refactoringc             C   s
   || _ dS )zT
        :param change_dct: dict(old_path=(new_path, old_lines, new_lines))
        N)
change_dct)selfr    r   /lib/python3.7/site-packages/jedi/refactoring.py__init__   s    zRefactoring.__init__c             C   s4   i }x*| j  D ]\}\}}}d|||< qW |S )N
)r   itemsjoin)r   dctold_pathnew_pathold_lnew_lr   r   r	   	old_files   s    zRefactoring.old_filesc             C   s4   i }x*| j  D ]\}\}}}d|||< qW |S )Nr   )r   r   r   )r   r   r   r   r   r   r   r   r	   	new_files%   s    zRefactoring.new_filesc             C   s^   g }xN| j  D ]@\}\}}}|r0t||}nt||||}|d| qW d|S )Nr   )r   r   difflibZunified_diffappendr   )r   Ztextsr   r   r   r   Zudiffr   r   r	   diff+   s    zRefactoring.diffN)__name__
__module____qualname__r
   r   r   r   r   r   r   r	   r      s   r   c             C   s   t t|  |S )z The `args` / `kwargs` params are the same as in `api.Script`.
    :param new_name: The new name of the script.
    :param script: The source Script object.
    :return: list of changed lines/changed files
    )r   _renameusages)scriptnew_namer   r   r	   rename6   s    r   c          
      s   t | dd dd} fdd}i  t }d }}x|D ]}| rDq6||jkr|j}|||| |dk	rt|}| }	W dQ R X tt|	}|dd }|j|j	 }
}||
d  }|d| | ||t
|j d  ||
d < q6W ||||  S )	z For both rename and inline. c             S   s   | j | j| jfS )N)module_pathlinecolumn)xr   r   r	   <lambda>A   s    z_rename.<locals>.<lambda>T)keyreversec                s   |d k	r| ||f | < d S )Nr   )path	old_lines	new_lines)r   r   r	   processD   s    z_rename.<locals>.processN   )sortedobjectZin_builtin_moduler    openreadr   r   r!   r"   lenname)namesreplace_strorderr*   Zcurrent_pathr)   r(   r1   fsourceZnrindentr!   r   )r   r	   r   ?   s.    



$r   c             C   sV  t t| j}|dd }| j }i }|r<| j}|d d }t||\}}	|dk	r<||	 j}
||	 j	}|d |
d kr|d nd}||
d d  }||
d | }x.t
|
d |d d D ]}|dt| 7 }qW |dkr||d d  }|d|d|d   7 }| }|
d t| t| }| }t|t| }|dkrx||d | d ||d d < t|}n|| }|d| | ||d  }|||
d d < g ||
d |d d < dddg}dd	d
g}d|kr|d |kr|d |||d  ksd| }|jd }dd| ||f }||| | j||f|| j< t|S )z The `args` / `kwargs` params are the same as in `api.Script`.
    :param operation: The refactoring operation to execute.
    :type operation: str
    :type source: str
    :return: list of changed lines/changed files
    Nr   r+   r   ([{)]}z(%s)z	%s%s = %s )r   r   r6   Z_parser	user_stmtZ_posr   Zarray_for_pos	start_posend_posrangestrlstripr0   rstripindexinsertr'   r   )r   r   r)   r(   r@   r   posZ
line_indexarrrG   rA   rB   eZ
start_linetextlZend_linetZ	del_startZdel_endZopen_bracketsZclose_bracketsr7   newr   r   r	   extractb   sP    





 



rP   c                sn  t t| j}i }|  }t|dks*t|d j |  } fdd|D }t|dd dd} 	 } j
d  jd kst j
d d }|| }||d j
d  jd d  }	|	 }	|rt|d tjr|d }
|	d d	krt|
dkrd
|	 }	t  dkr0|d j
d  | jd d  }t||	}|| j d }| r\|||< n
|| t|S )z"
    :type script: api.Script
    r+   r   c                s2   g | ]*} j |j|jf  kr( jksn |qS r   )rA   r!   r"   rB   ).0r)stmtr   r	   
<listcomp>   s    zinline.<locals>.<listcomp>c             S   s   | j | j| jfS )N)r    r!   r"   )r#   r   r   r	   r$      s    zinline.<locals>.<lambda>T)r%   r&   )r8   r9   r:   z(%s)N   )r   r   r6   Zgoto_assignmentsr0   AssertionErrorZ_definitionr   r,   expression_listrA   rB   strip
isinstanceZprZArrayZget_defined_namesr   r'   popr   )r   r)   r   Zdefinitionsr   ZinlinesrW   rG   r!   r3   rJ   r   )rS   r	   inline   s6    

 $



r[   )__doc__r   Zparsor   r   Zjedi.evaluater   r-   r   r   r   rP   r[   r   r   r   r	   <module>   s   	#?