Exemple #1
0
    def reorder_operations(self, outer_bin_op: ast.BinOp,
                           inner_bin_op: ast.BinOp) -> Tuple[Any, Any]:
        inner_first_value = self.literal_eval(inner_bin_op.left)
        inner_second_value = self.literal_eval(inner_bin_op.right)

        if (not (isinstance(outer_bin_op.op, BinaryOperation)
                 and outer_bin_op.op.is_symmetric)
                or not (isinstance(outer_bin_op.op, BinaryOperation)
                        and outer_bin_op.op.is_symmetric)):
            return inner_first_value, inner_second_value

        is_left_operand: bool = inner_bin_op is outer_bin_op.left
        other_value = self.literal_eval(
            outer_bin_op.right if is_left_operand else outer_bin_op.left)

        if inner_first_value is not Undefined or inner_second_value is not Undefined:
            if inner_first_value is Undefined:
                if other_value is Undefined:
                    if is_left_operand:
                        # (x + 1) + y -> (x + y) + 1
                        inner_bin_op.right, outer_bin_op.right = outer_bin_op.right, inner_bin_op.right
                    else:
                        # y + (x + 1) -> 1 + (x + y)
                        inner_bin_op.right, outer_bin_op.left = outer_bin_op.left, inner_bin_op.right
                else:
                    if is_left_operand:
                        # (x + 2) + 1 -> (1 + 2) + x
                        inner_bin_op.left, outer_bin_op.right = outer_bin_op.right, inner_bin_op.left
                    else:
                        # 1 + (x + 2) -> x + (1 + 2)
                        inner_bin_op.left, outer_bin_op.left = outer_bin_op.left, inner_bin_op.left
            else:
                if other_value is Undefined:
                    if is_left_operand:
                        # (1 + x) + y -> (y + x) + 1
                        inner_bin_op.left, outer_bin_op.right = outer_bin_op.right, inner_bin_op.left
                    else:
                        # y + (1 + x) ->  1 + (y + x)
                        inner_bin_op.left, outer_bin_op.left = outer_bin_op.left, inner_bin_op.left
                else:
                    if is_left_operand:
                        # (2 + x) + 1 -> (2 + 1) + x
                        inner_bin_op.right, outer_bin_op.right = outer_bin_op.right, inner_bin_op.right
                    else:
                        # 1 + (2 + x) -> x + (2 + 1)
                        inner_bin_op.right, outer_bin_op.left = outer_bin_op.left, inner_bin_op.right

        super().generic_visit(outer_bin_op)

        return self.literal_eval(outer_bin_op), self.literal_eval(outer_bin_op)
Exemple #2
0
    def visit_BinOp(self, node: ast.BinOp):
        """
        Transforms a string concat to an f-string
        """
        if is_string_concat(node):
            self.counter += 1
            left, right = node.left, node.right
            left = self.visit(left)
            right = self.visit(right)

            if not check_sns_depth(left) or not check_sns_depth(right):
                node.left = left
                node.right = right
                return node

            parts = []
            for p in [left, right]:
                if isinstance(p, ast.JoinedStr):
                    parts += p.values
                else:
                    parts.append(p)

            segments = []
            for p in parts:
                if isinstance(p, ast.Constant):
                    segments.append(ast_string_node(p.value))
                else:
                    segments.append(ast_formatted_value(p))

            return ast.JoinedStr(segments)
        else:
            return self.generic_visit(node)
Exemple #3
0
    def visit_BinOp(self, node: ast.BinOp) -> Union[ast.BinOp, ast.Num]:
        """Evaluate binary operation and return ast.Num if operands are bound.

        Args:
            node: Binary operation to evaluate.

        Returns:
            Evaluated value.
        """
        node.left = self.visit(node.left)
        node.right = self.visit(node.right)
        if isinstance(node.left, ast.Num) and isinstance(node.right, ast.Num):
            val = ast.Num(n=self._match_ops(node.op, self._binary_ops,
                                            node.left.n, node.right.n))
            return ast.copy_location(val, node)
        return node
Exemple #4
0
    def visit_BinOp(self, node: ast.BinOp):
        node.left = self.visit(node.left)
        node.right = self.visit(node.right)

        if not isinstance(node.left, ast.Num) or not isinstance(
                node.right, ast.Num):
            return node

        result = node
        try:
            op_type = type(node.op)
            result = ast.Num(
                n=self.binop_dict[op_type](node.left.n, node.right.n))
        except:
            print("Error: undefined type")

        return ast.copy_location(result, node)
Exemple #5
0
 def visit_BinOp(self, node: ast.BinOp) -> ast.BinOp:
     node = self.generic_visit(node)
     if self._is_numeric_mult(node):
         if isinstance(node.right, ast.Num):
             if node.right.n == 0:
                 node       = ast.copy_location(ast.Num(n = 0), node)
             elif node.right.n == 1:
                 node       = node.left
             elif node.right.n == 2:
                 node.op    = ast.copy_location(ast.Add(), node.op)
                 node.right = copy(node.left)
         elif isinstance(node.left , ast.Num):
             if node.left.n == 0:
                 node       = ast.copy_location(ast.Num(n = 0), node)
             elif node.left.n == 1:
                 node       = node.right
             elif node.left.n == 2:
                 node.op    = ast.copy_location(ast.Add(), node.op)
                 node.left  = copy(node.right)
     return node
Exemple #6
0
    def visit_BinOp(
            self, ast_node_BinOp: ast.BinOp) -> Union[ast.BinOp, ast.Constant]:
        """
        Evaluate binary operation and return ast.BinOp or ast.Constant if
        operands are bound.

        :param ast_node_BinOp: the AST node on which the binary operation
        is performed.
        :return: evaluated value.
        """
        ast_node_BinOp.left = self.visit(ast_node_BinOp.left)
        ast_node_BinOp.right = self.visit(ast_node_BinOp.right)

        left, right = ast_node_BinOp.left, ast_node_BinOp.right

        if isinstance(left, ast.Constant) and isinstance(right, ast.Constant):
            new_ast_node_BinOp = ast.Constant(value=self._match_operator(
                ast_node_BinOp.op, self._ast_math_BinaryOperators, left.value,
                right.value))
            return ast.copy_location(new_ast_node_BinOp, ast_node_BinOp)

        return ast_node_BinOp