def test_unexpected_rhs(self) -> None: deps = """\ Type A -> SMethod B::foo """ with self.assertRaises( expected_exception=NotImplementedError, msg="Not supported SMethod on the right hand side.", ): hh_codesynthesis.extract_logic_rules(deps.split("\n"))
def test_extends_dependency_with_rule_extraction(self) -> None: exp = [ 'add_method("A","foo")', 'add_method("B","foo")', 'class("B")', 'class("I")', 'extends("A","T")', 'extends("B","I")', 'implements("B","A")', 'interface("A")', 'interface("T")', ] deps = """\ Extends A -> Type B Extends I -> Type B Extends T -> Type A Method A::foo -> Type B Type A -> Type B Type I -> Type B Type T -> Type A, Type B """ raw_codegen = hh_codesynthesis.CodeGenerator() additional_programs = hh_codesynthesis.extract_logic_rules(deps.split("\n")) hh_codesynthesis.do_reasoning( additional_programs=additional_programs, generator=raw_codegen ) self.assertListEqual(sorted(str(raw_codegen).split()), exp)
def test_multiple_lines(self) -> None: exp = [ 'extends_to("I1", "C1").', 'extends_to("I1", "C2").', 'extends_to("I1", "C3").', 'extends_to("I1", "I2").', 'extends_to("I3", "C4").', 'extends_to("I4", "C5").', 'symbols("C1";"C2";"C3";"C4";"C5";"I1";"I2";"I3";"I4").', ] deps = """\ Extends I1 -> Type C1, Type C2, Type C3, Type I2 Extends I3 -> Type C4, Type C6, Type I5, Type I6, Type I7, Type I8 Extends I4 -> Type C5, Type C6, Type I9, Type I10, Type I11, Type I12, Type I13, Type I14""" self.assertListEqual( exp, hh_codesynthesis.extract_logic_rules(deps.split("\n")) )
def test_read(self) -> None: exp = [ 'extends_to("A", "B").', 'extends_to("I", "B").', 'extends_to("T", "A").', 'method("A", "foo", "B").', 'type("A", "B").', 'type("I", "B").', 'type("T", "A").', 'type("T", "B").', 'symbols("A";"B";"I";"T").', ] deps = """\ Extends A -> Type B Extends I -> Type B Extends T -> Type A Method A::foo -> Type B Type A -> Type B Type I -> Type B Type T -> Type A, Type B """ with tempfile.NamedTemporaryFile(mode="w") as fp: fp.write(deps) fp.flush() self.assertListEqual( exp, hh_codesynthesis.extract_logic_rules( hh_codesynthesis.read_from_file_or_stdin(fp.name)), )
def extract_run_and_compare( self, deps: str, exp: str, generator: hh_codesynthesis.CodeGenerator ) -> None: additional_programs = hh_codesynthesis.extract_logic_rules(deps.split("\n")) hh_codesynthesis.do_reasoning( additional_programs=additional_programs, generator=generator ) self.assertEqual(str(generator), exp)
def test_unsupported_type_dependency(self) -> None: # T94428437 Temporary skipping all built-in functions for now. exp = [ 'extends_to("A", "B").', 'type("A", "B").', 'symbols("A";"B").', ] deps = r""" Extends A -> Type B Type A -> Type B Type HH\Capabilities\AccessGlobals -> Type B Type HH\Contexts\Unsafe\globals -> Type A""" self.assertListEqual( exp, hh_codesynthesis.extract_logic_rules(deps.split("\n")))
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_multiple_lines_all(self) -> None: # T92303034 Temporary handle for the multiple lines using replace(",\n", ","), exp = [ 'extends_to("I1", "C1").', 'extends_to("I1", "C2").', 'extends_to("I1", "C3").', 'extends_to("I1", "I2").', 'extends_to("I3", "C4").', 'extends_to("I3", "C6").', 'extends_to("I3", "I5").', 'extends_to("I3", "I6").', 'extends_to("I3", "I7").', 'extends_to("I3", "I8").', 'extends_to("I4", "C5").', 'extends_to("I4", "C6").', 'extends_to("I4", "I9").', 'extends_to("I4", "I10").', 'extends_to("I4", "I11").', 'extends_to("I4", "I12").', 'extends_to("I4", "I13").', 'extends_to("I4", "I14").', 'symbols("C1";"C2";"C3";"C4";"C5";"C6";"I1";"I10";"I11";"I12";"I13";"I14";"I2";"I3";"I4";"I5";"I6";"I7";"I8";"I9").', ] deps = """\ Extends I1 -> Type C1, Type C2, Type C3, Type I2 Extends I3 -> Type C4, Type C6, Type I5, Type I6, Type I7, Type I8 Extends I4 -> Type C5, Type C6, Type I9, Type I10, Type I11, Type I12, Type I13, Type I14""" self.assertListEqual( exp, hh_codesynthesis.extract_logic_rules( deps.replace(",\n", ",").split("\n")), )
def test_extends_type_fun_dependency(self) -> None: exp = [ 'extends_to("I", "A").', 'method("I", "bar", "A").', 'invoked_by("F", "A").', 'type("A", "B").', 'type("A", "T").', 'type("I", "A").', 'symbols("A";"B";"I";"T").', 'funcs("F").', ] deps = """\ Extends I -> Type A Method I::bar -> Type A Fun F -> Type A Type A -> Type B, Type T Type I -> Type A""" self.assertListEqual( exp, hh_codesynthesis.extract_logic_rules(deps.split("\n")))
def test_extends_type_smethod_dependency(self) -> None: exp = [ 'extends_to("I", "A").', 'method("I", "bar", "A").', 'static_method("A", "foo", "B").', 'static_method("A", "foo", "T").', 'type("A", "B").', 'type("A", "T").', 'type("I", "A").', 'symbols("A";"I";"T").', 'funcs("B").', ] deps = """\ Extends I -> Type A Method I::bar -> Type A SMethod A::foo -> Fun B, Type T Type A -> Fun B, Type T Type I -> Type A""" self.assertListEqual( exp, hh_codesynthesis.extract_logic_rules(deps.split("\n")))
def test_extends_type_method_dependency(self) -> None: exp = [ 'extends_to("A", "B").', 'extends_to("I", "B").', 'extends_to("T", "A").', 'method("A", "foo", "B").', 'type("A", "B").', 'type("I", "B").', 'type("T", "A").', 'type("T", "B").', 'symbols("A";"B";"I";"T").', ] deps = """\ Extends A -> Type B Extends I -> Type B Extends T -> Type A Method A::foo -> Type B Type A -> Type B Type I -> Type B Type T -> Type A, Type B""" self.assertListEqual( exp, hh_codesynthesis.extract_logic_rules(deps.split("\n")))
def test_non_exist(self) -> None: test_file = "non_exist.in" with self.assertRaises(expected_exception=FileNotFoundError): hh_codesynthesis.extract_logic_rules( hh_codesynthesis.read_from_file_or_stdin(test_file) )