OLD | NEW |
| (Empty) |
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) 2010 by the Jinja Team. | |
17 :license: BSD. | |
18 """ | |
19 from jinja2 import nodes | |
20 from jinja2.visitor import NodeTransformer | |
21 | |
22 | |
23 def 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 | |
30 class Optimizer(NodeTransformer): | |
31 | |
32 def __init__(self, environment): | |
33 self.environment = environment | |
34 | |
35 def visit_If(self, node): | |
36 """Eliminate dead code.""" | |
37 # do not optimize ifs that have a block inside so that it doesn't | |
38 # break super(). | |
39 if node.find(nodes.Block) is not None: | |
40 return self.generic_visit(node) | |
41 try: | |
42 val = self.visit(node.test).as_const() | |
43 except nodes.Impossible: | |
44 return self.generic_visit(node) | |
45 if val: | |
46 body = node.body | |
47 else: | |
48 body = node.else_ | |
49 result = [] | |
50 for node in body: | |
51 result.extend(self.visit_list(node)) | |
52 return result | |
53 | |
54 def fold(self, node): | |
55 """Do constant folding.""" | |
56 node = self.generic_visit(node) | |
57 try: | |
58 return nodes.Const.from_untrusted(node.as_const(), | |
59 lineno=node.lineno, | |
60 environment=self.environment) | |
61 except nodes.Impossible: | |
62 return node | |
63 | |
64 visit_Add = visit_Sub = visit_Mul = visit_Div = visit_FloorDiv = \ | |
65 visit_Pow = visit_Mod = visit_And = visit_Or = visit_Pos = visit_Neg = \ | |
66 visit_Not = visit_Compare = visit_Getitem = visit_Getattr = visit_Call = \ | |
67 visit_Filter = visit_Test = visit_CondExpr = fold | |
68 del fold | |
OLD | NEW |