def test_hack_code_gen(self) -> None: ClingoContext.number_of_nodes = 12 ClingoContext.min_depth = 3 ClingoContext.min_classes = 3 ClingoContext.min_interfaces = 4 ClingoContext.lower_bound = 1 ClingoContext.higher_bound = 5 ClingoContext.avg_width = 0 exp = """\ <?hh class S9 {} class S10 {} class S11 {} interface S0 {} interface S1 {} interface S2 {} interface S3 {} interface S4 extends S0 {} interface S5 {} interface S6 {} interface S7 {} interface S8 extends S4 {} """ hack_codegen = hackGenerator.HackCodeGenerator() hh_codesynthesis.do_reasoning( additional_programs=hh_codesynthesis.generate_logic_rules(), generator=hack_codegen, ) self.assertEqual(str(hack_codegen), exp)
def test_circular_type_method_dependency_with_rule_extraction_hack_codegen( self, ) -> None: exp = """\ <?hh class C implements Compare { public function dummy_C_method(C $C_obj): void{ $C_obj->content(); } public function content(): void{} public function eq(): void{} } interface Compare { public function dummy_Compare_method(C $C_obj): void; public function eq(): void; } """ deps = """\ Extends Compare -> Type C Method C::content -> Type C Method Compare::eq -> Type C Type C -> Type Compare Type Compare -> Type C """ self.extract_run_and_compare(deps, exp, hackGenerator.HackCodeGenerator())
def test_function_interface_with_rule_extraction_hack_codegen(self) -> None: exp = """\ <?hh class A implements I { public static function foo(): void{} } class B { public function dummy_B_method(A $A_obj): void{ F1(); } } class T { public function dummy_T_method(A $A_obj): void{ A::foo(); } } interface I {} function F0(I $I_obj): void { A::foo(); } function F1(): void { $A_obj = new A(); F0($A_obj); } """ deps = """\ Extends I -> Type A SMethod A::foo -> Fun F0, Type T Fun F0 -> Fun F1 Fun F1 -> Type B Type A -> Type B, Type T Type I -> Type A, Fun F0 """ self.extract_run_and_compare(deps, exp, hackGenerator.HackCodeGenerator())
def test_smethod_dependency_with_rule_extraction_hack_codegen(self) -> None: exp = """\ <?hh class A implements I { public static function foo(): void{} } class T { public function dummy_T_method(A $A_obj): void{ A::foo(); } } interface I {} function B(): void { A::foo(); } function C(): void { A::foo(); } """ deps = """\ Extends I -> Type A SMethod A::foo -> Fun B, Fun C, Type T Type A -> Fun B, Fun C, Type T Type I -> Type A """ self.extract_run_and_compare(deps, exp, hackGenerator.HackCodeGenerator())
def test_type_dependency_with_rule_extraction_hack_codegen(self) -> None: exp = """\ <?hh class A {} interface B { public function dummy_B_method(A $A_obj): void; } """ deps = """\ Type A -> Type B """ self.extract_run_and_compare(deps, exp, hackGenerator.HackCodeGenerator())
def test_unsatisfiable_parameters(self) -> None: # Given 5 nodes, but asking for 3 classes + 4 interfaces with ClingoContext.number_of_nodes = 5 ClingoContext.min_classes = 3 ClingoContext.min_interfaces = 4 hack_codegen = hackGenerator.HackCodeGenerator() with self.assertRaises(expected_exception=RuntimeError, msg="Unsatisfiable."): hh_codesynthesis.do_reasoning( additional_programs=hh_codesynthesis.generate_logic_rules(), generator=hack_codegen, )
def test_unsatisfiable_parameters(self) -> None: # Given 5 nodes, but asking for 3 classes + 4 interfaces with solving_context = ClingoContext(number_of_nodes=5, min_classes=3, min_interfaces=4) hack_codegen = hackGenerator.HackCodeGenerator(solving_context) with self.assertRaises(expected_exception=RuntimeError, msg="Unsatisfiable."): agentGenerator.do_reasoning( additional_programs=agentGenerator.generate_logic_rules( solving_context), generator=hack_codegen, )
def test_only_method_dependency_with_rule_extraction_hack_codegen(self) -> None: exp = """\ <?hh class B { public function dummy_B_method(A $A_obj): void{ $A_obj->foo(); } } interface A { public function foo(): void; } """ deps = """\ Method A::foo -> Type B """ self.extract_run_and_compare(deps, exp, hackGenerator.HackCodeGenerator())
def test_hack_output(self) -> None: exp = """\ <?hh class C1 {} class C2 extends C1 implements I1 {} interface I1 {} """ generator = hackGenerator.HackCodeGenerator() generator._add_class("C1") generator._add_class("C2") generator._add_interface("I1") generator._add_extend("C2", "C1") generator._add_implement("C2", "I1") with tempfile.NamedTemporaryFile("r") as fp: hh_codesynthesis.output_to_file_or_stdout(generator, fp.name) lines = fp.readlines() self.assertEqual("".join(lines), exp)
def test_extends_dependency_with_rule_extraction_hack_codegen(self) -> None: exp = """\ <?hh class B extends I implements A {} class I {} interface A extends T {} interface T {} """ deps = """\ Extends A -> Type B Extends I -> Type B Extends T -> Type A Type A -> Type B Type I -> Type B Type T -> Type A, Type B """ self.extract_run_and_compare(deps, exp, hackGenerator.HackCodeGenerator())
def test_extends_dependency_hack_codegen(self) -> None: exp = """\ <?hh class B extends I implements A {} class I {} interface A extends T {} interface T {} """ rules = [ 'extends_to("A", "B").', 'extends_to("I", "B").', 'extends_to("T", "A").', 'symbols("A";"B";"I";"T").', ] hack_codegen = hackGenerator.HackCodeGenerator() hh_codesynthesis.do_reasoning(additional_programs=rules, generator=hack_codegen) self.assertEqual(str(hack_codegen), exp)
def test_hack_code_gen_with_partial_dependency_graph_given_by_user(self) -> None: ClingoContext.number_of_nodes = 12 ClingoContext.min_depth = 3 ClingoContext.min_classes = 3 ClingoContext.min_interfaces = 4 ClingoContext.lower_bound = 1 ClingoContext.higher_bound = 5 ClingoContext.avg_width = 0 deps = """\ Extends A -> Type B Extends I -> Type B Extends T -> Type A Type A -> Type B Type I -> Type B Type T -> Type A, Type B""" exp = """\ <?hh class S9 {} class S10 {} class S11 {} interface A extends T {} interface B extends A,I {} interface I {} interface T {} interface S0 {} interface S1 {} interface S2 {} interface S3 {} interface S4 extends S0 {} interface S5 {} interface S6 {} interface S7 {} interface S8 extends S4 {} """ hack_codegen = hackGenerator.HackCodeGenerator() combined_rules = ( hh_codesynthesis.generate_logic_rules() + hh_codesynthesis.extract_logic_rules(deps.split("\n")) ) hh_codesynthesis.do_reasoning( additional_programs=combined_rules, generator=hack_codegen, ) self.assertEqual(str(hack_codegen), exp)
def test_method_and_extends_dependency_with_rule_extraction_hack_codegen_override( self, ) -> None: exp = """\ <?hh class B implements A { public function foo(): void{} } interface A { public function foo(): void; } """ deps = """\ Extends A -> Type B Method A::foo -> Type B Type A -> Type B """ self.extract_run_and_compare(deps, exp, hackGenerator.HackCodeGenerator())
def test_hack_code_gen_with_partial_dependency_graph_given_by_user( self) -> None: solving_context = ClingoContext( number_of_nodes=12, min_depth=3, min_classes=3, min_interfaces=4, lower_bound=1, higher_bound=5, ) deps = """\ Extends A -> Type B Extends I -> Type B Extends T -> Type A Type A -> Type B Type I -> Type B Type T -> Type A, Type B""" exp = """\ <?hh class S9 {} class S10 {} class S11 {} interface A extends T {} interface B extends A,I {} interface I {} interface T {} interface S0 {} interface S1 {} interface S2 {} interface S3 {} interface S4 extends S0 {} interface S5 {} interface S6 {} interface S7 {} interface S8 extends S4 {} """ hack_codegen = hackGenerator.HackCodeGenerator(solving_context) combined_rules = agentGenerator.generate_logic_rules( solving_context) + agentGenerator.extract_logic_rules( deps.split("\n")) agentGenerator.do_reasoning(additional_programs=combined_rules, generator=hack_codegen) self.assertEqual(str(hack_codegen), exp)
def test_hack_code_gen(self) -> None: solving_context = ClingoContext( number_of_nodes=12, min_depth=3, min_classes=3, min_interfaces=4, lower_bound=1, higher_bound=5, min_stub_classes=4, min_stub_interfaces=1, degree_distribution=[1, 3, 5], ) hack_codegen = hackGenerator.HackCodeGenerator(solving_context) agentGenerator.do_reasoning( additional_programs=agentGenerator.generate_logic_rules( solving_context), generator=hack_codegen, ) self.assertTrue(hack_codegen.validate())
def test_function_class_with_rule_extraction_hack_codegen(self) -> None: exp = """\ <?hh class A extends I {} class I {} interface B { public function dummy_B_method(A $A_obj): void; } interface T { public function dummy_T_method(A $A_obj): void; } function F0(): void { $I_obj = new I(); } """ deps = """\ Extends I -> Type A Type A -> Type B, Type T Type I -> Type A, Fun F0 """ self.extract_run_and_compare(deps, exp, hackGenerator.HackCodeGenerator())