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