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": []
         },
     )
    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
示例#3
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
示例#4
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]]
示例#5
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_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": []
            },
        )
示例#7
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,))
                 """),
         },
     )
示例#8
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
                                 """),
         },
     )
    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_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_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
    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_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_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_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__"
示例#16
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,))
                                    """)
            },
        )
 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 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": []
            },
        )
示例#19
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()
示例#20
0
    def test_fill_df_given_7_blocks(self):
        r"""
        Note: '|' with no arrows means pointing down
             H
             |
             A  <---          DF(A) = A,
            / \    |          DF(B) = G,
           B   E ---          DF(C) = F
          / \  |              DF(D) = F
         C   D |              DF(E) = A, G
          \ /  |              DF(F) = G
           F   |              DF(G) = None
            \  |              DF(H) = None
              G
        """
        blocks = self.build_arbitrary_blocks(
            block_links={
                "H": ["A"],
                "A": ["B", "E"],
                "B": ["C", "D"],
                "C": ["F"],
                "D": ["F"],
                "E": ["G", "A"],
                "F": ["G"],
                "G": [],
            },
            block_type={
                "A": RawBasicBlock,
                "B": RawBasicBlock,
                "C": RawBasicBlock,
                "D": RawBasicBlock,
                "E": RawBasicBlock,
                "F": RawBasicBlock,
                "G": RawBasicBlock,
                "H": ParentScopeBlock,
            },
        )

        cfg_real = Cfg()
        cfg_real.block_list = blocks
        cfg_real.root = blocks[-1]
        cfg_real.root.blocks = blocks
        cfg_real.fill_df()

        self.assert_df_equal(
            cfg_real, {
                "A": ["A"],
                "B": ["G"],
                "C": ["F"],
                "D": ["F"],
                "E": ["A", "G"],
                "F": ["G"],
                "G": [],
                "H": []
            })
示例#21
0
    def assertCfgWithBasicBlocks(self, cfg_real, *args, **kwargs):
        block_links = kwargs.get("block_links")
        name_required = kwargs.get("name_required")
        from klara.core.cfg import Cfg, build_blocks

        cfg_expected = Cfg()

        block_list = build_blocks(*args, block_links=block_links)
        cfg_expected.block_list.extend(block_list)
        self.assertBasicBlockListEqual(cfg_real.block_list, block_list,
                                       name_required)
示例#22
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()
 def test_multi_line(self):
     as_tree = AstBuilder().string_build(
         dedent("""\
          s = foo(1,
                  2,
                  3,
                  4)
          z = 1
          """))
     cfg_real = Cfg(as_tree)
     self.assertCfgWithBasicBlocks(cfg_real, [1, 1, "Call", "L1"],
                                   [5, 5, "", "L5"],
                                   block_links={"0": [1]})
示例#24
0
    def test_ssa_generation_number(self):
        as_tree = AstBuilder().string_build(
            dedent(
                """\
            z = 4"""
            )
        )

        cfg = Cfg(as_tree)
        cfg.root.nxt_block_list[0].enumerate()
        expected_ssa_dict = {"z": deque([0])}
        real_ssa_dict = as_tree.ssa_record.var_version_list
        assert real_ssa_dict == expected_ssa_dict
示例#25
0
    def test_func_tail_given_no_return(self):
        as_tree = AstBuilder().string_build(
            dedent(
                """\
                            def foo(x):
                                x = 2
                                x = x + 1
                            """
            )
        )

        cfg_real = Cfg(as_tree)
        get_block = cfg_real.block_list.get_block_by_name
        assert get_block("foo").func_tail == []
示例#26
0
    def test_func_tail_given_only_if_with_no_else(self):
        as_tree = AstBuilder().string_build(
            dedent(
                """\
                            def foo(x):
                                if x < 2:
                                    return 5
                            """
            )
        )

        cfg_real = Cfg(as_tree)
        get_block = cfg_real.block_list.get_block_by_name
        assert get_block("foo").func_tail == [get_block("L3")]
 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
     }
    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))
示例#29
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_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