
    He\                    
   d Z ddlmZ ddlZddlZddlZddlZddlZddlZddl	Z	ddl
mZ ddlmZ ddlmZmZ ee	j"                     ZddZ G d d	ej(                        Zdd
Z G d d      Z e       j0                  ZddZy)z"Better tokenizing for coverage.py.    )annotationsN)Iterable)env)TLineNoTSourceTokenLinesc           	   #    K   d}d}d}| D ]  \  }}\  }}\  }}	}
||k7  r|r|j                  d      rd}|j                  d      rd}n4|t        j                  k(  r!d|v r|j                  dd	      d
   d   dk(  rd}|rBt	        |j                  d      d         d	z
  }t        j                  dd||f||dz   f|       |
}|t
        j                  t
        j                  fvr|}t        j                  ||||f||	f|
       |} yw)aB  Return all physical tokens, even line continuations.

    tokenize.generate_tokens() doesn't return a token for the backslash that
    continues lines.  This wrapper provides those tokens so that we can
    re-create a faithful representation of the original source.

    Returns the same values as generate_tokens()

    N z\
T\F
   r   i    )	endswithtokenSTRINGsplitlentokenize	TokenInfoNEWLINENL)toks	last_linelast_lineno
last_ttextttypettextslinenoscolelinenoecolltextinject_backslashccols                5/usr/lib/python3/dist-packages/coverage/phystokens.py_phys_tokensr'      s<     !IKJAE '=uow'!Y//7  $( &&t,',$ell*u}T1)=a)@)D)L ,1(#yt4R89A=D",,v $'46):! 
 I))8;;77J  $QVWWO's   DD
c                  f    e Zd ZdZddZej                  dk\  rd	dZej                  dk\  rd
dZyy)SoftKeywordFinderzCHelper for finding lines with soft keywords, like match/case lines.c                j    t               | _        | j                  t        j                  |             y N)setsoft_key_linesvisitastparse)selfsources     r&   __init__zSoftKeywordFinder.__init__R   s!    ,/E

399V$%       
   c                    | j                   j                  |j                         |j                  D ]1  }| j                   j                  |j                  j                         3 | j                  |       yz Invoked by ast.NodeVisitor.visitN)r-   addlinenocasespatterngeneric_visit)r1   nodecases      r&   visit_MatchzSoftKeywordFinder.visit_MatchX   sY    ##DKK0

 =##''(;(;<=t$r4   )r6      c                p    | j                   j                  |j                         | j                  |       yr9   )r-   r:   r;   r>   )r1   r?   s     r&   visit_TypeAliasz!SoftKeywordFinder.visit_TypeAlias`   s(    ##DKK0t$r4   N)r2   strreturnNone)r?   z	ast.MatchrF   rG   )r?   zast.TypeAliasrF   rG   )	__name__
__module____qualname____doc__r3   sysversion_inforA   rD    r4   r&   r)   r)   P   s9    M&
 7"	% 7"	% #r4   r)   c              #  :  K   t         j                  t         j                  t         j                  t        j
                  h}g }d}| j                  d      j                  dd      } t        |       }t        j                  j                  rt        |       j                  }t        |      D ]d  \  }}\  }}	\  }
}}
d}t        j                   d|      D ]3  }|dk(  r| g }d}d}n|dk(  rd}n||v rd}n|r |	|kD  r|j#                  d	d
|	|z
  z  f       d}t        j$                  j'                  |d      j)                         dd }|t         j*                  k(  rt-        j.                  |      rd}nyt0        j2                  dk\  rft        j                  j                  rLt-        j4                  |      r7t7        |      dk(  rd}nt7        |      dk(  r|d   d   d	k(  rd}nd}|r|v rd}|j#                  ||f       d}d}	6 sc|}g |r| yyw)a  Generate a series of lines, one for each line in `source`.

    Each line is a list of pairs, each pair is a token::

        [('key', 'def'), ('ws', ' '), ('nam', 'hello'), ('op', '('), ... ]

    Each pair has a token class, and the token text.

    If you concatenate all the token texts, and then join them with newlines,
    you should have your original `source` back, with two differences:
    trailing white space is not preserved, and a final line with no newline
    is indistinguishable from a final line with a newline.

    r      z
r   Tz(
)Fr
   ws xxNr6   keyr5   r   )r   INDENTDEDENTr   r   r   
expandtabsreplacegenerate_tokensr   
PYBEHAVIORsoft_keywordsr)   r-   r'   rer   appendtok_namegetlowerNAMEkeyword	iskeywordrL   rM   issoftkeywordr   )r2   	ws_tokenslinecoltokgenr-   r   r   sliner    _r"   
mark_startpartmark_end	tok_classis_start_of_lines                    r&   source_token_linesrp   f   s      u||U]]HKKHI"$D
Cq!))&$7FV$F
~~##*62AA5A&5I '1umudYa
HHVU+ #	Dt|
  )# $*KKsdSj'9 :;!&J$--11%>DDFrJ	EJJ&((/$)	))W4 >>77G<Q<QRW<X  #4yA~37 0"%d)q.d1gajD6H37 038 0/E^4K,1	Y-.DG#	H CO'R 
 s   H
HHc                       e Zd ZdZddZddZy)CachedTokenizeraX  A one-element cache around tokenize.generate_tokens.

    When reporting, coverage.py tokenizes files twice, once to find the
    structure of the file, and once to syntax-color it.  Tokenizing is
    expensive, and easily cached.

    This is a one-element cache so that our twice-in-a-row tokenizing doesn't
    actually tokenize twice.

    c                     d | _         g | _        y r+   )	last_textlast_tokens)r1   s    r&   r3   zCachedTokenizer.__init__   s    %)57r4   c                    || j                   k7  rV|| _         t        j                  |      j                  }	 t	        t        j                  |            | _        | j                  S | j                  S #  d| _          xY w)z*A stand-in for `tokenize.generate_tokens`.N)rt   ioStringIOreadlinelistr   rY   ru   )r1   textry   s      r&   rY   zCachedTokenizer.generate_tokens   sp    4>>!!DN{{4(11H#'(@(@(J#K  t!%s   #A2 2
A<N)rF   rG   )r{   rE   rF   
TokenInfos)rH   rI   rJ   rK   r3   rY   rN   r4   r&   rr   rr      s    	8
 r4   rr   c                z    t        | j                  d            j                  }t        j                  |      d   S )zDetermine the encoding for `source`, according to PEP 263.

    `source` is a byte string: the text of the program.

    Returns a string, the name of the encoding.

    Tr   )iter
splitlines__next__r   detect_encoding)r2   ry   s     r&   source_encodingr      s5     F%%d+,55H##H-a00r4   )r   r|   rF   r|   )r2   rE   rF   r   )r2   bytesrF   rE   )rK   
__future__r   r/   rw   rb   r\   rL   r   r   typingr   coverager   coverage.typesr   r   r   r|   r'   NodeVisitorr)   rp   rr   rY   r   rN   r4   r&   <module>r      sy    ) " 
 	  	 
     5 h(()
4n% %,DN   8 "#33	1r4   