
Á«‘_ì ã               @   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 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 d d l m Z d d l  m! Z! d d l" m# Z# d d l$ m% Z% d d d d d d  d! d" d# d$ d% d& d' d' d( d) i Z& e' e( d* ƒ rÔd* Z) n d+ Z) d, g Z* y e+ d- ƒ e* j, d. ƒ Wn e- k
 rYn Xy e+ d/ ƒ Wn e- k
 r;d0 Z. Yn Xd1 Z. d2 d3 „  Z/ d4 d0 d1 d5 d6 „ Z0 d7 d8 „  Z1 d9 d: „  Z2 Gd; d< „  d< e3 ƒ Z4 Gd= d> „  d> e3 ƒ Z5 Gd? d@ „  d@ e6 ƒ Z7 GdA dB „  dB e% ƒ Z8 GdC dD „  dD e% ƒ Z9 GdE dF „  dF e: ƒ Z; GdG dH „  dH e% ƒ Z< d4 S)Iz0Compiles nodes from the parser into Python code.é    )Ú
namedtuple)Úupdate_wrapper)Úchain)Ú	iskeyword)Úescape)ÚMarkupé   )Únodes)Úimap)Ú	iteritems)Úizip)ÚNativeStringIO)Ú
range_type)Ústring_types)Ú	text_type)ÚTemplateAssertionError)ÚSymbols)ÚVAR_LOAD_ALIAS)ÚVAR_LOAD_PARAMETER)ÚVAR_LOAD_RESOLVE)ÚVAR_LOAD_UNDEFINED)ÚEvalContext)Ú	Optimizer)Úconcat)ÚNodeVisitorÚeqz==Únez!=Úgtú>Zgteqz>=Últú<Zlteqz<=ÚinÚnotinznot inr   ÚitemsÚdivisionz%from __future__ import generator_stopÚgenerator_stopzdef f(): yield from x()FTc                s   ‡  f d d †  } t  | ˆ  ƒ S)Nc                s]   |  j  rJ | j j rJ |  j j | | j ƒ } | | k rJ |  j | | ƒ Sˆ  |  | | | � S)N)Ú	optimizedÚeval_ctxÚvolatileÚ	optimizerÚvisit)ÚselfÚnodeÚframeÚkwargsZnew_node)Úf© ú1/tmp/pip-build-5gj8f0j9/Jinja2/jinja2/compiler.pyÚnew_funcC   s
    zoptimizeconst.<locals>.new_func)r   )r/   r2   r0   )r/   r1   ÚoptimizeconstB   s    r3   Nc             C   sf   t  |  t j ƒ s t d ƒ ‚ | j | | | | | | ƒ } | j |  ƒ | d k rb | j j ƒ  Sd 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   ÚgenerateN   s    r>   c             C   sî   |  d k s$ |  t  k s$ |  t k r( d St |  ƒ t t t t t t f t	 k rT d St |  ƒ t
 t t t f k r— x |  D] } t | ƒ sy d Sqy Wd St |  ƒ t k rê x: t |  ƒ D], \ } }  t | ƒ sÒ d St |  ƒ s¶ d Sq¶ Wd Sd 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   \   s"    $(rJ   c             C   sJ   t  | ƒ } y" x |  D] } | j | ƒ q WWn t k
 rB Yn X| j S)z”Check 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_undeclaredq   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   ~   s   rU   c               @   sU   e  Z d  Z d Z d 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   s—   | |  _  t | r | j p d  d | ƒ|  _ d |  _ d |  _ | oK | j |  _ d  |  _ | ri | j pl d  |  _ | |  _ | d  k	 r“ | 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   s3   | r# t  |  j d |  j j d ƒSt  |  j |  ƒ S)zReturn an inner frame.r^   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)	rZ   r[   r\   Ú__doc__rY   rk   rn   ro   Ú__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\   rp   r0   r0   r0   r1   rP   Ã   s   rP   c               @   sF   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_visitrs   Úaddr:   )r+   r,   r0   r0   r1   Úvisit_FilterÎ   s    z$DependencyFinderVisitor.visit_Filterc             C   s$   |  j  | ƒ |  j j | j ƒ d  S)N)ru   rt   rv   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\   rp   rY   rw   rx   ry   r0   r0   r0   r1   rr   Ç   s
   rr   c               @   s:   e  Z d  Z d Z d d „  Z d d „  Z d d „  Z d S)	rO   z¡A 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   si   | j  d k rR | j |  j k rR |  j j | j ƒ |  j |  j k re t ƒ  ‚ n |  j j | j ƒ d  S)NÚload)Úctxr:   rR   rQ   rv   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   ry   ì   s    z!UndeclaredNameVisitor.visit_BlockN)rZ   r[   r\   rp   rY   r}   ry   r0   r0   r0   r1   rO   Ú   s   rO   c               @   s   e  Z d  Z d Z d S)ÚCompilerExitz¼Raised 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\   rp   r0   r0   r0   r1   r~   ð   s   r~   c               @   sn  e  Z d  Z d d d d d „ Z d d „  Z d d	 „  Z d
 d „  Z d d d „ Z d d „  Z d d d „ Z	 d d d „ Z
 d d „  Z d d d „ Z d d „  Z d d „  Z d d d d „ Z d d d  d! „ Z d d" d# „ Z d$ d% „  Z d& d' „  Z d d( d) „ Z d* d+ „  Z d, d- „  Z d. d/ „  Z d0 d1 „  Z d2 d3 „  Z d4 d5 „  Z d6 d7 „  Z d8 d9 „  Z d: d; „  Z d< d= „  Z d> d? „  Z d@ dA „  Z  dB dC „  Z! dD dE „  Z" dF dG „  Z# dH dI „  Z$ dJ dK „  Z% d dL dM „ Z& dN dO „  Z' dP dQ „  Z( dR dS „  Z) dT dU „  Z* dV dW „  Z+ dX dY „  Z, dZ d[ „  Z- d\ d] „  Z. d^ d_ „  Z/ d` da „  Z0 db dc „  Z1 dd de „  Z2 e3 df dÈ ƒ Z4 e5 Z6 d Z7 di dj „  Z8 dk dl „  Z9 dm dn „  Z: do dp „  Z; dq dr „  Z< ds dt „  Z= du dv „  Z> dw dx „  Z? dy dz „  Z@ d{ d| „  ZA d} d~ „  ZB d d€ „  ZC d� d‚ „  ZD dƒ d„ „  ZE d… d† „  ZF d d‡ dˆ „ ZG d d‰ dŠ „ ZH eG d‹ ƒ ZI eG dŒ ƒ ZJ eG d� ƒ ZK eG dŽ ƒ ZL eG d� ƒ ZM eG d� ƒ ZN eG d‘ ƒ ZO eG d’ d“ d ƒZP eG d” d“ d ƒZQ eH d‹ ƒ ZR eH dŒ ƒ ZS eH d• d“ d ƒZT [G [H eU d– d— „  ƒ ZV eU d˜ d™ „  ƒ ZW dš d› „  ZX eU dœ d� „  ƒ ZY eU dž dŸ „  ƒ ZZ d  d¡ „  Z[ eU d¢ d£ „  ƒ Z\ eU d¤ d¥ „  ƒ Z] eU d¦ d§ „  ƒ Z^ eU d d¨ d© „ ƒ Z_ dª d« „  Z` d¬ d­ „  Za d® d¯ „  Zb d° d± „  Zc d² d³ „  Zd d´ dµ „  Ze d¶ d· „  Zf d¸ d¹ „  Zg dº d» „  Zh d¼ d½ „  Zi d¾ d¿ „  Zj dÀ dÁ „  Zk dÂ dÃ „  Zl dÄ dÅ „  Zm dÆ dÇ „  Zn d S)ÉÚCodeGeneratorNFTc             C   s	  | d  k r t  ƒ  } | |  _ | |  _ | |  _ | |  _ d |  _ | |  _ | |  _ | ri t | ƒ |  _	 i  |  _
 i  |  _ d |  _ d |  _ d |  _ i  |  _ i  |  _ g  |  _ d  |  _ d |  _ d |  _ d |  _ d |  _ d |  _ g  |  _ g  |  _ d g |  _ d  S)NFr   r   TÚcontext)r   r9   r:   r;   r7   Zcreated_block_contextr<   r&   r   r)   Úimport_aliasesÚblocksÚextends_so_farÚhas_known_extendsÚcode_linenort   rs   Ú
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   Úfail<  s    zCodeGenerator.failc             C   s   |  j  d 7_  d |  j  S)zGet a new unique identifier.r   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   E  s    zCodeGenerator.bufferc             C   s¼   | s¤ | j  j r€ |  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_contentsJ  s    



z$CodeGenerator.return_buffer_contentsc             C   s   |  j  d 7_  d S)zIndent by one.r   N)rŒ   )r+   r0   r0   r1   r•   \  s    zCodeGenerator.indentr   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_writed  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_writek  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_writep  s    zCodeGenerator.simple_writec             C   sK   y2 |  j  d ƒ x | D] } |  j | | ƒ q WWn t k
 rF Yn Xd S)z•Visit 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   Ú
blockvisitv  s    zCodeGenerator.blockvisitc             C   s¬   |  j  r˜ |  j so |  j j d |  j  ƒ |  j |  j  7_ |  j d k	 ro |  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   sS   t  |  j d | ƒ |  _ | d k	 rO | j |  j k rO | j |  _ | j |  _ d S)z/Add one or more newlines before the next write.r   N)Úmaxrˆ   r‘   r‰   r‡   )r+   r,   r§   r0   r0   r1   r¦   ”  s    zCodeGenerator.newlinec       	      C   sV  d } x@ t  d d „  | j Dƒ | p( f  ƒ D] } t | ƒ r, d } Pq, Wx. | j D]# } |  j d ƒ |  j | | ƒ qS W| sñ x. | j D]# } |  j d ƒ |  j | | ƒ qŠ W| d k	 rñ x1 t | ƒ D]# \ } } |  j d | | f ƒ qÊ W| j r|  j d ƒ |  j | j | ƒ | r#| j d k	 r?|  j d	 ƒ n |  j d
 ƒ xE | j D]: } |  j d | j	 ƒ |  j | j
 | ƒ |  j d ƒ qVW| d k	 rÔx1 t | ƒ D]# \ } } |  j d | | f ƒ q­W| j d k	 r|  j d ƒ |  j | j | ƒ |  j d ƒ qR|  j d ƒ n/ | j d k	 rR|  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 occur.  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_workaroundZkwargÚargrN   rL   r0   r0   r1   Ú	signature›  sJ    	,	zCodeGenerator.signaturec             C   sŸ   t  ƒ  } x | D] } | j | ƒ q Wxq d D]i } t |  | ƒ } xQ t | | ƒ D]@ } | | k ru |  j ƒ  | | <|  j d | | | | f ƒ qS Wq. Wd S)zPull all the dependencies.rs   rt   z%s = environment.%s[%r]N)rs   rt   )rr   r*   Úgetattrr“   r”   )r+   r	   rS   r,   Ú
dependencyÚmappingr:   r0   r0   r1   Úpull_dependenciesÐ  s    	zCodeGenerator.pull_dependenciesc             C   sß   g  } x² t  | j j ƒ D]ž \ } \ } } | t k r: q | t k ri |  j d | |  j ƒ  | f ƒ q | t k r� |  j d | | f ƒ q | t k r« | 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   s`   | s\ g  } x- t  | j j ƒ D] \ } } | j | ƒ q W| r\ |  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 | Sd | 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  } xm t | j ƒ D]\ \ } } | j d k rn | } | j d k r� | j | j ƒ | j	 | j j
 | j ƒ ƒ qM Wt | j d ƒ }	 d |	 k r@| d k	 ry | j | t | j ƒ Wq7t k
 r|  j d | j ƒ Yq7Xn | j	 | j j d ƒ ƒ d | _ d |	 k rzd | k rz| j	 | j j d ƒ ƒ d | _ d |	 k r´d | k r´| j	 | j j d ƒ ƒ d | _ d | _ | j j | ƒ |  j d |  j d	 ƒ d
 j | ƒ f | ƒ |  j ƒ  |  j | ƒ |  j | ƒ |  j | ƒ xÜ t | j ƒ D]Ë \ } } | j j
 | j ƒ }
 |  j d |
 ƒ |  j ƒ  y | j | t | j ƒ } Wn6 t k
 rÌ|  j d |
 d | j | j f ƒ Yn" X|  j d |
 ƒ |  j | | ƒ |  j |
 ƒ |  j  ƒ  q:W|  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Ä   )%rn   r_   Úanalyze_noderU   rH   Ú	enumerater­   r:   rv   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 rY | 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ª   M  s    z*CodeGenerator.macro_def.<locals>.<genexpr>r:   Nr   ú,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_defK  s    "
zCodeGenerator.macro_defc             C   s7   d | j  } |  j d k	 r3 | 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   Úposition]  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ª   f  s   z3CodeGenerator.dump_local_context.<locals>.<genexpr>)r¸   r   r_   Zdump_stores)r+   r-   r0   r0   r1   Údump_local_contextd  s    		z CodeGenerator.dump_local_contextc             C   s8   |  j  d ƒ |  j  d ƒ |  j  d ƒ |  j  d ƒ d S)z·Writes 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cond_expr_undefined = Undefinedzif 0: yield NoneN)r”   )r+   r0   r0   r1   Úwrite_commonsj  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Î   v  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Ð     s    z'CodeGenerator.pop_parameter_definitionsc             C   s!   |  j  r |  j  d j | ƒ d S)z€Marks a parameter in the current parameter definitions as stored.
        This will skip the enforced undefined checks.
        r   Néÿÿÿÿ)rŽ   r|   )r+   rº   r0   r0   r1   rÏ   ƒ  s    	z#CodeGenerator.mark_parameter_storedc             C   s   |  j  j | ƒ d  S)N)r�   r¤   )r+   rº   r0   r0   r1   Úpush_context_referenceŠ  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)Nr   rÜ   )r�   )r+   r0   r0   r1   Úget_context_ref�  s    zCodeGenerator.get_context_refc             C   s%   |  j  d } | d k r d Sd | S)Nr   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.Fr   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   sQ  |  j  j ƒ  } | j s  | r$ d Sd d „  | Dƒ } t | ƒ d k r‡ t t | ƒ ƒ } | j j | ƒ } |  j d | | f ƒ ns |  j d ƒ xV t	 | ƒ D]H \ } } | rÀ |  j
 d ƒ | j j | ƒ } |  j
 d | | f ƒ q¡ W|  j
 d	 ƒ | rMt | ƒ 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)Nr   r¿   r0   )r©   r¥   r0   r0   r1   ú
<listcomp>°  s   	 z5CodeGenerator.pop_assign_tracking.<locals>.<listcomp>r   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   s3  | d  k s t  d ƒ ‚ t |  j |  j ƒ } d d l m } |  j d d j t ƒ ƒ |  j d d j | ƒ ƒ |  j j	 rŠ |  j d ƒ |  j
 rš d p� d	 } | j t j ƒ d  k	 } xV | j t j ƒ D]B } | j |  j k rý |  j d
 | j | j ƒ | |  j | j <qË Wx¤ | j t j ƒ D]� } | j |  j k r$| j }	 |  j ƒ  |  j |	 <}
 d |	 k r�|	 j d d ƒ \ } } |  j d | | |
 f ƒ q$|  j d |	 |
 f ƒ q$W|  j d |  j ƒ |  j d |  j d ƒ | f d d ƒ|  j ƒ  |  j ƒ  t | ƒ } d t | j d% ƒ k rM| j j d ƒ } |  j d | ƒ | j j  | ƒ d | _! | _" | oz|  j# | _$ | r“|  j d ƒ |  j% | ƒ |  j& | j ƒ |  j' | j | ƒ |  j( | d d ƒ|  j) ƒ  | rŒ|  j# s|  j ƒ  |  j d ƒ |  j ƒ  t* r3|  j j	 r3|  j d ƒ nD |  j d |  j j	 rNd pQd	 ƒ |  j ƒ  |  j d ƒ |  j) ƒ  |  j) d |  j# ƒ xFt+ |  j ƒ D]5\ } } |  j d |  j d | ƒ | f | d ƒ |  j ƒ  |  j ƒ  t | ƒ } t | j d& ƒ } d | k r3| j j d ƒ } |  j d | ƒ d | k rk| j j d ƒ } |  j d | | | f ƒ | j j  | ƒ | | _, |  j% | ƒ |  j& | j ƒ |  j' | j | ƒ |  j( | d d ƒ|  j) ƒ  qœW|  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   )Úexportedzfrom __future__ import %sz, zfrom jinja2.runtime import zHfrom jinja2.asyncsupport import auto_await, auto_aiter, AsyncLoopContextz, environment=environmentÚ zblock %r defined twiceÚ.zfrom %s import %s as %szimport %s as %sz	name = %rz%s(context, missing=missing%s):Úrootr§   r+   z%s = TemplateReference(context)Tzparent_template = Noner¾   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ª   A  s    )r+   )r+   rí   ).ÚAssertionErrorr   r9   r:   Z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'   ré   Z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  rL |  j r d S|  j d k rL |  j d ƒ |  j ƒ  | d 7} | j rg |  j | ƒ } n |  j ƒ  } t rµ |  j	 j
 rµ | j d k rµ |  j d | j | f | ƒ n\ |  j	 j
 rÇ d pÊ d } |  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:r   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   ry   D  s0    		

	

zCodeGenerator.visit_Blockc             C   s	  | j  s |  j d | j ƒ |  j d k r{ |  j sK |  j d ƒ |  j ƒ  |  j d d ƒ |  j rq t ƒ  ‚ n
 |  j ƒ  |  j d | ƒ |  j	 | j
 | ƒ |  j d |  j ƒ |  j d t ƒ |  j ƒ  |  j d	 ƒ |  j ƒ  | j rö d
 |  _ |  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)Tr   N)r`   r’   r‘   rƒ   r„   r”   r•   r~   r–   r*   Útemplater�   r:   Údict_item_iterra   )r+   r,   r-   r0   r0   r1   Úvisit_Extendsj  s*    		
	


		zCodeGenerator.visit_Extendsc             C   s  | j  r  |  j d ƒ |  j ƒ  d } t | j t j ƒ r} t | j j t ƒ rY d } q¡ t | j j t	 t
 f ƒ r¡ d } n$ t | j t j t j f ƒ r¡ d } |  j d | | ƒ |  j | j | ƒ |  j d |  j ƒ | j  r4|  j ƒ  |  j d ƒ |  j ƒ  |  j d ƒ |  j ƒ  |  j d	 ƒ |  j ƒ  d
 } | j r~|  j j rUd pXd } |  j d | |  j | ƒ f ƒ nE |  j j rš|  j d ƒ n) t r¶|  j d ƒ d } n |  j d ƒ | sí|  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   ZTupleZListr*   r�   r:   r–   Úwith_contextr9   rÁ   rÙ   rõ   r    )r+   r,   r-   Ú	func_nameZskip_event_yieldr   r0   r0   r1   Úvisit_Include—  sT    	
			



	
	

	zCodeGenerator.visit_Includec             C   s(  |  j  d | j j | j ƒ | ƒ | j r@ |  j d | j ƒ |  j j rY |  j d ƒ |  j d ƒ |  j | j	 | ƒ |  j d |  j
 ƒ | j rË |  j d |  j j r± d p´ d |  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 r• |  j d |  j j r{ d 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 | ƒ qÔ W| r<t | ƒ d k r| d } |  j d | ˆ  j j | ƒ f ƒ n- |  j d d j ‡  f d d †  | Dƒ ƒ ƒ | r�t | ƒ d k rl|  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¿   r   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ê  sf    	

	
 zCodeGenerator.visit_FromImportc             C   s•  | j  ƒ  } | j  ƒ  } | j  ƒ  } | j pK d t | j d d% ƒ d& ƒ k } d  } | rl | j j d ƒ } | j j | d d ƒ| j r¡ | j j | d d ƒ| j rõ|  j	 ƒ  } | j j | d d ƒ|  j
 d |  j | ƒ | j ƒ |  j ƒ  |  j | ƒ |  j
 |  j j rd pd	 ƒ |  j | j | ƒ |  j d
 ƒ |  j |  j j rZd p]d ƒ |  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 | _ | rU|  j
 d | ƒ xK | j t j ƒ D]7 }	 |	 j d k rh|	 j d k rh|  j d |	 j ƒ qhW| j rÉ|  j	 ƒ  }
 |  j
 d |
 ƒ |  j
 |  j j rád päd	 | ƒ |  j | j | ƒ | r8|  j j r$|  j d | ƒ qE|  j d | ƒ n |  j d
 ƒ | j r_|  j d | ƒ | j rx|  j d ƒ nS |  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 rW|  j
 d  |
 ƒ |  j ƒ  |  j | d | j o}| j ƒ| j rÜ|  j
 d! |
 ƒ |  j ƒ  |  j | ƒ |  j | j | ƒ |  j | ƒ |  j ƒ  | j r‘|  j  | ƒ |  j ƒ  |  j! | | ƒ |  j j r%|  j d" ƒ |  j d# ƒ |  j j rK|  j d ƒ |  j | j | ƒ |  j j rw|  j d ƒ |  j d$ ƒ |  j" | ƒ d  S)'Nr   ÚonlyrÉ   Z
for_branchÚelseÚtestz
%s(fiter):z
async for zfor z in zauto_aiter(fiter)Zfiterú:zif zyield é   r¾   Tz'%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 AsyncLoopContext(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   )#rn   Ú	recursiverT   Z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_For5  sÂ    		 


	
	"				
	
	

	
zCodeGenerator.visit_Forc             C   s  | j  ƒ  } |  j d | ƒ |  j | j | ƒ |  j d ƒ |  j ƒ  |  j | j | ƒ |  j ƒ  xh | j	 D]] } |  j d | ƒ |  j | j | ƒ |  j d ƒ |  j ƒ  |  j | j | ƒ |  j ƒ  qm W| j
 r|  j d ƒ |  j ƒ  |  j | j
 | ƒ |  j ƒ  d  S)Nzif r  zelif zelse:)ro   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 re | j j d ƒ sQ |  j d | 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Ñ   r0   r0   r1   Úvisit_MacroÐ  s    
	 zCodeGenerator.visit_Macroc             C   so   |  j  | | ƒ \ } } |  j d ƒ |  j | | ƒ |  j | | ƒ |  j | j | d d ƒ|  j | ƒ d  S)Nz	caller = Úforward_callerT)rÔ   r”   r×   r›   Ú
visit_CallÚcallrž   )r+   r,   r-   Z
call_framerÑ   r0   r0   r1   Úvisit_CallBlockÚ  s    zCodeGenerator.visit_CallBlockc             C   sŠ   | j  ƒ  } | j j | ƒ |  j | ƒ |  j | ƒ |  j | j | ƒ |  j | | ƒ |  j | j	 | ƒ |  j
 | ƒ |  j | ƒ d  S)N)rn   r_   rÆ   r½   rc   r¢   rÉ   r›   rw   Úfilterrž   rÀ   )r+   r,   r-   Zfilter_framer0   r0   r1   Úvisit_FilterBlockâ  s    zCodeGenerator.visit_FilterBlockc             C   sª   | j  ƒ  } | j j | ƒ |  j | ƒ xZ t | j | j ƒ D]C \ } } |  j ƒ  |  j | | ƒ |  j	 d ƒ |  j | | ƒ q? W|  j
 | j | ƒ |  j | ƒ d  S)Nz = )rn   r_   rÆ   r½   r   ÚtargetsÚvaluesr¦   r*   r�   r¢   rÉ   rÀ   )r+   r,   r-   Z
with_framerº   Ú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_ExprStmtÚ_FinalizeInfoÚconstÚsrcc                s  ˆ j  d k	 r ˆ j  Sˆ j } ‰  d } ˆ j j rì d } ˆ j j ‰ ‡  ‡ f d d †  } t ˆ d d ƒ d k r‡ | d 7} d } ne t ˆ d	 d ƒ d k r² | d
 7} d } n: t ˆ d d ƒ d k rì | d 7} ‡  ‡ ‡ f d d †  } ˆ j | | ƒ ˆ _  ˆ j  S)a‰  Build the finalize function to be used on constants and at
        runtime. Cached so it's only created once for all output nodes.

        Returns a ``namedtuple`` with the following attributes:

        ``const``
            A function to finalize constant data at compile time.

        ``src``
            Source code to output around nodes to be evaluated at
            runtime.
        Nzenvironment.finalize(c                s   ˆ  ˆ |  ƒ ƒ S)Nr0   )rL   )rÓ   Úenv_finalizer0   r1   Úfinalize  s    z.CodeGenerator._make_finalize.<locals>.finalizeZcontextfunctionFTz	context, Zevalcontextfunctionzcontext.eval_ctx, Zenvironmentfunctionzenvironment, c                s   ˆ  ˆ ˆ j  |  ƒ ƒ S)N)r9   )rL   )rÓ   r&  r+   r0   r1   r'  '  s    )Ú	_finalizeÚ_default_finalizer9   r'  r±   r#  )r+   r'  r%  r0   )rÓ   r&  r+   r1   Ú_make_finalize  s&    
	
	
zCodeGenerator._make_finalizec             C   s   t  t | ƒ ƒ S)z™Given a group of constant values converted from ``Output``
        child nodes, produce a string to write to the template module
        source.
        )rÕ   r   )r+   Úgroupr0   r0   r1   Ú_output_const_repr-  s    z CodeGenerator._output_const_reprc             C   sS   | j  | j ƒ } | j j r* t | ƒ } t | t j ƒ rF t | ƒ S| j | ƒ S)aC  Try to optimize a child of an ``Output`` node by trying to
        convert it to constant, finalized data at compile time.

        If :exc:`Impossible` is raised, the node is not constant and
        will be evaluated at runtime. Any other exception will also be
        evaluated at runtime for easier debugging.
        )	Úas_constr'   r—   r   r4   r	   ÚTemplateDatar   r$  )r+   r,   r-   r'  r$  r0   r0   r1   Ú_output_child_to_const4  s    
z$CodeGenerator._output_child_to_constc             C   sh   | j  j r |  j d ƒ n) | j  j r8 |  j d ƒ n |  j d ƒ | j d k	 rd |  j | j ƒ d S)zXOutput extra source code before visiting a child of an
        ``Output`` node.
        z7(escape if context.eval_ctx.autoescape else to_string)(zescape(z
to_string(N)r'   r(   r�   r—   r%  )r+   r,   r-   r'  r0   r0   r1   Ú_output_child_preG  s    zCodeGenerator._output_child_prec             C   s-   |  j  d ƒ | j d k	 r) |  j  d ƒ d S)zWOutput extra source code after visiting a child of an
        ``Output`` node.
        rœ   N)r�   r%  )r+   r,   r-   r'  r0   r0   r1   Ú_output_child_postU  s    z CodeGenerator._output_child_postc       	      C   s�  | j  r- |  j r d  S|  j d ƒ |  j ƒ  |  j ƒ  } g  } x¼ | j D]± } y@ | j pj t | t j ƒ sy t j	 ƒ  ‚ |  j
 | | | ƒ } Wn+ t j	 t f k
 r¼ | j | ƒ wI Yn X| rê t | d	 t ƒ rê | d
 j | ƒ qI | j | g ƒ qI W| j d  k	 rTt | ƒ d k r6|  j d | j ƒ n |  j d | j ƒ |  j ƒ  xä | D]Ü } t | t ƒ r¶|  j | ƒ } | j d  k r¢|  j d | ƒ q7|  j | d ƒ q[| j d  k rØ|  j d | ƒ n |  j | ƒ |  j | | | ƒ |  j | | ƒ |  j | | | ƒ | j d  k	 r[|  j d ƒ q[W| j d  k	 ry|  j ƒ  |  j t | ƒ d k rrd n d ƒ | j  rŒ|  j ƒ  d  S)Nzif parent_template is None:r   z
%s.append(z%s.extend((zyield rÖ   rœ   z))rÜ   rÜ   )rb   r„   r”   r•   r*  r	   r$  r4   r.  Ú
Impossibler/  Ú	Exceptionr¤   rG   rc   rË   r,  r¦   r0  r*   r1  r�   r–   )	r+   r,   r-   r'  rÉ   Úchildr$  rM   Úvalr0   r0   r1   Úvisit_Output^  sV    		
	

%	zCodeGenerator.visit_Outputc             C   s[   |  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_Assign­  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ã   rn   rb   r_   rÆ   r½   rc   r¢   rÉ   r¦   r*   rº   r�   r  rw   rè   rÀ   )r+   r,   r-   rû   r0   r0   r1   Úvisit_AssignBlockµ  s     
	zCodeGenerator.visit_AssignBlockc             C   sÌ   | j  d k r8 | j r8 |  j r8 |  j d j | j ƒ | j j | j ƒ } | j  d k r» | j j | ƒ } | d  k	 o— | d t k o— |  j	 | ƒ s» |  j
 d | j | | f ƒ d  S|  j
 | ƒ d  S)Nr  r   rz   r   z-(undefined(name=%r) if %s is missing else %s)rÜ   )r{   r`   r�   rv   r:   r_   rÈ   Z	find_loadr   râ   r�   )r+   r,   r-   rÈ   rz   r0   r0   r1   r}   Í  s    	zCodeGenerator.visit_Namec             C   si   | 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   sN   | j  | j ƒ } t | t ƒ r7 |  j t | ƒ ƒ n |  j t | ƒ ƒ d  S)N)r-  r'   r4   rD   r�   ÚstrrÕ   )r+   r,   r-   r5  r0   r0   r1   Úvisit_Constó  s    zCodeGenerator.visit_Constc             C   sS   y# |  j  t | j | j ƒ ƒ ƒ Wn) t j k
 rN |  j  d | j ƒ Yn Xd  S)Nz9(Markup if context.eval_ctx.autoescape else identity)(%r))r�   rÕ   r-  r'   r	   r2  Údata)r+   r,   r-   r0   r0   r1   Úvisit_TemplateDataú  s
    #z CodeGenerator.visit_TemplateDatac             C   sy   |  j  d ƒ d } x@ t | j ƒ D]/ \ } } | rB |  j  d ƒ |  j | | ƒ q# W|  j  | d k rn d pq d ƒ d  S)Nú(r   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   sa   |  j  d ƒ x@ t | 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   s„   |  j  d ƒ xc t | j ƒ D]R \ } } | 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 re ˆ  |  j  j k re |  j d ˆ  ƒ |  j | j | ƒ |  j d ƒ |  j | j | ƒ nD |  j d ƒ |  j | j | ƒ |  j d ˆ  ƒ |  j | j | ƒ |  j d ƒ d  S)Nz$environment.call_binop(context, %r, z, r?  z %s rœ   )r9   Ú	sandboxedZintercepted_binopsr�   r*   ÚleftÚright)r+   r,   r-   )Úoperatorr0   r1   rS     s    z$CodeGenerator.binop.<locals>.visitor)r3   )rI  ÚinterceptablerS   r0   )rI  r1   Úbinop  s    zCodeGenerator.binopc                s   t  ‡  f d d †  ƒ } | S)Nc                sz   |  j  j rE ˆ  |  j  j k rE |  j d ˆ  ƒ |  j | j | ƒ n$ |  j d ˆ  ƒ |  j | j | ƒ |  j d ƒ d  S)Nz#environment.call_unop(context, %r, r?  rœ   )r9   rF  Zintercepted_unopsr�   r*   r,   )r+   r,   r-   )rI  r0   r1   rS   2  s    z#CodeGenerator.uaop.<locals>.visitor)r3   )rI  rJ  rS   r0   )rI  r1   Úuaop1  s    zCodeGenerator.uaopú+ú-Ú*ú/z//z**ú%ÚandrJ  Úorznot c             C   sƒ   | j  j r d } n | j  j r* d } n d } |  j d | ƒ x. | j D]# } |  j | | ƒ |  j d ƒ qK W|  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_ConcatO  s    		zCodeGenerator.visit_Concatc             C   sU   |  j  d ƒ |  j | j | ƒ x! | j D] } |  j | | ƒ q* W|  j  d ƒ d  S)Nr?  rœ   )r�   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�   Ú	operatorsrV  r*   r   )r+   r,   r-   r0   r0   r1   Úvisit_Operande  s    zCodeGenerator.visit_Operandc             C   sj   |  j  j r |  j d ƒ |  j d ƒ |  j | j | ƒ |  j d | j ƒ |  j  j rf |  j d ƒ d  S)Nz(await auto_await(zenvironment.getattr(z, %r)z)))r9   rÁ   r�   r*   r,   r9  )r+   r,   r-   r0   r0   r1   Úvisit_Getattri  s    zCodeGenerator.visit_Getattrc             C   sÛ   t  | j t j ƒ rX |  j | j | ƒ |  j d ƒ |  j | j | ƒ |  j d ƒ n |  j j rq |  j d ƒ |  j d ƒ |  j | j | ƒ |  j d ƒ |  j | j | ƒ |  j d ƒ |  j j r× |  j d ƒ d  S)NrA  rB  z(await auto_await(zenvironment.getitem(z, rœ   z)))	r4   r¯   r	   ZSlicer*   r,   r�   r9   rÁ   )r+   r,   r-   r0   r0   r1   Úvisit_Getitemu  s    zCodeGenerator.visit_Getitemc             C   s„   | j  d  k	 r" |  j | j  | ƒ |  j d ƒ | j d  k	 rQ |  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 rr |  j d | j | j ƒ t | d d ƒ d k rš |  j d ƒ nM t | d d ƒ d k rÂ |  j d	 ƒ n% t | d
 d ƒ d k rç |  j d ƒ | j	 d  k	 r|  j
 | j	 | ƒ nc | j j r8|  j d | j | j f ƒ n7 | j j r[|  j d | j ƒ n |  j d | j ƒ |  j | | ƒ |  j d ƒ |  j  j r¥|  j d ƒ d  S)Nzawait auto_await(r?  zno filter named %rZcontextfilterFTz	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�   rs   r:   Úgetr’   r‘   r±   r,   r*   r'   r(   rc   r—   r°   )r+   r,   r-   rÂ   r0   r0   r1   rw   ”  s2    zCodeGenerator.visit_Filterc             C   s~   |  j  |  j | j d ƒ | j |  j j k rJ |  j d | j | j ƒ |  j | j | ƒ |  j | | ƒ |  j  d ƒ d  S)Nr?  zno test named %rrœ   )	r�   rt   r:   r9   r’   r‘   r*   r,   r°   )r+   r,   r-   r0   r0   r1   rx   µ  s    zCodeGenerator.visit_Testc                s}   ‡  ‡ ‡ f d d †  } ˆ j  d ƒ ˆ j ˆ j ˆ  ƒ ˆ j  d ƒ ˆ j ˆ j ˆ  ƒ ˆ j  d ƒ | ƒ  ˆ j  d ƒ d  S)Nc                  sD   ˆ j  d  k	 r" ˆ j ˆ j  ˆ  ƒ Sˆ j d d ˆ j ˆ ƒ ƒ d  S)Nzcond_expr_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_expr2À  s    z1CodeGenerator.visit_CondExpr.<locals>.write_expr2r?  z if z else rœ   )r�   r*   Zexpr1r  )r+   r,   r-   r`  r0   )r-   r,   r+   r1   Úvisit_CondExpr¾  s    zCodeGenerator.visit_CondExprc             C   sª   |  j  j r |  j d ƒ |  j  j r5 |  j d ƒ n |  j d ƒ |  j | j | ƒ | rg d d i pj d  } |  j | | | ƒ |  j d ƒ |  j  j r¦ |  j d ƒ d  S)Nzawait auto_await(zenvironment.call(context, zcontext.call(rÃ   rœ   )r9   rÁ   r�   rF  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_Keywordã  s    zCodeGenerator.visit_Keywordc             C   s1   |  j  d ƒ |  j | j | ƒ |  j  d ƒ d  S)NzMarkup(rœ   )r�   r*   r   )r+   r,   r-   r0   r0   r1   Úvisit_MarkSafeé  s    zCodeGenerator.visit_MarkSafec             C   s1   |  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_MarkSafeIfAutoescapeî  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  |  j | ƒ ƒ d  S)N)r�   rá   )r+   r,   r-   r0   r0   r1   Úvisit_DerivedContextReference  s    z+CodeGenerator.visit_DerivedContextReferencec             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   sM   | j  ƒ  } | j j | ƒ |  j | ƒ |  j | j | ƒ |  j | ƒ d  S)N)rn   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 = rm   T)r“   r”   rá   r*   r€   rÝ   rn   r_   rÆ   r½   r¢   rÉ   rÀ   rÞ   )r+   r,   r-   r{   rq  r0   r0   r1   Úvisit_OverlayScope  s     z CodeGenerator.visit_OverlayScopec             C   s’   x‹ | j  D]€ } |  j d | j ƒ |  j | j | ƒ y | j j | j ƒ } Wn! t j k
 rs d | j _	 Yq
 Xt
 | j | j | ƒ q
 Wd  S)Nzcontext.eval_ctx.%s = T)Úoptionsr”   rN   r*   rL   r-  r'   r	   r2  r(   Úsetattr)r+   r,   r-   Úkeywordr5  r0   r0   r1   Úvisit_EvalContextModifier   s    z'CodeGenerator.visit_EvalContextModifierc             C   s…   |  j  ƒ  } | j j ƒ  } |  j d | ƒ |  j | | ƒ x! | j D] } |  j | | ƒ qF W| j j | ƒ |  j d | ƒ d  S)Nz%s = context.eval_ctx.save()zcontext.eval_ctx.revert(%s))r“   r'   Úsaver”   rw  rÉ   r*   Úrevert)r+   r,   r-   Zold_ctx_nameZ	saved_ctxr4  r0   r0   r1   Úvisit_ScopedEvalContextModifier+  s    z-CodeGenerator.visit_ScopedEvalContextModifier)r$  r%  )orZ   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ü   ry   r  r  r	  r
  r  r  r  r  r  r!  r"  r   r#  r   r)  r(  r*  r,  r/  r0  r1  r6  r7  r8  r}   r:  r<  r>  r@  rC  rE  rK  rL  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   rT  rW  rY  rZ  r[  r^  rw   rx   ra  r  rc  rd  re  rf  rh  ri  rj  rk  rl  rn  rp  rr  rs  rw  rz  r0   r0   r0   r1   r   ÷   sÖ   C5P	|&-:K†
)	O	

!	r   )=rp   Úcollectionsr   Ú	functoolsr   Ú	itertoolsr   rv  r   r¬   Z
markupsafer   r   rê   r	   Ú_compatr
   r   r   r   r   r   r   Ú
exceptionsr   Z
idtrackingr   r   r   r   r   r   r)   r   Úutilsr   rS   r   rX  ÚhasattrrK   r  rð   Úexecr¤   ÚSyntaxErrorrõ   r3   r>   rJ   rT   rf   rU   r]   ÚRuntimeErrorrP   rr   rO   r3  r~   r   r0   r0   r0   r1   Ú<module>   sr   		
=