brintos

brintos / llvm-project-archived public Read only

0
0
Text · 13.8 KiB · 9557378 Raw
366 lines · python
1"""2Test lldb-dap evaluate request3"""4 5import re6 7import lldbdap_testcase8from lldbsuite.test.decorators import skipIfWindows9from lldbsuite.test.lldbtest import line_number10from typing import TypedDict, Optional11 12 13class EvaluateResponseBody(TypedDict, total=False):14    result: str15    variablesReference: int16    type: Optional[str]17    memoryReference: Optional[str]18    valueLocationReference: Optional[int]19 20 21class TestDAP_evaluate(lldbdap_testcase.DAPTestCaseBase):22    def assertEvaluate(23        self,24        expression,25        result: str,26        want_type="",27        want_varref=False,28        want_memref=True,29        want_locref=False,30        is_hex=None,31    ):32        resp = self.dap_server.request_evaluate(33            expression, context=self.context, is_hex=is_hex34        )35        self.assertTrue(36            resp["success"], f"Failed to evaluate expression {expression!r}"37        )38        body: EvaluateResponseBody = resp["body"]39        self.assertRegex(40            body["result"],41            result,42            f"Unexpected 'result' for expression {expression!r} in response body {body}",43        )44        if want_varref:45            self.assertNotEqual(46                body["variablesReference"],47                0,48                f"Unexpected 'variablesReference' for expression {expression!r} in response body {body}",49            )50        else:51            self.assertEqual(52                body["variablesReference"],53                0,54                f"Unexpected 'variablesReference' for expression {expression!r} in response body {body}",55            )56        if want_type:57            self.assertEqual(58                body["type"],59                want_type,60                f"Unexpected 'type' for expression {expression!r} in response body {body}",61            )62        if want_memref:63            self.assertIn(64                "memoryReference",65                body,66                f"Unexpected 'memoryReference' for expression {expression!r} in response body {body}",67            )68        if want_locref:69            self.assertIn(70                "valueLocationReference",71                body,72                f"Unexpected 'valueLocationReference' for expression {expression!r} in response body {body}",73            )74 75    def assertEvaluateFailure(self, expression):76        self.assertNotIn(77            "result",78            self.dap_server.request_evaluate(expression, context=self.context)["body"],79        )80 81    def isResultExpandedDescription(self):82        return self.context == "repl"83 84    def isExpressionParsedExpected(self):85        return self.context != "hover"86 87    def run_test_evaluate_expressions(88        self, context=None, enableAutoVariableSummaries=False89    ):90        """91        Tests the evaluate expression request at different breakpoints92        """93        self.context = context94        program = self.getBuildArtifact("a.out")95        self.build_and_launch(96            program,97            enableAutoVariableSummaries=enableAutoVariableSummaries,98        )99        source = "main.cpp"100        breakpoint_lines = [101            line_number(source, "// breakpoint 1"),102            line_number(source, "// breakpoint 2"),103            line_number(source, "// breakpoint 3"),104            line_number(source, "// breakpoint 4"),105            line_number(source, "// breakpoint 5"),106            line_number(source, "// breakpoint 6"),107            line_number(source, "// breakpoint 7"),108            line_number(source, "// breakpoint 8"),109        ]110        breakpoint_ids = self.set_source_breakpoints(source, breakpoint_lines)111 112        self.assertEqual(113            len(breakpoint_ids),114            len(breakpoint_lines),115            "Did not resolve all the breakpoints.",116        )117        breakpoint_1 = breakpoint_ids[0]118        breakpoint_2 = breakpoint_ids[1]119        breakpoint_3 = breakpoint_ids[2]120        breakpoint_4 = breakpoint_ids[3]121        breakpoint_5 = breakpoint_ids[4]122        breakpoint_6 = breakpoint_ids[5]123        breakpoint_7 = breakpoint_ids[6]124        breakpoint_8 = breakpoint_ids[7]125        self.continue_to_breakpoint(breakpoint_1)126 127        # Expressions at breakpoint 1, which is in main128        self.assertEvaluate("var1", "20", want_type="int")129        # Empty expression should equate to the previous expression.130        if context == "repl":131            self.assertEvaluate("", "20")132        else:133            self.assertEvaluateFailure("")134        self.assertEvaluate("var2", "21", want_type="int")135        if context == "repl":136            self.assertEvaluate("", "21", want_type="int")137            self.assertEvaluate("", "21", want_type="int")138        self.assertEvaluate("static_int", "0x0000002a", want_type="int", is_hex=True)139        self.assertEvaluate(140            "non_static_int", "0x0000002b", want_type="int", is_hex=True141        )142        self.assertEvaluate("struct1.foo", "0x0000000f", want_type="int", is_hex=True)143        self.assertEvaluate("struct2->foo", "0x00000010", want_type="int", is_hex=True)144        self.assertEvaluate("static_int", "42", want_type="int")145        self.assertEvaluate("non_static_int", "43", want_type="int")146        self.assertEvaluate("struct1.foo", "15", want_type="int")147        self.assertEvaluate("struct2->foo", "16", want_type="int")148 149        if self.isResultExpandedDescription():150            self.assertEvaluate(151                "struct1",152                r"\(my_struct\) (struct1|\$\d+) = \(foo = 15\)",153                want_type="my_struct",154                want_varref=True,155            )156            self.assertEvaluate(157                "struct2",158                r"\(my_struct \*\) (struct2|\$\d+) = 0x.*",159                want_type="my_struct *",160                want_varref=True,161            )162            self.assertEvaluate(163                "struct3",164                r"\(my_struct \*\) (struct3|\$\d+) = nullptr",165                want_type="my_struct *",166                want_varref=True,167            )168        else:169            self.assertEvaluate(170                "struct1",171                (172                    re.escape("{foo:15}")173                    if enableAutoVariableSummaries174                    else "my_struct @ 0x"175                ),176                want_varref=True,177            )178            self.assertEvaluate(179                "struct2",180                "0x.* {foo:16}" if enableAutoVariableSummaries else "0x.*",181                want_varref=True,182                want_type="my_struct *",183            )184            self.assertEvaluate(185                "struct3", "0x.*0", want_varref=True, want_type="my_struct *"186            )187 188        if context == "repl":189            # In the repl context expressions may be interpreted as lldb190            # commands since no variables have the same name as the command.191            self.assertEvaluate("list", r".*", want_memref=False)192        else:193            self.assertEvaluateFailure("list")  # local variable of a_function194 195        self.assertEvaluateFailure("my_struct")  # type name196        self.assertEvaluateFailure("int")  # type name197        self.assertEvaluateFailure("foo")  # member of my_struct198 199        if self.isExpressionParsedExpected():200            self.assertEvaluate(201                "a_function",202                "0x.*a.out`a_function.*",203                want_type="int (*)(int)",204                want_varref=True,205                want_memref=False,206                want_locref=True,207            )208            self.assertEvaluate(209                "a_function(1)", "1", want_memref=False, want_type="int"210            )211            self.assertEvaluate("var2 + struct1.foo", "36", want_memref=False)212            self.assertEvaluate(213                "foo_func",214                "0x.*a.out`foo_func.*",215                want_type="int (*)()",216                want_varref=True,217                want_memref=False,218                want_locref=True,219            )220            self.assertEvaluate("foo_var", "44")221        else:222            self.assertEvaluateFailure("a_function")223            self.assertEvaluateFailure("a_function(1)")224            self.assertEvaluateFailure("var2 + struct1.foo")225            self.assertEvaluateFailure("foo_func")226            self.assertEvaluate("foo_var", "44")227 228        # Expressions at breakpoint 2, which is an anonymous block229        self.continue_to_breakpoint(breakpoint_2)230        self.assertEvaluate("var1", "20")231        self.assertEvaluate("var2", "2")  # different variable with the same name232        self.assertEvaluate("static_int", "42")233        self.assertEvaluate(234            "non_static_int", "10"235        )  # different variable with the same name236        if self.isResultExpandedDescription():237            self.assertEvaluate(238                "struct1",239                r"\(my_struct\) (struct1|\$\d+) = \(foo = 15\)",240                want_type="my_struct",241                want_varref=True,242            )243        else:244            self.assertEvaluate(245                "struct1",246                (247                    re.escape("{foo:15}")248                    if enableAutoVariableSummaries249                    else "my_struct @ 0x"250                ),251                want_type="my_struct",252                want_varref=True,253            )254        self.assertEvaluate("struct1.foo", "15")255        self.assertEvaluate("struct2->foo", "16")256 257        if self.isExpressionParsedExpected():258            self.assertEvaluate(259                "a_function",260                "0x.*a.out`a_function.*",261                want_type="int (*)(int)",262                want_varref=True,263                want_memref=False,264                want_locref=True,265            )266            self.assertEvaluate("a_function(1)", "1", want_memref=False)267            self.assertEvaluate("var2 + struct1.foo", "17", want_memref=False)268            self.assertEvaluate(269                "foo_func", "0x.*a.out`foo_func.*", want_varref=True, want_memref=False270            )271            self.assertEvaluate("foo_var", "44")272        else:273            self.assertEvaluateFailure("a_function")274            self.assertEvaluateFailure("a_function(1)")275            self.assertEvaluateFailure("var2 + struct1.foo")276            self.assertEvaluateFailure("foo_func")277            self.assertEvaluate("foo_var", "44")278 279        # Expressions at breakpoint 3, which is inside a_function280        self.continue_to_breakpoint(breakpoint_3)281        self.assertEvaluate("list", "42")282        self.assertEvaluate("static_int", "42")283        self.assertEvaluate("non_static_int", "43")284 285        self.assertEvaluateFailure("var1")286        self.assertEvaluateFailure("var2")287        self.assertEvaluateFailure("struct1")288        self.assertEvaluateFailure("struct1.foo")289        self.assertEvaluateFailure("struct2->foo")290        self.assertEvaluateFailure("var2 + struct1.foo")291 292        if self.isExpressionParsedExpected():293            self.assertEvaluate(294                "a_function",295                "0x.*a.out`a_function.*",296                want_varref=True,297                want_memref=False,298                want_locref=True,299            )300            self.assertEvaluate("a_function(1)", "1", want_memref=False)301            self.assertEvaluate("list + 1", "43", want_memref=False)302            self.assertEvaluate(303                "foo_func", "0x.*a.out`foo_func.*", want_varref=True, want_memref=False304            )305            self.assertEvaluate("foo_var", "44")306        else:307            self.assertEvaluateFailure("a_function")308            self.assertEvaluateFailure("a_function(1)")309            self.assertEvaluateFailure("list + 1")310            self.assertEvaluateFailure("foo_func")311            self.assertEvaluate("foo_var", "44")312 313        # Now we check that values are updated after stepping314        self.continue_to_breakpoint(breakpoint_4)315        self.assertEvaluate("my_vec", "size=2", want_varref=True)316        self.continue_to_breakpoint(breakpoint_5)317        self.assertEvaluate("my_vec", "size=3", want_varref=True)318 319        self.assertEvaluate("my_map", "size=2", want_varref=True)320        self.continue_to_breakpoint(breakpoint_6)321        self.assertEvaluate("my_map", "size=3", want_varref=True)322 323        self.assertEvaluate("my_bool_vec", "size=1", want_varref=True)324        self.continue_to_breakpoint(breakpoint_7)325        self.assertEvaluate("my_bool_vec", "size=2", want_varref=True)326 327        self.continue_to_breakpoint(breakpoint_8)328        # Test memory read, especially with 'empty' repeat commands.329        if context == "repl":330            self.assertEvaluate(331                "memory read -c 1 &my_ints", ".* 05 .*\n", want_memref=False332            )333            self.assertEvaluate("", ".* 0a .*\n", want_memref=False)334            self.assertEvaluate("", ".* 0f .*\n", want_memref=False)335            self.assertEvaluate("", ".* 14 .*\n", want_memref=False)336            self.assertEvaluate("", ".* 19 .*\n", want_memref=False)337 338        self.continue_to_exit()339 340    @skipIfWindows341    def test_generic_evaluate_expressions(self):342        # Tests context-less expression evaluations343        self.run_test_evaluate_expressions(enableAutoVariableSummaries=False)344 345    @skipIfWindows346    def test_repl_evaluate_expressions(self):347        # Tests expression evaluations that are triggered from the Debug Console348        self.run_test_evaluate_expressions("repl", enableAutoVariableSummaries=False)349 350    @skipIfWindows351    def test_watch_evaluate_expressions(self):352        # Tests expression evaluations that are triggered from a watch expression353        self.run_test_evaluate_expressions("watch", enableAutoVariableSummaries=True)354 355    @skipIfWindows356    def test_hover_evaluate_expressions(self):357        # Tests expression evaluations that are triggered when hovering on the editor358        self.run_test_evaluate_expressions("hover", enableAutoVariableSummaries=False)359 360    @skipIfWindows361    def test_variable_evaluate_expressions(self):362        # Tests expression evaluations that are triggered in the variable explorer363        self.run_test_evaluate_expressions(364            "variables", enableAutoVariableSummaries=True365        )366