optimizer.py 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849
  1. # -*- coding: utf-8 -*-
  2. """
  3. jinja2.optimizer
  4. ~~~~~~~~~~~~~~~~
  5. The jinja optimizer is currently trying to constant fold a few expressions
  6. and modify the AST in place so that it should be easier to evaluate it.
  7. Because the AST does not contain all the scoping information and the
  8. compiler has to find that out, we cannot do all the optimizations we
  9. want. For example loop unrolling doesn't work because unrolled loops would
  10. have a different scoping.
  11. The solution would be a second syntax tree that has the scoping rules stored.
  12. :copyright: (c) 2017 by the Jinja Team.
  13. :license: BSD.
  14. """
  15. from jinja2 import nodes
  16. from jinja2.visitor import NodeTransformer
  17. def optimize(node, environment):
  18. """The context hint can be used to perform an static optimization
  19. based on the context given."""
  20. optimizer = Optimizer(environment)
  21. return optimizer.visit(node)
  22. class Optimizer(NodeTransformer):
  23. def __init__(self, environment):
  24. self.environment = environment
  25. def fold(self, node, eval_ctx=None):
  26. """Do constant folding."""
  27. node = self.generic_visit(node)
  28. try:
  29. return nodes.Const.from_untrusted(node.as_const(eval_ctx),
  30. lineno=node.lineno,
  31. environment=self.environment)
  32. except nodes.Impossible:
  33. return node
  34. visit_Add = visit_Sub = visit_Mul = visit_Div = visit_FloorDiv = \
  35. visit_Pow = visit_Mod = visit_And = visit_Or = visit_Pos = visit_Neg = \
  36. visit_Not = visit_Compare = visit_Getitem = visit_Getattr = visit_Call = \
  37. visit_Filter = visit_Test = visit_CondExpr = fold
  38. del fold