1# coding=utf8
2import textwrap
3
4import fluent.syntax.ast as FTL
5
6
7def ftl(code):
8    """Nicer indentation for FTL code.
9
10    The code returned by this function is meant to be compared against the
11    output of the FTL Serializer.  The input code will end with a newline to
12    match the output of the serializer.
13    """
14
15    # The code might be triple-quoted.
16    code = code.lstrip('\n')
17
18    return textwrap.dedent(code)
19
20
21def fold(fun, node, init):
22    """Reduce `node` to a single value using `fun`.
23
24    Apply `fun` against an accumulator and each subnode of `node` (in postorder
25    traversal) to reduce it to a single value.
26    """
27
28    def fold_(vals, acc):
29        if not vals:
30            return acc
31
32        head = list(vals)[0]
33        tail = list(vals)[1:]
34
35        if isinstance(head, FTL.BaseNode):
36            acc = fold(fun, head, acc)
37        if isinstance(head, list):
38            acc = fold_(head, acc)
39
40        return fold_(tail, fun(acc, head))
41
42    return fold_(vars(node).values(), init)
43