brintos

brintos / llvm-project-archived public Read only

0
0
Text · 8.8 KiB · 954a3a4 Raw
271 lines · python
1"""2Test lldb-dap completions request3"""4 5import lldbdap_testcase6import dap_server7from lldbsuite.test import lldbutil8from lldbsuite.test.decorators import *9from lldbsuite.test.lldbtest import *10 11session_completion = {12    "text": "session",13    "label": "session -- Commands controlling LLDB session.",14}15settings_completion = {16    "text": "settings",17    "label": "settings -- Commands for managing LLDB settings.",18}19memory_completion = {20    "text": "memory",21    "label": "memory -- Commands for operating on memory in the current target process.",22}23command_var_completion = {24    "text": "var",25    "label": "var -- Show variables for the current stack frame. Defaults to all arguments and local variables in scope. Names of argument, local, file static and file global variables can be specified.",26}27variable_var_completion = {28    "text": "var",29    "label": "var -- vector<baz> &",30}31variable_var1_completion = {"text": "var1", "label": "var1 -- int &"}32variable_var2_completion = {"text": "var2", "label": "var2 -- int &"}33 34 35# Older version of libcxx produce slightly different typename strings for36# templates like vector.37@skipIf(compiler="clang", compiler_version=["<", "16.0"])38class TestDAP_completions(lldbdap_testcase.DAPTestCaseBase):39    def verify_completions(self, actual_list, expected_list, not_expected_list=[]):40        for expected_item in expected_list:41            self.assertIn(expected_item, actual_list)42 43        for not_expected_item in not_expected_list:44            self.assertNotIn(not_expected_item, actual_list)45 46    def setup_debuggee(self):47        program = self.getBuildArtifact("a.out")48        source = "main.cpp"49        self.build_and_launch(program)50        self.set_source_breakpoints(51            source,52            [53                line_number(source, "// breakpoint 1"),54                line_number(source, "// breakpoint 2"),55            ],56        )57 58    def test_command_completions(self):59        """60        Tests completion requests for lldb commands, within "repl-mode=command"61        """62        self.setup_debuggee()63        self.continue_to_next_stop()64 65        res = self.dap_server.request_evaluate(66            "`lldb-dap repl-mode command", context="repl"67        )68        self.assertTrue(res["success"])69 70        # Provides completion for top-level commands71        self.verify_completions(72            self.dap_server.get_completions("se"),73            [session_completion, settings_completion],74        )75 76        # Provides completions for sub-commands77        self.verify_completions(78            self.dap_server.get_completions("memory "),79            [80                {81                    "text": "read",82                    "label": "read -- Read from the memory of the current target process.",83                },84                {85                    "text": "region",86                    "label": "region -- Get information on the memory region containing an address in the current target process.",87                },88            ],89        )90 91        # Provides completions for parameter values of commands92        self.verify_completions(93            self.dap_server.get_completions("`log enable  "),94            [{"text": "gdb-remote", "label": "gdb-remote"}],95        )96 97        # Also works if the escape prefix is used98        self.verify_completions(99            self.dap_server.get_completions("`mem"), [memory_completion]100        )101 102        self.verify_completions(103            self.dap_server.get_completions("`"),104            [session_completion, settings_completion, memory_completion],105        )106 107        # Completes an incomplete quoted token108        self.verify_completions(109            self.dap_server.get_completions('setting "se'),110            [111                {112                    "text": "set",113                    "label": "set -- Set the value of the specified debugger setting.",114                }115            ],116        )117 118        # Completes an incomplete quoted token119        self.verify_completions(120            self.dap_server.get_completions("'mem"),121            [memory_completion],122        )123 124        # Completes expressions with quotes inside125        self.verify_completions(126            self.dap_server.get_completions('expr " "; typed'),127            [{"text": "typedef", "label": "typedef"}],128        )129 130        # Provides completions for commands, but not variables131        self.verify_completions(132            self.dap_server.get_completions("var"),133            [command_var_completion],134            [variable_var_completion],135        )136 137    def test_variable_completions(self):138        """139        Tests completion requests in "repl-mode=variable"140        """141        self.setup_debuggee()142        self.continue_to_next_stop()143 144        res = self.dap_server.request_evaluate(145            "`lldb-dap repl-mode variable", context="repl"146        )147        self.assertTrue(res["success"])148 149        # Provides completions for varibles, but not command150        self.verify_completions(151            self.dap_server.get_completions("var"),152            [variable_var_completion],153            [command_var_completion],154        )155 156        # We stopped inside `fun`, so we shouldn't see variables from main157        self.verify_completions(158            self.dap_server.get_completions("var"),159            [variable_var_completion],160            [161                variable_var1_completion,162                variable_var2_completion,163            ],164        )165 166        # We should see global keywords but not variables inside main167        self.verify_completions(168            self.dap_server.get_completions("str"),169            [{"text": "struct", "label": "struct"}],170            [{"text": "str1", "label": "str1 -- std::string &"}],171        )172 173        self.continue_to_next_stop()174 175        # We stopped in `main`, so we should see variables from main but176        # not from the other function177        self.verify_completions(178            self.dap_server.get_completions("var"),179            [180                variable_var1_completion,181                variable_var2_completion,182            ],183            [184                variable_var_completion,185            ],186        )187 188        self.verify_completions(189            self.dap_server.get_completions("str"),190            [191                {"text": "struct", "label": "struct"},192                {"text": "str1", "label": "str1 -- std::string &"},193            ],194        )195 196        # Completion also works for more complex expressions197        self.verify_completions(198            self.dap_server.get_completions("foo1.v"),199            [{"text": "var1", "label": "foo1.var1 -- int"}],200        )201 202        self.verify_completions(203            self.dap_server.get_completions("foo1.my_bar_object.v"),204            [{"text": "var1", "label": "foo1.my_bar_object.var1 -- int"}],205        )206 207        self.verify_completions(208            self.dap_server.get_completions("foo1.var1 + foo1.v"),209            [{"text": "var1", "label": "foo1.var1 -- int"}],210        )211 212        self.verify_completions(213            self.dap_server.get_completions("foo1.var1 + v"),214            [{"text": "var1", "label": "var1 -- int &"}],215        )216 217        # should correctly handle spaces between objects and member operators218        self.verify_completions(219            self.dap_server.get_completions("foo1 .v"),220            [{"text": "var1", "label": ".var1 -- int"}],221            [{"text": "var2", "label": ".var2 -- int"}],222        )223 224        self.verify_completions(225            self.dap_server.get_completions("foo1 . v"),226            [{"text": "var1", "label": "var1 -- int"}],227            [{"text": "var2", "label": "var2 -- int"}],228        )229 230        # Even in variable mode, we can still use the escape prefix231        self.verify_completions(232            self.dap_server.get_completions("`mem"), [memory_completion]233        )234 235    def test_auto_completions(self):236        """237        Tests completion requests in "repl-mode=auto"238        """239        self.setup_debuggee()240 241        res = self.dap_server.request_evaluate(242            "`lldb-dap repl-mode auto", context="repl"243        )244        self.assertTrue(res["success"])245 246        self.continue_to_next_stop()247        self.continue_to_next_stop()248 249        # We are stopped inside `main`. Variables `var1` and `var2` are in scope.250        # Make sure, we offer all completions251        self.verify_completions(252            self.dap_server.get_completions("va"),253            [254                command_var_completion,255                variable_var1_completion,256                variable_var2_completion,257            ],258        )259 260        # If we are using the escape prefix, only commands are suggested, but no variables261        self.verify_completions(262            self.dap_server.get_completions("`va"),263            [264                command_var_completion,265            ],266            [267                variable_var1_completion,268                variable_var2_completion,269            ],270        )271