3
B^j                 @   s  d Z ddlmZ ddlmZ ddlmZ ddlm	Z	 ddl
mZ ddlmZ ddlmZ dd	lmZ dd
lmZ ddlmZmZmZ ddlmZmZmZmZmZmZmZ ddl m!Z!m"Z"m#Z#m$Z$m%Z% dddddddddZ&e'e(drdZ)ndZ)dgZ*ye+d e*j,d W n e-k
r    Y nX ye+d W n e-k
rH   dZ.Y nX dZ.dd  Z/d6d"d#Z0d$d% Z1d&d' Z2G d(d) d)e3Z4G d*d+ d+e3Z5G d,d- d-e6Z7G d.d/ d/eZ8G d0d1 d1eZ9G d2d3 d3e:Z;G d4d5 d5eZ<d!S )7z
    jinja2.compiler
    ~~~~~~~~~~~~~~~

    Compiles nodes into python code.

    :copyright: (c) 2017 by the Jinja Team.
    :license: BSD, see LICENSE for more details.
    )chain)deepcopy)	iskeyword)update_wrapper)nodes)EvalContext)NodeVisitor)	Optimizer)TemplateAssertionError)Markupconcatescape)
range_type	text_typestring_types	iteritemsNativeStringIOimapizip)SymbolsVAR_LOAD_PARAMETERVAR_LOAD_RESOLVEVAR_LOAD_ALIASVAR_LOAD_UNDEFINEDz==z!=>z>=<z<=inznot in)eqnegtZgteqltZlteqr   notinr   itemsdivisionz%from __future__ import generator_stopgenerator_stopzdef f(): yield from x()FTc                s    fdd}t | S )Nc                sD   | j r4|jj r4| jj||j}||kr4| j||S  | ||f|S )N)	optimizedeval_ctxvolatile	optimizervisit)selfnodeframekwargsnew_node)f 1/tmp/pip-build-8app2_gc/Jinja2/jinja2/compiler.pynew_func@   s
    zoptimizeconst.<locals>.new_func)r   )r/   r2   r0   )r/   r1   optimizeconst?   s    r3   Nc             C   sH   t | tjstd|j||||||}|j|  |dkrD|jj S dS )z+Generate the python source for a node tree.z Can't compile non template nodesN)
isinstancer   Template	TypeErrorZcode_generator_classr)   streamgetvalue)r+   environmentnamefilenamer7   
defer_initr%   	generatorr0   r0   r1   generateJ   s    

r>   c             C   s   | dks| t ks| tkrdS t| ttttttft	 kr<dS t| t
tttfkrnx| D ]}t|sVdS qVW dS t| tkrx,t| D ] \}} t|sdS t| sdS qW dS dS )z)Does the node have a safe representation?NTF)NotImplementedEllipsistypeboolintfloatcomplexr   r   r   tuplelistset	frozensethas_safe_reprdictr   )valueitemkeyr0   r0   r1   rJ   W   s"    
rJ   c             C   s@   t |}yx| D ]}|j| qW W n tk
r8   Y nX |jS )zCheck if the names passed are accessed undeclared.  The return value
    is a set of all the undeclared names from the sequence of names found.
    )UndeclaredNameVisitorr)   VisitorExit
undeclared)r   namesvisitorr+   r0   r0   r1   find_undeclaredl   s    
rT   c               @   s   e Zd Zdd ZdS )MacroRefc             C   s   || _ d| _d| _d| _d S )NF)r+   accesses_calleraccesses_kwargsaccesses_varargs)r*   r+   r0   r0   r1   __init__{   s    zMacroRef.__init__N)__name__
__module____qualname__rY   r0   r0   r0   r1   rU   y   s   rU   c               @   s8   e Zd ZdZdddZdd Zddd	Zd
d ZeZdS )Framez&Holds compile time information for us.Nc             C   sf   || _ t|r|jpd |d| _d| _d| _|o2|j| _d | _|rF|jpHd | _|| _|d k	rb|j| _d S )N)levelF)	r&   r   symbolstoplevel	rootlevelrequire_output_checkbufferblockparent)r*   r&   re   r^   r0   r0   r1   rY      s    
zFrame.__init__c             C   s*   t j| j}|jj| j | jj |_|S )z!Create a copy of the current one.)object__new__	__class____dict__updater_   copy)r*   rvr0   r0   r1   rk      s    z
Frame.copyFc             C   s&   |rt | j| jjd dS t | j| S )zReturn an inner frame.   )r^   )r]   r&   r_   r^   )r*   isolatedr0   r0   r1   inner   s    zFrame.innerc             C   s   | j  }d|_|S )a  Return a soft frame.  A soft frame may not be modified as
        standalone thing as it shares the resources with the frame it
        was created of, but it's not a rootlevel frame any longer.

        This is only used to implement if-statements.
        F)rk   ra   )r*   rl   r0   r0   r1   soft   s    z
Frame.soft)NN)F)	rZ   r[   r\   __doc__rY   rk   ro   rp   __copy__r0   r0   r0   r1   r]      s   
 
r]   c               @   s   e Zd ZdZdS )rP   z?Exception used by the `UndeclaredNameVisitor` to signal a stop.N)rZ   r[   r\   rq   r0   r0   r0   r1   rP      s   rP   c               @   s0   e Zd ZdZdd Zdd Zdd Zdd	 Zd
S )DependencyFinderVisitorz.A visitor that collects filter and test calls.c             C   s   t  | _t  | _d S )N)rH   filterstests)r*   r0   r0   r1   rY      s    z DependencyFinderVisitor.__init__c             C   s   | j | | jj|j d S )N)generic_visitrt   addr:   )r*   r+   r0   r0   r1   visit_Filter   s    
z$DependencyFinderVisitor.visit_Filterc             C   s   | j | | jj|j d S )N)rv   ru   rw   r:   )r*   r+   r0   r0   r1   
visit_Test   s    
z"DependencyFinderVisitor.visit_Testc             C   s   dS )zStop visiting at blocks.Nr0   )r*   r+   r0   r0   r1   visit_Block   s    z#DependencyFinderVisitor.visit_BlockN)rZ   r[   r\   rq   rY   rx   ry   rz   r0   r0   r0   r1   rs      s
   rs   c               @   s(   e Zd ZdZdd Zdd Zdd ZdS )	rO   zA visitor that checks if a name is accessed without being
    declared.  This is different from the frame visitor as it will
    not stop at closure frames.
    c             C   s   t || _t  | _d S )N)rH   rR   rQ   )r*   rR   r0   r0   r1   rY      s    
zUndeclaredNameVisitor.__init__c             C   sJ   |j dkr8|j| jkr8| jj|j | j| jkrFt n| jj|j d S )Nload)ctxr:   rR   rQ   rw   rP   discard)r*   r+   r0   r0   r1   
visit_Name   s
    z UndeclaredNameVisitor.visit_Namec             C   s   dS )zStop visiting a blocks.Nr0   )r*   r+   r0   r0   r1   rz      s    z!UndeclaredNameVisitor.visit_BlockN)rZ   r[   r\   rq   rY   r~   rz   r0   r0   r0   r1   rO      s   rO   c               @   s   e Zd ZdZdS )CompilerExitzRaised if the compiler encountered a situation where it just
    doesn't make sense to further process the code.  Any block that
    raises such an exception is not further processed.
    N)rZ   r[   r\   rq   r0   r0   r0   r1   r      s   r   c               @   sV  e Zd ZdddZdd Zdd	 Zd
d ZdddZdd ZdddZ	dddZ
dd ZdddZdd Zdd ZdddZdd d!Zdd"d#Zd$d% Zd&d' Zdd(d)Zd*d+ Zd,d- Zd.d/ Zd0d1 Zd2d3 Zd4d5 Zd6d7 Zd8d9 Zd:d; Zd<d= Zd>d? Zd@dA Z dBdC Z!dDdE Z"dFdG Z#dHdI Z$dJdK Z%ddLdMZ&dNdO Z'dPdQ Z(dRdS Z)dTdU Z*dVdW Z+dXdY Z,dZd[ Z-d\d] Z.d^d_ Z/d`da Z0dbdc Z1ddde Z2dfdg Z3dhdi Z4djdk Z5dldm Z6dndo Z7dpdq Z8drds Z9dtdu Z:dvdw Z;dxdy Z<ddzd{Z=dd|d}Z>e=d~Z?e=dZ@e=dZAe=dZBe=dZCe=dZDe=dZEe=dddZFe=dddZGe>d~ZHe>dZIe>dddZJ[=[>eKdd ZLeKdd ZMdd ZNeKdd ZOeKdd ZPdd ZQeKdd ZReKdd ZSeKdd ZTeKdddZUdd ZVdd ZWdd ZXdd ZYdd ZZdd Z[dd Z\dd Z]dd Z^dd Z_dd Z`dd Zadd Zbdd ZcdS )CodeGeneratorNFTc             C   s   |d krt  }|| _|| _|| _|| _d| _|| _|| _|rFt|| _	i | _
i | _d| _d| _d| _i | _i | _g | _d | _d| _d| _d| _d| _d| _g | _g | _dg| _d S )NFr   rm   Tcontext)r   r9   r:   r;   r7   Zcreated_block_contextr<   r%   r	   r(   import_aliasesblocksextends_so_farhas_known_extendscode_linenoru   rt   
debug_info_write_debug_info
_new_lines
_last_line_first_write_last_identifier_indentation_assign_stack_param_def_block_context_reference_stack)r*   r9   r:   r;   r7   r<   r%   r0   r0   r1   rY      s8    
zCodeGenerator.__init__c             C   s   t ||| j| jdS )z*Fail with a :exc:`TemplateAssertionError`.N)r
   r:   r;   )r*   msglinenor0   r0   r1   fail9  s    zCodeGenerator.failc             C   s   |  j d7  _ d| j  S )zGet a new unique identifier.rm   zt_%d)r   )r*   r0   r0   r1   temporary_identifier=  s    z"CodeGenerator.temporary_identifierc             C   s   | j  |_| jd|j  dS )z7Enable buffering for the frame from that point onwards.z%s = []N)r   rc   	writeline)r*   r,   r0   r0   r1   rc   B  s    
zCodeGenerator.bufferc             C   s   |s|j jrd| jd | j  | jd|j  | j  | jd | j  | jd|j  | j  dS |j jr| jd|j  dS | jd|j  dS )z(Return the buffer contents of the frame.zif context.eval_ctx.autoescape:zreturn Markup(concat(%s))zelse:zreturn concat(%s)N)r&   r'   r   indentrc   outdent
autoescape)r*   r,   force_unescapedr0   r0   r1   return_buffer_contentsG  s    

z$CodeGenerator.return_buffer_contentsc             C   s   |  j d7  _ dS )zIndent by one.rm   N)r   )r*   r0   r0   r1   r   Y  s    zCodeGenerator.indentrm   c             C   s   |  j |8  _ dS )zOutdent by step.N)r   )r*   stepr0   r0   r1   r   ]  s    zCodeGenerator.outdentc             C   s.   |j dkr| jd| n| jd|j  | dS )z%Yield or write into the frame buffer.Nzyield z
%s.append()rc   r   )r*   r,   r+   r0   r0   r1   start_writea  s    
zCodeGenerator.start_writec             C   s   |j dk	r| jd dS )z1End the writing process started by `start_write`.N))rc   write)r*   r,   r0   r0   r1   	end_writeh  s    
zCodeGenerator.end_writec             C   s$   | j || | j| | j| dS )z4Simple shortcut for start_write + write + end_write.N)r   r   r   )r*   sr,   r+   r0   r0   r1   simple_writem  s    
zCodeGenerator.simple_writec             C   sB   y(| j d x|D ]}| j|| qW W n tk
r<   Y nX dS )zVisit a list of nodes as block in a frame.  If the current frame
        is no buffer a dummy ``if 0: yield None`` is written automatically.
        passN)r   r)   r   )r*   r   r,   r+   r0   r0   r1   
blockvisits  s    

zCodeGenerator.blockvisitc             C   s   | j rp| jsR| jjd| j   |  j| j 7  _| jdk	rR| jj| j| jf d| _d| _| jjd| j  d| _ | jj| dS )z&Write a string into the output stream.
NFz    r   )	r   r   r7   r   r   r   r   appendr   )r*   xr0   r0   r1   r   ~  s    


zCodeGenerator.writer   c             C   s   | j || | j| dS )z!Combination of newline and write.N)newliner   )r*   r   r+   extrar0   r0   r1   r     s    zCodeGenerator.writelinec             C   s:   t | jd| | _|dk	r6|j| jkr6|j| _|j| _dS )z/Add one or more newlines before the next write.rm   N)maxr   r   r   r   )r*   r+   r   r0   r0   r1   r     s    zCodeGenerator.newlinec       	      C   s  d}x0t dd |jD |pf D ]}t|r d}P q W x$|jD ]}| jd | j|| q>W |sx$|jD ]}| jd | j|| qhW |dk	rx&t|D ]\}}| jd||f  qW |jr| jd | j|j| |r|jdk	r| jd	 n
| jd
 x8|jD ].}| jd|j	  | j|j
| | jd qW |dk	rhx(t|D ]\}}| jd||f  qHW |jdk	r| jd | j|j| | jd n
| jd n$|jdk	r| jd | j|j| dS )a,  Writes a function call to the stream for the current node.
        A leading comma is added automatically.  The extra keyword
        arguments may not include python keywords otherwise a syntax
        error could occour.  The extra keyword arguments should be given
        as python dict.
        Fc             s   s   | ]}|j V  qd S )N)rN   ).0r   r0   r0   r1   	<genexpr>  s    z*CodeGenerator.signature.<locals>.<genexpr>Tz, Nz, %s=%sz, *z
, **dict({z, **{z%r: z%r: %s, z}, **r   }z, **)r   r-   is_python_keywordargsr   r)   r   Zdyn_argsZ
dyn_kwargsrN   rL   )	r*   r+   r,   extra_kwargsZkwarg_workaroundkwargargrN   rL   r0   r0   r1   	signature  sJ    	 







zCodeGenerator.signaturec             C   sz   t  }x|D ]}|j| qW xVdD ]N}t| |}x>t||D ]0}||krV| j ||< | jd|| ||f  q>W q$W dS )zPull all the dependencies.rt   ru   z%s = environment.%s[%r]N)rt   ru   )rs   r)   getattrr   r   )r*   r   rS   r+   
dependencymappingr:   r0   r0   r1   pull_dependencies  s    


zCodeGenerator.pull_dependenciesc             C   s   g }xt |jjD ]p\}\}}|tkr(q|tkrJ| jd|| j |f  q|tkrf| jd||f  q|tkrz|j	| qt
dqW |r| jddj|  d S )Nz%s = %s(%r)z%s = %szunknown load instructionz%s = missingz = )r   r_   loadsr   r   r   get_resolve_funcr   r   r   NotImplementedErrorjoin)r*   r,   undefstargetactionparamr0   r0   r1   enter_frame  s    zCodeGenerator.enter_framec             C   sH   |sDg }x"t |jjD ]\}}|j| qW |rD| jddj|  d S )Nz%s = missingz = )r   r_   r   r   r   r   )r*   r,   with_python_scoper   r   _r0   r0   r1   leave_frame  s    zCodeGenerator.leave_framec             C   s   | j jrd| S d| S )Nzasync def %szdef %s)r9   is_async)r*   r:   r0   r0   r1   func  s    zCodeGenerator.funcc             C   s  |j  }|jj| t|}d}t }g }xNt|jD ]@\}}|jdkrL|}|jdkrb|j|j |j	|jj
|j q6W t|jd}	d|	kr|dk	ry|j|t|j   W q tk
r   | jd|j Y qX n|j	|jjd d|_d|	krd|kr|j	|jjd d|_d|	krDd|krD|j	|jjd d|_d|_|jj| | jd| jd	d
j|f | | j  | j| | j| | j| xt|jD ]\}}|jj
|j}
| jd|
  | j  y|j|t|j  }W n2 tk
r   | jd|
d|j |jf  Y nX | jd|
  | j|| | j|
 | j   qW | j!  | j"|j| | j#|dd | j$|dd | j   ||fS )z/Dump the function def of a macro or call block.Ncallerr-   varargszhWhen defining macros or call blocks the special "caller" argument must be omitted or be given a default.TFz%s(%s):macroz, zif %s is missing:z%s = undefined(%r, name=%r)zparameter %r was not providedz%s = )r   )r   )r-   r   )r   r-   r   )%ro   r_   analyze_noderU   rH   	enumerater   r:   rw   r   refrT   bodydefaultslen
IndexErrorr   r   declare_parameterrV   rW   rX   rb   r   r   r   r   rc   r   push_parameter_definitionsr)   mark_parameter_storedr   pop_parameter_definitionsr   r   r   )r*   r+   r,   	macro_refZexplicit_callerZskip_special_paramsr   idxr   rQ   r   defaultr0   r0   r1   
macro_body  sp    

 



zCodeGenerator.macro_bodyc             C   s`   dj dd |jjD }t|jdd}t|jjdkr>|d7 }| jd|||j|j|jf  dS )	z<Dump the macro definition for the def created by macro_body.z, c             s   s   | ]}t |jV  qd S )N)reprr:   )r   r   r0   r0   r1   r   H  s    z*CodeGenerator.macro_def.<locals>.<genexpr>r:   Nrm   ,zLMacro(environment, macro, %r, (%s), %r, %r, %r, context.eval_ctx.autoescape))	r   r+   r   r   r   r   rW   rX   rV   )r*   r   r,   Z	arg_tupler:   r0   r0   r1   	macro_defF  s    zCodeGenerator.macro_defc             C   s*   d|j  }| jdk	r&|dt| j 7 }|S )z.Return a human readable position for the node.zline %dNz in )r   r:   r   )r*   r+   rl   r0   r0   r1   positionQ  s    

zCodeGenerator.positionc             C   s"   ddj dd t|jj D  S )Nz{%s}z, c             s   s   | ]\}}d ||f V  qdS )z%r: %sNr0   )r   r:   r   r0   r0   r1   r   Z  s    z3CodeGenerator.dump_local_context.<locals>.<genexpr>)r   r   r_   Zdump_stores)r*   r,   r0   r0   r1   dump_local_contextX  s    z CodeGenerator.dump_local_contextc             C   s"   | j d | j d | j d dS )zWrites a common preamble that is used by root and block functions.
        Primarily this sets up common local helpers and enforces a generator
        through a dead branch.
        z$resolve = context.resolve_or_missingz!undefined = environment.undefinedzif 0: yield NoneN)r   )r*   r0   r0   r1   write_commons]  s    

zCodeGenerator.write_commonsc             C   s   | j j|jj  dS )aQ  Pushes all parameter targets from the given frame into a local
        stack that permits tracking of yet to be assigned parameters.  In
        particular this enables the optimization from `visit_Name` to skip
        undefined expressions for parameters in macros as macros can reference
        otherwise unbound parameters.
        N)r   r   r_   Zdump_param_targets)r*   r,   r0   r0   r1   r   f  s    z(CodeGenerator.push_parameter_definitionsc             C   s   | j j  dS )z+Pops the current parameter definitions set.N)r   pop)r*   r0   r0   r1   r   o  s    z'CodeGenerator.pop_parameter_definitionsc             C   s   | j r| j d j| dS )zMarks a parameter in the current parameter definitions as stored.
        This will skip the enforced undefined checks.
        rm   N)r   r}   )r*   r   r0   r0   r1   r   s  s    z#CodeGenerator.mark_parameter_storedc             C   s   | j j| d S )N)r   r   )r*   r   r0   r0   r1   push_context_referencez  s    z$CodeGenerator.push_context_referencec             C   s   | j j  d S )N)r   r   )r*   r0   r0   r1   pop_context_reference}  s    z#CodeGenerator.pop_context_referencec             C   s
   | j d S )Nrm   r   )r   )r*   r0   r0   r1   get_context_ref  s    zCodeGenerator.get_context_refc             C   s   | j d }|dkrdS d| S )Nrm   r   resolvez
%s.resolver   )r   )r*   r   r0   r0   r1   r     s    
zCodeGenerator.get_resolve_funcc             C   s   d| j  | j|f S )Nz%s.derived(%s))r   r   )r*   r,   r0   r0   r1   derive_context  s    zCodeGenerator.derive_contextc             C   s   | j s
dS || j d kS )z4Checks if a given target is an undeclared parameter.Frm   r   )r   )r*   r   r0   r0   r1   parameter_is_undeclared  s    z%CodeGenerator.parameter_is_undeclaredc             C   s   | j jt  dS )z+Pushes a new layer for assignment tracking.N)r   r   rH   )r*   r0   r0   r1   push_assign_tracking  s    z"CodeGenerator.push_assign_trackingc             C   s   | j j }|j s| rdS dd |D }t|dkrbtt|}|jj|}| jd||f  nV| jd x@t	|D ]4\}}|r| j
d |jj|}| j
d||f  qvW | j
d	 |rt|dkr| jd
|d   n| jddjtt|  dS )zoPops the topmost level for assignment tracking and updates the
        context variables if necessary.
        Nc             S   s    g | ]}|d d dkr|qS )Nrm   r   r0   )r   r   r0   r0   r1   
<listcomp>  s    z5CodeGenerator.pop_assign_tracking.<locals>.<listcomp>rm   zcontext.vars[%r] = %szcontext.vars.update({z, z%r: %sz})zcontext.exported_vars.add(%r)r   z"context.exported_vars.update((%s)))r   r   r`   r   nextiterr_   r   r   r   r   r   r   r   )r*   r,   varsZpublic_namesr:   r   r   r0   r0   r1   pop_assign_tracking  s*    



z!CodeGenerator.pop_assign_trackingc             C   s  |d kst dt| j| j}ddlm} | jddjt  | jddj|  | jj	rd| jd | j
 rpdprd	}|jtjd k	}x@|jtjD ]0}|j| jkr| jd
|j |j || j|j< qW xz|jtjD ]j}|j| jkr|j}	| j  | j|	< }
d|	kr,|	jdd\}}| jd|||
f  q| jd|	|
f  qW | jd| j  | jd| jd|f dd | j  | j  t|}dt|jd&kr|jjd}| jd|  |jj | d |_!|_"|o| j# |_$|r| jd | j%| | j&|j | j'|j| | j(|dd | j)  |r| j#sD| j  | jd | j  t*rj| jj	 rj| jd n8| jd| jj	rdpd	  | j  | jd | j)  | j)d| j#   xt+| jD ]\}}| jd| jd| |f |d | j  | j  t|}t|jd'}d|kr0|jjd}| jd|  d|krZ|jjd}| jd|||f  |jj | ||_,| j%| | j&|j | j'|j| | j(|dd | j)  qW | jd djd!d" | jD  dd | jd#d$jd%d" | j-D   d S )(Nzno root frame allowedr   )__all__zfrom __future__ import %sz, zfrom jinja2.runtime import zOfrom jinja2.asyncsupport import auto_await, auto_aiter, make_async_loop_contextz, environment=environment zblock %r defined twice.rm   zfrom %s import %s as %szimport %s as %sz	name = %rz%s(context, missing=missing%s):root)r   r*   z%s = TemplateReference(context)Tzparent_template = None)r   zif parent_template is not None:z4yield from parent_template.root_render_func(context)z9%sfor event in parent_template.root_render_func(context):zasync zyield eventZblock_superz %s = context.super(%r, block_%s)zblocks = {%s}c             s   s   | ]}d ||f V  qdS )z%r: block_%sNr0   )r   r   r0   r0   r1   r   #  s   z/CodeGenerator.visit_Template.<locals>.<genexpr>zdebug_info = %r&c             s   s   | ]}d | V  qdS )z%s=%sNr0   )r   r   r0   r0   r1   r   (  s    )r*   )r*   r   ).AssertionErrorr   r9   r:   Zjinja2.runtimer   r   r   code_featuresr   r<   findr   ZExtendsfind_allZBlockr   r   r   ZImportedName
importnamer   r   rsplitr   r   r   r]   rT   r   r_   r   r   r`   ra   r   rb   r   r   r   r   r   supports_yield_fromr   rd   r   )r*   r+   r,   r&   ZexportedZenvenvZhave_extendsrd   import_impaliasmoduleobjr   r:   block_framerQ   r0   r0   r1   visit_Template  s    








zCodeGenerator.visit_Templatec             C   s   d}|j r8| jrdS | jdkr8| jd | j  |d7 }|jrJ| j|}n| j }tr| j	j
 r|jdkr| jd|j|f | nD| j	j
rdpd}| jd||j|f | | j  | jd	| | j  | j| dS )
z.Call a block and register it for the template.r   Nzif parent_template is None:rm   z$yield from context.blocks[%r][0](%s)z	async forforz&%s event in context.blocks[%r][0](%s):event)r`   r   r   r   r   scopedr   r   r   r9   r   rc   r:   r   r   )r*   r+   r,   r^   r   loopr0   r0   r1   rz   +  s,    


zCodeGenerator.visit_Blockc             C   s   |j s| jd|j | jdkrZ| js6| jd | j  | jdd  | jrRt n| j  | jd| | j	|j
| | jd| j  | jdt  | j  | jd	 | j  |jrd
| _|  jd7  _dS )zCalls the extender.z,cannot use extend from a non top-level scoper   zif parent_template is not None:zraise TemplateRuntimeError(%r)zextended multiple timesz+parent_template = environment.get_template(z, %r)z6for name, parent_block in parent_template.blocks.%s():z8context.blocks.setdefault(name, []).append(parent_block)Trm   N)r`   r   r   r   r   r   r   r   r   r)   templater   r:   dict_item_iterra   )r*   r+   r,   r0   r0   r1   visit_ExtendsK  s.    


zCodeGenerator.visit_Extendsc             C   s  |j r| jd | j  d}t|jtjrVt|jjtr>d}qnt|jjt	t
frnd}nt|jtjtjfrnd}| jd| | | j|j| | jd| j  |j r| j  | jd | j  | jd | j  | jd	 | j  d
}|jr| jjrdpd}| jd|| j|f  n6| jjr,| jd n trB| jd d}n
| jd |sn| j  | jd| | j  |j r~| j  dS )zHandles includes.ztry:Zget_or_select_templateZget_templateZselect_templateztemplate = environment.%s(z, %r)zexcept TemplateNotFound:r   zelse:Fz	async forr   zY%s event in template.root_render_func(template.new_context(context.get_all(), True, %s)):zGfor event in (await template._get_default_module_async())._body_stream:z6yield from template._get_default_module()._body_streamTz9for event in template._get_default_module()._body_stream:r   N)Zignore_missingr   r   r4   r  r   ZConstrL   r   rF   rG   TupleListr)   r   r:   r   with_contextr9   r   r   r   r   )r*   r+   r,   	func_nameZskip_event_yieldr  r0   r0   r1   visit_Includez  sN    






zCodeGenerator.visit_Includec             C   s   | j d|jj|j | |jr0| jd|j  | jjrB| jd | jd | j|j	| | jd| j
  |jr| jd| jjrdpd| j|f  n| jjr| jd	 n
| jd
 |jr|jjd r| j d|j  dS )zVisit regular imports.z%s = zcontext.vars[%r] = zawait zenvironment.get_template(z, %r).z*make_module%s(context.get_all(), True, %s)_asyncr   z_get_default_module_async()z_get_default_module()r   z!context.exported_vars.discard(%r)N)r   r_   r   r   r`   r   r9   r   r)   r  r:   r  r   
startswith)r*   r+   r,   r0   r0   r1   visit_Import  s"    


zCodeGenerator.visit_Importc                s  | j | | jd| jjrdpd  | j|j  | jd| j  |jrn| jd| jjrZdp\d| j f  n| jjr| jd n
| jd g }g }x|j	D ]}t
|tr|\}}n|}| jd	 jj||f  | jd
 jj|  | j  | jd jj|d| j|t|f |f  | j   jr|j| |jds|j| qW |rt|dkr|d }| jd| jj|f  n"| jddj fdd|D   |rt|dkr| jd|d   n| jddjtt|  dS )zVisit named imports.z/included_template = %senvironment.get_template(zawait r   z, %r).z*make_module%s(context.get_all(), True, %s)r  z_get_default_module_async()z_get_default_module()z,%s = getattr(included_template, %r, missing)zif %s is missing:z9%s = undefined(%r %% included_template.__name__, name=%r)zGthe template %%r (imported on %s) does not export the requested name %sr   rm   r   zcontext.vars[%r] = %szcontext.vars.update({%s})z, c             3   s"   | ]}d | j j|f V  qdS )z%r: %sN)r_   r   )r   r:   )r,   r0   r1   r     s    z1CodeGenerator.visit_FromImport.<locals>.<genexpr>z!context.exported_vars.discard(%r)z-context.exported_vars.difference_update((%s))N)r   r   r9   r   r)   r  r:   r  r   rR   r4   rF   r   r_   r   r   r   r   r   r`   r   r  r   r   r   )r*   r+   r,   Z	var_namesZdiscarded_namesr:   r   r0   )r,   r1   visit_FromImport  s\    









zCodeGenerator.visit_FromImportc             C   sV  |j  }|j  }|j  }|jp2dt|jd%dd&k}d }|rH|jjd}|jj|dd |jrn|jj|dd |jrl| j	 }|jj|dd | j
d| j| |j | j  | j| | j
| jjrdpd	 | j|j| | jd
 | j| jjrdpd | jd | j  | j
d|j | j|j| | jd | j  | j
d | j|j| | jd | j|dd |jr| j
d| jd | | j  | j| |j|_|r| j
d|  x<|jtjD ],}	|	jdkr|	jdkr| jd|	j qW |jr| j	 }
| j
d|
  | j
| jjr(dp*d	| | j|j| |rn| jjr^| jd|  n| jd|  n
| jd
 |jr| jd|  |jr| jd nF| jjr| r| jd | j|j| | jjr| r| jd |jr| jd |jr| jd n| j|rdp d | j  | j| | j|j| |jrZ| j
d |
  | j  | j||jov|j d |jr| j
d!|
  | j  | j| | j|j| | j| | j  |jrR| j | | j  | j!|| | jjr| jd" | jd# | jjr| jd | j|j| | jjr>| jd | jd$ | j"| d S )'Nr  r   )only)Z
for_branchelsetestz
%s(fiter):z
async for zfor z in zauto_aiter(fiter)Zfiter:zif zyield    T)r   z'%s(reciter, loop_render_func, depth=0):z%s = missingstorez8Can't assign to special loop variable in for-loop targetz%s = 1z&, %s in await make_async_loop_context(z, %s in LoopContext(z%s(Zreciterzauto_aiter(r   z&, undefined, loop_render_func, depth):z, undefined):z%s = 0zif %s:zawait zloop(z, loop))r   )r  )#ro   	recursiverT   iter_child_nodesr_   r   r   else_r  r   r   r   r   r   r9   r   r)   r   r   r   r   rc   r   r   Namer|   r:   r   r   r   r   r   r   r   r   )r*   r+   r,   Z
loop_frameZ
test_frameZ
else_frameZextended_loopZloop_refZloop_filter_funcr:   Ziteration_indicatorr0   r0   r1   	visit_For   s    























zCodeGenerator.visit_Forc             C   s   |j  }| jd| | j|j| | jd | j  | j|j| | j  xP|j	D ]F}| jd| | j|j| | jd | j  | j|j| | j  qRW |j
r| jd | j  | j|j
| | j  d S )Nzif r  zelif zelse:)rp   r   r)   r  r   r   r   r   r   elif_r  )r*   r+   r,   Zif_framer  r0   r0   r1   visit_If  s&    


zCodeGenerator.visit_Ifc             C   s   | j ||\}}| j  |jrX|jjds:| jd|j  |jj|j}| jd|j  | jd|jj|j  | j	|| d S )Nr   zcontext.exported_vars.add(%r)zcontext.vars[%r] = z%s = )
r   r   r`   r:   r  r   r_   r   r   r   )r*   r+   r,   Zmacro_framer   r   r0   r0   r1   visit_Macro  s    zCodeGenerator.visit_Macroc             C   sR   | j ||\}}| jd | j|| | j|| | j|j|dd | j| d S )Nz	caller = T)forward_caller)r   r   r   r   
visit_Callcallr   )r*   r+   r,   Z
call_framer   r0   r0   r1   visit_CallBlock  s    
zCodeGenerator.visit_CallBlockc             C   sh   |j  }|jj| | j| | j| | j|j| | j|| | j|j	| | j
| | j| d S )N)ro   r_   r   r   rc   r   r   r   rx   filterr   r   )r*   r+   r,   Zfilter_framer0   r0   r1   visit_FilterBlock  s    


zCodeGenerator.visit_FilterBlockc             C   s   |j  }|jj| | j| xLtt|j|jD ]6\}\}}| j  | j	|| | j
d | j	|| q2W | j|j| | j| d S )Nz = )ro   r_   r   r   r   r   targetsvaluesr   r)   r   r   r   r   )r*   r+   r,   Z
with_framer   r   exprr0   r0   r1   
visit_With  s    
 
zCodeGenerator.visit_Withc             C   s   | j | | j|j| d S )N)r   r)   r+   )r*   r+   r,   r0   r0   r1   visit_ExprStmt  s    
zCodeGenerator.visit_ExprStmtc                s   j r|jrd S d} jjrj jj}t|dds<t|ddrBd}qnt|ddr\ fdd}qn fdd}nt}d}|jr jd	  j  d}g }x|jD ]}y|stj	 |j
|j}	W n" tj	k
r   |j| wY nX y4|jjrt|	d
r |	j }	nt|	}	||	}	W n" tk
r4   |j| wY nX |r\t|d  tr\|d! j|	 q|j|	g qW t|dk s|jd k	r"|jd k	rt|dkr jd|j  n jd|j   j  x|D ]}
t|
trtt|
}|jd kr jd|  n j|d  n|jd kr6 jd|
 n
 j|
 d}|jjrZ jd n |jjrp jd n
 jd  jjd k	r jd t jjddr jd |d7 } j|
|  jd|  |jd k	r҈ jd qW |jd k	r j   jt|dkrdpd nxg }g }xF|D ]>}
t|
trX|jt|
jdd n|jd |j|
 q0W  jd  jtt|d   j  x|D ]} j| d}|jjrЈ jd |d7 }n|jjr jd |d7 } jjd k	rd jd t jjddr" jd n:t jjddr@ jd nt jjddr\ jd |d7 } j||  jd| d  qW  j   jd |r j  d S )"NTZcontextfunctionFZevalcontextfunctionZenvironmentfunctionc                s   t  jj j| S )N)r   r9   finalize)r   )r*   r0   r1   <lambda>  s   z,CodeGenerator.visit_Output.<locals>.<lambda>c                s   t  jj| S )N)r   r9   r(  )r   )r*   r0   r1   r)    s    zif parent_template is None:__html__rm   r  z
%s.append(z%s.extend((zyield r   z7(escape if context.eval_ctx.autoescape else to_string)(zescape(z
to_string(zenvironment.finalize(z	context, r   z))%z%%z%sz % (r   zcontext.eval_ctx, zenvironment, z, r   r   )r   rb   r9   r(  r   r   r   r   r   
Impossibleas_constr&   r   r   hasattrr*  r   	Exceptionr4   rG   r   rc   r   r   r   r'   r   r)   r   replace)r*   r+   r,   Zallow_constant_finalizer   r(  Zoutdent_laterr   childconstrM   valcloseformat	argumentsargumentr0   )r*   r1   visit_Output  s    











"















zCodeGenerator.visit_Outputc             C   sF   | j   | j| | j|j| | jd | j|j| | j| d S )Nz = )r   r   r)   r   r   r+   r   )r*   r+   r,   r0   r0   r1   visit_AssignV  s    

zCodeGenerator.visit_Assignc             C   s   | j   |j }d|_|jj| | j| | j| | j|j| | j	| | j
|j| | jd |jd k	r| j|j| n| jd|j  | jd | j| | j| d S )NFz9 = (Markup if context.eval_ctx.autoescape else identity)(z
concat(%s)r   )r   ro   rb   r_   r   r   rc   r   r   r   r)   r   r   r!  rx   r   r   )r*   r+   r,   r   r0   r0   r1   visit_AssignBlock^  s     






zCodeGenerator.visit_AssignBlockc             C   s   |j dkr(|jr(| jr(| jd j|j |jj|j}|j dkr|jj|}|d k	oj|d tkoj| j	| s| j
d|j||f  d S | j
| d S )Nr  rm   r{   r   z-(undefined(name=%r) if %s is missing else %s)r   )r|   r`   r   rw   r:   r_   r   Z	find_loadr   r   r   )r*   r+   r,   r   r{   r0   r0   r1   r~   w  s    
zCodeGenerator.visit_Namec             C   sR   |j j|j}| jd|  | j  | jdd  | j  | jd||jf  d S )Nz!if not isinstance(%s, Namespace):zraise TemplateRuntimeError(%r)z/cannot assign attribute on non-namespace objectz%s[%r])r_   r   r:   r   r   r   attr)r*   r+   r,   r   r0   r0   r1   visit_NSRef  s    zCodeGenerator.visit_NSRefc             C   s8   |j |j}t|tr&| jt| n| jt| d S )N)r-  r&   r4   rD   r   strr   )r*   r+   r,   r3  r0   r0   r1   visit_Const  s    
zCodeGenerator.visit_Constc             C   sF   y| j t|j|j W n& tjk
r@   | j d|j  Y nX d S )Nz9(Markup if context.eval_ctx.autoescape else identity)(%r))r   r   r-  r&   r   r,  data)r*   r+   r,   r0   r0   r1   visit_TemplateData  s
    z CodeGenerator.visit_TemplateDatac             C   sZ   | j d d}x0t|jD ]"\}}|r0| j d | j|| qW | j |dkrPdpRd d S )N(rm   z, r   z,)r   r   )r   r   r"   r)   )r*   r+   r,   r   rM   r0   r0   r1   visit_Tuple  s    

zCodeGenerator.visit_Tuplec             C   sJ   | j d x0t|jD ]"\}}|r,| j d | j|| qW | j d d S )N[z, ])r   r   r"   r)   )r*   r+   r,   r   rM   r0   r0   r1   
visit_List  s    

zCodeGenerator.visit_Listc             C   sd   | j d xJt|jD ]<\}}|r,| j d | j|j| | j d | j|j| qW | j d d S )N{z, z: r   )r   r   r"   r)   rN   rL   )r*   r+   r,   r   rM   r0   r0   r1   
visit_Dict  s    


zCodeGenerator.visit_Dictc                s   t  fdd}|S )Nc                s   | j jrJ | j jkrJ| jd   | j|j| | jd | j|j| n4| jd | j|j| | jd   | j|j| | jd d S )Nz$environment.call_binop(context, %r, z, rA  z %s r   )r9   	sandboxedZintercepted_binopsr   r)   leftright)r*   r+   r,   )operatorr0   r1   rS     s    

z$CodeGenerator.binop.<locals>.visitor)r3   )rK  interceptablerS   r0   )rK  r1   binop  s    zCodeGenerator.binopc                s   t  fdd}|S )Nc                s\   | j jr2 | j jkr2| jd   | j|j| n| jd   | j|j| | jd d S )Nz#environment.call_unop(context, %r, rA  r   )r9   rH  Zintercepted_unopsr   r)   r+   )r*   r+   r,   )rK  r0   r1   rS     s    z#CodeGenerator.uaop.<locals>.visitor)r3   )rK  rL  rS   r0   )rK  r1   uaop  s    
zCodeGenerator.uaop+-*/z//z**r+  and)rL  orznot c             C   sb   |j jrd}n|j jrd}nd}| jd|  x$|jD ]}| j|| | jd q6W | jd d S )Nz;(context.eval_ctx.volatile and markup_join or unicode_join)Zmarkup_joinZunicode_joinz%s((z, z)))r&   r'   r   r   r   r)   )r*   r+   r,   r	  r   r0   r0   r1   visit_Concat  s    zCodeGenerator.visit_Concatc             C   s.   | j |j| x|jD ]}| j || qW d S )N)r)   r%  ops)r*   r+   r,   opr0   r0   r1   visit_Compare  s    zCodeGenerator.visit_Comparec             C   s&   | j dt|j   | j|j| d S )Nz %s )r   	operatorsrW  r)   r%  )r*   r+   r,   r0   r0   r1   visit_Operand   s    zCodeGenerator.visit_Operandc             C   s,   | j d | j|j| | j d|j  d S )Nzenvironment.getattr(z, %r))r   r)   r+   r;  )r*   r+   r,   r0   r0   r1   visit_Getattr  s    
zCodeGenerator.visit_Getattrc             C   s~   t |jtjr@| j|j| | jd | j|j| | jd n:| jd | j|j| | jd | j|j| | jd d S )NrC  rD  zenvironment.getitem(z, r   )r4   r   r   Slicer)   r+   r   )r*   r+   r,   r0   r0   r1   visit_Getitem
  s    


zCodeGenerator.visit_Getitemc             C   s`   |j d k	r| j|j | | jd |jd k	r:| j|j| |jd k	r\| jd | j|j| d S )Nr  )startr)   r   stopr   )r*   r+   r,   r0   r0   r1   visit_Slice  s    




zCodeGenerator.visit_Slicec             C   s,  | j jr| jd | j| j|j d  | j jj|j}|d krT| jd|j |j t|ddrl| jd n.t|ddr| jd nt|d	dr| jd
 |j	d k	r| j
|j	| nJ|jjr| jd|j|jf  n*|jjr| jd|j  n| jd|j  | j|| | jd | j jr(| jd d S )Nzawait auto_await(rA  zno filter named %rZcontextfilterFz	context, Zevalcontextfilterzcontext.eval_ctx, Zenvironmentfilterzenvironment, zB(context.eval_ctx.autoescape and Markup(concat(%s)) or concat(%s))zMarkup(concat(%s))z
concat(%s)r   )r9   r   r   rt   r:   getr   r   r   r+   r)   r&   r'   rc   r   r   )r*   r+   r,   r   r0   r0   r1   rx   #  s0    




zCodeGenerator.visit_Filterc             C   s`   | j | j|j d  |j| jjkr8| jd|j |j | j|j| | j|| | j d d S )NrA  zno test named %rr   )	r   ru   r:   r9   r   r   r)   r+   r   )r*   r+   r,   r0   r0   r1   ry   C  s    zCodeGenerator.visit_Testc                s^    fdd}j d jj  j d jj  j d |  j d d S )Nc                  s4   j d k	rjj  S jddj   d S )Nzundefined(%r)zRthe inline if-expression on %s evaluated to false and no else section was defined.)Zexpr2r)   r   r   r0   )r,   r+   r*   r0   r1   write_expr2N  s    
z1CodeGenerator.visit_CondExpr.<locals>.write_expr2rA  z if z else r   )r   r)   Zexpr1r  )r*   r+   r,   rb  r0   )r,   r+   r*   r1   visit_CondExprL  s    


zCodeGenerator.visit_CondExprc             C   s|   | j jr| jd | j jr&| jd n
| jd | j|j| |rJddipLd }| j||| | jd | j jrx| jd d S )Nzawait auto_await(zenvironment.call(context, zcontext.call(r   r   )r9   r   r   rH  r)   r+   r   )r*   r+   r,   r  r   r0   r0   r1   r  ]  s    


zCodeGenerator.visit_Callc             C   s"   | j |jd  | j|j| d S )N=)r   rN   r)   rL   )r*   r+   r,   r0   r0   r1   visit_Keywordl  s    zCodeGenerator.visit_Keywordc             C   s&   | j d | j|j| | j d d S )NzMarkup(r   )r   r)   r%  )r*   r+   r,   r0   r0   r1   visit_MarkSafer  s    
zCodeGenerator.visit_MarkSafec             C   s&   | j d | j|j| | j d d S )Nz5(context.eval_ctx.autoescape and Markup or identity)(r   )r   r)   r%  )r*   r+   r,   r0   r0   r1   visit_MarkSafeIfAutoescapew  s    
z(CodeGenerator.visit_MarkSafeIfAutoescapec             C   s   | j d|j  d S )Nzenvironment.)r   r:   )r*   r+   r,   r0   r0   r1   visit_EnvironmentAttribute|  s    z(CodeGenerator.visit_EnvironmentAttributec             C   s   | j d|j|jf  d S )Nzenvironment.extensions[%r].%s)r   
identifierr:   )r*   r+   r,   r0   r0   r1   visit_ExtensionAttribute  s    z&CodeGenerator.visit_ExtensionAttributec             C   s   | j | j|j  d S )N)r   r   r   )r*   r+   r,   r0   r0   r1   visit_ImportedName  s    z CodeGenerator.visit_ImportedNamec             C   s   | j |j d S )N)r   r:   )r*   r+   r,   r0   r0   r1   visit_InternalName  s    z CodeGenerator.visit_InternalNamec             C   s   | j d d S )Nr   )r   )r*   r+   r,   r0   r0   r1   visit_ContextReference  s    z$CodeGenerator.visit_ContextReferencec             C   s   | j d| d S )Ncontinue)r   )r*   r+   r,   r0   r0   r1   visit_Continue  s    zCodeGenerator.visit_Continuec             C   s   | j d| d S )Nbreak)r   )r*   r+   r,   r0   r0   r1   visit_Break  s    zCodeGenerator.visit_Breakc             C   s:   |j  }|jj| | j| | j|j| | j| d S )N)ro   r_   r   r   r   r   r   )r*   r+   r,   scope_framer0   r0   r1   visit_Scope  s
    
zCodeGenerator.visit_Scopec             C   s   | j  }| jd|| j|f  | jd|  | j|j| | j| |jdd}|jj| | j	| | j
|j| | j| | j  d S )Nz%s = %sz
%s.vars = T)rn   )r   r   r   r)   r   r   ro   r_   r   r   r   r   r   r   )r*   r+   r,   r|   rr  r0   r0   r1   visit_OverlayScope  s    


z CodeGenerator.visit_OverlayScopec             C   st   xn|j D ]d}| jd|j  | j|j| y|jj|j}W n tjk
rZ   d|j_	Y qX t
|j|j| qW d S )Nzcontext.eval_ctx.%s = T)optionsr   rN   r)   rL   r-  r&   r   r,  r'   setattr)r*   r+   r,   keywordr3  r0   r0   r1   visit_EvalContextModifier  s    z'CodeGenerator.visit_EvalContextModifierc             C   sf   | j  }|jj }| jd|  | j|| x|jD ]}| j|| q4W |jj| | jd|  d S )Nz%s = context.eval_ctx.save()zcontext.eval_ctx.revert(%s))r   r&   saver   rx  r   r)   revert)r*   r+   r,   Zold_ctx_nameZ	saved_ctxr1  r0   r0   r1   visit_ScopedEvalContextModifier  s    
z-CodeGenerator.visit_ScopedEvalContextModifier)NFT)F)rm   )N)N)Nr   )Nr   )N)F)N)T)T)F)drZ   r[   r\   rY   r   r   rc   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   rz   r  r
  r  r  r  r  r  r   r"  r&  r'  r8  r9  r:  r~   r<  r>  r@  rB  rE  rG  rM  rN  Z	visit_AddZ	visit_SubZ	visit_MulZ	visit_DivZvisit_FloorDivZ	visit_PowZ	visit_ModZ	visit_AndZvisit_OrZ	visit_PosZ	visit_NegZ	visit_Notr3   rU  rX  rZ  r[  r]  r`  rx   ry   rc  r  re  rf  rg  rh  rj  rk  rl  rm  ro  rq  rs  rt  rx  r{  r0   r0   r0   r1   r      s    
B






5
M		
t /6;  	



 	r   )NFT)=rq   	itertoolsr   rk   r   rw  r   r   	functoolsr   Zjinja2r   Zjinja2.nodesr   Zjinja2.visitorr   Zjinja2.optimizerr	   Zjinja2.exceptionsr
   Zjinja2.utilsr   r   r   Zjinja2._compatr   r   r   r   r   r   r   Zjinja2.idtrackingr   r   r   r   r   rY  r.  rK   r  r   execr   SyntaxErrorr   r3   r>   rJ   rT   rf   rU   r]   RuntimeErrorrP   rs   rO   r/  r   r   r0   r0   r0   r1   <module>
   s\   $

 
	>