From 89198c864831bea0a17f136b897aebc59f606166 Mon Sep 17 00:00:00 2001 From: Stefanie Nobel Date: Fri, 24 Jun 2011 17:50:36 +0000 Subject: initial commit --- (limited to 'jinja2/optimizer.py') diff --git a/jinja2/optimizer.py b/jinja2/optimizer.py new file mode 100644 index 0000000..00eab11 --- /dev/null +++ b/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 -- cgit v0.9.1