~brad-marshall/charms/trusty/apache2-wsgi/fix-haproxy-relations

« back to all changes in this revision

Viewing changes to hooks/lib/jinja2/optimizer.py

  • Committer: Robin Winslow
  • Date: 2014-05-27 14:00:44 UTC
  • Revision ID: robin.winslow@canonical.com-20140527140044-8rpmb3wx4djzwa83
Add all files

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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