def test_initial_info_given_3_simple_stmt_given_if(self):
        as_tree = AstBuilder().string_build(
            dedent(
                """\
            a = 3
            if c < 3:
                y = a + b
                x = a
                y = b
                a.b = c
            """
            )
        )

        cfg_real = Cfg(as_tree)
        cfg_real.gather_initial_info()

        expected_ue_var = (set(), {"c"}, {"a", "b", "c"}, set())
        expected_var_kill = (set(), {"a"}, {"y", "x", "a.b"}, set())
        self.assert_uevar_varkill(cfg_real.block_list, expected_ue_var, expected_var_kill)

        expected_globals_var = {"b", "a", "c"}
        assert cfg_real.globals_var == expected_globals_var

        real_block_set = {str(k): v for k, v in cfg_real.block_set.items()}
        expected_block_set = {
            "x": cfg_real.block_list[2],
            "a": cfg_real.block_list[1],
            "y": cfg_real.block_list[2],
            "a.b": cfg_real.block_list[2],
        }
        assert real_block_set == expected_block_set
    def test_initial_info_given_3_simple_stmt_expect_ue_a_vk_a_y_x(self):
        as_tree = AstBuilder().string_build(
            dedent(
                """\
            a = 3
            y = a + b
            x = a
            y = b
            """
            )
        )
        cfg_real = Cfg(as_tree)
        cfg_real.gather_initial_info()

        expected_ue_var = {"b"}
        expected_var_kill = {"a", "y", "x"}

        assert cfg_real.block_list[1].ue_var == expected_ue_var
        assert cfg_real.block_list[1].var_kill == expected_var_kill

        expected_globals_var = {"b"}
        assert cfg_real.globals_var == expected_globals_var

        real_block_set = {str(k): v for k, v in cfg_real.block_set.items()}
        expected_block_set = {"x": cfg_real.block_list[1], "a": cfg_real.block_list[1], "y": cfg_real.block_list[1]}
        assert real_block_set == expected_block_set
Ejemplo n.º 3
0
 def test_renaming_given_3_scopes(self):
     as_tree = AstBuilder().string_build(
         dedent("""\
                     class Foo():
                         x = 1
                         def __init__(self):
                             x = 2
                     x = 3
                     f = Foo(2)
                     """))
     cfg_real = Cfg(as_tree)
     cfg_real.convert_to_ssa()
     self.assertBlockSsaList(
         cfg_real.block_list,
         {
             "L2":
             dedent("""\
                 Assign: (x_0,) = 1
                 Assign: (__init___0,) = Proxy to the object: Function __init__ in scope Class "Foo" in scope Module
                 """),
             "L4":
             "Assign: (x_0,) = 2",
             "L5":
             dedent("""\
                 Assign: (x_0,) = 3
                 Assign: (f_0,) = Call: Foo_0((2,))
                 """),
         },
     )
Ejemplo n.º 4
0
    def test_renaming_multiple_scope(self):
        as_tree = AstBuilder().string_build(
            dedent("""\
                        def foo(x):
                            a = 3
                            return x

                        a = 2
                        foo(a)
                        """))
        cfg_real = Cfg(as_tree)
        cfg_real.convert_to_ssa()
        self.assertBlockSsaList(
            cfg_real.block_list,
            {
                "L2":
                dedent("""\
                                            Assign: (ret_val_0,) = x_0
                                            Assign: (a_0,) = 3
                                    """),
                "L5":
                dedent("""\
                                            Assign: (a_0,) = 2
                                            Call: foo_0((a_0,))
                                            """),
            },
        )
 def test_get_dunder_binop(self):
     as_tree = AstBuilder().string_build("""\
         a = 1
         a - 2
         class F:
             def __add__(self, other):
                 pass
         f = F()
     """)
     cfg_real = Cfg(as_tree)
     cfg_real.convert_to_ssa()
     with self.assertRaises(exceptions.OperationIncompatible) as e:
         list(
             protocols.get_custom_dunder_method(as_tree.body[1].value.left,
                                                "-"))
     assert e.exception.msg == "the node: 1 is not of type ClassInstance"
     meth = list(
         protocols.get_custom_dunder_method(as_tree.body[-1].targets[0],
                                            "+"))[0]
     assert str(
         meth
     ) == 'Proxy to the object: Function __add__ in scope Class "F" in scope Module'
     with self.assertRaises(exceptions.DunderUnimplemented) as e:
         list(
             protocols.get_custom_dunder_method(as_tree.body[-1].targets[0],
                                                "<"))
     assert e.exception.method_name == "__lt__"
Ejemplo n.º 6
0
    def test_renaming_args_attribute(self):
        as_tree = AstBuilder().string_build(
            dedent("""\
                        class Temp:
                            def __init__(self):
                                pass

                        def foo(x):
                            return x + 1

                        y = Temp()
                        y.z = 3
                        foo(y.z)
                        """))
        cfg_real = Cfg(as_tree)
        cfg_real.convert_to_ssa()
        self.assertBlockSsaList(
            cfg_real.block_list,
            {
                "L9":
                dedent("""\
                                    Assign: (y_0.z_0,) = 3
                                    Call: foo_0((y_0.z_0,))
                                    """)
            },
        )
Ejemplo n.º 7
0
 def test_renaming_nameconstant(self):
     as_tree = AstBuilder().string_build(
         dedent("""\
                     if True:
                         x = True
                     else:
                         x = None
                     if False:
                         pass
                     """))
     cfg_real = Cfg(as_tree)
     cfg_real.convert_to_ssa()
     self.assertBlockSsaList(
         cfg_real.block_list,
         {
             "L1":
             dedent("""\
                                 True
                                 """),
             "L4":
             "Assign: (x_1,) = None",
             "L5":
             dedent("""\
                                 Assign: (x_2,) = Phi(x_0, x_1)
                                 False
                                 """),
         },
     )
Ejemplo n.º 8
0
    def test_1_function_def(self):
        as_tree = AstBuilder().string_build(
            dedent("""\
             def foo(x):
                if x < 2:
                    x = 2
                else:
                    x = 1
                z = 1

             f = 5
             z = 5
            """))
        cfg_real = Cfg(as_tree)
        cfg_real.fill_df()
        expected_idom = {
            "foo": ["L2"],
            "L2": ["L3", "L5", "L6"],
            "L3": [],
            "L5": [],
            "L6": ["PhiStub"],
            "PhiStub": []
        }
        self.assert_idom_equal(cfg_real, expected_idom)
        assert cfg_real.block_list[4].df == [cfg_real.block_list[6]]
Ejemplo n.º 9
0
 def test_renaming_str_format(self):
     as_tree = AstBuilder().string_build(
         dedent("""\
                 v = 1
                 s = "some{}".format(v)
                 """))
     cfg_real = Cfg(as_tree)
     cfg_real.convert_to_ssa()
 def test_compute_liveout_with_attr(self):
     blocks, as_tree = self.build_arbitrary_blocks(
         block_links={"A": ["B"], "B": []},
         code={
             "A": dedent(
                 """\
                                                                 a = 4
                                                                 a.b = 2
                                                                 """
             ),
             "B": dedent(
                 """\
                                                                 c = a.b
                                                                 """
             ),
         },
     )
     cfg_real = Cfg()
     cfg_real.block_list = blocks
     cfg_real.as_tree = as_tree
     cfg_real.root = cfg_real.block_list[0]
     cfg_real.gather_initial_info()
     cfg_real.compute_live_out()
     expected_live_out = {"A": {"a", "a.b"}, "B": set()}
     self.assertLiveOutEqual(cfg_real.block_list, expected_live_out)
def build_arbitrary_blocks(block_links, code=None, block_type=None):
    # build all block and assume it's in module scope
    block_list = BlockList()
    as_tree_string = ""
    current_line_number = 1
    for i in range(len(block_links)):
        block_name = chr(65 + i)
        if block_type:
            type_instance = block_type.get(block_name)
            if type_instance is not None:
                if type_instance.__name__ == "ParentScopeBlock":
                    basic_block = type_instance(current_line_number,
                                                current_line_number,
                                                None,
                                                scope_name=block_name)
                else:
                    basic_block = type_instance(current_line_number,
                                                current_line_number, None)
            else:
                basic_block = RawBasicBlock(current_line_number,
                                            current_line_number, None)
        else:
            basic_block = RawBasicBlock(current_line_number,
                                        current_line_number, None)
        current_line_number += 1
        basic_block.name = block_name
        block_list.append(basic_block)

        if code is not None:
            ast_stmts = code.get(basic_block.name)  # type: str
            as_tree_string += ast_stmts

    as_tree = AstBuilder().string_build(as_tree_string)
    for i in range(len(block_links)):
        basic_block = block_list[i]
        if code is not None:
            ast_stmts = code.get(basic_block.name)  # type: str
            ast = AstBuilder().string_build(ast_stmts)
            for b in ast.body:
                b.parent = as_tree
            basic_block.ssa_code.code_list = ast.body
            basic_block.end_line += ast_stmts.count("\n") - 1

    for key, value in block_links.items():
        key_block = block_list.get_block_by_name(key)
        for value_block_str in value:
            Cfg.connect_2_blocks(key_block,
                                 block_list.get_block_by_name(value_block_str))

    if code is None:
        return block_list
    else:
        return block_list, as_tree
Ejemplo n.º 12
0
 def test_renaming_for_var(self):
     as_tree = AstBuilder().string_build(
         dedent("""\
                 for line in something:
                     if x:
                         line = "s".join('y')
                     else:
                         line = "z".join('y')
                     line.strip()
                 """))
     cfg_real = Cfg(as_tree)
     cfg_real.convert_to_ssa()
Ejemplo n.º 13
0
 def remove_block(self, blk):
     if len(blk.nxt_block_list) == 0:
         for prev in blk.prev_block_list:
             prev.nxt_block_list.remove(blk)
     elif len(blk.prev_block_list) == 0:
         for nxt in blk.nxt_block_list:
             nxt.prev_block_list.remove(blk)
     for prev, nxt in itertools.product(blk.prev_block_list,
                                        blk.nxt_block_list):
         prev.nxt_block_list.remove(blk)
         nxt.prev_block_list.remove(blk)
         Cfg.connect_2_blocks(prev, nxt)
    def test_delete_node(self):
        as_tree = AstBuilder().string_build(
            dedent("""\
             z = 2           # 0th block
             while a < 3:    # 1st block
                 if a < 2:   # 2nd block
                      z = 2  # 3rd block
                 b = 2       # 4th block
             c = 3           # 5th block
             """))

        cfg_real = Cfg(as_tree)
        cfg_real.root = cfg_common.delete_node(cfg_real.root,
                                               RawBasicBlock(1, 1))
 def test_locals_dict_if(self):
     as_tree = AstBuilder().string_build(
         dedent("""\
                 x = 1
                 y = 2
                 if x < 2:
                     pass
                     """))
     cfg_real = Cfg(as_tree)
     cfg_real.convert_to_ssa()
     assert as_tree.locals == {
         "x_0": as_tree.body[0].value,
         "y_0": as_tree.body[1].value
     }
Ejemplo n.º 16
0
    def test_rename_given_repeated_definition(self):
        as_tree = AstBuilder().string_build(
            dedent("""\
                    a = 3           # 1st
                    if a > 3:       #  |
                        a = 3       # 2nd
                        a = 98
                    else:           # 3rd
                        z = 4       #  |
                    # expected phi func for 'a' here
                    y = a           # 4th
                    a = 4
                    """))
        cfg_real = Cfg(as_tree)
        cfg_real.fill_df()
        cfg_real.gather_initial_info()
        cfg_real.ins_phi_function_all()
        cfg_real.rename_to_ssa()

        self.assertBlockSsaList(
            cfg_real.block_list,
            {
                "Module":
                dedent("""\
                                      Module
                                            """),
                "L1":
                dedent("""\
                                      Assign: (a_0,) = 3
                                      a_0 > 3
                                      """),
                "L3":
                dedent("""\
                                      Assign: (a_1,) = 3
                                      Assign: (a_2,) = 98
                                      """),
                "L6":
                dedent("""\
                                      Assign: (z_0,) = 4
                                      """),
                "L8":
                """\
                                      Assign: (z_1,) = Phi(z, z_0)
                                      Assign: (a_3,) = Phi(a_2, a_0)
                                      Assign: (y_0,) = a_3
                                      Assign: (a_4,) = 4
                                      """,
            },
        )
 def test_locals_dict_functiondef(self):
     as_tree = AstBuilder().string_build(
         dedent("""\
                     def foo(x):
                         y = 2
                         return y
                     """))
     cfg_real = Cfg(as_tree)
     cfg_real.convert_to_ssa()
     self.assert_locals_str(
         {
             "x_0": "Arg: 'x'",
             "y_0": "2",
             "ret_val_0": "y_0"
         }, as_tree.body[0].locals)
    def test_with_simple_attr(self):
        as_tree = AstBuilder().string_build(
            dedent(
                """\
            a.b = c.d
            """
            )
        )

        cfg_real = Cfg(as_tree)
        cfg_real.gather_initial_info()
        expected_ue_var = {"a", "c", "c.d"}
        expected_var_kill = {"a.b"}
        assert cfg_real.block_list[1].ue_var == expected_ue_var
        assert cfg_real.block_list[1].var_kill == expected_var_kill
    def test_cfg_given_while_body_if(self):
        as_tree = AstBuilder().string_build(
            dedent("""\
            z = 2           # 0th block
            while a < 3:    # 1st block
                if a < 2:   # 2nd block
                     z = 2  # 3rd block
                b = 2       # 4th block
            c = 3           # 5th block
            """))

        cfg_real = Cfg(as_tree)

        self.assertCfgWithBasicBlocks(
            cfg_real,
            [1, 1, "", "L1"],
            [2, 2, "While", "L2"],
            [3, 3, "If", "L3"],
            [4, 4, "", "L4"],
            [5, 5, "", "L5"],
            [6, 6, "", "L6"],
            block_links={
                "0": [1],
                "1": [2, 5],
                "2": [3, 4],
                "3": [4],
                "4": [1],
                "5": []
            },
        )
 def test_locals_dict_multiple_assignment(self):
     as_tree = AstBuilder().string_build(
         dedent("""\
                     y = 3
                     x = 1
                     z = y
                     x = 1
                     """))
     cfg_real = Cfg(as_tree)
     cfg_real.convert_to_ssa()
     assert as_tree.locals == {
         "y_0": as_tree.body[0].value,
         "x_0": as_tree.body[1].value,
         "z_0": as_tree.body[2].value,
         "x_1": as_tree.body[3].value,
     }
    def test_cfg_given_if_else_with_link_tail(self):
        as_tree = AstBuilder().string_build(
            dedent("""\
            a = 3           # 1st
            if a > 3:       #  |
                a = 4       # 2nd
            else:           # 3rd
                z = 5       #  |
            y = 5           # 4th
            """))
        cfg_real = Cfg(as_tree)

        self.assertCfgWithBasicBlocks(
            cfg_real,
            [1, 2, "If", "L1"],
            [3, 3, "", "L3"],
            [5, 5, "", "L5"],
            [6, 6, "", "L6"],
            [None, None, "Module", "Module"],
            [-1, -1, "", "PhiStub"],
            block_links={
                "0": [1, 2],
                "1": [3],
                "2": [3],
                "3": [5],
                "4": [0],
                "5": []
            },
        )
    def test_cfg_given_if_elif_no_else(self):
        as_tree = AstBuilder().string_build(
            dedent("""\
            a = 3          #--- 1st
            if a > 3:      #---  |
                a = 4      #--- 2nd
            elif a < 1:    #--- 3rd
                a = 5      #--- 4th
            c = 5          #--- 5th
            """))
        cfg_real = Cfg(as_tree)

        self.assertCfgWithBasicBlocks(
            cfg_real,
            [1, 2, "If", "L1"],
            [3, 3, "", "L3"],
            [4, 4, "If", "L4"],
            [5, 5, "", "L5"],
            [6, 6, "", "L6"],
            [None, None, "Module", "Module"],
            [-1, -1, "", "PhiStub"],
            block_links={
                "0": [1, 2],
                "1": [4],
                "2": [3, 4],
                "3": [4],
                "4": [6],
                "5": [0],
                "6": []
            },
        )
    def test_cfg_given_for(self):
        as_tree = AstBuilder().string_build(
            dedent("""\
            for a in z:     # 0st block
                if a < 2:   # 1nd block
                     z = 2  # 2rd block
                b = 2       # 3th block
            z = 4
            """))

        cfg_real = Cfg(as_tree)

        self.assertCfgWithBasicBlocks(
            cfg_real,
            [1, 1, "For", "L1"],
            [2, 2, "If", "L2"],
            [3, 3, "", "L3"],
            [4, 4, "", "L4"],
            [5, 5, "", "L5"],
            block_links={
                "0": [1, 4],
                "1": [2, 3],
                "2": [3],
                "3": [0],
                "4": []
            },
        )
    def test_cfg_given_while(self):
        as_tree = AstBuilder().string_build(
            dedent("""\
            while 3 < 4:
                x = 3
                if x < 2:
                    y = 5
            """))
        cfg_real = Cfg(as_tree)

        self.assertCfgWithBasicBlocks(
            cfg_real,
            [1, 1, "While", "L1"],
            [2, 3, "If", "L2"],
            [4, 4, "", "L4"],
            [None, None, "Module", "Module"],
            [-1, -1, "", "PhiStub"],
            block_links={
                "0": [1, 4],
                "1": [2, 0],
                "2": [0],
                "3": [0],
                "4": []
            },
        )
 def test_cfg_given_simple_class(self):
     as_tree = AstBuilder().string_build(
         dedent("""\
             class SomeClass:
                 def __init__(self):
                     pass
         """))
     cfg_real = Cfg(as_tree)
     self.assertCfgWithBasicBlocks(
         cfg_real,
         [1, 1, "ClassDef", "SomeClass"],
         [2, 2, "FunctionDef", "__init__"],
         [3, 3, "", "L3"],
         [None, None, "Module", "Module"],
         [1, 1, TEMP_ASSIGN, TEMP_ASSIGN],
         [2, 2, TEMP_ASSIGN, TEMP_ASSIGN],
         [-1, -1, "", "PhiStub"],
         [-1, -1, "", "PhiStub"],
         [-1, -1, "", "PhiStub"],
         block_links={
             "0": [5],
             "1": [2],
             "2": [6],
             "3": [4],
             "4": [7],
             "5": [6],
             "6": [],
             "7": [],
             "8": []
         },
     )
 def test_cfg_given_simple_class_stmt_between(self):
     as_tree = AstBuilder().string_build(
         dedent("""\
             class SomeClass:
                 if True:
                     x = 1
                 else:
                     x = 3
                 def __init__(self):
                     pass
         """))
     cfg_real = Cfg(as_tree)
     self.assertCfgWithBasicBlocks(
         cfg_real,
         [1, 1, "ClassDef", "SomeClass"],
         [2, 2, "If", "L2"],
         [3, 3, "", "L3"],
         [5, 5, "", "L5"],
         [6, 6, TEMP_ASSIGN, TEMP_ASSIGN],
         block_links={
             "0": [1],
             "1": [2, 3],
             "2": [4],
             "3": [4],
             "4": []
         },
     )
Ejemplo n.º 27
0
    def test_ssa_generation_2_stmt(self):
        as_tree = AstBuilder().string_build(
            dedent(
                """\
            a = 1
            y = 2
            b = 3
            c = 4
            z = a + y
            x = b + c"""
            )
        )

        cfg = Cfg(as_tree)
        cfg.root.nxt_block_list[0].enumerate()
        expected_ssa_dict = {
            "z": deque([0]),
            "a": deque([0]),
            "y": deque([0]),
            "x": deque([0]),
            "b": deque([0]),
            "c": deque([0]),
        }
        real_ssa_dict = as_tree.ssa_record.var_version_list
        assert real_ssa_dict == expected_ssa_dict
    def test_cfg_given_for_with_else(self):
        as_tree = AstBuilder().string_build(
            dedent("""\
            z = 2           # 0th block
            for a in z:     # 1st block
                if a < 2:   # 2nd block
                     z = 2  # 3rd block
                b = 2       # 4th block
            else:
                c = 3       # 5th block
            z = 4
            """))

        cfg_real = Cfg(as_tree)

        self.assertCfgWithBasicBlocks(
            cfg_real,
            [1, 1, "", "L1"],
            [2, 2, "For", "L2"],
            [3, 3, "If", "L3"],
            [4, 4, "", "L4"],
            [5, 5, "", "L5"],
            [7, 7, "", "L7"],
            [8, 8, "", "L8"],
            block_links={
                "0": [1],
                "1": [2, 5, 6],
                "2": [3, 4],
                "3": [4],
                "4": [1],
                "5": [6],
                "6": []
            },
        )
Ejemplo n.º 29
0
 def test_renaming_globals_var_1_var(self):
     as_tree = AstBuilder().string_build(
         dedent("""\
                     def foo(x):
                         x = y
                     """))
     cfg_real = Cfg(as_tree)
     cfg_real.convert_to_ssa()
     self.assertBlockSsaList(
         cfg_real.block_list,
         {
             "L2":
             dedent("""\
                                 Assign: (x_1,) = y
                                 """)
         },
     )
 def test_locals_functiondef_default_args(self):
     as_tree = AstBuilder().string_build(
         dedent("""\
         def foo(x, y=1.5):
             f = 4
     """),
         name="test_mod",
     )
     cfg_real = Cfg(as_tree)
     cfg_real.convert_to_ssa()
     # y_0 = Arg: y because handling of default arg will be `infer_arg` job
     self.assert_locals_str(
         {
             "x_0": "Arg: 'x'",
             "y_0": "Arg: 'y'",
             "f_0": "4"
         }, as_tree.body[0].locals)