"""AST nodes generated by the parser for the compiler. Also provides
some node tree helper functions used by the parser and compiler in order
to normalize nodes.
"""
import inspect
import operator
import typing as t
from collections import deque

from markupsafe import Markup

from .utils import _PassArg

if t.TYPE_CHECKING:
    import typing_extensions as te
    from .environment import Environment

_NodeBound = t.TypeVar("_NodeBound", bound="Node")

_binop_to_func: t.Dict[str, t.Callable[[t.Any, t.Any], t.Any]] = {
    "*": operator.mul,
    "/": operator.truediv,
    "//": operator.floordiv,
    "**": operator.pow,
    "%": operator.mod,
    "+": operator.add,
    "-": operator.sub,
}

_uaop_to_func: t.Dict[str, t.Callable[[t.Any], t.Any]] = {
    "not": operator.not_,
    "+": operator.pos,
    "-": operator.neg,
}

_cmpop_to_func: t.Dict[str, t.Callable[[t.Any, t.Any], t.Any]] = {
    "eq": operator.eq,
    "ne": operator.ne,
    "gt": operator.gt,
    "gteq": operator.ge,
    "lt": operator.lt,
    "lteq": operator.le,
    "in": lambda a, b: a in b,
    "notin": lambda a, b: a not in b,
}


class Impossible(Exception):
    """Raised if the node could not perform a requested action."""


class NodeType(type):
    """A metaclass for nodes that handles the field and attribute
    inheritance.  fields and attributes from the parent class are
    automatically forwarded to the child."""

    def __new__(mcs, name, bases, d):  # type: ignore
        for attr in "fields", "attributes":
            storage = []
            storage.extend(getattr(bases[0] if bases else object, attr, ()))
            storage.extend(d.get(attr, ()))
            assert len(bases) <= 1, "multiple inheritance not allowed"
            assert len(storage) == len(set(storage)), "layout conflict"
            d[attr] = tuple(storage)
        d.setdefault("abstract", False)
        return type.__new__(mcs, name, bases, d)


class EvalContext:
    """Holds evaluation time information.  Custom attributes can be attached
    to it in extensions.
    """

    def __init__(
        self, environment: "Environment", template_name: t.Optional[str] = None
    ) -> None:
        self.environment = environment
        if callable(environment.autoescape):
            self.autoescape = environment.autoescape(template_name)
        else:
            self.autoescape = environment.autoescape
        self.volatile = False

    def save(self) -> t.Mapping[str, t.Any]:
        return self.__dict__.copy()

    def revert(self, old: t.Mapping[str, t.Any]) -> None:
        self.__dict__.clear()
        self.__dict__.update(old)


def get_eval_context(node: "Node", ctx: t.Optional[EvalContext]) -> EvalContext:
    if ctx is None:
        if node.environment is None:
            raise RuntimeError(
                "if no eval context is passed, the node must have an"
                " attached environment."
            )
        return EvalContext(node.environment)
    return ctx


class Node(metaclass=NodeType):
    """Baseclass for all Jinja nodes.  There are a number of nodes available
    of different types.  There are four major types:

    -   :class:`Stmt`: statements
    -   :class:`Expr`: expressions
    -   :class:`Helper`: helper nodes
    -   :class:`Template`: the outermost wrapper node

    All nodes have fields and attributes.  Fields may be other nodes, lists,
    or arbitrary values.  Fields are passed to the constructor as regular
    positional arguments, attributes as keyword arguments.  Each node has
    two attributes: `lineno` (the line number of the node) and `environment`.
    The `environment` attribute is set at the end of the parsing process for
    all nodes automatically.
    """

    fields: t.Tuple[str, ...] = ()
    attributes: t.Tuple[str, ...] = ("lineno", "environment")
    abstract = True

    lineno: int
    environment: t.Optional["Environment"]

    def __init__(self, *fields: t.Any, **attributes: t.Any) -> None:
        if self.abstract:
            raise TypeError("abstract nodes are not instantiable")
        if fields:
            if len(fields) != len(self.fields):
                if not self.fields:
                    raise TypeError(f"{type(self).__name__!r} takes 0 arguments")
                raise TypeError(
                    f"{type(self).__name__!r} takes 0 or {len(self.fields)}"
                    f" argument{'s' if len(self.fields) != 1 else ''}"
                )
            for name, arg in zip(self.fields, fields):
                setattr(self, name, arg)
        for attr in self.attributes:
            setattr(self, attr, attributes.pop(attr, None))
        if attributes:
            raise TypeError(f"unknown attribute {next(iter(attributes))!r}")

    def iter_fields(
        self,
        exclude: t.Optional[t.Container[str]] = None,
        only: t.Optional[t.Container[str]] = None,
    ) -> t.Iterator[t.Tuple[str, t.Any]]:
        """This method iterates over all fields that are defined and yields
        ``(key, value)`` tuples.  Per default all fields are returned, but
        it's possible to limit that to some fields by providing the `only`
        parameter or to exclude some using the `exclude` parameter.  Both
        should be sets or tuples of field names.
        """
        for name in self.fields:
            if (
                (exclude is None and only is None)
                or (exclude is not None and name not in exclude)
                or (only is not None and name in only)
            ):
                try:
                    yield name, getattr(self, name)
                except AttributeError:
                    pass

    def iter_child_nodes(
        self,
        exclude: t.Optional[t.Container[str]] = None,
        only: t.Optional[t.Container[str]] = None,
    ) -> t.Iterator["Node"]:
        """Iterates over all direct child nodes of the node.  This iterates
        over all fields and yields the values of they are nodes.  If the value
        of a field is a list all the nodes in that list are returned.
        """
        for _, item in self.iter_fields(exclude, only):
            if isinstance(item, list):
                for n in item:
                    if isinstance(n, Node):
                        yield n
            elif isinstance(item, Node):
                yield item

    def find(self, node_type: t.Type[_NodeBound]) -> t.Optional[_NodeBound]:
        """Find the first node of a given type.  If no such node exists the
        return value is `None`.
        """
        for result in self.find_all(node_type):
            return result

        return None

    def find_all(
        self, node_type: t.Union[t.Type[_NodeBound], t.Tuple[t.Type[_NodeBound], ...]]
    ) -> t.Iterator[_NodeBound]:
        """Find all the nodes of a given type.  If the type is a tuple,
        the check is performed for any of the tuple items.
        """
        for child in self.iter_child_nodes():
            if isinstance(child, node_type):
                yield child  # type: ignore
            yield from child.find_all(node_type)

    def set_ctx(self, ctx: str) -> "Node":
        """Reset the context of a node and all child nodes.  Per default the
        parser will all generate nodes that have a 'load' context as it's the
        most common one.  This method is used in the parser to set assignment
        targets and other nodes to a store context.
        """
        todo = deque([self])
        while todo:
            node = todo.popleft()
            if "ctx" in node.fields:
                node.ctx = ctx  # type: ignore
            todo.extend(node.iter_child_nodes())
        return self

    def set_lineno(self, lineno: int, override: bool = False) -> "Node":
        """Set the line numbers of the node and children."""
        todo = deque([self])
        while todo:
            node = todo.popleft()
            if "lineno" in node.attributes:
                if node.lineno is None or override:
                    node.lineno = lineno
            todo.extend(node.iter_child_nodes())
        return self

    def set_environment(self, environment: "Environment") -> "Node":
        """Set the environment for all nodes."""
        todo = deque([self])
        while todo:
            node = todo.popleft()
            node.environment = environment
            todo.extend(node.iter_child_nodes())
        return self

    def __eq__(self, other: t.Any) -> bool:
        if type(self) is not type(other):
            return NotImplemented

        return tuple(self.iter_fields()) == tuple(other.iter_fields())

    __hash__ = object.__hash__

    def __repr__(self) -> str:
        args_str = ", ".join(f"{a}={getattr(self, a, None)!r}" for a in self.fields)
        return f"{type(self).__name__}({args_str})"

    def dump(self) -> str:
        def _dump(node: t.Union[Node, t.Any]) -> None:
            if not isinstance(node, Node):
                buf.append(repr(node))
                return

            buf.append(f"nodes.{type(node).__name__}(")
            if not node.fields:
                buf.append(")")
                return
            for idx, field in enumerate(node.fields):
                if idx:
                    buf.append(", ")
                value = getattr(node, field)
                if isinstance(value, list):
                    buf.append("[")
                    for idx, item in enumerate(value):
                        if idx:
                            buf.append(", ")
                        _dump(item)
                    buf.append("]")
                else:
                    _dump(value)
            buf.append(")")

        buf: t.List[str] = []
        _dump(self)
        return "".join(buf)


class Stmt(Node):
    """Base node for all statements."""

    abstract = True


class Helper(Node):
    """Nodes that exist in a specific context only."""

    abstract = True


class Template(Node):
    """Node that represents a template.  This must be the outermost node that
    is passed to the compiler.
    """

    fields = ("body",)
    body: t.List[Node]


class Output(Stmt):
    """A node that holds multiple expressions which are then printed out.
    This is used both for the `print` statement and the regular template data.
    """

    fields = ("nodes",)
    nodes: t.List["Expr"]


class Extends(Stmt):
    """Represents an extends statement."""

    fields = ("template",)
    template: "Expr"


class For(Stmt):
    """The for loop.  `target` is the target for the iteration (usually a
    :class:`Name` or :class:`Tuple`), `iter` the iterable.  `body` is a list
    of nodes that are used as loop-body, and `else_` a list of nodes for the
    `else` block.  If no else node exists it has to be an empty list.

    For filtered nodes an expression can be stored as `test`, otherwise `None`.
    """

    fields = ("target", "iter", "body", "else_", "test", "recursive")
    target: Node
    iter: Node
    body: t.List[Node]
    else_: t.List[Node]
    test: t.Optional[Node]
    recursive: bool


class If(Stmt):
    """If `test` is true, `body` is rendered, else `else_`."""

    fields = ("test", "body", "elif_", "else_")
    test: Node
    body: t.List[Node]
    elif_: t.List["If"]
    else_: t.List[Node]


class Macro(Stmt):
    """A macro definition.  `name` is the name of the macro, `args` a list of
    arguments and `defaults` a list of defaults if there are any.  `body` is
    a list of nodes for the macro body.
    """

    fields = ("name", "args", "defaults", "body")
    name: str
    args: t.List["Name"]
    defaults: t.List["Expr"]
    body: t.List[Node]


class CallBlock(Stmt):
    """Like a macro without a name but a call instead.  `call` is called with
    the unnamed macro as `caller` argument this node holds.
    """

    fields = ("call", "args", "defaults", "body")
    call: "Call"
    args: t.List["Name"]
    defaults: t.List["Expr"]
    body: t.List[Node]


class FilterBlock(Stmt):
    """Node for filter sections."""

    fields = ("body", "filter")
    body: t.List[Node]
    filter: "Filter"


class With(Stmt):
    """Specific node for with statements.  In older versions of Jinja the
    with statement was implemented on the base of the `Scope` node instead.

    .. versionadded:: 2.9.3
    """

    fields = ("targets", "values", "body")
    targets: t.List["Expr"]
    values: t.List["Expr"]
    body: t.List[Node]


class Block(Stmt):
    """A node that represents a block.

    .. versionchanged:: 3.0.0
        the `required` field was added.
    """

    fields = ("name", "body", "scoped", "required")
    name: str
    body: t.List[Node]
    scoped: bool
    required: bool


class Include(Stmt):
    """A node that represents the include tag."""

    fields = ("template", "with_context", "ignore_missing")
    template: "Expr"
    with_context: bool
    ignore_missing: bool


class Import(Stmt):
    """A node that represents the import tag."""

    fields = ("template", "target", "with_context")
    template: "Expr"
    target: str
    with_context: bool


class FromImport(Stmt):
    """A node that represents the from import tag.  It's important to not
    pass unsafe names to the name attribute.  The compiler translates the
    attribute lookups directly into getattr calls and does *not* use the
    subscript callback of the interface.  As exported variables may not
    start with double underscores (which the parser asserts) this is not a
    problem for regular Jinja code, but if this node is used in an extension
    extra care must be taken.

    The list of names may contain tuples if aliases are wanted.
    """

    fields = ("template", "names", "with_context")
    template: "Expr"
    names: t.List[t.Union[str, t.Tuple[str, str]]]
    with_context: bool


class ExprStmt(Stmt):
    """A statement that evaluates an expression and discards the result."""

    fields = ("node",)
    node: Node


class Assign(Stmt):
    """Assigns an expression to a target."""

    fields = ("target", "node")
    target: "Expr"
    node: Node


class AssignBlock(Stmt):
    """Assigns a block to a target."""

    fields = ("target", "filter", "body")
    target: "Expr"
    filter: t.Optional["Filter"]
    body: t.List[Node]


class Expr(Node):
    """Baseclass for all expressions."""

    abstract = True

    def as_const(self, eval_ctx: t.Optional[EvalContext] = None) -> t.Any:
        """Return the value of the expression as constant or raise
        :exc:`Impossible` if this was not possible.

        An :class:`EvalContext` can be provided, if none is given
        a default context is created which requires the nodes to have
        an attached environment.

        .. versionchanged:: 2.4
           the `eval_ctx` parameter was added.
        """
        raise Impossible()

    def can_assign(self) -> bool:
        """Check if it's possible to assign something to this node."""
        return False


class BinExpr(Expr):
    """Baseclass for all binary expressions."""

    fields = ("left", "right")
    left: Expr
    right: Expr
    operator: str
    abstract = True

    def as_const(self, eval_ctx: t.Optional[EvalContext] = None) -> t.Any:
        eval_ctx = get_eval_context(self, eval_ctx)

        # intercepted operators cannot be folded at compile time
        if (
            eval_ctx.environment.sandboxed
            and self.operator in eval_ctx.environment.intercepted_binops  # type: ignore
        ):
            raise Impossible()
        f = _binop_to_func[self.operator]
        try:
            return f(self.left.as_const(eval_ctx), self.right.as_const(eval_ctx))
        except Exception as e:
            raise Impossible() from e


class UnaryExpr(Expr):
    """Baseclass for all unary expressions."""

    fields = ("node",)
    node: Expr
    operator: str
    abstract = True

    def as_const(self, eval_ctx: t.Optional[EvalContext] = None) -> t.Any:
        eval_ctx = get_eval_context(self, eval_ctx)

        # intercepted operators cannot be folded at compile time
        if (
            eval_ctx.environment.sandboxed
            and self.operator in eval_ctx.environment.intercepted_unops  # type: ignore
        ):
            raise Impossible()
        f = _uaop_to_func[self.operator]
        try:
            return f(self.node.as_const(eval_ctx))
        except Exception as e:
            raise Impossible() from e


class Name(Expr):
    """Looks up a name or stores a value in a name.
    The `ctx` of the node can be one of the following values:

    -   `store`: store a value in the name
    -   `load`: load that name
    -   `param`: like `store` but if the name was defined as function parameter.
    """

    fields = ("name", "ctx")
    name: str
    ctx: str

    def can_assign(self) -> bool:
        return self.name not in {"true", "false", "none", "True", "False", "None"}


class NSRef(Expr):
    """Reference to a namespace value assignment"""

    fields = ("name", "attr")
    name: str
    attr: str

    def can_assign(self) -> bool:
        # We don't need any special checks here; NSRef assignments have a
        # runtime check to ensure the target is a namespace object which will
        # have been checked already as it is created using a normal assignment
        # which goes through a `Name` node.
        return True


class Literal(Expr):
    """Baseclass for literals."""

    abstract = True


class Const(Literal):
    """All constant values.  The parser will return this node for simple
    constants such as ``42`` or ``"foo"`` but it can be used to store more
    complex values such as lists too.  Only constants with a safe
    representation (objects where ``eval(repr(x)) == x`` is true).
    """

    fields = ("value",)
    value: t.Any

    def as_const(self, eval_ctx: t.Optional[EvalContext] = None) -> t.Any:
        return self.value

    @classmethod
    def from_untrusted(
        cls,
        value: t.Any,
        lineno: t.Optional[int] = None,
        environment: "t.Optional[Environment]" = None,
    ) -> "Const":
        """Return a const object if the value is representable as
        constant value in the generated code, otherwise it will raise
        an `Impossible` exception.
        """
        from .compiler import has_safe_repr

        if not has_safe_repr(value):
            raise Impossible()
        return cls(value, lineno=lineno, environment=environment)


class TemplateData(Literal):
    """A constant template string."""

    fields = ("data",)
    data: str

    def as_const(self, eval_ctx: t.Optional[EvalContext] = None) -> str:
        eval_ctx = get_eval_context(self, eval_ctx)
        if eval_ctx.volatile:
            raise Impossible()
        if eval_ctx.autoescape:
            return Markup(self.data)
        return self.data


class Tuple(Literal):
    """For loop unpacking and some other things like multiple arguments
    for subscripts.  Like for :class:`Name` `ctx` specifies if the tuple
    is used for loading the names or storing.
    """

    fields = ("items", "ctx")
    items: t.List[Expr]
    ctx: str

    def as_const(self, eval_ctx: t.Optional[EvalContext] = None) -> t.Tuple[t.Any, ...]:
        eval_ctx = get_eval_context(self, eval_ctx)
        return tuple(x.as_const(eval_ctx) for x in self.items)

    def can_assign(self) -> bool:
        for item in self.items:
            if not item.can_assign():
                return False
        return True


class List(Literal):
    """Any list literal such as ``[1, 2, 3]``"""

    fields = ("items",)
    items: t.List[Expr]

    def as_const(self, eval_ctx: t.Optional[EvalContext] = None) -> t.List[t.Any]:
        eval_ctx = get_eval_context(self, eval_ctx)
        return [x.as_const(eval_ctx) for x in self.items]


class Dict(Literal):
    """Any dict literal such as ``{1: 2, 3: 4}``.  The items must be a list of
    :class:`Pair` nodes.
    """

    fields = ("items",)
    items: t.List["Pair"]

    def as_const(
        self, eval_ctx: t.Optional[EvalContext] = None
    ) -> t.Dict[t.Any, t.Any]:
        eval_ctx = get_eval_context(self, eval_ctx)
        return dict(x.as_const(eval_ctx) for x in self.items)


class Pair(Helper):
    """A key, value pair for dicts."""

    fields = ("key", "value")
    key: Expr
    value: Expr

    def as_const(
        self, eval_ctx: t.Optional[EvalContext] = None
    ) -> t.Tuple[t.Any, t.Any]:
        eval_ctx = get_eval_context(self, eval_ctx)
        return self.key.as_const(eval_ctx), self.value.as_const(eval_ctx)


class Keyword(Helper):
    """A key, value pair for keyword arguments where key is a string."""

    fields = ("key", "value")
    key: str
    value: Expr

    def as_const(self, eval_ctx: t.Optional[EvalContext] = None) -> t.Tuple[str, t.Any]:
        eval_ctx = get_eval_context(self, eval_ctx)
        return self.key, self.value.as_const(eval_ctx)


class CondExpr(Expr):
    """A conditional expression (inline if expression).  (``{{
    foo if bar else baz }}``)
    """

    fields = ("test", "expr1", "expr2")
    test: Expr
    expr1: Expr
    expr2: t.Optional[Expr]

    def as_const(self, eval_ctx: t.Optional[EvalContext] = None) -> t.Any:
        eval_ctx = get_eval_context(self, eval_ctx)
        if self.test.as_const(eval_ctx):
            return self.expr1.as_const(eval_ctx)

        # if we evaluate to an undefined object, we better do that at runtime
        if self.expr2 is None:
            raise Impossible()

        return self.expr2.as_const(eval_ctx)


def args_as_const(
    node: t.Union["_FilterTestCommon", "Call"], eval_ctx: t.Optional[EvalContext]
) -> t.Tuple[t.List[t.Any], t.Dict[t.Any, t.Any]]:
    args = [x.as_const(eval_ctx) for x in node.args]
    kwargs = dict(x.as_const(eval_ctx) for x in node.kwargs)

    if node.dyn_args is not None:
        try:
            args.extend(node.dyn_args.as_const(eval_ctx))
        except Exception as e:
            raise Impossible() from e

    if node.dyn_kwargs is not None:
        try:
            kwargs.update(node.dyn_kwargs.as_const(eval_ctx))
        except Exception as e:
            raise Impossible() from e

    return args, kwargs


class _FilterTestCommon(Expr):
    fields = ("node", "name", "args", "kwargs", "dyn_args", "dyn_kwargs")
    node: Expr
    name: str
    args: t.List[Expr]
    kwargs: t.List[Pair]
    dyn_args: t.Optional[Expr]
    dyn_kwargs: t.Optional[Expr]
    abstract = True
    _is_filter = True

    def as_const(self, eval_ctx: t.Optional[EvalContext] = None) -> t.Any:
        eval_ctx = get_eval_context(self, eval_ctx)

        if eval_ctx.volatile:
            raise Impossible()

        if self._is_filter:
            env_map = eval_ctx.environment.filters
        else:
            env_map = eval_ctx.environment.tests

        func = env_map.get(self.name)
        pass_arg = _PassArg.from_obj(func)  # type: ignore

        if func is None or pass_arg is _PassArg.context:
            raise Impossible()

        if eval_ctx.environment.is_async and (
            getattr(func, "jinja_async_variant", False) is True
            or inspect.iscoroutinefunction(func)
        ):
            raise Impossible()

        args, kwargs = args_as_const(self, eval_ctx)
        args.insert(0, self.node.as_const(eval_ctx))

        if pass_arg is _PassArg.eval_context:
            args.insert(0, eval_ctx)
        elif pass_arg is _PassArg.environment:
            args.insert(0, eval_ctx.environment)

        try:
            return func(*args, **kwargs)
        except Exception as e:
            raise Impossible() from e


class Filter(_FilterTestCommon):
    """Apply a filter to an expression. ``name`` is the name of the
    filter, the other fields are the same as :class:`Call`.

    If ``node`` is ``None``, the filter is being used in a filter block
    and is applied to the content of the block.
    """

    node: t.Optional[Expr]  # type: ignore

    def as_const(self, eval_ctx: t.Optional[EvalContext] = None) -> t.Any:
        if self.node is None:
            raise Impossible()

        return super().as_const(eval_ctx=eval_ctx)


class Test(_FilterTestCommon):
    """Apply a test to an expression. ``name`` is the name of the test,
    the other field are the same as :class:`Call`.

    .. versionchanged:: 3.0
        ``as_const`` shares the same logic for filters and tests. Tests
        check for volatile, async, and ``@pass_context`` etc.
        decorators.
    """

    _is_filter = False


class Call(Expr):
    """Calls an expression.  `args` is a list of arguments, `kwargs` a list
    of keyword arguments (list of :class:`Keyword` nodes), and `dyn_args`
    and `dyn_kwargs` has to be either `None` or a node that is used as
    node for dynamic positional (``*args``) or keyword (``**kwargs``)
    arguments.
    """

    fields = ("node", "args", "kwargs", "dyn_args", "dyn_kwargs")
    node: Expr
    args: t.List[Expr]
    kwargs: t.List[Keyword]
    dyn_args: t.Optional[Expr]
    dyn_kwargs: t.Optional[Expr]


class Getitem(Expr):
    """Get an attribute or item from an expression and prefer the item."""

    fields = ("node", "arg", "ctx")
    node: Expr
    arg: Expr
    ctx: str

    def as_const(self, eval_ctx: t.Optional[EvalContext] = None) -> t.Any:
        if self.ctx != "load":
            raise Impossible()

        eval_ctx = get_eval_context(self, eval_ctx)

        try:
            return eval_ctx.environment.getitem(
                self.node.as_const(eval_ctx), self.arg.as_const(eval_ctx)
            )
        except Exception as e:
            raise Impossible() from e


class Getattr(Expr):
    """Get an attribute or item from an expression that is a ascii-only
    bytestring and prefer the attribute.
    """

    fields = ("node", "attr", "ctx")
    node: Expr
    attr: str
    ctx: str

    def as_const(self, eval_ctx: t.Optional[EvalContext] = None) -> t.Any:
        if self.ctx != "load":
            raise Impossible()

        eval_ctx = get_eval_context(self, eval_ctx)

        try:
            return eval_ctx.environment.getattr(self.node.as_const(eval_ctx), self.attr)
        except Exception as e:
            raise Impossible() from e


class Slice(Expr):
    """Represents a slice object.  This must only be used as argument for
    :class:`Subscript`.
    """

    fields = ("start", "stop", "step")
    start: t.Optional[Expr]
    stop: t.Optional[Expr]
    step: t.Optional[Expr]

    def as_const(self, eval_ctx: t.Optional[EvalContext] = None) -> slice:
        eval_ctx = get_eval_context(self, eval_ctx)

        def const(obj: t.Optional[Expr]) -> t.Optional[t.Any]:
            if obj is None:
                return None
            return obj.as_const(eval_ctx)

        return slice(const(self.start), const(self.stop), const(self.step))


class Concat(Expr):
    """Concatenates the list of expressions provided after converting
    them to strings.
    """

    fields = ("nodes",)
    nodes: t.List[Expr]

    def as_const(self, eval_ctx: t.Optional[EvalContext] = None) -> str:
        eval_ctx = get_eval_context(self, eval_ctx)
        return "".join(str(x.as_const(eval_ctx)) for x in self.nodes)


class Compare(Expr):
    """Compares an expression with some other expressions.  `ops` must be a
    list of :class:`Operand`\\s.
    """

    fields = ("expr", "ops")
    expr: Expr
    ops: t.List["Operand"]

    def as_const(self, eval_ctx: t.Optional[EvalContext] = None) -> t.Any:
        eval_ctx = get_eval_context(self, eval_ctx)
        result = value = self.expr.as_const(eval_ctx)

        try:
            for op in self.ops:
                new_value = op.expr.as_const(eval_ctx)
                result = _cmpop_to_func[op.op](value, new_value)

                if not result:
                    return False

                value = new_value
        except Exception as e:
            raise Impossible() from e

        return result


class Operand(Helper):
    """Holds an operator and an expression."""

    fields = ("op", "expr")
    op: str
    expr: Expr


class Mul(BinExpr):
    """Multiplies the left with the right node."""

    operator = "*"


class Div(BinExpr):
    """Divides the left by the right node."""

    operator = "/"


class FloorDiv(BinExpr):
    """Divides the left by the right node and converts the
    result into an integer by truncating.
    """

    operator = "//"


class Add(BinExpr):
    """Add the left to the right node."""

    operator = "+"


class Sub(BinExpr):
    """Subtract the right from the left node."""

    operator = "-"


class Mod(BinExpr):
    """Left modulo right."""

    operator = "%"


class Pow(BinExpr):
    """Left to the power of right."""

    operator = "**"


class And(BinExpr):
    """Short circuited AND."""

    operator = "and"

    def as_const(self, eval_ctx: t.Optional[EvalContext] = None) -> t.Any:
        eval_ctx = get_eval_context(self, eval_ctx)
        return self.left.as_const(eval_ctx) and self.right.as_const(eval_ctx)


class Or(BinExpr):
    """Short circuited OR."""

    operator = "or"

    def as_const(self, eval_ctx: t.Optional[EvalContext] = None) -> t.Any:
        eval_ctx = get_eval_context(self, eval_ctx)
        return self.left.as_const(eval_ctx) or self.right.as_const(eval_ctx)


class Not(UnaryExpr):
    """Negate the expression."""

    operator = "not"


class Neg(UnaryExpr):
    """Make the expression negative."""

    operator = "-"


class Pos(UnaryExpr):
    """Make the expression positive (noop for most expressions)"""

    operator = "+"


# Helpers for extensions


class EnvironmentAttribute(Expr):
    """Loads an attribute from the environment object.  This is useful for
    extensions that want to call a callback stored on the environment.
    """

    fields = ("name",)
    name: str


class ExtensionAttribute(Expr):
    """Returns the attribute of an extension bound to the environment.
    The identifier is the identifier of the :class:`Extension`.

    This node is usually constructed by calling the
    :meth:`~jinja2.ext.Extension.attr` method on an extension.
    """

    fields = ("identifier", "name")
    identifier: str
    name: str


class ImportedName(Expr):
    """If created with an import name the import name is returned on node
    access.  For example ``ImportedName('cgi.escape')`` returns the `escape`
    function from the cgi module on evaluation.  Imports are optimized by the
    compiler so there is no need to assign them to local variables.
    """

    fields = ("importname",)
    importname: str


class InternalName(Expr):
    """An internal name in the compiler.  You cannot create these nodes
    yourself but the parser provides a
    :meth:`~jinja2.parser.Parser.free_identifier` method that creates
    a new identifier for you.  This identifier is not available from the
    template and is not treated specially by the compiler.
    """

    fields = ("name",)
    name: str

    def __init__(self) -> None:
        raise TypeError(
            "Can't create internal names.  Use the "
            "`free_identifier` method on a parser."
        )


class MarkSafe(Expr):
    """Mark the wrapped expression as safe (wrap it as `Markup`)."""

    fields = ("expr",)
    expr: Expr

    def as_const(self, eval_ctx: t.Optional[EvalContext] = None) -> Markup:
        eval_ctx = get_eval_context(self, eval_ctx)
        return Markup(self.expr.as_const(eval_ctx))


class MarkSafeIfAutoescape(Expr):
    """Mark the wrapped expression as safe (wrap it as `Markup`) but
    only if autoescaping is active.

    .. versionadded:: 2.5
    """

    fields = ("expr",)
    expr: Expr

    def as_const(
        self, eval_ctx: t.Optional[EvalContext] = None
    ) -> t.Union[Markup, t.Any]:
        eval_ctx = get_eval_context(self, eval_ctx)
        if eval_ctx.volatile:
            raise Impossible()
        expr = self.expr.as_const(eval_ctx)
        if eval_ctx.autoescape:
            return Markup(expr)
        return expr


class ContextReference(Expr):
    """Returns the current template context.  It can be used like a
    :class:`Name` node, with a ``'load'`` ctx and will return the
    current :class:`~jinja2.runtime.Context` object.

    Here an example that assigns the current template name to a
    variable named `foo`::

        Assign(Name('foo', ctx='store'),
               Getattr(ContextReference(), 'name'))

    This is basically equivalent to using the
    :func:`~jinja2.pass_context` decorator when using the high-level
    API, which causes a reference to the context to be passed as the
    first argument to a function.
    """


class DerivedContextReference(Expr):
    """Return the current template context including locals. Behaves
    exactly like :class:`ContextReference`, but includes local
    variables, such as from a ``for`` loop.

    .. versionadded:: 2.11
    """


class Continue(Stmt):
    """Continue a loop."""


class Break(Stmt):
    """Break a loop."""


class Scope(Stmt):
    """An artificial scope."""

    fields = ("body",)
    body: t.List[Node]


class OverlayScope(Stmt):
    """An overlay scope for extensions.  This is a largely unoptimized scope
    that however can be used to introduce completely arbitrary variables into
    a sub scope from a dictionary or dictionary like object.  The `context`
    field has to evaluate to a dictionary object.

    Example usage::

        OverlayScope(context=self.call_method('get_context'),
                     body=[...])

    .. versionadded:: 2.10
    """

    fields = ("context", "body")
    context: Expr
    body: t.List[Node]


class EvalContextModifier(Stmt):
    """Modifies the eval context.  For each option that should be modified,
    a :class:`Keyword` has to be added to the :attr:`options` list.

    Example to change the `autoescape` setting::

        EvalContextModifier(options=[Keyword('autoescape', Const(True))])
    """

    fields = ("options",)
    options: t.List[Keyword]


class ScopedEvalContextModifier(EvalContextModifier):
    """Modifies the eval context and reverts it later.  Works exactly like
    :class:`EvalContextModifier` but will only modify the
    :class:`~jinja2.nodes.EvalContext` for nodes in the :attr:`body`.
    """

    fields = ("body",)
    body: t.List[Node]


# make sure nobody creates custom nodes
def _failing_new(*args: t.Any, **kwargs: t.Any) -> "te.NoReturn":
    raise TypeError("can't create custom node types")


NodeType.__new__ = staticmethod(_failing_new)  # type: ignore
del _failing_new
