You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
50 lines
1.7 KiB
Python
50 lines
1.7 KiB
Python
8 years ago
|
# -*- 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) 2017 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 fold(self, node, eval_ctx=None):
|
||
|
"""Do constant folding."""
|
||
|
node = self.generic_visit(node)
|
||
|
try:
|
||
|
return nodes.Const.from_untrusted(node.as_const(eval_ctx),
|
||
|
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
|