| Index: third_party/jinja2/optimizer.py
|
| diff --git a/third_party/jinja2/optimizer.py b/third_party/jinja2/optimizer.py
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..00eab115e1c19a86bb1ec64b7cf626fbf413e126
|
| --- /dev/null
|
| +++ b/third_party/jinja2/optimizer.py
|
| @@ -0,0 +1,68 @@
|
| +# -*- coding: utf-8 -*-
|
| +"""
|
| + jinja2.optimizer
|
| + ~~~~~~~~~~~~~~~~
|
| +
|
| + The jinja optimizer is currently trying to constant fold a few expressions
|
| + and modify the AST in place so that it should be easier to evaluate it.
|
| +
|
| + Because the AST does not contain all the scoping information and the
|
| + compiler has to find that out, we cannot do all the optimizations we
|
| + want. For example loop unrolling doesn't work because unrolled loops would
|
| + have a different scoping.
|
| +
|
| + The solution would be a second syntax tree that has the scoping rules stored.
|
| +
|
| + :copyright: (c) 2010 by the Jinja Team.
|
| + :license: BSD.
|
| +"""
|
| +from jinja2 import nodes
|
| +from jinja2.visitor import NodeTransformer
|
| +
|
| +
|
| +def optimize(node, environment):
|
| + """The context hint can be used to perform an static optimization
|
| + based on the context given."""
|
| + optimizer = Optimizer(environment)
|
| + return optimizer.visit(node)
|
| +
|
| +
|
| +class Optimizer(NodeTransformer):
|
| +
|
| + def __init__(self, environment):
|
| + self.environment = environment
|
| +
|
| + def visit_If(self, node):
|
| + """Eliminate dead code."""
|
| + # do not optimize ifs that have a block inside so that it doesn't
|
| + # break super().
|
| + if node.find(nodes.Block) is not None:
|
| + return self.generic_visit(node)
|
| + try:
|
| + val = self.visit(node.test).as_const()
|
| + except nodes.Impossible:
|
| + return self.generic_visit(node)
|
| + if val:
|
| + body = node.body
|
| + else:
|
| + body = node.else_
|
| + result = []
|
| + for node in body:
|
| + result.extend(self.visit_list(node))
|
| + return result
|
| +
|
| + def fold(self, node):
|
| + """Do constant folding."""
|
| + node = self.generic_visit(node)
|
| + try:
|
| + return nodes.Const.from_untrusted(node.as_const(),
|
| + lineno=node.lineno,
|
| + environment=self.environment)
|
| + except nodes.Impossible:
|
| + return node
|
| +
|
| + visit_Add = visit_Sub = visit_Mul = visit_Div = visit_FloorDiv = \
|
| + visit_Pow = visit_Mod = visit_And = visit_Or = visit_Pos = visit_Neg = \
|
| + visit_Not = visit_Compare = visit_Getitem = visit_Getattr = visit_Call = \
|
| + visit_Filter = visit_Test = visit_CondExpr = fold
|
| + del fold
|
|
|