a
    8^i.                     @   s  d dl mZmZmZmZmZ d dlmZmZm	Z	m
Z
mZmZmZmZmZmZmZmZ d dlZd dlZd dlZi ae ZG dd de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 a(d!d" Z)d#d$ Z*dS )%    )divisionabsolute_importwith_statementprint_functionunicode_literals)PY2
basestringbchrbordchropenpystrrangeroundstrtobytesunicodeNc                   @   s    e Zd ZdZdd Zdd ZdS )Linez.
    Represents a logical line in a file.
    c                 C   s:   | dd}|| _|| _|| _|| _|| _d| _d| _d S )N\/ )replacefilenamenumberstartend	end_delimtext	full_text)selfr   r   r    r    TC:\Program Files (x86)\Steam\steamapps\common\Selene ~Apoptosis~\renpy\scriptedit.py__init__/   s    zLine.__init__c                 C   s   d | j| j| jS )Nz<Line {}:{} {!r}>)formatr   r   r   )r   r    r    r!   __repr__I   s    zLine.__repr__N)__name__
__module____qualname____doc__r"   r$   r    r    r    r!   r   *   s   r   c                 C   sN   |  ds|  dsdS | tv r$dS t|  tj| }tjj|dd dS )z}
    Ensures that the given filename and linenumber are loaded. Doesn't do
    anything if the filename can't be loaded.
    z.rpyz.rpycNT)Z	add_lines)endswithfilesaddrenpyparserZunelide_filenameZlist_logical_lines)r   fnr    r    r!   ensure_loadedM   s    
r/   c                 C   s6   |  dd} t|  | |ftv r.t| |f jS dS dS )zq
    Gets the text of the line with `filename` and `linenumber`, or the None if
    the line does not exist.
    r   r   N)r   r/   linesr   r   
linenumberr    r    r!   get_line_text_   s
    r3   c           	      C   s   |  dd} t|  i }t D ]l\}}|\}}|| kr||kr||7 }| j|7  _| j|7  _| j|7  _| j|7  _||||f< q |adS )a8  
    Adjusts the locations in the line data structure.

    `filename`, `linenumber`
        The filename and first line number to adjust.

    `char_offset`
        The number of characters in the file to offset the code by,.

    `line_offset`
        The number of line in the file to offset the code by.
    r   r   N)r   r/   r0   itemsr   r   r   r   )	r   r2   Zchar_offsetline_offsetZ	new_lineskeyliner.   lnr    r    r!   adjust_line_locationso   s    r9   c              	   C   s  | dd}tjjrtdt| t||f }td|j	}|
d}| sPd}|j	dsh|j	dsnd}nd}||  }||  | } t|j|j|j}||_	| |_|jt| |_|jt|  |_t|jd	d
}	|	 }
W d   n1 s0    Y  |
d|j |  |
|jd  }
t||t| | d tjj^ t|jdd
}	|	|
 W d   n1 sp0    Y  tjj|jdd W d   n1 s0    Y  |t||f< dS )z
    Adds `code` immediately before `filename` and `linenumber`. Those must
    correspond to an existing line, and the code is inserted with the same
    indentation as that line.
    r   r   <config.clear_lines must be False for script editing to work.z *r   r   z

rutf-8NwTforce)r   r,   configclear_lines	Exceptionr/   r0   rematchr   groupr)   r   r   r   r   r   lenr   r   codecsr   readr9   countloader	auto_lockwriteadd_auto)coder   r2   Zold_linemindentZline_endingZraw_codeZnew_linefdatar    r    r!   insert_line_before   s8    
& 
*2rT   c              	   C   s4  |  dd} tjjrtdt|  t| |f }t|j	dd}|
 }W d   n1 s^0    Y  ||j|j }|d|j ||jd  }t| |f= t| |t| |d  tjj\ t|j	dd}|| W d   n1 s0    Y  tjj|j	d	d
 W d   n1 s&0    Y  dS )zi
    Removes `linenumber` from `filename`. The line must exist and correspond
    to a logical line.
    r   r   r:   r<   r=   Nr;   r>   Tr?   )r   r,   rA   rB   rC   r/   r0   rH   r   r   rI   r   r   r9   rG   rJ   rK   rL   rM   rN   )r   r2   r7   rR   rS   rO   r    r    r!   remove_line   s    &

(rU   c                 C   s2   |  dd} t|  | |ftvr$dS t| |f jS )z~
    Returns the full text of `linenumber` from `filename`, including
    any comment or delimiter characters that exist.
    r   r   N)r   r/   r0   r   r1   r    r    r!   get_full_text   s
    rV   c                 C   sH   t |  g }tjjjD ],}|j| kr|j|kr|jdkr|| q|S )zC
    Returns a list of nodes that are found on the given line.
    never)	r/   r,   gamescript	all_stmtsr   r2   rollbackappend)r   r2   rvir    r    r!   nodes_on_line   s    r_   c                    s8   t    fddtjjjD }|s*g S t t|S )zL
    Returns a list of nodes that are found at or after the given line.
    c                    s0   g | ](}|j  kr|jkr|jd kr|jqS )rW   )r   r2   r[   ).0r^   r1   r    r!   
<listcomp>  s
   


z-nodes_on_line_at_or_after.<locals>.<listcomp>)r/   r,   rX   rY   rZ   r_   min)r   r2   r0   r    r1   r!   nodes_on_line_at_or_after
  s    rc   c                 C   s   g }g }| D ]H}| D ]}|j |u r q2q|| | D ]}|j |u r6 qq6|| qt|dkrjtdt|dkr~td|d |d fS )z
    Finds the first and last nodes in `nodes`, a list of nodes. This assumes
    that all the nodes are "simple", with no control flow, and that all of
    the relevant nodes are in `nodes`.
       z%Could not find unique first AST node.z$Could not find unique last AST node.r   )nextr\   rG   rC   )nodesZfirstsZlastsr^   jr    r    r!   first_and_last_nodes  s     


rh   c                 C   s6   t jjjD ]&}|j| kr
|j|kr
| j|7  _q
dS )z
    This adjusts the line numbers in the the ast.

    `filename`
        The filename to adjust.

    `linenumber`
        The first line to adjust.

    `offset`
        The amount to adjust by. Positive numbers increase the line
    N)r,   rX   rY   rZ   r   r2   )r   r2   offsetr^   r    r    r!   adjust_ast_linenumbers>  s    rj   c           
      C   s   t ||}t|\}}t|j|d tjjj|j| |d\}}| }tjjj	
| |s^dS tjjj	D ]}	|	||d  qhtj|| tjjD ]}	|	||d  qtjj||d  dS )zr
    Adds `code`, which must be a textual line of Ren'Py code,
    before the given filename and line number.
    rd   )r2   Nr   )rc   rh   rj   r   r,   rX   rY   load_stringpoprZ   removereplace_nextastchain_blockcontextsreplace_nodelog)
rO   r   r2   rf   old_block_initZret_stmtr^   r    r    r!   add_to_ast_beforeQ  s    
rx   c                 C   s2   zt | |}t| W dS  ty,   Y dS 0 dS )z
    Returns True if it's possible to add a line before the given filename
    and linenumber, and False if it's not possible.
    TFN)r_   rh   rC   )r   r2   rf   r    r    r!   can_add_beforep  s    
ry   c           	      C   s   t | |}t|\}}g }tjjjD ]&}||v r2q$|||j || q$|tjj_tjjj	}t
|D ]}|| |v rh|j||< qht| |d dS )z
    Removes from the AST all statements that happen to be at `filename`
    and `linenumber`, then adjusts the line numbers appropriately.

    There's an assumption that the statement(s) on the line are "simple",
    not involving control flow.
    N)r_   rh   r,   rX   rY   rZ   rn   re   r\   namemaplistrj   )	r   r2   rf   firstlastZ	new_stmtsr^   r{   kr    r    r!   remove_from_ast  s    	


r   rd   c                  C   sX   dt  } t d7 a tjjtj j}|j}|j}t	| || t
| || tj  d S )Nz'Hello world %f'rd   )serialr,   rX   rY   lookupcontextcurrentr   r2   rx   rT   exportsrestart_interaction)snoder   r2   r    r    r!   test_add  s    r   c                  C   sL   t jjt j j} | j}| j}t|| t	|| t j
jdddd d S )Nr   T)checkpointsr@   greedy)r,   rX   rY   r   r   r   r   r2   r   rU   r   r[   )r   r   r2   r    r    r!   test_remove  s    

r   )+
__future__r   r   r   r   r   renpy.compatr   r   r	   r
   r   r   r   r   r   r   r   r   r,   rD   rH   r0   setr*   objectr   r/   r3   r9   rT   rU   rV   r_   rc   rh   rj   rx   ry   r   r   r   r   r    r    r    r!   <module>   s.   8#&5 !%