a
    ]9śaĪ  ć                   @   s   d dl 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 G dd deZdd ZdS )é    N)Śbuiltins)Ś
exceptions)Ślibutils)Śpynames)Ś	pyobjects)Ś	resources)Śresourceobserver)Ś
taskhandle)Śimportutilsc                   @   s“   e Zd ZdZd'ddZdd Zdd	 Zd
d Zdd Zdde	 
” fddZde	 
” fddZdd Zdd Zd(ddZd)ddZdd Zdd Zdd  Zd!d" Zd#d$ Zd%d& ZdS )*Ś
AutoImportzĮA class for finding the module that provides a name

    This class maintains a cache of global names in python modules.
    Note that this cache is not accurate and might be out of date.

    TFc                 C   s`   || _ || _|j d”| _| jdu r*i | _|j | j” tj| j	| j
| jd}|r\| |” dS )zĒConstruct an AutoImport object

        If `observe` is `True`, listen for project changes and update
        the cache.

        If `underlined` is `True`, underlined names are cached, too.
        ŚglobalnamesN)ZchangedZmovedZremoved)ŚprojectŚ
underlinedŚ
data_filesZ	read_dataŚnamesZadd_write_hookŚ_writer   ZResourceObserverŚ_changedŚ_movedŚ_removedZadd_observer)Śselfr   Zobserver   Zobserver© r   ś6lib/python3.9/site-packages/rope/contrib/autoimport.pyŚ__init__   s    
’zAutoImport.__init__c                 C   s<   g }| j D ],}| j | D ]}| |”r| ||f” qq
|S )zReturn a list of ``(name, module)`` tuples

        This function tries to find modules that have a global name
        that starts with `starting`.
        )r   Ś
startswithŚappend)r   ZstartingŚresultŚmoduleZglobal_namer   r   r   Śimport_assist+   s    

zAutoImport.import_assistc                 C   s,   g }| j D ]}|| j | v r
| |” q
|S )z2Return the list of modules that have global `name`)r   r   )r   Śnamer   r   r   r   r   Śget_modules9   s
    
zAutoImport.get_modulesc                 C   s*   t  }| jD ]}| t | j| ” q|S )z*Return the list of all cached global names)Śsetr   Śupdate)r   r   r   r   r   r   Śget_all_namesA   s    
zAutoImport.get_all_namesc              	   C   s   g }| j D ]}|| j | v r
z^| j |”}||v rx|| }| ” \}}|durx| ”  ” }|durx|durx| ||f” W q
 tjy   Y q
0 q
|S )z.Return a list of ``(resource, lineno)`` tuplesN)r   r   Ś
get_moduleZget_definition_locationZget_resourcer   r   ŚModuleNotFoundError)r   r   r   r   ŚpymoduleŚpynameŚlinenoŚresourcer   r   r   Śget_name_locationsH   s    
zAutoImport.get_name_locationsNc                 C   sT   |du r| j  ” }| dt|”}|D ](}| d|j ” |  ||” | ”  q&dS )zŻGenerate global name cache for project files

        If `resources` is a list of `rope.base.resource.File`, only
        those files are searched; otherwise all python modules in the
        project are cached.

        NzGenerating autoimport cacheśWorking on <%s>)r   Zget_python_filesŚcreate_jobsetŚlenŚstarted_jobŚpathŚupdate_resourceŚfinished_job)r   r   r   Śtask_handleŚjob_setŚfiler   r   r   Śgenerate_cacheZ   s    

’zAutoImport.generate_cachec                 C   s~   |  dt|”}|D ]d}| d| ” | d”rd| j |dd ”}|rpt|D ]}|  ||” qPn|  ||” | 	”  qdS )z:Generate global name cache for modules listed in `modules`z'Generating autoimport cache for modulesr*   z.*Néž’’’)
r+   r,   r-   Śendswithr   Śfind_moduleŚ
submodulesr/   Śupdate_moduler0   )r   Śmodulesr   r1   r2   ŚmodnameŚmodŚsubr   r   r   Śgenerate_modules_cachen   s    ’
z!AutoImport.generate_modules_cachec                 C   s   | j  ”  dS )zClear all entries in global-name cache

        It might be a good idea to use this function before
        regenerating global names.

        N)r   Śclear©r   r   r   r   Śclear_cache   s    zAutoImport.clear_cachec           	      C   s¢   t  d|”}|dur$|d| ”  }zt | j|”}W n tjyL   Y dS 0 d}t 	|dff”}t 
| j|”}| |” | ” }| |”}| dd|”d }|S )z4Guess at what line the new import should be insertedz^(def|class)\s+Né   Z__rope_testmodule_ropeŚ
r   )ŚreŚsearchŚstartr   Zget_string_moduler   r   ŚModuleSyntaxErrorr
   ZNormalImportZget_module_importsZ
add_importZget_changed_sourceŚindexŚcount)	r   ŚcodeŚmatchr%   ZtestmodnameZ
importinfoZmodule_importsŚoffsetr'   r   r   r   Śfind_insertion_line   s    

zAutoImport.find_insertion_linec                 C   sB   z(| j  |”}|  |”}|  |||” W n tjy<   Y n0 dS )z/Update the cache for global names in `resource`N)r   Zget_pymoduleŚ_module_nameŚ
_add_namesr   rG   )r   r(   r   r%   r;   r   r   r   r/      s    
zAutoImport.update_resourcec                 C   s8   z| j  |”}|  |||” W n tjy2   Y n0 dS )zjUpdate the cache for global names in `modname` module

        `modname` is the name of a module.
        N)r   r#   rO   r   r$   )r   r;   r   r%   r   r   r   r9   ¤   s
    zAutoImport.update_modulec                 C   s
   t  |”S ©N)r   r;   ©r   r(   r   r   r   rN   Æ   s    zAutoImport._module_namec                 C   s   |d u r| j }g }t|tjr(| ” }n| ” }| ” D ]J\}}|sP| d”rPq8t|tj	tj
frl| |” t|tjr8| |” q8|| j|< d S )NŚ_)r   Ś
isinstancer   ZPyDefinedObjectZ_get_structural_attributesZget_attributesŚitemsr   r   ZAssignedNameZDefinedNamer   r   ZBuiltinModuler   )r   r%   r;   r   ŚglobalsZ
attributesr   r&   r   r   r   rO   ²   s    

zAutoImport._add_namesc                 C   s   | j j d| j” d S )Nr   )r   r   Z
write_datar   r@   r   r   r   r   Ć   s    zAutoImport._writec                 C   s   |  ” s|  |” d S rP   )Ś	is_folderr/   rQ   r   r   r   r   Ę   s    zAutoImport._changedc                 C   s2   |  ” s.|  |”}|| jv r$| j|= |  |” d S rP   )rV   rN   r   r/   )r   r(   Znewresourcer;   r   r   r   r   Ź   s
    

zAutoImport._movedc                 C   s(   |  ” s$|  |”}|| jv r$| j|= d S rP   )rV   rN   r   )r   r(   r;   r   r   r   r   Ń   s    

zAutoImport._removed)TF)N)N)Ś__name__Ś
__module__Ś__qualname__Ś__doc__r   r   r   r"   r)   r	   ZNullTaskHandler4   r>   rA   rM   r/   r9   rN   rO   r   r   r   r   r   r   r   r   r      s(   

’
’
	
	
r   c                 C   sj   t | tjr2| j d”r,| jdkr,t| gS t S |  d”sBt S t| g}|  ” D ]}|t|O }qT|S )Nz.pyz__init__.py)	rS   r   ZFiler   r6   r    Z	has_childZget_childrenr8   )r<   r   Śchildr   r   r   r8   Ų   s    


r8   )rD   Z	rope.baser   r   r   r   r   r   r   r	   Zrope.refactorr
   Śobjectr   r8   r   r   r   r   Ś<module>   s    K