brintos

brintos / llvm-project-archived public Read only

0
0
Text · 13.3 KiB · 09f2ffe Raw
375 lines · python
1"""2Test the lldb command line completion mechanism for the 'expr' command.3"""4 5 6import lldb7from lldbsuite.test.decorators import *8from lldbsuite.test.lldbtest import *9from lldbsuite.test import lldbplatform10from lldbsuite.test import lldbutil11 12 13class CommandLineExprCompletionTestCase(TestBase):14    NO_DEBUG_INFO_TESTCASE = True15 16    def test_expr_completion(self):17        self.build()18        self.main_source = "main.cpp"19        self.main_source_spec = lldb.SBFileSpec(self.main_source)20        self.createTestTarget()21 22        # Try the completion before we have a context to complete on.23        self.assume_no_completions("expr some_expr")24        self.assume_no_completions("expr ")25        self.assume_no_completions("expr f")26 27        (target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint(28            self, "// Break here", self.main_source_spec29        )30 31        # Completing member functions32        self.complete_from_to(33            "expr some_expr.FooNoArgs", "expr some_expr.FooNoArgsBar()"34        )35        self.complete_from_to(36            "expr some_expr.FooWithArgs", "expr some_expr.FooWithArgsBar("37        )38        self.complete_from_to(39            "expr some_expr.FooWithMultipleArgs",40            "expr some_expr.FooWithMultipleArgsBar(",41        )42        self.complete_from_to(43            "expr some_expr.FooUnderscore", "expr some_expr.FooUnderscoreBar_()"44        )45        self.complete_from_to(46            "expr some_expr.FooNumbers", "expr some_expr.FooNumbersBar1()"47        )48        self.complete_from_to(49            "expr some_expr.StaticMemberMethod",50            "expr some_expr.StaticMemberMethodBar()",51        )52 53        # Completing static functions54        self.complete_from_to(55            "expr Expr::StaticMemberMethod", "expr Expr::StaticMemberMethodBar()"56        )57 58        # Completing member variables59        self.complete_from_to(60            "expr some_expr.MemberVariab", "expr some_expr.MemberVariableBar"61        )62 63        # Multiple completions64        self.completions_contain(65            "expr some_expr.",66            [67                "some_expr.FooNumbersBar1()",68                "some_expr.FooUnderscoreBar_()",69                "some_expr.FooWithArgsBar(",70                "some_expr.MemberVariableBar",71            ],72        )73 74        self.completions_contain(75            "expr some_expr.Foo",76            [77                "some_expr.FooNumbersBar1()",78                "some_expr.FooUnderscoreBar_()",79                "some_expr.FooWithArgsBar(",80            ],81        )82 83        self.completions_contain(84            "expr ", ["static_cast", "reinterpret_cast", "dynamic_cast"]85        )86 87        self.completions_contain(88            "expr 1 + ", ["static_cast", "reinterpret_cast", "dynamic_cast"]89        )90 91        # Completion expr without spaces92        # This is a bit awkward looking for the user, but that's how93        # the completion API works at the moment.94        self.completions_contain("expr 1+", ["1+some_expr", "1+static_cast"])95 96        # Test with spaces97        self.complete_from_to(98            "expr   some_expr .FooNoArgs", "expr   some_expr .FooNoArgsBar()"99        )100        self.complete_from_to(101            "expr  some_expr .FooNoArgs", "expr  some_expr .FooNoArgsBar()"102        )103        self.complete_from_to(104            "expr some_expr .FooNoArgs", "expr some_expr .FooNoArgsBar()"105        )106        self.complete_from_to(107            "expr some_expr. FooNoArgs", "expr some_expr. FooNoArgsBar()"108        )109        self.complete_from_to(110            "expr some_expr . FooNoArgs", "expr some_expr . FooNoArgsBar()"111        )112        self.complete_from_to(113            "expr Expr :: StaticMemberMethod", "expr Expr :: StaticMemberMethodBar()"114        )115        self.complete_from_to(116            "expr Expr ::StaticMemberMethod", "expr Expr ::StaticMemberMethodBar()"117        )118        self.complete_from_to(119            "expr Expr:: StaticMemberMethod", "expr Expr:: StaticMemberMethodBar()"120        )121 122        # Test that string literals don't break our parsing logic.123        self.complete_from_to(124            'expr const char *cstr = "some_e"; char c = *cst',125            'expr const char *cstr = "some_e"; char c = *cstr',126        )127        self.complete_from_to(128            'expr const char *cstr = "some_e" ; char c = *cst',129            'expr const char *cstr = "some_e" ; char c = *cstr',130        )131        # Requesting completions inside an incomplete string doesn't provide any132        # completions.133        self.complete_from_to(134            'expr const char *cstr = "some_e', 'expr const char *cstr = "some_e'135        )136 137        # Completing inside double dash should do nothing138        self.assume_no_completions("expr -i0 -- some_expr.", 10)139        self.assume_no_completions("expr -i0 -- some_expr.", 11)140 141        # Test with expr arguments142        self.complete_from_to(143            "expr -i0 -- some_expr .FooNoArgs", "expr -i0 -- some_expr .FooNoArgsBar()"144        )145        self.complete_from_to(146            "expr  -i0 -- some_expr .FooNoArgs",147            "expr  -i0 -- some_expr .FooNoArgsBar()",148        )149 150        # Addrof and deref151        self.complete_from_to(152            "expr (*(&some_expr)).FooNoArgs", "expr (*(&some_expr)).FooNoArgsBar()"153        )154        self.complete_from_to(155            "expr (*(&some_expr)) .FooNoArgs", "expr (*(&some_expr)) .FooNoArgsBar()"156        )157        self.complete_from_to(158            "expr (* (&some_expr)) .FooNoArgs", "expr (* (&some_expr)) .FooNoArgsBar()"159        )160        self.complete_from_to(161            "expr (* (& some_expr)) .FooNoArgs",162            "expr (* (& some_expr)) .FooNoArgsBar()",163        )164 165        # Addrof and deref (part 2)166        self.complete_from_to(167            "expr (&some_expr)->FooNoArgs", "expr (&some_expr)->FooNoArgsBar()"168        )169        self.complete_from_to(170            "expr (&some_expr) ->FooNoArgs", "expr (&some_expr) ->FooNoArgsBar()"171        )172        self.complete_from_to(173            "expr (&some_expr) -> FooNoArgs", "expr (&some_expr) -> FooNoArgsBar()"174        )175        self.complete_from_to(176            "expr (&some_expr)-> FooNoArgs", "expr (&some_expr)-> FooNoArgsBar()"177        )178 179        # Builtin arg180        self.complete_from_to("expr static_ca", "expr static_cast")181 182        # From other files183        self.complete_from_to(184            "expr fwd_decl_ptr->Hidden", "expr fwd_decl_ptr->HiddenMember"185        )186 187        # Types188        self.complete_from_to("expr LongClassNa", "expr LongClassName")189        self.complete_from_to(190            "expr LongNamespaceName::NestedCla", "expr LongNamespaceName::NestedClass"191        )192 193        # Namespaces194        self.complete_from_to("expr LongNamespaceNa", "expr LongNamespaceName::")195 196        # Multiple arguments197        self.complete_from_to(198            "expr &some_expr + &some_e", "expr &some_expr + &some_expr"199        )200        self.complete_from_to(201            "expr SomeLongVarNameWithCapitals + SomeLongVarName",202            "expr SomeLongVarNameWithCapitals + SomeLongVarNameWithCapitals",203        )204        self.complete_from_to(205            "expr SomeIntVar + SomeIntV", "expr SomeIntVar + SomeIntVar"206        )207 208        # Multiple statements209        self.complete_from_to(210            "expr long LocalVariable = 0; LocalVaria",211            "expr long LocalVariable = 0; LocalVariable",212        )213 214        # Custom Decls215        self.complete_from_to(216            "expr auto l = [](int LeftHandSide, int bx){ return LeftHandS",217            "expr auto l = [](int LeftHandSide, int bx){ return LeftHandSide",218        )219        self.complete_from_to(220            "expr struct LocalStruct { long MemberName; } ; LocalStruct S; S.Mem",221            "expr struct LocalStruct { long MemberName; } ; LocalStruct S; S.MemberName",222        )223 224        # Completing function call arguments225        self.complete_from_to(226            "expr some_expr.FooWithArgsBar(some_exp",227            "expr some_expr.FooWithArgsBar(some_expr",228        )229        self.complete_from_to(230            "expr some_expr.FooWithArgsBar(SomeIntV",231            "expr some_expr.FooWithArgsBar(SomeIntVar",232        )233        self.complete_from_to(234            "expr some_expr.FooWithMultipleArgsBar(SomeIntVar, SomeIntVa",235            "expr some_expr.FooWithMultipleArgsBar(SomeIntVar, SomeIntVar",236        )237 238        # Function return values239        self.complete_from_to(240            "expr some_expr.Self().FooNoArgs", "expr some_expr.Self().FooNoArgsBar()"241        )242        self.complete_from_to(243            "expr some_expr.Self() .FooNoArgs", "expr some_expr.Self() .FooNoArgsBar()"244        )245        self.complete_from_to(246            "expr some_expr.Self(). FooNoArgs", "expr some_expr.Self(). FooNoArgsBar()"247        )248 249        self.complete_from_to("expr myVec.__f", "expr myVec.__func()")250        self.complete_from_to("expr myVec._F", "expr myVec._Func()")251        self.complete_from_to("expr myVec.__m", "expr myVec.__mem")252        self.complete_from_to("expr myVec._M", "expr myVec._Mem")253 254    def test_expr_completion_with_descriptions(self):255        self.build()256        self.main_source = "main.cpp"257        self.main_source_spec = lldb.SBFileSpec(self.main_source)258        self.createTestTarget()259 260        (target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint(261            self, "// Break here", self.main_source_spec262        )263 264        self.check_completion_with_desc(265            "expr ",266            [267                # builtin types have no description.268                ["int", ""],269                ["float", ""],270                # VarDecls have their type as description.271                ["some_expr", "Expr &"],272            ],273            enforce_order=True,274        )275        self.check_completion_with_desc(276            "expr some_expr.",277            [278                # Functions have their signature as description.279                ["some_expr.~Expr()", "inline ~Expr()"],280                ["some_expr.operator=(", "inline Expr &operator=(const Expr &)"],281                # FieldDecls have their type as description.282                ["some_expr.MemberVariableBar", "int"],283                [284                    "some_expr.StaticMemberMethodBar()",285                    "static int StaticMemberMethodBar()",286                ],287                ["some_expr.Self()", "Expr &Self()"],288                ["some_expr.FooNoArgsBar()", "int FooNoArgsBar()"],289                ["some_expr.FooWithArgsBar(", "int FooWithArgsBar(int)"],290                ["some_expr.FooNumbersBar1()", "int FooNumbersBar1()"],291                ["some_expr.FooUnderscoreBar_()", "int FooUnderscoreBar_()"],292                [293                    "some_expr.FooWithMultipleArgsBar(",294                    "int FooWithMultipleArgsBar(int, int)",295                ],296            ],297            enforce_order=True,298        )299 300    def test_expr_completion_max_results(self):301        self.build()302        self.main_source = "main.cpp"303        self.main_source_spec = lldb.SBFileSpec(self.main_source)304        self.createTestTarget()305 306        (target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint(307            self, "// Break here", self.main_source_spec308        )309 310        expected_completions = [311            "some_expr.~Expr()",312            "some_expr.operator=(",  # Copy operator313            "some_expr.operator=(",  # Move operator314            "some_expr.MemberVariableBar",315            "some_expr.StaticMemberMethodBar()",316            "some_expr.Self()",317            "some_expr.FooNoArgsBar()",318            "some_expr.FooWithArgsBar(",319            "some_expr.FooNumbersBar1()",320            "some_expr.FooUnderscoreBar_()",321            "some_expr.FooWithMultipleArgsBar(",322        ]323 324        for i in range(1, len(expected_completions)):325            self.completions_match(326                "expr some_expr.",327                expected_completions[:i],328                max_completions=i,329            )330 331    def assume_no_completions(self, str_input, cursor_pos=None):332        interp = self.dbg.GetCommandInterpreter()333        match_strings = lldb.SBStringList()334        if cursor_pos is None:335            cursor_pos = len(str_input)336        num_matches = interp.HandleCompletion(337            str_input, cursor_pos, 0, -1, match_strings338        )339 340        available_completions = []341        for m in match_strings:342            available_completions.append(m)343 344        self.assertEqual(345            num_matches,346            0,347            "Got matches, but didn't expect any: " + str(available_completions),348        )349 350    def completions_contain(self, str_input, items):351        interp = self.dbg.GetCommandInterpreter()352        match_strings = lldb.SBStringList()353        num_matches = interp.HandleCompletion(354            str_input, len(str_input), 0, -1, match_strings355        )356        common_match = match_strings.GetStringAtIndex(0)357 358        for item in items:359            found = False360            for m in match_strings:361                if m == item:362                    found = True363            if not found:364                # Transform match_strings to a python list with strings365                available_completions = []366                for m in match_strings:367                    available_completions.append(m)368                self.assertTrue(369                    found,370                    "Couldn't find completion "371                    + item372                    + " in completions "373                    + str(available_completions),374                )375