def flatten_select_expressions()

in pontoon/pretranslation/transformer.py [0:0]


def flatten_select_expressions(pattern: FTL.Pattern):
    """
    If the pattern contains any select expressions,
    flatten it to only contain select expressions.
    Leading and trailing elements are copied into each variant,
    and any single leading or trailing spaces are lifted out of the select expressions.
    """

    def isSelExp(el: FTL.PatternElement):
        return isinstance(el, FTL.Placeable) and isinstance(
            el.expression, FTL.SelectExpression
        )

    def patternStartsWithSpace(pat: list[FTL.PatternElement]):
        return isinstance(pat[0], FTL.TextElement) and pat[0].value.startswith(" ")

    def patternEndsWithSpace(pat: list[FTL.PatternElement]):
        return isinstance(pat[-1], FTL.TextElement) and pat[-1].value.endswith(" ")

    prev = -1
    select = None
    for idx, placeable in filter(lambda x: isSelExp(x[1]), enumerate(pattern.elements)):
        before = pattern.elements[prev + 1 : idx]
        if before:
            select = cast(FTL.SelectExpression, placeable.expression)
            for variant in select.variants:
                variant.value.elements[0:0] = deepcopy(before)
        prev = idx
    if select:
        after = pattern.elements[prev + 1 :]
        if after:
            for variant in select.variants:
                variant.value.elements += deepcopy(after)

        res: list[FTL.PatternElement] = []
        for placeable in filter(isSelExp, pattern.elements):
            patterns = tuple(
                map(lambda var: var.value.elements, placeable.expression.variants)
            )

            # Collect leading spaces
            if all(map(patternStartsWithSpace, patterns)):
                res.append(FTL.Placeable(FTL.StringLiteral(" ")))
                for pat in patterns:
                    pat[0].value = pat[0].value[1:]

            res.append(placeable)

            # Collect trailing spaces
            if all(map(patternEndsWithSpace, patterns)):
                res.append(FTL.Placeable(FTL.StringLiteral(" ")))
                for pat in patterns:
                    pat[-1].value = pat[-1].value[:-1]
        pattern.elements = res