B
    ¥éZ)2  ã               @   s   d Z 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	 G d
d„ de
ƒZd&dd„ZG dd„ de
ƒZdd„ Zd'dd„ZG dd„ de
ƒZG dd„ de
ƒZG dd„ de
ƒZG dd„ de
ƒZG dd„ de
ƒZG d d!„ d!e
ƒZG d"d#„ d#e
ƒZG d$d%„ d%e
ƒZdS )(a  Find occurrences of a name in a project.

This module consists of a `Finder` that finds all occurrences of a name
in a project. The `Finder.find_occurrences()` method is a generator that
yields `Occurrence` instances for each occurrence of the name. To create
a `Finder` object, use the `create_finder()` function:

    finder = occurrences.create_finder(project, 'foo', pyname)
    for occurrence in finder.find_occurrences():
        pass

It's possible to filter the occurrences. They can be specified when
calling the `create_finder()` function.

  * `only_calls`: If True, return only those instances where the name is
    a function that's being called.

  * `imports`: If False, don't return instances that are in import
    statements.

  * `unsure`: If a prediate function, return instances where we don't
    know what the name references. It also filters based on the
    predicate function.

  * `docs`: If True, it will search for occurrences in regions normally
    ignored. E.g., strings and comments.

  * `in_hierarchy`: If True, it will find occurrences if the name is in
    the class's hierarchy.

  * `instance`: Used only when you want implicit interfaces to be
    considered.

  * `keywords`: If False, don't return instances that are the names of keyword
    arguments
é    N)Úcodeanalyze)Úevaluate)Ú
exceptions)Úpynames)Ú	pyobjects)Úutils)Úworderc               @   s.   e Zd ZdZdd„ gdfdd„Zd
dd	„ZdS )ÚFindera  For finding occurrences of a name

    The constructor takes a `filters` argument.  It should be a list
    of functions that take a single argument.  For each possible
    occurrence, these functions are called in order with the an
    instance of `Occurrence`:

      * If it returns `None` other filters are tried.
      * If it returns `True`, the occurrence will be a match.
      * If it returns `False`, the occurrence will be skipped.
      * If all of the filters return `None`, it is skipped also.

    c             C   s   dS )NT© )Úor
   r
   ú8lib/python3.7/site-packages/rope/refactor/occurrences.pyÚ<lambda>@   s    zFinder.<lambda>Fc             C   s*   || _ || _|| _|| _t||d| _d S )N)Údocs)ÚprojectÚnamer   ÚfiltersÚ_TextualFinderÚ_textual_finder)Úselfr   r   r   r   r
   r
   r   Ú__init__@   s
    zFinder.__init__Nc             c   sh   t | j||| jd}xN| j |j¡D ]<}t||ƒ}x,| jD ]"}||ƒ}|dkrPq:|rZ|V  P q:W q$W dS )zGenerate `Occurrence` instances)ÚresourceÚpymoduler   N)Ú_OccurrenceToolsCreatorr   r   r   Úfind_offsetsÚsource_codeÚ
Occurrencer   )r   r   r   ÚtoolsÚoffsetÚ
occurrenceÚfilterÚresultr
   r
   r   Úfind_occurrencesG   s    
zFinder.find_occurrences)NN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r!   r
   r
   r
   r   r	   1   s   r	   FTc
          	   C   sÖ   t |gƒ}
g }|r| tƒ ¡ |s.| tƒ ¡ |	s>| tƒ ¡ t|tjƒr†x:| ¡ D ].}y|
 	|| ¡ W qT t
jk
r€   Y qTX qTW x,|
D ]$}| t|ƒ¡ |rŒ| t|ƒ¡ qŒW |rÆ| t|ƒ¡ t| |||dS )z¶A factory for `Finder`

    Based on the arguments it creates a list of filters.  `instance`
    argument is needed only when you want implicit interfaces to be
    considered.

    )r   r   )ÚsetÚappendÚCallsFilterÚNoImportsFilterÚNoKeywordsFilterÚ
isinstancer   ZParameterNameZget_objectsÚaddr   ZAttributeNotFoundErrorÚPyNameFilterÚInHierarchyFilterÚUnsureFilterr	   )r   r   ÚpynameZ
only_callsZimportsÚunsurer   ÚinstanceZin_hierarchyÚkeywordsZpynames_r   Úpyobjectr
   r
   r   Úcreate_finderV   s*    



r5   c               @   sœ   e Zd Zdd„ Zejdd„ ƒZejdd„ ƒZejdd„ ƒZejd	d
„ ƒZ	ejdd„ ƒZ
dd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zeejdd„ ƒƒZdS )r   c             C   s   || _ || _|j| _d S )N)r   r   r   )r   r   r   r
   r
   r   r   y   s    zOccurrence.__init__c             C   s   | j j | j¡S )N)r   Úword_finderÚget_word_ranger   )r   r
   r
   r   r7   ~   s    zOccurrence.get_word_rangec             C   s   | j j | j¡S )N)r   r6   Úget_primary_ranger   )r   r
   r
   r   r8   ‚   s    zOccurrence.get_primary_rangec             C   s,   y| j j | j¡S  tjk
r&   Y nX d S )N)r   Úname_finderZget_pyname_atr   r   ÚBadIdentifierError)r   r
   r
   r   Ú
get_pyname†   s    zOccurrence.get_pynamec             C   s,   y| j j | j¡S  tjk
r&   Y nX d S )N)r   r9   Zget_primary_and_pyname_atr   r   r:   )r   r
   r
   r   Úget_primary_and_pyname   s
    z!Occurrence.get_primary_and_pynamec             C   s    | j j | j¡p| j j | j¡S )N)r   r6   Zis_from_statementr   Zis_import_statement)r   r
   r
   r   Úis_in_import_statement•   s    z!Occurrence.is_in_import_statementc             C   s   | j j | j¡S )N)r   r6   Zis_a_function_being_calledr   )r   r
   r
   r   Ú	is_calledš   s    zOccurrence.is_calledc             C   s   | j j | j¡S )N)r   r6   Ú%is_a_class_or_function_name_in_headerr   )r   r
   r
   r   Ú
is_defined   s    zOccurrence.is_definedc             C   s    | j j | j¡p| j j | j¡S )N)r   r6   r?   r   Zis_a_name_after_from_import)r   r
   r
   r   Úis_a_fixed_primary¡   s    zOccurrence.is_a_fixed_primaryc             C   s   | j j | j¡S )N)r   r6   Zis_assigned_herer   )r   r
   r
   r   Ú
is_written¦   s    zOccurrence.is_writtenc             C   s   t |  ¡ ƒS )N)Úunsure_pynamer;   )r   r
   r
   r   Ú	is_unsure©   s    zOccurrence.is_unsurec             C   s   | j j | j¡S )N)r   r6   Úis_function_keyword_parameterr   )r   r
   r
   r   rE   ¬   s    z(Occurrence.is_function_keyword_parameterc             C   s   |   ¡ d }| jjj |¡S )Nr   )r7   r   r   ÚlinesZget_line_number)r   r   r
   r
   r   Úlineno°   s    zOccurrence.linenoN)r"   r#   r$   r   r   Úsaveitr7   r8   r;   r<   r=   r>   r@   rA   rB   rD   rE   ÚpropertyrG   r
   r
   r
   r   r   w   s   r   c             C   sl   | dks|dkrdS | |kr dS t | ƒtjtjfkrLt |ƒtjtjfkrLdS |  ¡ | ¡ koj|  ¡ | ¡ kS )z2Check whether `expected` and `pyname` are the sameNFT)Útyper   ZImportedModuleZImportedNameZget_definition_locationÚ
get_object)Zexpectedr0   r
   r
   r   Úsame_pyname·   s    
rL   c             C   s8   | dkrdS |r t | tjƒs dS |  ¡ t ¡ kr4dS dS )z8Return `True` if we don't know what this name referencesNTF)r+   r   ZUnboundNamerK   r   Zget_unknown)r0   Zunboundr
   r
   r   rC   Æ   s    rC   c               @   s    e Zd ZdZdd„ Zdd„ ZdS )r-   z"For finding occurrences of a name.c             C   s
   || _ d S )N)r0   )r   r0   r
   r
   r   r   Ó   s    zPyNameFilter.__init__c             C   s   t | j| ¡ ƒrdS d S )NT)rL   r0   r;   )r   r   r
   r
   r   Ú__call__Ö   s    zPyNameFilter.__call__N)r"   r#   r$   r%   r   rM   r
   r
   r
   r   r-   Ð   s   r-   c               @   s2   e Zd ZdZddd„Zdd„ Zdd„ Zd	d
„ ZdS )r.   z=Finds the occurrence if the name is in the class's hierarchy.Fc             C   sN   || _ || _|  |¡| _| jd k	rD| ¡  ¡ | _|  | j| j¡| _nd | _d S )N)	r0   Ú	impl_onlyÚ_get_containing_classÚpyclassrK   Zget_namer   Ú_get_root_classesÚroots)r   r0   Zimplementations_onlyr
   r
   r   r   Þ   s    
zInHierarchyFilter.__init__c             C   sF   | j d krd S |  | ¡ ¡}|d k	rB|  || j¡}| j  |¡rBdS d S )NT)rR   rO   r;   rQ   r   Úintersection)r   r   rP   rR   r
   r
   r   rM   è   s    
zInHierarchyFilter.__call__c             C   s<   t |tjƒr8| ¡  ¡ }|j}|d k	r8| ¡ dkr8|jS d S )NZClass)r+   r   ZDefinedNamerK   Z	get_scopeÚparentZget_kindr4   )r   r0   ZscoperT   r
   r
   r   rO   ñ   s
    z'InHierarchyFilter._get_containing_classc             C   s^   | j r|| jkrt|gƒS tƒ }x*| ¡ D ]}||kr*| |  ||¡¡ q*W |sZt|gƒS |S )N)rN   rP   r&   Zget_superclassesÚupdaterQ   )r   rP   r   r    Z
superclassr
   r
   r   rQ   ø   s    

z#InHierarchyFilter._get_root_classesN)F)r"   r#   r$   r%   r   rM   rO   rQ   r
   r
   r
   r   r.   Û   s
   

	r.   c               @   s    e Zd ZdZdd„ Zdd„ ZdS )r/   z:Occurrences where we don't knoow what the name references.c             C   s
   || _ d S )N)r1   )r   r1   r
   r
   r   r     s    zUnsureFilter.__init__c             C   s   |  ¡ r|  |¡rdS d S )NT)rD   r1   )r   r   r
   r
   r   rM   
  s    zUnsureFilter.__call__N)r"   r#   r$   r%   r   rM   r
   r
   r
   r   r/     s   r/   c               @   s   e Zd ZdZdd„ ZdS )r)   z/Don't include import statements as occurrences.c             C   s   |  ¡ rdS d S )NF)r=   )r   r   r
   r
   r   rM     s    zNoImportsFilter.__call__N)r"   r#   r$   r%   rM   r
   r
   r
   r   r)     s   r)   c               @   s   e Zd ZdZdd„ ZdS )r(   z Filter out non-call occurrences.c             C   s   |  ¡ sdS d S )NF)r>   )r   r   r
   r
   r   rM     s    zCallsFilter.__call__N)r"   r#   r$   r%   rM   r
   r
   r
   r   r(     s   r(   c               @   s   e Zd ZdZdd„ ZdS )r*   zFilter out keyword parameters.c             C   s   |  ¡ rdS d S )NF)rE   )r   r   r
   r
   r   rM   "  s    zNoKeywordsFilter.__call__N)r"   r#   r$   r%   rM   r
   r
   r
   r   r*     s   r*   c               @   sZ   e Z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d„ Z
edd„ ƒZdS )r   Fc             C   sB   || _ || _t ddg¡| _t dt ¡ g¡| _|  | j ¡| _	d S )NÚcommentz#[^\n]*Ústring)
r   r   r   ÚanyÚcomment_patternr   Zget_string_patternÚstring_patternÚ_get_occurrence_patternÚpattern)r   r   r   r
   r
   r   r   )  s    z_TextualFinder.__init__c             c   s>   |   |¡sd S | jr| j}n| j}x||ƒD ]
}|V  q,W d S )N)Ú_fast_file_queryr   Ú_normal_searchÚ
_re_search)r   ÚsourceZsearcherZmatchedr
   r
   r   r   1  s    
z_TextualFinder.find_offsetsc             c   sL   xF| j  |¡D ]6}x0| ¡  ¡ D ] \}}|r |dkr | |¡V  q W qW d S )Nr   )r\   ÚfinditerÚ	groupdictÚitemsÚstart)r   r`   ÚmatchÚkeyÚvaluer
   r
   r   r_   ;  s    z_TextualFinder._re_searchc             c   s€   d}xvyZ|  | j|¡}|t| jƒ }|dks>|  ||d  ¡s^|t|ƒksX|  || ¡s^|V  W q tk
rv   P Y qX qW d S )Nr   é   )Úindexr   ÚlenÚ_is_id_charÚ
ValueError)r   r`   ZcurrentÚfoundr
   r
   r   r^   A  s    
z_TextualFinder._normal_searchc             C   s   |  ¡ p|dkS )NÚ_)Úisalnum)r   Úcr
   r
   r   rk   O  s    z_TextualFinder._is_id_charc             C   s*   y|  | j¡ dS  tk
r$   dS X d S )NTF)ri   r   rl   )r   r`   r
   r
   r   r]   R  s
    z_TextualFinder._fast_file_queryc             C   s   |d k	r|  ¡ S |jS d S )N)Úreadr   )r   r   r   r
   r
   r   Ú_get_sourceY  s    z_TextualFinder._get_sourcec             C   s8   t  dd| d g¡}t |d | j d | j ¡}|S )Nr   z\bú|)r   rX   ÚreÚcompilerY   rZ   )r   r   Zoccurrence_patternr\   r
   r
   r   r[   _  s
    z&_TextualFinder._get_occurrence_patternc             C   s   d|  d  |¡ d S )Nz(?P<%s>rs   ú))Újoin)r   Zlist_r
   r
   r   rX   f  s    z_TextualFinder.anyN)F)r"   r#   r$   r   r   r_   r^   rk   r]   rr   r[   ÚstaticmethodrX   r
   r
   r
   r   r   '  s   

r   c               @   sp   e Zd Zddd„Zeejdd„ ƒƒZeejdd„ ƒƒZeejd	d
„ ƒƒZ	eejdd„ ƒƒZ
eejdd„ ƒƒZdS )r   NFc             C   s   || _ || _|| _|| _d S )N)r   Ú!_OccurrenceToolsCreator__resourceÚ!_OccurrenceToolsCreator__pymoduler   )r   r   r   r   r   r
   r
   r   r   m  s    z _OccurrenceToolsCreator.__init__c             C   s   t  | j¡S )N)r   ZScopeNameFinderr   )r   r
   r
   r   r9   s  s    z#_OccurrenceToolsCreator.name_finderc             C   s    | j d k	r| j ¡ S | jjS d S )N)ry   r   rq   r   r   )r   r
   r
   r   r   x  s    

z#_OccurrenceToolsCreator.source_codec             C   s   t  | j| j¡S )N)r   ZWorderr   r   )r   r
   r
   r   r6   €  s    z#_OccurrenceToolsCreator.word_finderc             C   s&   | j d k	r| j S | jd k	r"| jjS d S )N)ry   rz   r   )r   r
   r
   r   r   …  s    

z _OccurrenceToolsCreator.resourcec             C   s   | j d k	r| j S | j | j¡S )N)rz   r   Zget_pymoduler   )r   r
   r
   r   r     s    
z _OccurrenceToolsCreator.pymodule)NNF)r"   r#   r$   r   rI   r   rH   r9   r   r6   r   r   r
   r
   r
   r   r   k  s   
r   )FTNFNFT)T)r%   rt   Z	rope.baser   r   r   r   r   r   r   Úobjectr	   r5   r   rL   rC   r-   r.   r/   r)   r(   r*   r   r   r
   r
   r
   r   Ú<module>$   s.   %  
@

)D