1# -*- coding: utf-8 -*- 2""" 3 jinja2.optimizer 4 ~~~~~~~~~~~~~~~~ 5 6 The jinja optimizer is currently trying to constant fold a few expressions 7 and modify the AST in place so that it should be easier to evaluate it. 8 9 Because the AST does not contain all the scoping information and the 10 compiler has to find that out, we cannot do all the optimizations we 11 want. For example loop unrolling doesn't work because unrolled loops would 12 have a different scoping. 13 14 The solution would be a second syntax tree that has the scoping rules stored. 15 16 :copyright: (c) 2017 by the Jinja Team. 17 :license: BSD. 18""" 19from jinja2 import nodes 20from jinja2.visitor import NodeTransformer 21 22 23def optimize(node, environment): 24 """The context hint can be used to perform an static optimization 25 based on the context given.""" 26 optimizer = Optimizer(environment) 27 return optimizer.visit(node) 28 29 30class Optimizer(NodeTransformer): 31 32 def __init__(self, environment): 33 self.environment = environment 34 35 def fold(self, node, eval_ctx=None): 36 """Do constant folding.""" 37 node = self.generic_visit(node) 38 try: 39 return nodes.Const.from_untrusted(node.as_const(eval_ctx), 40 lineno=node.lineno, 41 environment=self.environment) 42 except nodes.Impossible: 43 return node 44 45 visit_Add = visit_Sub = visit_Mul = visit_Div = visit_FloorDiv = \ 46 visit_Pow = visit_Mod = visit_And = visit_Or = visit_Pos = visit_Neg = \ 47 visit_Not = visit_Compare = visit_Getitem = visit_Getattr = visit_Call = \ 48 visit_Filter = visit_Test = visit_CondExpr = fold 49 del fold 50