11cb0ef41Sopenharmony_ci# -*- coding: utf-8 -*-
21cb0ef41Sopenharmony_ci"""
31cb0ef41Sopenharmony_ci    jinja2.optimizer
41cb0ef41Sopenharmony_ci    ~~~~~~~~~~~~~~~~
51cb0ef41Sopenharmony_ci
61cb0ef41Sopenharmony_ci    The jinja optimizer is currently trying to constant fold a few expressions
71cb0ef41Sopenharmony_ci    and modify the AST in place so that it should be easier to evaluate it.
81cb0ef41Sopenharmony_ci
91cb0ef41Sopenharmony_ci    Because the AST does not contain all the scoping information and the
101cb0ef41Sopenharmony_ci    compiler has to find that out, we cannot do all the optimizations we
111cb0ef41Sopenharmony_ci    want.  For example loop unrolling doesn't work because unrolled loops would
121cb0ef41Sopenharmony_ci    have a different scoping.
131cb0ef41Sopenharmony_ci
141cb0ef41Sopenharmony_ci    The solution would be a second syntax tree that has the scoping rules stored.
151cb0ef41Sopenharmony_ci
161cb0ef41Sopenharmony_ci    :copyright: (c) 2017 by the Jinja Team.
171cb0ef41Sopenharmony_ci    :license: BSD.
181cb0ef41Sopenharmony_ci"""
191cb0ef41Sopenharmony_cifrom jinja2 import nodes
201cb0ef41Sopenharmony_cifrom jinja2.visitor import NodeTransformer
211cb0ef41Sopenharmony_ci
221cb0ef41Sopenharmony_ci
231cb0ef41Sopenharmony_cidef optimize(node, environment):
241cb0ef41Sopenharmony_ci    """The context hint can be used to perform an static optimization
251cb0ef41Sopenharmony_ci    based on the context given."""
261cb0ef41Sopenharmony_ci    optimizer = Optimizer(environment)
271cb0ef41Sopenharmony_ci    return optimizer.visit(node)
281cb0ef41Sopenharmony_ci
291cb0ef41Sopenharmony_ci
301cb0ef41Sopenharmony_ciclass Optimizer(NodeTransformer):
311cb0ef41Sopenharmony_ci
321cb0ef41Sopenharmony_ci    def __init__(self, environment):
331cb0ef41Sopenharmony_ci        self.environment = environment
341cb0ef41Sopenharmony_ci
351cb0ef41Sopenharmony_ci    def fold(self, node, eval_ctx=None):
361cb0ef41Sopenharmony_ci        """Do constant folding."""
371cb0ef41Sopenharmony_ci        node = self.generic_visit(node)
381cb0ef41Sopenharmony_ci        try:
391cb0ef41Sopenharmony_ci            return nodes.Const.from_untrusted(node.as_const(eval_ctx),
401cb0ef41Sopenharmony_ci                                              lineno=node.lineno,
411cb0ef41Sopenharmony_ci                                              environment=self.environment)
421cb0ef41Sopenharmony_ci        except nodes.Impossible:
431cb0ef41Sopenharmony_ci            return node
441cb0ef41Sopenharmony_ci
451cb0ef41Sopenharmony_ci    visit_Add = visit_Sub = visit_Mul = visit_Div = visit_FloorDiv = \
461cb0ef41Sopenharmony_ci    visit_Pow = visit_Mod = visit_And = visit_Or = visit_Pos = visit_Neg = \
471cb0ef41Sopenharmony_ci    visit_Not = visit_Compare = visit_Getitem = visit_Getattr = visit_Call = \
481cb0ef41Sopenharmony_ci    visit_Filter = visit_Test = visit_CondExpr = fold
491cb0ef41Sopenharmony_ci    del fold
50