
    "eD                        d Z ddlZddlmZ ddlmZ ddlZddlZddlm	Z	  G d de
      Z e
       Z e
       Z e
       ZdZ G d	 d
e
      Z G d de
      Z G d de
      Zi Zd Z G d de      Z G d de      Ze G d de             Ze G d de             Ze G d de             Ze G d de             Ze G d de             Ze G d de             Ze G d  d!e             Ze G d" d#e             Ze G d$ d%e             Ze G d& d'e             Z e G d( d)e             Z!e!Z"d/d*Z#d+ Z$ G d, d-e
      Z%d. Z&y)0z
Decompiler that can be used with the debugger (where statements correctly represent the
line numbers).

Note: this is a work in progress / proof of concept / not ready to be used.
    N)iter_instructions)	pydev_log)StringIOc                       e Zd Zd Zd Zd Zy)_Stackc                     g | _         y N)	_contentsselfs    F/usr/lib/python3/dist-packages/_pydevd_bundle/pydevd_code_to_source.py__init__z_Stack.__init__   s	        c                 :    | j                   j                  |       y r	   )r
   append)r   objs     r   pushz_Stack.push   s    c"r   c                 8    | j                   j                  d      S )N)r
   popr   s    r   r   z
_Stack.pop   s    ~~!!"%%r   N)__name__
__module____qualname__r   r   r    r   r   r   r      s    #&r   r   Fc                   4    e Zd ZdedddfdZd Zd Zd ZeZy)_TokenNr   Fc                 ^   || _         |t        ur|| _        nO|Bt        j                  |j
                        rd| _        n&t        |j
                        | _        nt        d      || _        || _	        || _
        t               | _        t               | _        |r| j                  |       yy)z
        :param i_line:
        :param instruction:
        :param tok:
        :param priority:
        :param after:
        :param end_of_line:
            Marker to signal only after all the other tokens have been written.
        N z,Either the tok or the instruction is needed.)i_line	_SENTINELtokinspectiscodeargvalstrAssertionErrorinstructionpriorityend_of_lineset_after_tokens_after_handler_tokens
mark_after)r   r   r'   r!   r(   afterr)   s          r   r   z_Token.__init__'   s     iDH&>>+"4"45!DH";#5#56DH$%STT& & U%(U"OOE" r   c                     t        |t              r| j                  j                  |       y t        |t              r| j
                  j                  |       y t        d|      )NzUnhandled: )
isinstancer   r+   add_BaseHandlerr,   r&   )r   vs     r   r-   z_Token.mark_afterD   sN    a ""1%<(&&**1- !A!788r   c                     | j                   j                         }| j                  D ]  }|j                  |j                          |S r	   )r+   copyr,   updatetokens)r   rethandlers      r   get_after_tokensz_Token.get_after_tokensM   s@      %%'11 	'GJJw~~&	'
r   c                 D    d| j                   d| j                         dS )NzToken(z	, after: ))r!   r:   r   s    r   __repr__z_Token.__repr__S   s    )-43H3H3JKKr   )	r   r   r   r    r   r-   r:   r=   __str__r   r   r   r   r   %   s+    +/YRVdi #:9L Gr   r   c                   *    e Zd Zd Zd Zd Zd Zd Zy)_Writerc                 0    i | _         t               | _        y r	   )line_to_contentsr*   
all_tokensr   s    r   r   z_Writer.__init__[   s     "%r   c                 b    | j                   j                  |      }|g x}| j                   |<   |S r	   )rB   get)r   linelsts      r   get_linez_Writer.get_line_   s7    ##''-;022C$''-
r   c                 L    | j                  |      j                  t               y r	   )rH   r   INDENT_MARKERr   rF   s     r   indentz_Writer.indente       d""=1r   c                 L    | j                  |      j                  t               y r	   )rH   r   DEDENT_MARKERrK   s     r   dedentz_Writer.dedenth   rM   r   c                     || j                   v ry | j                   j                  |       t        |t              sJ | j	                  |      }|j                  |       y r	   )rC   r1   r0   r   rH   r   )r   rF   tokenrG   s       r   writez_Writer.writek   sM    DOO#E"%(((mmD!

5r   N)r   r   r   r   rH   rL   rP   rS   r   r   r   r@   r@   Y   s     22r   r@   c                   (    e Zd Zd Zd Zd Zd ZeZy)r2   c                 x    || _         || _        || _        || _        || _        g | _        | j                          y r	   )r   r'   stackwriterdisassemblerr7   _handle)r   r   r'   rV   rW   rX   s         r   r   z_BaseHandler.__init__v   s7    &
(r   c                 r    | j                   D ](  }| j                  j                  |j                  |       * y r	   )r7   rW   rS   r   )r   rR   s     r   _write_tokensz_BaseHandler._write_tokens   s-    [[ 	3EKKellE2	3r   c                     t        |       r	   )NotImplementedErrorr   s    r   rY   z_BaseHandler._handle   s    !$''r   c                 r    	 | j                   d| j                  S #  t        j                  |       cY S xY w)Nz line:)r'   r   objectr=   )r   argskwargss      r   r=   z_BaseHandler.__repr__   s2    	)#'#3#3T[[AA	)??4((s    6N)r   r   r   r   r[   rY   r=   r>   r   r   r   r2   r2   t   s    3() Gr   r2   c                 ,    | t         | j                  <   | S r	   )_op_name_to_handleropname)clss    r   	_registerrf      s    &)

#Jr   c                       e Zd Zd Zy)_BasePushHandlerc                 :    | j                   j                  |        y r	   )rV   r   r   s    r   rY   z_BasePushHandler._handle   s    

r   Nr   r   r   rY   r   r   r   rh   rh      s    r   rh   c                       e Zd Zd Zy)_BaseLoadHandlerc                 z    t         j                  |        t        | j                  | j                        g| _        y r	   )rh   rY   r   r   r'   r7   r   s    r   rY   z_BaseLoadHandler._handle   s+      &dkk4+;+;<=r   Nrj   r   r   r   rl   rl      s    >r   rl   c                       e Zd ZdZy)_LoadBuildClassLOAD_BUILD_CLASSNr   r   r   rd   r   r   r   ro   ro      s    Fr   ro   c                       e Zd ZdZy)
_LoadConst
LOAD_CONSTNrq   r   r   r   rs   rs      s    Fr   rs   c                       e Zd ZdZy)	_LoadName	LOAD_NAMENrq   r   r   r   rv   rv          Fr   rv   c                       e Zd ZdZy)_LoadGlobalLOAD_GLOBALNrq   r   r   r   rz   rz      s    Fr   rz   c                       e Zd ZdZy)	_LoadFast	LOAD_FASTNrq   r   r   r   r}   r}      rx   r   r}   c                       e Zd ZdZdZdZd Zy)_GetIterz%
    Implements TOS = iter(TOS).
    GET_ITERNc                     | j                   j                         | _        | j                  j	                  | j                  j                         | j                   j                  |        y r	   )rV   r   iter_targetr7   extendr   r   s    r   rY   z_GetIter._handle   sC    ::>>+4++223

r   )r   r   r   __doc__rd   r   rY   r   r   r   r   r      s     FKr   r   c                   $    e Zd ZdZdZdZd Zd Zy)_ForIterz
    TOS is an iterator. Call its __next__() method. If this yields a new value, push it on the stack
    (leaving the iterator below it). If the iterator indicates it is exhausted TOS is popped, and
    the byte code counter is incremented by delta.
    FOR_ITERNc                 x    | j                   j                         | _        | j                   j                  |        y r	   )rV   r   iter_inr   r   s    r   rY   z_ForIter._handle   s$    zz~~'

r   c                    t        | j                  d d      }| j                  j                  |       |}t        |j                  |j                  |      }| j                  j                  |       |}t        |j                  d d|      }| j                  j                  |       |}|j                  }| j
                  rs| j
                  j                  D ]+  }|j                  |       t        ||j                        }|}- | j                  j                  | j
                  j                         t        | j                  d d|      }| j                  j                  |       |}| j                          y )Nzfor r.   z in :)
r   r   r7   r   r'   r   r-   maxr   r[   )	r   
store_name	for_tokenprevt_namein_tokenmax_linetcolon_tokens	            r   store_in_namez_ForIter.store_in_name   s*   4;;f5	9%
)):+A+AN6"*++T6F8$$$<<\\(( T"x2 KKt||223T[[$4@;'r   )r   r   r   r   rd   r   rY   r   r   r   r   r   r      s    
 FGr   r   c                       e Zd ZdZdZd Zy)
_StoreNamez
    Implements name = TOS. namei is the index of name in the attribute co_names of the code object.
    The compiler tries to use STORE_FAST or STORE_GLOBAL if possible.
    
STORE_NAMEc                    | j                   j                         }t        |t              r|j	                  |        y t        |t
              r|j                  r| j                  }|j                  D ]  }t        ||j                        } t        || j                        }t        |d d|      }| j                  j                  |       | j                  j                  |       |j                  D ]  }|j                  |        | j                  j                  |j                         | j                          y y )N=r   )rV   r   r0   r   r   _MakeFunction	is_lambdar   r7   minr   r'   r   r-   r   r[   )r   r3   rF   r   r   t_equals         r   rY   z_StoreName._handle   s    JJNNa"OOD!a/1;;{{ /AtQXX.D/  d&6&67 tS?""6*""7+ *ALL)*""188,""$ 4?r   Nr   r   r   r   rd   rY   r   r   r   r   r      s    
 F%r   r   c                       e Zd ZdZdZd Zy)_ReturnValuez9
    Returns with TOS to the caller of the function.
    RETURN_VALUEc                 N   | j                   j                         }t        | j                  d dd      }| j                  j                  |       |j                  D ]  }|j                  |        | j                  j                  |j                         | j                          y )Nzreturn T)r)   )	rV   r   r   r   r7   r   r-   r   r[   )r   r3   return_tokenrR   s       r   rY   z_ReturnValue._handle  s{    JJNNdkk4M<(XX 	+E\*	+188$r   Nr   r   r   r   r   r     s     Fr   r   c                       e Zd ZdZdZd Zy)_CallFunctionaM  

    CALL_FUNCTION(argc)

        Calls a callable object with positional arguments. argc indicates the number of positional
        arguments. The top of the stack contains positional arguments, with the right-most argument
        on top. Below the arguments is a callable object to call. CALL_FUNCTION pops all arguments
        and the callable object off the stack, calls the callable object with those arguments, and
        pushes the return value returned by the callable object.

        Changed in version 3.6: This opcode is used only for calls with positional arguments.

    CALL_FUNCTIONc                    g }t        | j                  j                  dz         D ]-  }| j                  j	                         }|j                  |       / t        |      }t        |      }|j                  }|j                  D ]  }| j                  j                  |        t        |j                  d d|      }| j                  j                  |       |}	t        |      D ]  \  }
}|j                  D ]U  }|j                  |       |j                  |	       t        ||j                        }| j                  j                  |       W |}	|
dkD  srt        |	j                  d d|	      }| j                  j                  |       |}	 t        |d d|	      }| j                  j                  |       | j                          | j                  j                  |        y )N   (r   r   ,r<   )ranger'   r$   rV   r   r   reversednextr   r7   r   	enumerater-   r   r[   r   )r   r`   _iargitnamer   r   tok_open_parensr   icomma_tokentok_close_parenss                r   rY   z_CallFunction._handle<  s   ((//!34 	B**.."CKK	 d^Bx;; 	"AKKq!	" !dCtD?+m 	#FAsZZ &T"T"x2""1%	&
 D1u$T[[$4H"";/"	# "(D#TB+,

r   Nr   r   r   r   r   r   *  s     F!r   r   c                       e Zd ZdZdZdZd Zy)_MakeFunctionPy3aA  
    Pushes a new function object on the stack. From bottom to top, the consumed stack must consist
    of values if the argument carries a specified flag value

        0x01 a tuple of default values for positional-only and positional-or-keyword parameters in positional order

        0x02 a dictionary of keyword-only parameters' default values

        0x04 an annotation dictionary

        0x08 a tuple containing cells for free variables, making a closure

        the code associated with the function (at TOS1)

        the qualified name of the function (at TOS)
    MAKE_FUNCTIONFc                 v   | j                   }|j                         | _        |j                         | _        d }| j                  j
                  dz  r|j                         }d| j                  j                  D cg c]  }|j                   c}v x}| _        |s2t        | j                  d d      }| j                  j                  |       | j                  j                  D ]1  }| j                  j                  |       |r!|j                         3 }t        | j                  d d|      }| j                  j                  |       |}| j                  j                  j
                  }	|r^t        gt        |	j                        t        |j                  j
                        z
  z  t!        |j                  j
                        z   }
nt        gt        |	j                        z  }
t#        |	j                        D ]  \  }}|dkD  r6t        |j                  d d|      }| j                  j                  |       |}t        | j                  d ||      }| j                  j                  |       |
|   }|t        ust        |j                  d d|      }| j                  j                  |       |}t        |j                  d t%        |      |      }| j                  j                  |       |} t        |j                  d d	|      }| j                  j                  |       | j'                          |j)                  |        | j*                  j-                  |j                  dz          | j*                  j/                  t1        | j2                  j5                  |	                   y c c}w )
Nr   z<lambda>zdef r   r   r   z, r   z):)rV   r   qualified_namecoder'   r$   r7   r!   r   r   r   r   r-   r    lenco_varnameslistr   r%   r[   r   rW   rL   rP   r   rX   
merge_code)r   rV   default_nodexr   	def_tokenrR   r   open_parens_tokenr   defaultsr   r   r   	arg_tokendefaulteq_tokendefault_tokenr   s                      r   rY   z_MakeFunctionPy3._handlev  s   

#iikIIK	""T) 99;L%/4CVCVC]C]3^aAEE3^%^^	DNt{{D&9IKKy)((// 	,EKKu%  +	, "4;;cF,- yy$$++"s4+;+;'<s<C[C[CbCb?c'cdhlmy  nF  nF  nM  nM  iN  NH!{S)9)9%::H 0 01 	%FAs1u$T[[$DI"";/"t{{D#TBIKKy)qkGi'!,"5"5tSM""8, &|':':D#g,VZ [""=1$#	%& "$++tTF+,

44;;?+3t00;;DABCc 4_s   ;N6N)r   r   r   r   rd   r   rY   r   r   r   r   r   `  s    " FI:Dr   r   c           	      V   |t         j                  }| D ]  }|j                         }|rWt        |j                        dddj                  d |j                         D              z   dz   d}|j                  |       l|j                  dt        |j                        z          y )Nz after: "z", "c              3   4   K   | ]  }|j                     y wr	   )r!   ).0r   s     r   	<genexpr>z$_print_after_info.<locals>.<genexpr>  s     "KQ155"Ks   
z%s      (NO REQUISITES))sysstdoutr:   reprr!   joinrS   )line_contentsstreamrR   after_tokensss        r   _print_after_infor     s    ~ F--/UYYv{{"K%2H2H2J"KKKcQTA LLOLL2T%))_DEFr   c                 0   g }t               }g }g }t        |       D ]4  \  }}|j                  s|j                  |       |j                  |       6 t	        |      D ]  }| |=  ~| rd}g }t        |       D ]w  \  }}|j                         }	|	D ]  }
|
|vs|
|vs ' d}|j                  |       |j                  |       |j                  |j                         |j                  |       y t	        |      D ]  }| |=  |s{|r| j                  |       |d d = | D ]"  }||vs|j                  |j                         $ t               }t        | |       t        j                  d|j                                n| rdj                  |      S )NFTz(Error. After markers are not correct:
%sr   )r*   r   r)   r   r   r:   r1   r!   r   r   r   r   criticalgetvaluer   )r   previous_line_tokensrG   handledadd_to_end_of_linedelete_indexesr   rR   addedr   r.   r   s               r   _compose_line_contentsr     s   
CeGNm, %5%%e,!!!$% n% !
!-0 
	)HAu 113L% )'E9M,M) $((/E"

599%%%a(
	) .) 	!Aa 	! !$$%78&q) ' *'JJuyy)* ZFmV4JFOOL]^C D 773<r   c                   ,    e Zd ZddZd Zd Zd Zd Zy)_PyCodeToSourceNc                     |i }|| _         || _        t        t        |            | _        t               | _        t               | _        y r	   )	memocor   r   instructionsr   rV   r@   rW   )r   r   r   s      r   r   z_PyCodeToSource.__init__  s?    <D	 !22!67X
ir   c                    | j                   j                  d      }t        j                  |j                        }|3 |||| j
                  | j                  |       }t        rt        |       y y t        rt        d|       y y )Nr   	UNHANDLED)	r   r   rc   rE   rd   rV   rW   DEBUGprint)r   r   r'   handler_classr   s        r   _process_nextz_PyCodeToSource._process_next  sq    ''++A.+//0B0BC$fk4::t{{DQAa  k;/ r   c                    | j                   }t        t        j                  |            }d}| j                  }|r:|d   }|j                  |j                        }|||}| j                  |       |r:| j                  j                  S )Nr   )
r   dictdisfindlinestartsr   rE   offsetr   rW   rB   )r   r   op_offset_to_linecurr_line_indexr   r'   new_line_indexs          r   build_line_to_contentsz&_PyCodeToSource.build_line_to_contents  s    WW !3!3B!78((&q/K.22;3E3EFN)!-&4O/  {{+++r   c                 N   t         rt        d       t        || j                        j	                         }g }t        |j                               D ]@  \  }}|j                  |       | j                  j                  |      j                  |       B t         rt        d       |S )Nzmerge code ----zend merge code ----)r   r   r   r   r   sorteditemsr   rW   rH   r   )r   r   rB   linesrF   contentss         r   r   z_PyCodeToSource.merge_code  s    #$ +4;RRT$%5%;%;%=> 	8ND(LLKK  &--h7	8 '(r   c                    d}| j                         }t               }d}d}t               }t        |j	                               D ]  \  }}||dz
  k  r9|r|j                  |dz   d       n|j                  d       |dz  }||dz
  k  r9g }	d}
|D ]S  }|t        u rt        rt        d|       |dz  }#|t        u rt        rt        d	|       |
dz  }
C|	j                  |       U |t        |	|      z   }|r|j                  |d
|d       n|j                  d|z         |
r	|d d|
z    }|} |j                         S )NFr   r   r   z.
r   zfound indentz    zfound dedentz. z%s
   )r   r   r*   r   r   rS   rJ   r   r   rO   r   r   r   )r   
show_linesrB   r   	last_linerL   r   r   r   r   dedents_foundpartr   s                r   disassemblez_PyCodeToSource.disassemble.  sj   
668	"u &'7'='='? @ 	FHfqj(LLY]!<=LL'Q	 fqj( MM  +=(nf5f$F=(nf5!Q&M$$T*+ /?STTAFA67Wq[) 51}#4!56I?	B   r   r	   )r   r   r   r   r   r   r   r  r   r   r   r   r     s     
0,"(!r   r   c                 Z    t        |       j                         }t        rt        |       |S )z
    Converts a code object to source code to provide a suitable representation for the compiler when
    the actual source code is not found.

    This is a work in progress / proof of concept / not ready to be used.
    )r   r  r   r   )r   r8   s     r   code_obj_to_sourcer  Y  s&     "

)
)
+Cc
Jr   r	   )'r   r   +_pydevd_bundle.pydevd_collect_bytecode_infor   _pydev_bundler   r   r"   ior   r_   r   rJ   rO   r    r   r   r@   r2   rc   rf   rh   rl   ro   rs   rv   rz   r}   r   r   r   r   r   r   r   r   r   r   r  r   r   r   <module>r     s    I # 
  
&V 
& H	1V 1hf 66 6  
| >' >  &     !       "       
| 
 
 '| ' 'T % % %@ <  $ 2L 2 2j OD| OD ODd !F0f_!f _!D
r   