
    Æe2                     ,   d Z ddlZddlZddlmZmZmZmZmZm	Z	m
Z
mZ  G d d      Z	 	 	 	 	 	 	 ddZ G d d      Zd	 Zdd
Z G d d      Z G d d      Z G d d      Z G d d      Z G d d      Z G d d      Z G d d      Z G d d      Zy)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 predicate 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)astcodeanalyzeevaluate
exceptionspynames	pyobjectsutilsworderc                        e Zd ZdZddZddZy)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.

    Nc                 l    |d g}|| _         || _        || _        || _        t	        ||      | _        y )Nc                      yNT )os    ;/usr/lib/python3/dist-packages/rope/refactor/occurrences.py<lambda>z!Finder.__init__.<locals>.<lambda>G   s        )docs)projectnamer   filters_TextualFinder_textual_finder)selfr   r   r   r   s        r   __init__zFinder.__init__E   s:    ?%&G		-d>r   c              #     K   t        | j                  ||| j                        }| j                  j	                  |j
                        D ]1  }t        ||      }| j                  D ]  } ||      }||r|  1 3 yw)zGenerate `Occurrence` instances)resourcepymoduler   N)_OccurrenceToolsCreatorr   r   r   find_offsetssource_code
Occurrencer   )r   r   r   toolsoffset
occurrencefilterresults           r   find_occurrenceszFinder.find_occurrencesN   s     'LL8hTYY
 **778I8IJ 	F#E62J,, 
+>$$	s   A>B NF)NN)__name__
__module____qualname____doc__r   r)   r   r   r   r   r   6   s    ?r   r   c
                 :   |h}
g }|r|j                  t                      |s|j                  t                      |	s|j                  t                      t	        |t
        j                        r*|j                         D ]  }	 |
j                  ||           |
D ]9  }|j                  t        |             |s |j                  t        |             ; |r|j                  t        |             t        | |||      S # t        j                  $ r Y w xY w)zA 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   )appendCallsFilterNoImportsFilterNoKeywordsFilter
isinstancer   ParameterNameget_objectsaddr   AttributeNotFoundErrorPyNameFilterInHierarchyFilterUnsureFilterr   )r   r   pyname
only_callsimportsunsurer   instancein_hierarchykeywordspynames_r   pyobjects                r   create_finderrE   ^   s    & xHG{}%()')*(G112 ,,. 	HXd^,	
  6|F+,NN,V456 |F+,'4t<< 44 s   DDDc                      e Zd Zd Zej
                  d        Zej
                  d        Zej
                  d        Zej
                  d        Z	ej
                  d        Z
d Zd Zd	 Zd
 Zd Zd Zeej
                  d               Zy)r#   c                 B    || _         || _        |j                  | _        y N)r$   r%   r   )r   r$   r%   s      r   r   zOccurrence.__init__   s    
r   c                 `    | j                   j                  j                  | j                        S rH   )r$   word_finderget_word_ranger%   r   s    r   rK   zOccurrence.get_word_range   s!    zz%%44T[[AAr   c                 `    | j                   j                  j                  | j                        S rH   )r$   rJ   get_primary_ranger%   rL   s    r   rN   zOccurrence.get_primary_range   s!    zz%%77DDr   c                     t        j                  t        j                        5  | j                  j
                  j                  | j                        cd d d        S # 1 sw Y   y xY wrH   )
contextlibsuppressr   BadIdentifierErrorr$   name_finderget_pyname_atr%   rL   s    r   
get_pynamezOccurrence.get_pyname   sK      !>!>? 	E::))77D	E 	E 	E   /AA&c                     t        j                  t        j                        5  | j                  j
                  j                  | j                        cd d d        S # 1 sw Y   y xY wrH   )rP   rQ   r   rR   r$   rS   get_primary_and_pyname_atr%   rL   s    r   get_primary_and_pynamez!Occurrence.get_primary_and_pyname   sK      !>!>? 	Q::))CCDKKP	Q 	Q 	QrV   c                     | j                   j                  j                  | j                        xs/ | j                   j                  j	                  | j                        S rH   )r$   rJ   is_from_statementr%   is_import_statementrL   s    r   is_in_import_statementz!Occurrence.is_in_import_statement   sI    zz%%77KK
 EZZ##77D	Er   c                 `    | j                   j                  j                  | j                        S rH   )r$   rJ   is_a_function_being_calledr%   rL   s    r   	is_calledzOccurrence.is_called   s!    zz%%@@MMr   c                 `    | j                   j                  j                  | j                        S rH   )r$   rJ   %is_a_class_or_function_name_in_headerr%   rL   s    r   
is_definedzOccurrence.is_defined   s!    zz%%KKDKKXXr   c                     | j                   j                  j                  | j                        xs/ | j                   j                  j	                  | j                        S rH   )r$   rJ   rb   r%   is_a_name_after_from_importrL   s    r   is_a_fixed_primaryzOccurrence.is_a_fixed_primary   sI    zz%%KKKK
 MZZ##??L	Mr   c                 `    | j                   j                  j                  | j                        S rH   )r$   rJ   is_assigned_herer%   rL   s    r   
is_writtenzOccurrence.is_written   s!    zz%%66t{{CCr   c                 4    t        | j                               S rH   )unsure_pynamerU   rL   s    r   	is_unsurezOccurrence.is_unsure   s    T__.//r   c                 `    | j                   j                  j                  | j                        S rH   )r$   rJ   is_function_keyword_parameterr%   rL   s    r   rn   z(Occurrence.is_function_keyword_parameter   s!    zz%%CCDKKPPr   c                     | j                         d   }| j                  j                  j                  j	                  |      S )Nr   )rK   r$   r   linesget_line_number)r   r%   s     r   linenozOccurrence.lineno   s8     $$&q)zz""((88@@r   N)r+   r,   r-   r   r	   saveitrK   rN   rU   rY   r]   r`   rc   rf   ri   rl   rn   propertyrr   r   r   r   r#   r#      s    '
 \\B B \\E E \\E E \\Q Q \\E E
NYM
D0Q 
\\A  Ar   r#   c                 J   | |y| |k(  ryt        | t        j                  t        j                  f      s+t        |t        j                  t        j                  f      sy| j	                         |j	                         k(  xr! | j                         |j                         k(  S )z2Check whether `expected` and `pyname` are the sameFT)r4   r   ImportedModuleImportedNameget_definition_location
get_object)expectedr<   s     r   same_pynamer{      s    6>6			!5!56 			!5!56 ((*f.L.L.NN 	9!V%6%6%88r   c                     | y|rt        | t        j                        sy| j                         t	        j
                         k(  ryy)z8Return `True` if we don't know what this name referencesNTF)r4   r   UnboundNamery   r   get_unknown)r<   unbounds     r   rk   rk      sA    ~z&'*=*=>i3355 6r   c                       e Zd ZdZd Zd Zy)r9   z"For finding occurrences of a name.c                     || _         y rH   )r<   )r   r<   s     r   r   zPyNameFilter.__init__   	    r   c                 N    t        | j                  |j                               ryy r   )r{   r<   rU   r   r&   s     r   __call__zPyNameFilter.__call__   s!    t{{J$9$9$;< =r   Nr+   r,   r-   r.   r   r   r   r   r   r9   r9      s    ,r   r9   c                   *    e Zd ZdZddZd Zd Zd Zy)r:   z=Finds the occurrence if the name is in the class's hierarchy.c                    || _         || _        | j                  |      | _        | j                  O|j	                         j                         | _        | j                  | j                  | j                        | _        y d | _        y rH   )	r<   	impl_only_get_containing_classpyclassry   get_namer   _get_root_classesroots)r   r<   implementations_onlys      r   r   zInHierarchyFilter.__init__   sh    -11&9<<#))+446DI//diiHDJDJr   c                     | j                   y | j                  |j                               }|9| j                  || j                        }| j                   j                  |      ryy y r   )r   r   rU   r   r   intersection)r   r&   r   r   s       r   r   zInHierarchyFilter.__call__   sc    ::,,Z-B-B-DE**7DII>Ezz&&u- . r   c                     t        |t        j                        rM|j                         j	                         }|j
                  }| |j                         dk(  r|j                  S y y y )NClass)r4   r   DefinedNamery   	get_scopeparentget_kindrD   )r   r<   scoper   s       r   r   z'InHierarchyFilter._get_containing_class   s^    fg112%%'113E\\F!foo&77&B& 'C! 3r   c                     | j                   r|| j                  k(  r|hS t               }|j                         D ](  }||v s|j	                  | j                  ||             * |s|hS |S rH   )r   r   setget_superclassesupdater   )r   r   r   r(   
superclasss        r   r   z#InHierarchyFilter._get_root_classes  sp    >>g59!224 	HJz!d44ZFG	H 9r   NF)r+   r,   r-   r.   r   r   r   r   r   r   r   r:   r:      s    G'	r   r:   c                       e Zd ZdZd Zd Zy)r;   z:Occurrences where we don't knoow what the name references.c                     || _         y rH   )r?   )r   r?   s     r   r   zUnsureFilter.__init__  r   r   c                 J    |j                         r| j                  |      ryy y r   )rl   r?   r   s     r   r   zUnsureFilter.__call__  s$    !dkk*&= '>!r   Nr   r   r   r   r;   r;     s    Dr   r;   c                       e Zd ZdZd Zy)r2   z/Don't include import statements as occurrences.c                 &    |j                         ryy r*   )r]   r   s     r   r   zNoImportsFilter.__call__!  s    ,,. /r   Nr+   r,   r-   r.   r   r   r   r   r2   r2     s
    9r   r2   c                       e Zd ZdZd Zy)r1   z Filter out non-call occurrences.c                 &    |j                         syy r*   )r`   r   s     r   r   zCallsFilter.__call__)  s    ##% &r   Nr   r   r   r   r1   r1   &  s
    *r   r1   c                       e Zd ZdZd Zy)r3   zFilter out keyword parameters.c                 &    |j                         ryy r*   )rn   r   s     r   r   zNoKeywordsFilter.__call__1  s    335 6r   Nr   r   r   r   r3   r3   .  s
    (r   r3   c                   T    e Zd ZddZd Zd Zd Zd Zd Zd Z	d Z
d	 Zed
        Zy)r   c                 P   || _         || _        t        j                  ddg      | _        t        j                  dt        j                         g      | _        t        j                  dt        j                         g      | _	        | j                  | j                         | _        y )Ncommentz#[^\n]*stringfstring)r   r   r   anycomment_patternr   get_string_patternstring_patternget_formatted_string_patternf_string_pattern_get_occurrence_patternpattern)r   r   r   s      r   r   z_TextualFinder.__init__7  s    		-11)j\J,00{5578
 !/ 2 2@@BC!
 33DII>r   c              #      K   | j                  |      sy | j                  r| j                  }n| j                  } ||      E d {    y 7 wrH   )_fast_file_queryr   _normal_search
_re_search)r   sourcesearchers      r   r!   z_TextualFinder.find_offsetsC  s@     $$V,99**HHF###s   AAAAc              #   T  K   | j                   j                  |      D ]  }|j                         d   r|j                  d       *|j                         d   s>|j                         d   }| j	                  |      D ]"  }|j                  d      |j
                  z    $  y w)Nr&   r   )r   finditer	groupdictstart_search_in_f_string
col_offset)r   r   matchf_stringoccurrence_nodes        r   r   z_TextualFinder._re_searchL  s     \\**62 	NE .kk,//"9- ??,Y7'+'?'?'I NO++i0?3M3MMMN	Ns   AB(AB(c              #      K   t        j                  |      }t        j                  |      D ];  }t        |t         j                        s|j
                  | j                  k(  s8| = y wrH   )r   parsewalkr4   Nameidr   )r   r   treenodes       r   r   z"_TextualFinder._search_in_f_stringU  sM     yy"HHTN 	D$)dgg.B
	s   AA,A,%A,c              #     K   d}	 	 |j                  | j                  |      }|t        | j                        z   }|dk(  s| j                  ||dz
           s&|t        |      k(  s| j                  ||         s| x# t        $ r Y y w xY ww)Nr      )indexr   len_is_id_char
ValueError)r   r   currentfounds       r   r   z_TextualFinder._normal_search[  s     TYY8#dii.0QJd&6&6veai7H&Is6{*$2B2B6'?2SK   s)   BA6A> =B>	B
B	B

Bc                 0    |j                         xs |dk(  S )N_)isalnum)r   cs     r   r   z_TextualFinder._is_id_charh  s    yy{&a3h&r   c                     | j                   |v S rH   )r   )r   r   s     r   r   z_TextualFinder._fast_file_queryk  s    yyF""r   c                 >    ||j                         S |j                  S rH   )readr"   )r   r   r   s      r   _get_sourcez_TextualFinder._get_sourcen  s     ==?"'''r   c                     t         j                  dd|z   dz   g      }t        j                  |dz   | j                  z   dz   | j
                  z   dz   | j                  z         }|S )Nr&   z\b|)r   r   recompiler   r   r   )r   r   occurrence_patternr   s       r   r   z&_TextualFinder._get_occurrence_patternt  s    +//ut|e?S>TU**""#  !!	"
  ##$
 r   c                 6    d| z  dj                  |      z   dz   S )Nz(?P<%s>r   ))join)r   list_s     r   r   z_TextualFinder.any  s    4#((5/1C77r   Nr   )r+   r,   r-   r   r!   r   r   r   r   r   r   r   staticmethodr   r   r   r   r   r   6  sD    
?$N'#( 8 8r   r   c                       e Zd ZddZeej                  d               Zeej                  d               Zeej                  d               Z	eej                  d               Z
eej                  d               Zy)	r    Nc                 <    || _         || _        || _        || _        y rH   )r   !_OccurrenceToolsCreator__resource!_OccurrenceToolsCreator__pymoduler   )r   r   r   r   r   s        r   r   z _OccurrenceToolsCreator.__init__  s    ""	r   c                 @    t        j                  | j                        S rH   )r   ScopeNameFinderr   rL   s    r   rS   z#_OccurrenceToolsCreator.name_finder  s     ''66r   c                 .    | j                   j                  S rH   )r   r"   rL   s    r   r"   z#_OccurrenceToolsCreator.source_code  s     }}(((r   c                 V    t        j                  | j                  | j                        S rH   )r
   Worderr"   r   rL   s    r   rJ   z#_OccurrenceToolsCreator.word_finder  s     }}T--tyy99r   c                 x    | j                   | j                   S | j                  | j                  j                  S y rH   )r   r   r   rL   s    r   r   z _OccurrenceToolsCreator.resource  s7     ??&??"??&??+++ 'r   c                 |    | j                   | j                   S | j                  j                  | j                        S rH   )r   r   get_pymoduler   rL   s    r   r   z _OccurrenceToolsCreator.pymodule  s1     ??&??"||((77r   )NNF)r+   r,   r-   r   rt   r	   rs   rS   r"   rJ   r   r   r   r   r   r    r      s     
\\7  7 
\\)  ) 
\\:  : 
\\,  , 
\\8  8r   r    )FTNFNFT)T)r.   rP   r   	rope.baser   r   r   r   r   r   r	   r
   r   rE   r#   r{   rk   r9   r:   r;   r2   r1   r3   r   r    r   r   r   <module>r      s   #L  		 	 	% %X 	'=T6A 6Ar( & &R    M8 M8`#8 #8r   