
    Æe1                     *   d Z ddlZddlZddlZddlmZmZmZm	Z	 ddl
mZ ddlmZ  G d dej                        Z G d d	      Z G d
 d      Z G d d      Z G d d      Z G d de      Z G d de      Z G d d      Z G d d      Zd Zd Zy)z0This module can be used for finding similar code    N)astcodeanalyze
exceptionslibutils)
patchedast)MismatchedTokenErrorc                       e Zd Zy)BadNameInCheckErrorN)__name__
__module____qualname__     =/usr/lib/python3/dist-packages/rope/refactor/similarfinder.pyr
   r
      s    r   r
   c                   ,    e Zd ZdZddZddZd Zd Zy)	SimilarFinderz`SimilarFinder` can be used to find similar pieces of code

    See the notes in the `rope.refactor.restructure` module for more
    info.

    Nc                    |j                   | _        	 t        |j                   |j                         | j                        | _        || _
        |hi | _        t        j                  j                  j                  |j                  j                         fD ]  }|| j                  |j#                         <   ! y|| _        y# t        $ r$ t        d|j                  j                  z          w xY w)zConstruct a SimilarFinderz
in file %sN)source_codesourceRawSimilarFinderget_ast_does_match
raw_finderr   printresourcepathpymodule	wildcardsroperefactorDefaultWildcardpycoreprojectget_name)selfr   r   wildcards       r   __init__zSimilarFinder.__init__   s    **	.$$h&6&6&8$:J:JDO !DN''778O8OP ? 7?x0023?
 'DN $ 	,!2!2!7!778	s   4C   -C-c                    |i }|| _         |t        | j                        }d }d|j                  di       v r*|d   d   \  }}|| j                  j                         k(  r|}| j                  j                  ||||      S )Nskip )startendr)   )argslenr   getr   get_resourcer   get_matches)r%   coder-   r+   r,   skip_regionr   regions           r   r1   zSimilarFinder.get_matches+   s    <D	;dkk"CTXXb"%%#Bx/Hf4==5577$**4u#K*XXr   c              /   ^   K    | j                   |i |D ]  }|j                           y wN)r1   
get_region)r%   r-   kwdsmatchs       r   get_match_regionszSimilarFinder.get_match_regions8   s6     %T%%t4t4 	%E""$$	%s   +-c                 &   | j                   j                  |d      }d}t        |t        t        f      r
|d   }|d   }t
        j                  j                  j                  | j                  ||      }| j                  |   j                  ||      S )Nr*   defaultr      )r-   r/   
isinstancetuplelistr   r    r   Suspectr   matches)r%   nodenameargkindsuspects         r   r   zSimilarFinder._does_match<   sy    iimmD"%cE4=)q6Da&C--))11$--tL~~d#++GS99r   r6   )Nr   N)r   r   r   __doc__r'   r1   r:   r   r   r   r   r   r      s    '(Y%:r   r   c                   >    e Zd ZdZd
dZd Zd ZddZd Zd Z	d	 Z
y)r   z6A class for finding similar expressions and statementsNc                     |	 t        j                  |      }|| j                  | _        n|| _        | j                  ||       y # t        $ r t        j                  d|z   dz         }Y Tw xY w)N())r   parseSyntaxError_simple_does_match
does_match_init_using_ast)r%   r   rC   rP   s       r   r'   zRawSimilarFinder.__init__I   sn    <5yy( "55DO(DOT6*  5yyv!345s   A $A.-A.c                 V    t        |t        j                  t        j                  f      S r6   )r>   r   exprName)r%   rC   rD   s      r   rO   z#RawSimilarFinder._simple_does_matchV   s    $388 455r   c                 r    || _         i | _        t        |d      st        j                  ||       || _        y )Nr4   )r   _matched_astshasattrr   	patch_astr   )r%   rC   r   s      r   rQ   z RawSimilarFinder._init_using_astY   s2    tX&  v.r   c              #      K   |t        | j                        }| j                  |      D ]8  }|j                         \  }}||k  s||k  s"||d   |k  r	|d   |kD  r5| : yw)a%  Search for `code` in source and return a list of `Match`-es

        `code` can contain wildcards.  ``${name}`` matches normal
        names and ``${?name} can match any expression.  You can use
        `Match.get_ast()` for getting the node that has matched a
        given pattern.

        Nr   r=   )r.   r   _get_matched_astsr7   )r%   r2   r+   r,   r)   r9   match_start	match_ends           r   r1   zRawSimilarFinder.get_matches`   s{      ;dkk"C++D1 	E%*%5%5%7"K#	S(8#a9)<a;AV	s   AA'A'A'c                     || j                   vrO| j                  |      }t        | j                  || j                        j                         }|| j                   |<   | j                   |   S r6   )rV   _create_pattern_ASTMatcherr   rP   find_matches)r%   r2   wantedrB   s       r   rZ   z"RawSimilarFinder._get_matched_astsr   s`    t)))))$/F!$((FDOODQQSG'.Dt$!!$''r   c                     | j                  |      }t        j                  |      }|j                  }t	        |      dk(  r.t        |d   t        j                        r|d   j                  }|S |}|S )Nr=   r   )_replace_wildcardsr   rM   bodyr.   r>   Exprvalue)r%   
expressionrC   nodesra   s        r   r^   z RawSimilarFinder._create_patterny   se    ,,Z8
yy$		u:?z%(CHH=1X^^F  Fr   c                     t               }t        |      }|j                         D ci c]  }||j                  |       }}|j	                  |      S c c}w r6   )_RopeVariableCodeTemplate	get_namesget_var
substitute)r%   rg   ropevartemplaterD   mappings         r   rc   z#RawSimilarFinder._replace_wildcards   sT    /
+;C;M;M;OP44..PP""7++ Qs   A)NN)r   NN)r   r   r   rH   r'   rO   rQ   r1   rZ   r^   rc   r   r   r   r   r   F   s(    @+6$(
,r   r   c                   H    e Zd Zd Zd Zd Zd Zd Zd Zd Z	d Z
d	 Zd
 Zy)r_   c                 Z    || _         || _        d| _        t               | _        || _        y)zSearches the given pattern in the body AST.

        body is an AST node and pattern can be either an AST node or
        a list of ASTs nodes
        N)rd   patternrB   rj   ro   matches_callback)r%   rd   rt   rP   s       r   r'   z_ASTMatcher.__init__   s*     	$ *r   c                     | j                   1g | _         t        j                  | j                  | j                         | j                   S r6   )rB   r   call_for_nodesrd   _check_noder%   s    r   r`   z_ASTMatcher.find_matches   s9    <<DL tyy$*:*:;||r   c                 ~    t        | j                  t              r| j                  |       y | j	                  |       y r6   )r>   rt   r@   _check_statements_check_expression)r%   rC   s     r   rx   z_ASTMatcher._check_node   s,    dllD)""4(""4(r   c                     i }| j                  | j                  ||      r&| j                  j                  t	        ||             y y r6   )_match_nodesrt   rB   appendExpressionMatch)r%   rC   rq   s      r   r|   z_ASTMatcher._check_expression   s;    T\\49LLg >? :r   c                     t        j                  |      D ]-  \  }}t        |t        t        f      s| j                  |       / y r6   )r   iter_fieldsr>   r@   r?   _ASTMatcher__check_stmt_listr%   rC   fieldchilds       r   r{   z_ASTMatcher._check_statements   s:    OOD1 	.LE5%$/&&u-	.r   c                 *   t        t        |            D ]|  }t        |      |z
  t        | j                        k\  s(|||t        | j                        z    }i }| j                  ||      sX| j                  j                  t        ||             ~ y r6   )ranger.   rt   _match_stmtsrB   r   StatementMatch)r%   rh   indexcurrent_stmtsrq   s        r   __check_stmt_listz_ASTMatcher.__check_stmt_list   s~    3u:& 	PE5zE!S%66 %eec$,,6G.G H$$]G<LL''}g(NO	Pr   c                 0   t        |t        j                        r8| j                  j	                  |j
                        r| j                  |||      S t        |t        j                        s||k(  S |j                  |j                  k7  ry| j                  |      }| j                  |      }t        |      t        |      k7  ryt        ||      D ]  \  }}t        |t        j                        r| j                  |||      r4 yt        |t        t        f      rZt        |t        t        f      rt        |      t        |      k7  r yt        ||      D ]  \  }}	| j                  ||	|      r  y t        |      t        |      us||k7  s y yNFT)r>   r   rT   ro   is_varid_match_wildcardAST	__class___get_childrenr.   zipr~   r@   r?   type)
r%   expectedrC   rq   	children1	children2child1child2c1c2s
             r   r~   z_ASTMatcher._match_nodes   sW   h)||""8;;/++HdGDD(CGG,t##/&&x0	&&t,	y>S^+!)Y7 	!NFF&#''*((A FT5M2!&4-8CK3v;<V !&&1 %FB,,RW=$% <tF|3v7G 	! r   c                     t        j                  |      D cg c]!  \  }}t        |t         j                        s|# c}}S c c}}w )z0Return not `ast.expr_context` children of `node`)r   r   r>   expr_contextr   s       r   r   z_ASTMatcher._get_children   sA     !$ 5
ueS%5%56 
 	
 
s   &Ac                     t        |      t        | j                        k7  ryt        || j                        D ]  \  }}| j                  |||      r y yr   )r.   rt   r   r~   )r%   r   rq   stmtr   s        r   r   z_ASTMatcher._match_stmts   sS    }T\\!22!-> 	ND($$XtW=	 r   c                     | j                   j                  |j                        }||vr| j                  ||      r|||<   yy| j	                  ||   |i       S )NTF)ro   get_baser   ru   r~   )r%   node1node2rq   rD   s        r   r   z_ASTMatcher._match_wildcard   sZ    ||$$UXX.w$$UD1 %$$WT]E2>>r   N)r   r   r   r'   r`   rx   r|   r{   r   r~   r   r   r   r   r   r   r_   r_      s6    
+)@
.
P8
?r   r_   c                       e Zd Zd Zd Zd Zy)Matchc                     || _         y r6   )rq   )r%   rq   s     r   r'   zMatch.__init__   s	    r   c                      y)zReturns match regionNr   ry   s    r   r7   zMatch.get_region   s    r   c                 :    | j                   j                  |d      S )z3Return the ast node that has matched rope variablesN)rq   r/   r%   rD   s     r   r   zMatch.get_ast   s    ||d++r   N)r   r   r   r'   r7   r   r   r   r   r   r      s    #,r   r   c                   $     e Zd Z fdZd Z xZS )r   c                 2    t         |   |       || _        y r6   )superr'   r   )r%   r   rq   r   s      r   r'   zExpressionMatch.__init__   s    !r   c                 .    | j                   j                  S r6   )r   r4   ry   s    r   r7   zExpressionMatch.get_region  s    xxr   r   r   r   r'   r7   __classcell__r   s   @r   r   r      s    r   r   c                   $     e Zd Z fdZd Z xZS )r   c                 2    t         |   |       || _        y r6   )r   r'   ast_list)r%   r   rq   r   s      r   r'   zStatementMatch.__init__  s    ! r   c                 r    | j                   d   j                  d   | j                   d   j                  d   fS )Nr   r=   )r   r4   ry   s    r   r7   zStatementMatch.get_region
  s5    }}Q&&q)4==+<+C+CA+FFFr   r   r   s   @r   r   r     s    !Gr   r   c                   8    e Zd Zd Zd Zd Zd ZdZed        Z	y)rk   c                 2    || _         | j                          y r6   )rp   _find_names)r%   rp   s     r   r'   zCodeTemplate.__init__  s     r   c                    i | _         t        j                         j                  | j                        D ]  }d|j                         v s|j                  d      (|j                  d      \  }}| j                  |dz   |dz
   }|| j                   vrg | j                   |<   | j                   |   j                  ||f        y )NrD      r=   )	namesrk   _get_patternfinditerrp   	groupdictgroupspanr   )r%   r9   r+   r,   rD   s        r   r   zCodeTemplate._find_names  s    
!..099$--H 	6E**u{{6/B/N"ZZ/
s}}UQYq9tzz)')DJJt$

4 ''5	6r   c                 6    | j                   j                         S r6   )r   keysry   s    r   rl   zCodeTemplate.get_names  s    zz  r   c                 
   t        j                  | j                        }| j                  j	                         D ](  \  }}|D ]  }|j                  |d   |d   ||            * |j                         }|| j                  S |S )Nr   r=   )r   ChangeCollectorrp   r   items
add_changeget_changed)r%   rq   	collectorrD   occurrencesr4   results          r   rn   zCodeTemplate.substitute   s    //>	!%!1!1!3 	JD+% J$$VAYq	74=IJ	J &&(>== r   Nc                     | j                   Lt        j                         dz   t        j                         z   dz   dz   }t	        j
                  |      | _         | j                   S )N|z(?P<name>\$\{[^\s\$\}]*\}))_match_patternr   get_comment_patternget_string_patternrecompile)clsrt   s     r   r   zCodeTemplate._get_pattern,  sk    %//10023  0	0  "$G!4C!!!r   )
r   r   r   r'   r   rl   rn   r   classmethodr   r   r   r   rk   rk     s/    6! N
" 
"r   rk   c                   B    e Zd ZdZdZdZd Zd Zd Zd Z	d Z
d	 Zd
 Zy)rj   z.Transform and identify rope inserted wildcards__rope__variable_normal___rope__variable_any_c                 h    |j                  d      r| j                  |      S | j                  |      S N?)
startswith_get_any_get_normalr   s     r   rm   z_RopeVariable.get_var@  s.    ??3==&&##D))r   c                 J    | j                  |      xs | j                  |      S r6   )
_is_normal_is_varr   s     r   r   z_RopeVariable.is_varF  s    t$:T(::r   c                     | j                  |      r|t        | j                        d  S | j                  |      rd|t        | j                        d  z   S y r   )r   r.   _normal_prefixr   _any_prefixr   s     r   r   z_RopeVariable.get_baseI  sV    ??4 D//0233<<c$"2"235666 r   c                      | j                   |z   S r6   )r   r   s     r   r   z_RopeVariable._get_normalO  s    ""T))r   c                 &    | j                   |dd  z   S )Nr=   )r   r   s     r   r   z_RopeVariable._get_anyR  s    $qr(**r   c                 8    |j                  | j                        S r6   )r   r   r   s     r   r   z_RopeVariable._is_normalU  s    t2233r   c                 8    |j                  | j                        S r6   )r   r   r   s     r   r   z_RopeVariable._is_varX  s    t//00r   N)r   r   r   rH   r   r   rm   r   r   r   r   r   r   r   r   r   rj   rj   :  s2    8/N)K*;7*+41r   rj   c                     t        |      }t        j                  |       }d }t        | |      }|D ]D  }|j	                  d|z        D ]+  }|j                         \  }}|j                  ||d|z         - F |j                         }	|	|	S | S )Nc                 X    t        | t        j                        xr | j                  |k(  S r6   )r>   r   rT   r   )rC   rD   s     r   rP   z make_pattern.<locals>.does_match`  s     $)=dggo=r   )rP   z${%s})setr   r   r   r1   r7   r   r   )
r2   	variablesr   rP   findervariabler9   r+   r,   r   s
             r   make_patternr   \  s    II++D1I> dz:F A''((:; 	AE))+JE3  Wx-?@	AA ""$F'61T1r   c                    g }t        | t        j                  j                  j                  t        j                  j                  j
                  f      rd| j                          S | j                  9|j                  d| j                                | j                  } | j                  9t        j                  | j                        }dj                  |j                  d      |z         S )Nz__builtins__.r   .)r>   r   basebuiltinsBuiltinClassBuiltinFunctionr$   parentinsertr   modnamer   joinsplit)	pydefinedaddressmodule_names      r   _pydefined_to_strr   l  s    GDII&&33TYY5G5G5W5WX y113455



&q),,./$$	 


& ""9#5#56K88K%%c*W455r   )rH   r   rope.base.builtinsr   rope.refactor.wildcards	rope.baser   r   r   r   rope.refactorr   rope.refactor.patchedastr   RefactoringErrorr
   r   r   r_   r   r   r   rk   rj   r   r   r   r   r   <module>r     s    6 	   < < $ 9	*55 	4: 4:nC, C,La? a?H	, 	,e GU G)" )"X1 1D2 
6r   