ó
ÔŒ\c        {   @` sù  d  d l  m Z d  d l  m Z d  d l  m Z d  d l  m Z d  d l Z d  d l m Z d  d l Z d  d l	 Z	 d  d l
 m Z m Z d d	 d
 h Z d d d d d d d d d d d d d d d d d d d d d d  d! d" d# d$ d% d& d' d( d) d* d+ d, d- d. d/ d0 d1 d2 d3 d4 d5 d6 d7 d8 d9 d: d; d< d= d> d? d@ dA dB dC dD dE dF dG dH dI dJ dK dL dM dN dO dP dQ dR dS dT dU dV dW dX dY dZ d[ d\ d] d^ d_ d` da db dc dd de df dg dh di dj dk dl dm dn do dp dq dr ds dt du dv dw dx dy dz d{ d| d} d~ d d€ d d‚ dƒ d„ d… h{ Z d† d‡ h e Be BZ e ƒ  Z e ƒ  Z dˆ „  Z d‰ „  Z dŠ „  Z d‹ e f dŒ „  ƒ  YZ d Z dŽ Z d  Z d e f d „  ƒ  YZ d‘ e f d’ „  ƒ  YZ d“ e j f d” „  ƒ  YZ d• e f d– „  ƒ  YZ e ƒ  Z  d— Z! d˜ „  Z" d™ „  Z# d S(š   i    (   t   print_function(   t   unicode_literals(   t   division(   t   absolute_importN(   t
   py_compile(   t   loadst   dumpsu   Trueu   Falseu   Noneu   absu   allu   anyu   applyu   binu   boolu   bytesu   callableu   chru   cmpu   dictu   divmodu   filteru   floatu	   frozensetu   getattru   globalsu   hasattru   hashu   hexu   intu
   isinstanceu   lenu   listu   longu   mapu   maxu   minu   octu   ordu   powu   rangeu   reduceu   repru   roundu   setu   sortedu   stru   sumu   tupleu   unichru   unicodeu   varsu   zipu   _u   _pu   absoluteu   ImageReferenceu   Imageu   Frameu   Solidu   LiveCompositeu   LiveCropu   LiveTileu   Flattenu   Nullu   Windowu   Viewportu   DynamicDisplayableu   ConditionSwitchu   ShowingSwitchu	   Transformu	   Animationu   Movieu	   Particlesu   SnowBlossomu   Textu   ParameterizedTextu	   FontGroupu   Dragu   Alphau	   AlphaMasku   Positionu   Panu   Moveu   Motionu   Revolveu   Zoomu   RotoZoomu
   FactorZoomu   SizeZoomu   Fadeu   Dissolveu   ImageDissolveu   AlphaDissolveu   CropMoveu   PushMoveu	   Pixellateu   OldMoveTransitionu   MoveTransitionu   MoveFactoryu   MoveInu   MoveOutu	   ZoomInOutu   RevolveInOutu   MultipleTransitionu   ComposeTransitionu   Pauseu   SubTransitionu
   ADVSpeakeru   ADVCharacteru   Speakeru	   Characteru   DynamicCharacteru   Fixedu   HBoxu   VBoxu   Gridu
   AlphaBlendu   Atu   coloru   Coloru
   ui.returnsu   ui.jumpsu   ui.jumpsoutofcontextu   ui.callsinnewcontextu   ui.invokesinnewcontextu   ui.gamemenusu   renpy.version_stringu   renpy.version_onlyu   renpy.version_tupleu   renpy.version_nameu   renpy.licenseu   configu   stylec         C` s    |  t  k r t j |  ƒ n  d S(   ut  
    :doc: const

    Declares a variable in the store to be constant.

    A variable is constant if nothing can change its value, or any value
    reached by indexing it or accessing its attributes. Variables must
    remain constant out of define, init, and translate python blocks.

    `name`
        A string giving the name of the variable to declare constant.
    N(   t   not_constantst	   constantst   add(   t   name(    (    s   renpy/pyanalysis.pyt   constb   s    c         C` s+   t  j |  ƒ t j |  ƒ t j |  ƒ d S(   uÙ   
    :doc: const

    Declares a name in the store to be not constant.

    This undoes the effect of calls to :func:`renpy.const` and
    :func:`renpy.pure`.

    `name`
        The name to declare not constant.
    N(   R   t   discardt   pure_functionsR   R	   (   R
   (    (    s   renpy/pyanalysis.pyt	   not_constt   s    c         C` sN   |  } t  | t ƒ s! |  j } n  | t k rJ t j | ƒ t j | ƒ n  |  S(   u´  
    :doc: const

    Declares a function as pure. A pure function must always return the
    same value when it is called with the same arguments, outside of
    define, init, and translate python blocks.

    `fn`
        The name of the function to declare pure. This may either be a string
        containing the name of the function, or the function itself.

    Returns `fn`, allowing this function to be used as a decorator.
    (   t
   isinstancet
   basestringt   __name__R   R   R	   R   (   t   fnR
   (    (    s   renpy/pyanalysis.pyt   pure†   s    t   Controlc           B` s   e  Z d  Z d „  Z RS(   uã   
    Represents control flow.

    `const`
        True if this statement always executes.

    `loop`
        True if this corresponds to a loop.

    `imagemap`
        True if this control is in a non-constant imagemap.
    c         C` s   | |  _  | |  _ | |  _ d  S(   N(   R   t   loopt   imagemap(   t   selfR   R   R   (    (    s   renpy/pyanalysis.pyt   __init__¯   s    		(   R   t
   __module__t   __doc__R   (    (    (    s   renpy/pyanalysis.pyR   ¡   s   i   i   t   DeltaSetc           B` sA   e  Z d d  „ Z d „  Z d „  Z d „  Z d „  Z d „  Z RS(   c         C` sa   | |  _  | d k	 r< t | j ƒ |  _ t | j ƒ |  _ n t ƒ  |  _ t ƒ  |  _ t |  _ d S(   uc   
        Represents a set that stores its contents as differences from a base
        set.
        N(   t   baset   Nonet   sett   addedt   removedt   Falset   changed(   R   R   t   copy(    (    s   renpy/pyanalysis.pyR   ½   s    	c         C` si   | |  j  k r+ |  j  j | ƒ t |  _ n: | |  j k re | |  j k re |  j j | ƒ t |  _ n  d  S(   N(   R    R   t   TrueR"   R   R   R	   (   R   t   v(    (    s   renpy/pyanalysis.pyR	   Î   s    c         C` si   | |  j  k r+ |  j  j | ƒ t |  _ n: | |  j k re | |  j k re |  j j | ƒ t |  _ n  d  S(   N(   R   R   R$   R"   R   R    R	   (   R   R%   (    (    s   renpy/pyanalysis.pyR   ×   s    c         C` s+   | |  j  k p* | |  j k o* | |  j k S(   N(   R   R   R    (   R   R%   (    (    s   renpy/pyanalysis.pyt   __contains__à   s    c         C` s   t  |  j |  ƒ S(   N(   R   R   (   R   (    (    s   renpy/pyanalysis.pyR#   ã   s    c         c` sH   x( |  j  D] } | |  j k r
 | Vq
 q
 Wx |  j D] } | Vq5 Wd  S(   N(   R   R    R   (   R   t   i(    (    s   renpy/pyanalysis.pyt   __iter__æ   s
    N(	   R   R   R   R   R	   R   R&   R#   R(   (    (    (    s   renpy/pyanalysis.pyR   »   s   						t   Analysisc           B` s   e  Z d  Z d d „ Z d „  Z e e e d „ Z d „  Z	 d „  Z
 d „  Z d „  Z d „  Z d	 „  Z d
 „  Z d „  Z d „  Z d „  Z RS(   ub   
    Represents the result of code analysis, and provides tools to perform
    code analysis.
    c         C` sv   | |  _  i  |  _ t t ƒ |  _ t t ƒ |  _ t t ƒ |  _ t t	 ƒ |  _	 t
 t t t ƒ |  _ |  j g |  _ d  S(   N(   t   parentt   childrenR   R   t   not_constantt   local_constantst   local_constantt   always_constantst   global_constantR   R   R$   R!   t   controlt   control_stack(   R   R*   (    (    s   renpy/pyanalysis.pyR   ö   s    		c         C` s7   | |  j  k r |  j  | St |  ƒ } | |  j  | <| S(   N(   R+   R)   (   R   t
   identifiert   rv(    (    s   renpy/pyanalysis.pyt	   get_child  s
    c         C` sA   t  |  j j o | | |  j p! | ƒ |  _ |  j j |  j ƒ d  S(   N(   R   R1   R   R   R2   t   append(   R   R   R   R   (    (    s   renpy/pyanalysis.pyt   push_control  s    *c         C` s#   |  j  j ƒ  } |  j  d |  _ | S(   Niÿÿÿÿ(   R2   t   popR1   (   R   R4   (    (    s   renpy/pyanalysis.pyt   pop_control  s    c         C` s   |  j  j r t St Sd S(   uH   
        Returns NOT_CONST if we're in a non-constant imagemap.
        N(   R1   R   t	   NOT_CONSTt   GLOBAL_CONST(   R   (    (    s   renpy/pyanalysis.pyR   #  s    c         C` sD   t  |  j ƒ } | j ƒ  x$ | D] } t | _ | j r  Pq  q  Wd S(   uu   
        Call this to indicate the current loop is being exited by the
        continue or break statements.
        N(   t   listR2   t   reverseR!   R   R   (   R   t   lR'   (    (    s   renpy/pyanalysis.pyt	   exit_loop-  s    
		c         C` s’   x' |  j  j ƒ  D] } | j ƒ  s t Sq W|  j j sZ |  j j sZ |  j j sZ |  j j rŽ t |  j _ t |  j _ t |  j _ t |  j _ t St	 S(   u–   
        Returns True if we've reached a fixed point, where the analysis has
        not changed since the last time we called this function.
        (
   R+   t   valuest   at_fixed_pointR!   R,   R"   R0   R.   R   R$   (   R   R'   (    (    s   renpy/pyanalysis.pyRA   <  s    c         C` sF   | |  j  k rB |  j j | ƒ |  j j | ƒ |  j j | ƒ n  d S(   u=   
        Marks `name` as a potential local constant.
        N(   R,   R.   R	   R0   R   R   (   R   R
   (    (    s   renpy/pyanalysis.pyt   mark_constantT  s    c         C` sD   |  j  j | ƒ |  j j | ƒ |  j j | ƒ |  j j | ƒ d S(   u:   
        Marks `name` as definitely not-constant.
        N(   R,   R	   R   R   R.   R0   (   R   R
   (    (    s   renpy/pyanalysis.pyt   mark_not_constant^  s    c         ` sX   ‡ f d †  ‰ ‡  ‡ ‡ f d †  ‰  ‡ f d †  ‰ ‡  ‡ ‡ ‡ ‡ f d †  ‰ ˆ | ƒ S(   uà   
        Returns true if `node` is constant for the purpose of screen
        language. Node should be a python AST node.

        Screen language ignores object identity for the purposes of
        object equality.
        c         ` s¸   t  |  t j ƒ r ˆ  |  j ƒ St  |  t j ƒ r´ g  } |  j rY | j ˆ  |  j ƒ ƒ n  |  j r{ | j ˆ  |  j ƒ ƒ n  |  j r | j ˆ  |  j ƒ ƒ n  | s§ t	 St
 | ƒ Sn  t S(   N(   R   t   astt   Indext   valuet   Slicet   lowerR6   t   uppert   stepR;   t   minR:   (   t   slicet   consts(   t
   check_node(    s   renpy/pyanalysis.pyt   check_slicer  s    			c         ` s×   t  |  t j ƒ r$ t } |  j } nZ t  |  t j ƒ rn ˆ  |  j ƒ \ } } | d k	 r~ | d |  j } q~ n ˆ |  ƒ d f S| ˆ j	 k r— t | f S| ˆ j
 k r° t | f S| ˆ j k rÉ t | f S| | f Sd S(   u5  
            Check nodes that make up a name. This returns a pair:

            * The first element is True if the node is constant, and False
              otherwise.
            * The second element is None if the node is constant or the name is
              not known, and the name otherwise.
            u   .N(   R   RD   t   NameR:   t   idt	   AttributeRF   R   t   attrR,   R0   R;   R.   t   LOCAL_CONST(   t   nodeR   R
   (   t
   check_nameRN   R   (    s   renpy/pyanalysis.pyRV   ˆ  s    



c         ` s0   t  |  ƒ }  |  s t St ‡  f d †  |  Dƒ ƒ S(   u?   
            Checks a list of nodes for constness.
            c         3` s   |  ] } ˆ  | ƒ Vq d  S(   N(    (   t   .0R'   (   RN   (    s   renpy/pyanalysis.pys	   <genexpr>²  s    (   R<   R;   RK   (   t   nodes(   RN   (    s   renpy/pyanalysis.pyt   check_nodes¨  s    c         ` sÝ  |  d k r t St |  t j t j f ƒ r/ t St |  t j t j f ƒ rW ˆ |  j ƒ St |  t j	 t j
 f ƒ r€ ˆ  |  ƒ d St |  t j ƒ rŸ ˆ |  j ƒ St |  t j ƒ rÐ t ˆ |  j ƒ ˆ |  j ƒ ƒ St |  t j ƒ rï ˆ |  j ƒ St |  t j ƒ rËˆ  |  j ƒ \ } } | t k s1| ˆ j k r5t Sg  } | j ˆ |  j ƒ ƒ | j ˆ d „  |  j Dƒ ƒ ƒ |  j d k	 r™| j ˆ |  j ƒ ƒ n  |  j d k	 rÁ| j ˆ |  j ƒ ƒ n  t | ƒ St |  t j ƒ rt ˆ |  j ƒ ˆ |  j ƒ ˆ |  j ƒ ƒ St |  t j  ƒ r9t ˆ |  j! ƒ ˆ |  j ƒ ƒ St |  t j" ƒ rXˆ |  j ƒ St |  t j# ƒ r‰t ˆ |  j ƒ ˆ |  j$ ƒ ƒ St |  t j% ƒ r¨ˆ |  j& ƒ St |  t j' ƒ rÙt ˆ |  j& ƒ ˆ |  j( ƒ ƒ St S(   uJ   
            Returns true if the ast node `node` is constant.
            i    c         s` s   |  ] } | j  Vq d  S(   N(   RF   (   RW   R'   (    (    s   renpy/pyanalysis.pys	   <genexpr>ß  s    N()   R   R;   R   RD   t   Numt   Strt   Listt   Tuplet   eltsRR   RP   t   BoolOpR@   t   BinOpRK   t   leftt   rightt   UnaryOpt   operandt   Callt   funcR   R:   R6   t   argst   keywordst   starargst   kwargst   IfExpt   testt   bodyt   orelset   Dictt   keyst   Sett   Comparet   comparatorst   ReprRF   t	   SubscriptRL   (   RU   R   R
   RM   (   RV   RN   RY   RO   R   (    s   renpy/pyanalysis.pyRN   ´  sd     
(    (   R   RU   (    (   RV   RN   RY   RO   R   s   renpy/pyanalysis.pyt   is_constanti  s
    	 Vc         C` s0   t  j | ƒ \ } } | r t S|  j | ƒ Sd S(   u|   
        Compiles `expr` into an AST node, then returns the result of
        self.is_constant called on that node.
        N(   t   ccachet   ast_eval_literalR;   Rv   (   R   t   exprRU   t   literal(    (    s   renpy/pyanalysis.pyt   is_constant_expr  s    c         C` s=   t  j | ƒ } t |  ƒ } x | D] } | j | ƒ q" Wd S(   u>   
        Performs analysis on a block of python code.
        N(   Rw   t   ast_exect
   PyAnalysist   visit(   R   t   codeRX   t   aR'   (    (    s   renpy/pyanalysis.pyt   python  s    c         C` s~   t  t ƒ |  _ x$ | j D] \ } } |  j | ƒ q W| j d k	 rX |  j | j ƒ n  | j d k	 rz |  j | j ƒ n  d S(   u8   
        Analyzes the parameters to the screen.
        N(   R   R   R0   t
   parametersRC   t   extraposR   t   extrakw(   R   R‚   R
   t   _default(    (    s   renpy/pyanalysis.pyR‚   %  s    N(   R   R   R   R   R   R5   R$   R!   R7   R9   R   R?   RA   RB   RC   Rv   R{   R   R‚   (    (    (    s   renpy/pyanalysis.pyR)   ð   s   				
			
		£		R}   c           B` s_   e  Z d  Z d „  Z d „  Z d „  Z d „  Z d „  Z d „  Z d „  Z	 d „  Z
 d	 „  Z RS(
   u‚   
    This analyzes Python code to determine which variables should be
    marked const, and which should be marked non-const.
    c         C` s   | |  _  d  S(   N(   t   analysis(   R   R†   (    (    s   renpy/pyanalysis.pyR   >  s    c         C` s|   t  | t j ƒ r( |  j j | j ƒ nP t  | j t j ƒ rx |  j j j	 rb |  j j
 | j ƒ qx |  j j | j ƒ n  d  S(   N(   R   RD   t   AugStoreR†   RC   RQ   t   ctxt   StoreR1   R   RB   (   R   RU   (    (    s   renpy/pyanalysis.pyt
   visit_NameB  s    c         C` sF   |  j  j | j ƒ } |  j  j | t ƒ |  j | ƒ |  j  j ƒ  d  S(   N(   R†   Rv   RF   R7   R!   t   generic_visitR9   (   R   RU   R   (    (    s   renpy/pyanalysis.pyt   visit_AssignM  s    c         C` s1   |  j  j t t ƒ |  j | ƒ |  j  j ƒ  d  S(   N(   R†   R7   R!   R‹   R9   (   R   RU   (    (    s   renpy/pyanalysis.pyt   visit_AugAssignV  s    c         C` s€   |  j  j | j ƒ } |  j  j d | d t ƒ |  j  j j } |  j | ƒ |  j  j j | k ro |  j | ƒ n  |  j  j ƒ  d  S(   NR   R   (	   R†   Rv   t   iterR7   R$   R1   R   R‹   R9   (   R   RU   R   t	   old_const(    (    s   renpy/pyanalysis.pyt	   visit_For^  s    c         C` s€   |  j  j | j ƒ } |  j  j d | d t ƒ |  j  j j } |  j | ƒ |  j  j j | k ro |  j | ƒ n  |  j  j ƒ  d  S(   NR   R   (	   R†   Rv   Rl   R7   R$   R1   R   R‹   R9   (   R   RU   R   R   (    (    s   renpy/pyanalysis.pyt   visit_Whilel  s    c         C` sF   |  j  j | j ƒ } |  j  j | t ƒ |  j | ƒ |  j  j ƒ  d  S(   N(   R†   Rv   Rl   R7   R!   R‹   R9   (   R   RU   R   (    (    s   renpy/pyanalysis.pyt   visit_Ifz  s    c         C` s   |  j  j ƒ  d  S(   N(   R†   R?   (   R   RU   (    (    s   renpy/pyanalysis.pyt   visit_Break…  s    c         C` s   |  j  j ƒ  d  S(   N(   R†   R?   (   R   RU   (    (    s   renpy/pyanalysis.pyt   visit_Continueˆ  s    (   R   R   R   R   RŠ   RŒ   R   R   R‘   R’   R“   R”   (    (    (    s   renpy/pyanalysis.pyR}   8  s   									t   CompilerCachec           B` s2   e  Z d  Z d „  Z d „  Z d „  Z d „  Z RS(   uR   
    Objects of this class are used to cache the compiliation of Python code.
    c         C` s(   i  |  _  i  |  _ t |  _ d |  _ d  S(   Ni   (   t   ast_eval_cachet   ast_exec_cacheR!   t   updatedt   version(   R   (    (    s   renpy/pyanalysis.pyR   ‘  s    			c         C` sË   t  | t j j ƒ r* | j } | j } n d } d } | | | f } |  j j | d ƒ } | d k rÇ t	 | d d t
 ƒ} y t j | ƒ t
 } Wn t } n X| | f } | |  j | <t
 |  _ n  | S(   u5   
        Compiles an expression into an AST.
        u   evalt   ast_nodeN(   R   t   renpyRD   t   PyExprt   filenamet
   linenumberR   R–   t   getR   R$   t   literal_evalR!   R˜   (   R   Ry   R   Rž   t   keyR4   Rz   (    (    s   renpy/pyanalysis.pyRx   ›  s$    	

c         C` s   |  j  | ƒ d S(   Ni    (   Rx   (   R   Ry   (    (    s   renpy/pyanalysis.pyt   ast_eval»  s    c         C` s   t  | t j j ƒ r- | | j | j f } n | d d f } |  j j | d ƒ } | d k r‹ t	 | d d t
 ƒ} | |  j | <t
 |  _ n  | S(   u/   
        Compiles a block into an AST.
        u   execRš   N(   R   R›   RD   Rœ   R   Rž   R   R—   RŸ   R   R$   R˜   (   R   R   R¡   R4   (    (    s   renpy/pyanalysis.pyR|   ¾  s    (   R   R   R   R   Rx   R¢   R|   (    (    (    s   renpy/pyanalysis.pyR•   Œ  s
   	
	 	u   cache/pyanalysis.rpybc          C` s—   t  j j j r d  Syv t  j j t ƒ }  t t j	 |  j
 ƒ  ƒ ƒ } |  j ƒ  | j t j k rˆ t j j | j ƒ t j j | j ƒ n  Wn n Xd  S(   N(   R›   t   gameRg   t   compilet   loadert   loadt   CACHE_FILENAMER   t   zlibt
   decompresst   readt   closeR™   Rw   R–   t   updateR—   (   t   ft   c(    (    s   renpy/pyanalysis.pyt
   load_cache×  s    
c          C` sx   t  j s d  St j r d  SyP t j t t  d ƒ d ƒ }  t t j j	 t
 ƒ d ƒ  } | j |  ƒ Wd  QXWn n Xd  S(   Ni   i	   u   wb(   Rw   R˜   R›   t   macappR¨   t   compressR   t   openR¥   t   get_pathR§   t   write(   t   dataR­   (    (    s   renpy/pyanalysis.pyt
   save_cacheç  s    		($   t
   __future__R    R   R   R   R›   t   renpy.pythonR   RD   R¨   t   cPickleR   R   R/   R   R   R   R   R-   R   R   R   t   objectR   R;   RT   R:   R   R)   t   NodeVisitorR}   R•   Rw   R§   R¯   R¶   (    (    (    s   renpy/pyanalysis.pyt   <module>   sz   								5ÿ ITF		