Exemple #1
0
def translate_printf_style_formatting(builder: IRBuilder,
                                      format_expr: Union[StrExpr, BytesExpr],
                                      rhs: Expression) -> Optional[Value]:
    tokens = tokenizer_printf_style(format_expr.value)
    if tokens is not None:
        literals, format_ops = tokens

        exprs = []
        if isinstance(rhs, TupleExpr):
            exprs = rhs.items
        elif isinstance(rhs, Expression):
            exprs.append(rhs)

        if isinstance(format_expr, BytesExpr):
            substitutions = convert_format_expr_to_bytes(builder, format_ops,
                                                         exprs, format_expr.line)
            if substitutions is not None:
                return join_formatted_bytes(builder, literals, substitutions, format_expr.line)
        else:
            substitutions = convert_format_expr_to_str(builder, format_ops,
                                                       exprs, format_expr.line)
            if substitutions is not None:
                return join_formatted_strings(builder, literals, substitutions, format_expr.line)

    return None
Exemple #2
0
def translate_str_format_percent_sign(builder: IRBuilder, format_expr: StrExpr,
                                      rhs: Expression) -> Value:
    tokens = tokenizer_printf_style(format_expr.value)
    if tokens is not None:
        literals, format_ops = tokens

        exprs = []
        if isinstance(rhs, TupleExpr):
            exprs = rhs.items
        elif isinstance(rhs, Expression):
            exprs.append(rhs)

        substitutions = convert_expr(builder, format_ops, exprs,
                                     format_expr.line)
        if substitutions is not None:
            return join_formatted_strings(builder, literals, substitutions,
                                          format_expr.line)

    call_c_ops_candidates = binary_ops.get('%', [])
    ret = builder.builder.matching_call_c(
        call_c_ops_candidates,
        [builder.accept(format_expr),
         builder.accept(rhs)], format_expr.line)
    assert ret is not None, 'Cannot use binary op % at line {}'.format(
        format_expr.line)
    return ret
Exemple #3
0
def translate_str_format(
        builder: IRBuilder, expr: CallExpr, callee: RefExpr) -> Optional[Value]:
    if (isinstance(callee, MemberExpr) and isinstance(callee.expr, StrExpr)
            and expr.arg_kinds.count(ARG_POS) == len(expr.arg_kinds)):
        format_str = callee.expr.value
        tokens = tokenizer_format_call(format_str)
        if tokens is None:
            return None
        literals, format_ops = tokens
        # Convert variables to strings
        substitutions = convert_format_expr_to_str(builder, format_ops, expr.args, expr.line)
        if substitutions is None:
            return None
        return join_formatted_strings(builder, literals, substitutions, expr.line)
    return None
Exemple #4
0
def translate_fstring(builder: IRBuilder, expr: CallExpr,
                      callee: RefExpr) -> Optional[Value]:
    """Special case for f-string, which is translated into str.join()
    in mypy AST.

    This specializer optimizes simplest f-strings which don't contain
    any format operation.
    """
    if (isinstance(callee, MemberExpr) and isinstance(callee.expr, StrExpr)
            and callee.expr.value == '' and expr.arg_kinds == [ARG_POS]
            and isinstance(expr.args[0], ListExpr)):
        for item in expr.args[0].items:
            if isinstance(item, StrExpr):
                continue
            elif isinstance(item, CallExpr):
                if (not isinstance(item.callee, MemberExpr)
                        or item.callee.name != 'format'):
                    return None
                elif (not isinstance(item.callee.expr, StrExpr)
                      or item.callee.expr.value != '{:{}}'):
                    return None

                if not isinstance(item.args[1],
                                  StrExpr) or item.args[1].value != '':
                    return None
            else:
                return None

        format_ops = []
        exprs: List[Expression] = []

        for item in expr.args[0].items:
            if isinstance(item, StrExpr) and item.value != '':
                format_ops.append(FormatOp.STR)
                exprs.append(item)
            elif isinstance(item, CallExpr):
                format_ops.append(FormatOp.STR)
                exprs.append(item.args[0])

        substitutions = convert_format_expr_to_str(builder, format_ops, exprs,
                                                   expr.line)
        if substitutions is None:
            return None

        return join_formatted_strings(builder, None, substitutions, expr.line)
    return None