brintos

brintos / llvm-project-archived public Read only

0
0
Text · 37.7 KiB · 45750c7 Raw
949 lines · python
1"""2Test the lldb command line completion mechanism.3"""4 5 6import os7from multiprocessing import Process8import lldb9from lldbsuite.test.decorators import *10from lldbsuite.test.lldbtest import *11from lldbsuite.test import lldbplatform12from lldbsuite.test import lldbutil13 14 15class CommandLineCompletionTestCase(TestBase):16    NO_DEBUG_INFO_TESTCASE = True17 18    @classmethod19    def classCleanup(cls):20        """Cleanup the test byproducts."""21        try:22            os.remove("child_send.txt")23            os.remove("child_read.txt")24        except:25            pass26 27    def test_at(self):28        """Test that 'at' completes to 'attach '."""29        self.complete_from_to("at", "attach ")30 31    def test_de(self):32        """Test that 'de' completes to 'detach '."""33        self.complete_from_to("de", "detach ")34 35    def test_frame_variable(self):36        self.build()37 38        _, process, _, _ = lldbutil.run_to_source_breakpoint(39            self, "// Break here", lldb.SBFileSpec("main.cpp")40        )41        self.assertState(process.GetState(), lldb.eStateStopped)42 43        # Since CommandInterpreter has been corrected to update the current execution44        # context at the beginning of HandleCompletion, we're here explicitly testing45        # the scenario where "frame var" is completed without any preceding commands.46        self.do_test_variable_completion("frame variable")47 48    def test_dwim_print(self):49        self.build()50 51        _, process, _, _ = lldbutil.run_to_source_breakpoint(52            self, "// Break here", lldb.SBFileSpec("main.cpp")53        )54        self.assertState(process.GetState(), lldb.eStateStopped)55 56        # Since CommandInterpreter has been corrected to update the current execution57        # context at the beginning of HandleCompletion, we're here explicitly testing58        # the scenario where "frame var" is completed without any preceding commands.59        self.do_test_variable_completion("dwim-print")60 61    def do_test_variable_completion(self, command):62        self.complete_from_to(f"{command} fo", f"{command} fooo")63        self.complete_from_to(f"{command} fooo.", f"{command} fooo.t")64        self.complete_from_to(f"{command} fooo.t.", f"{command} fooo.t.x")65        self.complete_from_to(f"{command} fooo.dd", f"{command} fooo.dd")66 67        self.complete_from_to(f"{command} ptr_fooo->", f"{command} ptr_fooo->t")68        self.complete_from_to(f"{command} ptr_fooo->t.", f"{command} ptr_fooo->t.x")69        self.complete_from_to(f"{command} ptr_fooo->dd", f"{command} ptr_fooo->dd")70 71        self.complete_from_to(f"{command} cont", f"{command} container")72        self.complete_from_to(f"{command} container.", f"{command} container.MemberVar")73        self.complete_from_to(74            f"{command} container.Mem", f"{command} container.MemberVar"75        )76 77        self.complete_from_to(f"{command} ptr_cont", f"{command} ptr_container")78        self.complete_from_to(79            f"{command} ptr_container->", f"{command} ptr_container->MemberVar"80        )81        self.complete_from_to(82            f"{command} ptr_container->Mem", f"{command} ptr_container->MemberVar"83        )84 85    def test_process_attach_dash_dash_con(self):86        """Test that 'process attach --con' completes to 'process attach --continue '."""87        self.complete_from_to("process attach --con", "process attach --continue ")88 89    def test_process_launch_arch(self):90        self.complete_from_to("process launch --arch ", ["mips", "arm64"])91 92    def test_process_load(self):93        self.build()94        lldbutil.run_to_source_breakpoint(95            self, "// Break here", lldb.SBFileSpec("main.cpp")96        )97        self.complete_from_to("process load Makef", "process load Makefile")98 99    @skipUnlessPlatform(["linux"])100    def test_process_unload(self):101        """Test the completion for "process unload <index>" """102        # This tab completion should not work without a running process.103        self.complete_from_to("process unload ", "process unload ")104 105        self.build()106        lldbutil.run_to_source_breakpoint(107            self, "// Break here", lldb.SBFileSpec("main.cpp")108        )109        err = lldb.SBError()110        local_spec = lldb.SBFileSpec(self.getBuildArtifact("libshared.so"))111        if lldb.remote_platform:112            self.process().LoadImage(113                local_spec,114                lldb.SBFileSpec(115                    lldbutil.append_to_process_working_directory(self, "libshared.so"),116                    False,117                ),118                err,119            )120        else:121            self.process().LoadImage(local_spec, err)122        self.assertSuccess(err)123 124        self.complete_from_to("process unload ", "process unload 0")125 126        self.process().UnloadImage(0)127        self.complete_from_to("process unload ", "process unload ")128 129    def test_process_plugin_completion(self):130        subcommands = ["attach -P", "connect -p", "launch -p"]131 132        for subcommand in subcommands:133            self.complete_from_to(134                "process " + subcommand + " mac",135                "process " + subcommand + " mach-o-core",136            )137 138    def completions_contain_str(self, input, needle):139        interp = self.dbg.GetCommandInterpreter()140        match_strings = lldb.SBStringList()141        num_matches = interp.HandleCompletion(input, len(input), 0, -1, match_strings)142        found_needle = False143        for match in match_strings:144            if needle in match:145                found_needle = True146                break147        self.assertTrue(148            found_needle, "Returned completions: " + "\n".join(match_strings)149        )150 151    @skipIfRemote152    def test_common_completion_process_pid_and_name(self):153        # The LLDB process itself and the process already attached to are both154        # ignored by the process discovery mechanism, thus we need a process known155        # to us here.156        self.build()157        server = self.spawnSubprocess(158            self.getBuildArtifact("a.out"),159            [160                "-x"161            ],  # Arg "-x" makes the subprocess wait for input thus it won't be terminated too early162            install_remote=False,163        )164        self.assertIsNotNone(server)165        pid = server.pid166 167        self.completions_contain("process attach -p ", [str(pid)])168        self.completions_contain("platform process attach -p ", [str(pid)])169        self.completions_contain("platform process info ", [str(pid)])170 171        self.completions_contain_str("process attach -n ", "a.out")172        self.completions_contain_str("platform process attach -n ", "a.out")173 174    def test_process_signal(self):175        # The tab completion for "process signal"  won't work without a running process.176        self.complete_from_to("process signal ", "process signal ")177 178        # Test with a running process.179        self.build()180        self.main_source = "main.cpp"181        self.main_source_spec = lldb.SBFileSpec(self.main_source)182        lldbutil.run_to_source_breakpoint(self, "// Break here", self.main_source_spec)183 184        self.complete_from_to("process signal ", "process signal SIG")185        self.complete_from_to("process signal SIGPIP", "process signal SIGPIPE")186        self.complete_from_to("process signal SIGA", ["SIGABRT", "SIGALRM"])187 188    def test_ambiguous_long_opt(self):189        self.completions_match(190            "breakpoint modify --th", ["--thread-id", "--thread-index", "--thread-name"]191        )192 193    def test_disassemble_dash_f(self):194        self.completions_match("disassemble -F ", ["default", "intel", "att"])195 196    def test_plugin_load(self):197        self.complete_from_to("plugin load ", [])198 199    def test_log_enable(self):200        self.complete_from_to("log disable ll", ["lldb"])201        self.complete_from_to("log disable dw", ["dwarf"])202        self.complete_from_to("log disable lldb al", ["all"])203        self.complete_from_to("log disable lldb sym", ["symbol"])204 205    def test_log_list(self):206        self.complete_from_to("log list ll", ["lldb"])207        self.complete_from_to("log list dw", ["dwarf"])208        self.complete_from_to("log list ll", ["lldb"])209        self.complete_from_to("log list lldb dwa", ["dwarf"])210 211    def test_quoted_command(self):212        self.complete_from_to('"set', ['"settings" '])213 214    def test_quoted_arg_with_quoted_command(self):215        self.complete_from_to('"settings" "repl', ['"replace" '])216 217    def test_quoted_arg_without_quoted_command(self):218        self.complete_from_to('settings "repl', ['"replace" '])219 220    def test_single_quote_command(self):221        self.complete_from_to("'set", ["'settings' "])222 223    def test_terminated_quote_command(self):224        # This should not crash, but we don't get any225        # reasonable completions from this.226        self.complete_from_to("'settings'", [])227 228    def test_process_launch_arch_arm(self):229        self.complete_from_to("process launch --arch arm", ["arm64"])230 231    def test_target_symbols_add_shlib(self):232        # Doesn't seem to work, but at least it shouldn't crash.233        self.complete_from_to("target symbols add --shlib ", [])234 235    def test_log_file(self):236        # Complete in our source directory which contains a 'main.cpp' file.237        src_dir = self.getSourceDir() + "/"238        self.complete_from_to("log enable lldb expr -f " + src_dir, ["main.cpp"])239 240    def test_log_dir(self):241        # Complete our source directory.242        src_dir = os.path.dirname(os.path.realpath(__file__))243        self.complete_from_to("log enable lldb expr -f " + src_dir, [src_dir + os.sep])244 245    # <rdar://problem/11052829>246    def test_infinite_loop_while_completing(self):247        """Test that 'process print hello\' completes to itself and does not infinite loop."""248        self.complete_from_to("process print hello\\", "process print hello\\")249 250    def test_watchpoint_co(self):251        """Test that 'watchpoint co' completes to 'watchpoint command '."""252        self.complete_from_to("watchpoint co", "watchpoint command ")253 254    def test_watchpoint_command_space(self):255        """Test that 'watchpoint command ' completes to ['add', 'delete', 'list']."""256        self.complete_from_to("watchpoint command ", ["add", "delete", "list"])257 258    def test_watchpoint_command_a(self):259        """Test that 'watchpoint command a' completes to 'watchpoint command add '."""260        self.complete_from_to("watchpoint command a", "watchpoint command add ")261 262    def test_watchpoint_set_ex(self):263        """Test that 'watchpoint set ex' completes to 'watchpoint set expression '."""264        self.complete_from_to("watchpoint set ex", "watchpoint set expression ")265 266    def test_watchpoint_set_var(self):267        """Test that 'watchpoint set var' completes to 'watchpoint set variable '."""268        self.complete_from_to("watchpoint set var", "watchpoint set variable ")269 270    def test_watchpoint_set_variable_foo(self):271        self.build()272        lldbutil.run_to_source_breakpoint(273            self, "// Break here", lldb.SBFileSpec("main.cpp")274        )275        self.complete_from_to(276            "watchpoint set variable fo", "watchpoint set variable fooo"277        )278        # Only complete the first argument.279        self.complete_from_to(280            "watchpoint set variable fooo ", "watchpoint set variable fooo "281        )282 283    def test_help_fi(self):284        """Test that 'help fi' completes to ['file', 'finish']."""285        self.complete_from_to("help fi", ["file", "finish"])286 287    def test_help_watchpoint_s(self):288        """Test that 'help watchpoint s' completes to 'help watchpoint set '."""289        self.complete_from_to("help watchpoint s", "help watchpoint set ")290 291    @expectedFailureNetBSD292    @add_test_categories(["watchpoint"])293    def test_common_complete_watchpoint_ids(self):294        subcommands = ["enable", "disable", "delete", "modify", "ignore"]295 296        # Completion should not work without a target.297        for subcommand in subcommands:298            self.complete_from_to(299                "watchpoint " + subcommand + " ", "watchpoint " + subcommand + " "300            )301 302        # Create a process to provide a target and enable watchpoint setting.303        self.build()304        lldbutil.run_to_source_breakpoint(305            self, "// Break here", lldb.SBFileSpec("main.cpp")306        )307 308        self.runCmd("watchpoint set variable ptr_fooo")309        for subcommand in subcommands:310            self.complete_from_to("watchpoint " + subcommand + " ", ["1"])311 312    def test_settings_append_target_er(self):313        """Test that 'settings append target.er' completes to 'settings append target.error-path'."""314        self.complete_from_to(315            "settings append target.er", "settings append target.error-path"316        )317 318    def test_settings_insert_after_target_en(self):319        """Test that 'settings insert-after target.env' completes to 'settings insert-after target.env-vars'."""320        self.complete_from_to(321            "settings insert-after target.env", "settings insert-after target.env-vars"322        )323 324    def test_settings_insert_before_target_en(self):325        """Test that 'settings insert-before target.env' completes to 'settings insert-before target.env-vars'."""326        self.complete_from_to(327            "settings insert-before target.env",328            "settings insert-before target.env-vars",329        )330 331    def test_settings_replace_target_ru(self):332        """Test that 'settings replace target.ru' completes to 'settings replace target.run-args'."""333        self.complete_from_to(334            "settings replace target.ru", "settings replace target.run-args"335        )336 337    def test_settings_show_term_width(self):338        self.complete_from_to("settings show term-w", "settings show term-width")339 340    def test_settings_list_term_width(self):341        self.complete_from_to("settings list term-w", "settings list term-width")342 343    def test_settings_show_term_height(self):344        self.complete_from_to("settings show term-h", "settings show term-height")345 346    def test_settings_list_term_height(self):347        self.complete_from_to("settings list term-h", "settings list term-height")348 349    def test_settings_remove_term_width(self):350        self.complete_from_to("settings remove term-w", "settings remove term-width")351 352    def test_settings_remove_term_height(self):353        self.complete_from_to("settings remove term-h", "settings remove term-height")354 355    def test_settings_s(self):356        """Test that 'settings s' completes to ['set', 'show']."""357        self.complete_from_to("settings s", ["set", "show"])358 359    def test_settings_set_th(self):360        """Test that 'settings set thread-f' completes to 'settings set thread-format'."""361        self.complete_from_to("settings set thread-f", "settings set thread-format")362 363    def test_settings_s_dash(self):364        """Test that 'settings set --g' completes to 'settings set --global'."""365        self.complete_from_to("settings set --g", "settings set --global")366 367    def test_settings_clear_th(self):368        """Test that 'settings clear thread-f' completes to 'settings clear thread-format'."""369        self.complete_from_to("settings clear thread-f", "settings clear thread-format")370 371    def test_settings_set_ta(self):372        """Test that 'settings set ta' completes to 'settings set target.'."""373        self.complete_from_to("settings set target.ma", "settings set target.max-")374 375    def test_settings_set_target_exec(self):376        """Test that 'settings set target.exec' completes to 'settings set target.exec-search-paths '."""377        self.complete_from_to(378            "settings set target.exec", "settings set target.exec-search-paths"379        )380 381    def test_settings_set_target_pr(self):382        """Test that 'settings set target.pr' completes to [383        'target.prefer-dynamic-value', 'target.process.']."""384        self.complete_from_to(385            "settings set target.pr", ["target.prefer-dynamic-value", "target.process."]386        )387 388    def test_settings_set_target_process(self):389        """Test that 'settings set target.process' completes to 'settings set target.process.'."""390        self.complete_from_to(391            "settings set target.process", "settings set target.process."392        )393 394    def test_settings_set_target_process_dot(self):395        """Test that 'settings set target.process.t' completes to 'settings set target.process.thread.'."""396        self.complete_from_to(397            "settings set target.process.thr", "settings set target.process.thread."398        )399 400    def test_settings_set_target_process_thread_dot(self):401        """Test that 'settings set target.process.thread.' completes to [402        'target.process.thread.step-avoid-regexp', 'target.process.thread.trace-thread'].403        """404        self.complete_from_to(405            "settings set target.process.thread.",406            [407                "target.process.thread.step-avoid-regexp",408                "target.process.thread.trace-thread",409            ],410        )411 412    def test_settings_set_can_complete_setting_enum_values(self):413        """Checks that we can complete the values of an enum setting."""414        self.complete_from_to(415            "settings set stop-disassembly-display ",416            ["never", "always", "no-debuginfo", "no-source"],417        )418 419    def test_thread_plan_discard(self):420        self.build()421        (_, _, thread, _) = lldbutil.run_to_source_breakpoint(422            self, "ptr_foo", lldb.SBFileSpec("main.cpp")423        )424        self.assertTrue(thread)425        self.complete_from_to("thread plan discard ", "thread plan discard ")426 427        source_path = os.path.join(self.getSourceDir(), "thread_plan_script.py")428        self.runCmd("command script import '%s'" % (source_path))429        self.runCmd("thread step-scripted -C thread_plan_script.PushPlanStack")430        self.complete_from_to("thread plan discard ", "thread plan discard 1")431        self.runCmd("thread plan discard 1")432 433    def test_target_space(self):434        """Test that 'target ' completes to ['create', 'delete', 'list',435        'modules', 'select', 'stop-hook', 'variable']."""436        self.complete_from_to(437            "target ",438            ["create", "delete", "list", "modules", "select", "stop-hook", "variable"],439        )440 441    def test_target_modules_dump_line_table(self):442        """Tests source file completion by completing the line-table argument."""443        self.build()444        self.dbg.CreateTarget(self.getBuildArtifact("a.out"))445        self.complete_from_to("target modules dump line-table main.cp", ["main.cpp"])446 447    def test_custom_command_completion(self):448        """Tests completion in custom user provided commands."""449        completion_types = [450            "none",451            "source-file",452            "disk-file",453            "disk-directory",454            "symbol",455            "module",456            "settings-name",457            "platform-plugin",458            "architecture",459            "variable-path",460            "register",461            "breakpoint",462            "process-plugin",463            "disassembly-flavor",464            "type-language",465            "frame-index",466            "module-uuid",467            "stophook-id",468            "thread-index",469            "watchpoint-id",470            "breakpoint-name",471            "process-id",472            "process-name",473            "remote-disk-file",474            "remote-disk-directory",475            "type-category-name",476            "custom",477        ]478        self.completions_contain("command script add -C ", completion_types)479 480        source_path = os.path.join(self.getSourceDir(), "my_test_cmd.py")481        self.runCmd("command script import '%s'" % (source_path))482        self.runCmd(483            "command script add -C disk-file -f my_test_cmd.my_test_cmd my_test_cmd"484        )485        self.complete_from_to("my_test_cmd main.cp", ["main.cpp"])486        self.expect("my_test_cmd main.cpp", substrs=["main.cpp"])487 488    @skipIf(hostoslist=["windows"])489    def test_completion_target_create_from_root_dir(self):490        """Tests source file completion by completing ."""491        root_dir = os.path.abspath(os.sep)492        self.completions_contain(493            "target create " + root_dir,494            list(495                filter(496                    lambda x: os.path.exists(x) and os.path.isdir(x),497                    map(lambda x: root_dir + x + os.sep, os.listdir(root_dir)),498                )499            ),500        )501 502    def test_target_modules_load_aout(self):503        """Tests modules completion by completing the target modules load argument."""504        self.build()505        self.dbg.CreateTarget(self.getBuildArtifact("a.out"))506        self.complete_from_to("target modules load a.ou", ["a.out"])507 508    def test_target_modules_search_paths_insert(self):509        # Completion won't work without a valid target.510        self.complete_from_to(511            "target modules search-paths insert ", "target modules search-paths insert "512        )513        self.build()514        target = self.dbg.CreateTarget(self.getBuildArtifact("a.out"))515        self.assertTrue(target, VALID_TARGET)516        self.complete_from_to(517            "target modules search-paths insert ", "target modules search-paths insert "518        )519        self.runCmd("target modules search-paths add a b")520        self.complete_from_to(521            "target modules search-paths insert ",522            "target modules search-paths insert 0",523        )524        # Completion only works for the first arg.525        self.complete_from_to(526            "target modules search-paths insert 0 ",527            "target modules search-paths insert 0 ",528        )529 530    def test_target_create_dash_co(self):531        """Test that 'target create --co' completes to 'target variable --core '."""532        self.complete_from_to("target create --co", "target create --core ")533 534    def test_target_va(self):535        """Test that 'target va' completes to 'target variable '."""536        self.complete_from_to("target va", "target variable ")537 538    def test_common_completion_thread_index(self):539        subcommands = [540            "continue",541            "info",542            "exception",543            "select",544            "step-in",545            "step-inst",546            "step-inst-over",547            "step-out",548            "step-over",549            "step-script",550        ]551 552        # Completion should do nothing without threads.553        for subcommand in subcommands:554            self.complete_from_to(555                "thread " + subcommand + " ", "thread " + subcommand + " "556            )557 558        self.build()559        lldbutil.run_to_source_breakpoint(560            self, "// Break here", lldb.SBFileSpec("main.cpp")561        )562 563        # At least we have the thread at the index of 1 now.564        for subcommand in subcommands:565            self.complete_from_to("thread " + subcommand + " ", ["1"])566 567    def test_common_completion_type_category_name(self):568        subcommands = ["delete", "list", "enable", "disable", "define"]569        for subcommand in subcommands:570            self.complete_from_to("type category " + subcommand + " ", ["default"])571        self.complete_from_to("type filter add -w ", ["default"])572 573    def test_command_argument_completion(self):574        """Test completion of command arguments"""575        self.complete_from_to("watchpoint set variable -", ["-w", "-s"])576        self.complete_from_to(577            "watchpoint set variable -w", "watchpoint set variable -w "578        )579        self.complete_from_to("watchpoint set variable --", ["--watch", "--size"])580        self.complete_from_to(581            "watchpoint set variable --w", "watchpoint set variable --watch"582        )583        self.complete_from_to(584            "watchpoint set variable -w ", ["read", "write", "read_write"]585        )586        self.complete_from_to(587            "watchpoint set variable --watch ", ["read", "write", "read_write"]588        )589        self.complete_from_to(590            "watchpoint set variable --watch w", "watchpoint set variable --watch write"591        )592        self.complete_from_to(593            "watchpoint set variable -w read_", "watchpoint set variable -w read_write"594        )595        # Now try the same thing with a variable name (non-option argument) to596        # test that getopts arg reshuffling doesn't confuse us.597        self.complete_from_to("watchpoint set variable foo -", ["-w", "-s"])598        self.complete_from_to(599            "watchpoint set variable foo -w", "watchpoint set variable foo -w "600        )601        self.complete_from_to("watchpoint set variable foo --", ["--watch", "--size"])602        self.complete_from_to(603            "watchpoint set variable foo --w", "watchpoint set variable foo --watch"604        )605        self.complete_from_to(606            "watchpoint set variable foo -w ", ["read", "write", "read_write"]607        )608        self.complete_from_to(609            "watchpoint set variable foo --watch ", ["read", "write", "read_write"]610        )611        self.complete_from_to(612            "watchpoint set variable foo --watch w",613            "watchpoint set variable foo --watch write",614        )615        self.complete_from_to(616            "watchpoint set variable foo -w read_",617            "watchpoint set variable foo -w read_write",618        )619 620    def test_command_script_delete(self):621        self.runCmd("command script add -h test_desc -f none -s current usercmd1")622        self.check_completion_with_desc("command script delete ", [["usercmd1", ""]])623 624    def test_command_delete(self):625        self.runCmd(626            r"command regex test_command s/^$/finish/ 's/([0-9]+)/frame select %1/'"627        )628        self.complete_from_to("command delete test_c", "command delete test_command")629 630    def test_command_unalias(self):631        self.complete_from_to("command unalias ima", "command unalias image")632 633    def test_command_aliases(self):634        self.runCmd("command alias brkpt breakpoint")635        # Exact matches are chosen if possible, even if there are longer636        # completions we could use.637        self.complete_from_to("b", "b ")638        # Aliases are included in possible completions.639        self.complete_from_to("br", ["breakpoint", "brkpt"])640        # An alias can be the chosen completion.641        self.complete_from_to("brk", "brkpt")642 643        # The list can contain only aliases if there's no built-ins to match.644        self.runCmd("command alias test_1 breakpoint")645        self.runCmd("command alias test_2 breakpoint")646        self.complete_from_to("test_", ["test_1", "test_2"])647 648    def test_completion_description_commands(self):649        """Test descriptions of top-level command completions"""650        self.check_completion_with_desc(651            "",652            [653                ["command", "Commands for managing custom LLDB commands."],654                [655                    "breakpoint",656                    "Commands for operating on breakpoints (see 'help b' for shorthand.)",657                ],658            ],659        )660 661        self.check_completion_with_desc(662            "pl",663            [664                ["platform", "Commands to manage and create platforms."],665                ["plugin", "Commands for managing LLDB plugins."],666            ],667        )668 669        # Just check that this doesn't crash.670        self.check_completion_with_desc("comman", [])671        self.check_completion_with_desc("non-existent-command", [])672 673    def test_completion_description_command_options(self):674        """Test descriptions of command options"""675        # Short options676        self.check_completion_with_desc(677            "breakpoint set -",678            [679                ["-h", "Set the breakpoint on exception catch."],680                ["-w", "Set the breakpoint on exception throw."],681            ],682        )683 684        # Long options.685        self.check_completion_with_desc(686            "breakpoint set --",687            [688                ["--on-catch", "Set the breakpoint on exception catch."],689                ["--on-throw", "Set the breakpoint on exception throw."],690            ],691        )692 693        # Ambiguous long options.694        self.check_completion_with_desc(695            "breakpoint set --on-",696            [697                ["--on-catch", "Set the breakpoint on exception catch."],698                ["--on-throw", "Set the breakpoint on exception throw."],699            ],700        )701 702        # Unknown long option.703        self.check_completion_with_desc("breakpoint set --Z", [])704 705    def test_common_completion_frame_index(self):706        self.build()707        lldbutil.run_to_source_breakpoint(708            self, "// Break here", lldb.SBFileSpec("main.cpp")709        )710 711        self.complete_from_to("frame select ", ["0"])712        self.complete_from_to("thread backtrace -s ", ["0"])713 714    def test_frame_recognizer_delete(self):715        self.runCmd(716            "frame recognizer add -l py_class -s module_name -n recognizer_name"717        )718        self.check_completion_with_desc(719            "frame recognizer delete ",720            [["0", "py_class, module module_name, demangled symbol recognizer_name"]],721        )722 723    def test_platform_install_local_file(self):724        self.complete_from_to(725            "platform target-install main.cp", "platform target-install main.cpp"726        )727 728    @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24489")729    def test_symbol_name(self):730        self.build()731        self.dbg.CreateTarget(self.getBuildArtifact("a.out"))732        self.complete_from_to(733            "breakpoint set -n Fo", "breakpoint set -n Foo::Bar(int,\\ int)"734        )735        # No completion for Qu because the candidate is736        # (anonymous namespace)::Quux().737        self.complete_from_to("breakpoint set -n Qu", "")738 739    def test_completion_type_formatter_delete(self):740        self.runCmd("type filter add --child a Aoo")741        self.complete_from_to("type filter delete ", ["Aoo"])742        self.runCmd("type filter add --child b -x Boo")743        self.complete_from_to("type filter delete ", ["Boo"])744 745        self.runCmd("type format add -f hex Coo")746        self.complete_from_to("type format delete ", ["Coo"])747        self.runCmd("type format add -f hex -x Doo")748        self.complete_from_to("type format delete ", ["Doo"])749 750        self.runCmd("type summary add -c Eoo")751        self.complete_from_to("type summary delete ", ["Eoo"])752        self.runCmd("type summary add -x -c Foo")753        self.complete_from_to("type summary delete ", ["Foo"])754 755        self.runCmd("type synthetic add Goo -l test")756        self.complete_from_to("type synthetic delete ", ["Goo"])757        self.runCmd("type synthetic add -x Hoo -l test")758        self.complete_from_to("type synthetic delete ", ["Hoo"])759 760    def test_register_no_complete(self):761        # The tab completion for "register read/write"  won't work without a running process.762        self.complete_from_to("register read ", "register read ")763        self.complete_from_to("register write ", "register write ")764        self.complete_from_to("register info ", "register info ")765 766        self.build()767        self.runCmd("target create {}".format(self.getBuildArtifact("a.out")))768        self.runCmd("run")769 770        # Once a program has finished you have an execution context but no register771        # context so completion cannot work.772        self.complete_from_to("register read ", "register read ")773        self.complete_from_to("register write ", "register write ")774        self.complete_from_to("register info ", "register info ")775 776    @skipIf(archs=no_match(["x86_64"]))777    def test_register_read_and_write_on_x86(self):778        """Test the completion of the commands register read and write on x86"""779 780        self.build()781        self.main_source_spec = lldb.SBFileSpec("main.cpp")782        lldbutil.run_to_source_breakpoint(self, "// Break here", self.main_source_spec)783 784        # test cases for register read785        self.complete_from_to("register read ", ["rax", "rbx", "rcx"])786        self.complete_from_to("register read r", ["rax", "rbx", "rcx"])787        self.complete_from_to("register read ra", "register read rax")788        # register read can take multiple register names as arguments789        self.complete_from_to("register read rax ", ["rax", "rbx", "rcx"])790        # complete with prefix '$'791        self.completions_match("register read $rb", ["$rbx", "$rbp"])792        self.completions_match("register read $ra", ["$rax"])793        self.complete_from_to("register read rax $", ["$rax", "$rbx", "$rcx"])794        self.complete_from_to("register read $rax ", ["rax", "rbx", "rcx"])795 796        # test cases for register write797        self.complete_from_to("register write ", ["rax", "rbx", "rcx"])798        self.complete_from_to("register write r", ["rax", "rbx", "rcx"])799        self.complete_from_to("register write ra", "register write rax")800        self.complete_from_to("register write rb", ["rbx", "rbp"])801        # register write can only take exact one register name as argument802        self.complete_from_to("register write rbx ", [])803 804    def test_common_completion_target_stophook_ids(self):805        subcommands = ["delete", "enable", "disable"]806 807        for subcommand in subcommands:808            self.complete_from_to(809                "target stop-hook " + subcommand + " ",810                "target stop-hook " + subcommand + " ",811            )812 813        self.build()814        self.dbg.CreateTarget(self.getBuildArtifact("a.out"))815        self.runCmd("target stop-hook add -o test")816 817        for subcommand in subcommands:818            self.complete_from_to(819                "target stop-hook " + subcommand + " ",820                "target stop-hook " + subcommand + " 1",821            )822 823        # Completion should work only on the first argument.824        for subcommand in subcommands:825            self.complete_from_to(826                "target stop-hook " + subcommand + " 1 ",827                "target stop-hook " + subcommand + " 1 ",828            )829 830    def test_common_completion_type_language(self):831        self.complete_from_to("type category -l ", ["c"])832 833    def test_target_modules_load_dash_u(self):834        self.build()835        target = self.dbg.CreateTarget(self.getBuildArtifact("a.out"))836        self.complete_from_to(837            "target modules load -u ", [target.GetModuleAtIndex(0).GetUUIDString()]838        )839 840    def test_complete_breakpoint_with_ids(self):841        """These breakpoint subcommands should be completed with a list of breakpoint ids"""842 843        subcommands = [844            "enable",845            "disable",846            "delete",847            "modify",848            "name add",849            "name delete",850            "write",851        ]852 853        # The tab completion here is unavailable without a target854        for subcommand in subcommands:855            self.complete_from_to(856                "breakpoint " + subcommand + " ", "breakpoint " + subcommand + " "857            )858 859        self.build()860        target = self.dbg.CreateTarget(self.getBuildArtifact("a.out"))861        self.assertTrue(target, VALID_TARGET)862 863        bp = target.BreakpointCreateByName("main", "a.out")864        self.assertTrue(bp)865        self.assertEqual(bp.GetNumLocations(), 1)866 867        for subcommand in subcommands:868            self.complete_from_to("breakpoint " + subcommand + " ", ["1"])869 870        bp2 = target.BreakpointCreateByName("Bar", "a.out")871        self.assertTrue(bp2)872        self.assertEqual(bp2.GetNumLocations(), 1)873 874        for subcommand in subcommands:875            self.complete_from_to("breakpoint " + subcommand + " ", ["1", "2"])876 877        for subcommand in subcommands:878            self.complete_from_to("breakpoint " + subcommand + " 1 ", ["1", "2"])879 880    def test_complete_breakpoint_with_names(self):881        self.build()882        target = self.dbg.CreateTarget(self.getBuildArtifact("a.out"))883        self.assertTrue(target, VALID_TARGET)884 885        # test breakpoint read dedicated886        self.complete_from_to("breakpoint read -N ", "breakpoint read -N ")887        self.complete_from_to("breakpoint read -f breakpoints.json -N ", ["mm"])888        self.complete_from_to(889            "breakpoint read -f breakpoints.json -N n",890            "breakpoint read -f breakpoints.json -N n",891        )892        self.complete_from_to(893            "breakpoint read -f breakpoints_invalid.json -N ",894            "breakpoint read -f breakpoints_invalid.json -N ",895        )896 897        # test common breapoint name completion898        bp1 = target.BreakpointCreateByName("main", "a.out")899        self.assertTrue(bp1)900        self.assertEqual(bp1.GetNumLocations(), 1)901        self.complete_from_to("breakpoint set -N n", "breakpoint set -N n")902        self.assertTrue(bp1.AddNameWithErrorHandling("nn"))903        self.complete_from_to("breakpoint set -N ", "breakpoint set -N nn")904 905    def test_ambiguous_command(self):906        """Test completing an ambiguous commands"""907        self.complete_from_to("settings s", ["set", "show"])908 909    def test_ambiguous_subcommand(self):910        """Test completing a subcommand of an ambiguous command"""911        self.complete_from_to("settings s ta", [])912 913    def test_shlib_name(self):914        self.build()915        error = lldb.SBError()916        # Create a target, but don't load dependent modules917        target = self.dbg.CreateTarget(self.getBuildArtifact("a.out"), None, None, False, error)918        self.assertSuccess(error)919        self.registerSharedLibrariesWithTarget(target, ["shared"])920 921        basenames = []922        paths = []923        for m in target.modules:924            basenames.append(m.file.basename)925            paths.append(m.file.fullpath)926 927        # To see all the diffs928        self.maxDiff = None929 930        # An empty string completes to everything931        self.completions_match("target symbols add -s ", basenames + paths)932 933        # Base name completion934        self.completions_match("target symbols add -s a.", ["a.out"])935 936        # Full path completion937        prefix = os.path.commonpath(paths)938        self.completions_match("target symbols add -s '" + prefix, paths)939 940        # Full path, but ending with a path separator941        prefix_sep = prefix + os.path.sep942        self.completions_match("target symbols add -s '" + prefix_sep, paths)943 944        # The completed path should match the spelling of the input, so if the945        # input contains a double separator, so should the completions.946        prefix_sep_sep = prefix_sep + os.path.sep947        paths_sep = [prefix_sep_sep + p[len(prefix_sep) :] for p in paths]948        self.completions_match("target symbols add -s '" + prefix_sep_sep, paths_sep)949