199451b44SJordan Rupprecht""" 299451b44SJordan RupprechtTest the lldb command line completion mechanism for the 'expr' command. 399451b44SJordan Rupprecht""" 499451b44SJordan Rupprecht 599451b44SJordan Rupprecht 699451b44SJordan Rupprechtimport lldb 799451b44SJordan Rupprechtfrom lldbsuite.test.decorators import * 899451b44SJordan Rupprechtfrom lldbsuite.test.lldbtest import * 999451b44SJordan Rupprechtfrom lldbsuite.test import lldbplatform 1099451b44SJordan Rupprechtfrom lldbsuite.test import lldbutil 1199451b44SJordan Rupprecht 1299451b44SJordan Rupprecht 132238dcc3SJonas Devlieghereclass CommandLineExprCompletionTestCase(TestBase): 1499451b44SJordan Rupprecht NO_DEBUG_INFO_TESTCASE = True 1599451b44SJordan Rupprecht 1699451b44SJordan Rupprecht def test_expr_completion(self): 1799451b44SJordan Rupprecht self.build() 1899451b44SJordan Rupprecht self.main_source = "main.cpp" 1999451b44SJordan Rupprecht self.main_source_spec = lldb.SBFileSpec(self.main_source) 2054c26872SRaphael Isemann self.createTestTarget() 2199451b44SJordan Rupprecht 2299451b44SJordan Rupprecht # Try the completion before we have a context to complete on. 232238dcc3SJonas Devlieghere self.assume_no_completions("expr some_expr") 242238dcc3SJonas Devlieghere self.assume_no_completions("expr ") 252238dcc3SJonas Devlieghere self.assume_no_completions("expr f") 2699451b44SJordan Rupprecht 272238dcc3SJonas Devlieghere (target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint( 282238dcc3SJonas Devlieghere self, "// Break here", self.main_source_spec 292238dcc3SJonas Devlieghere ) 3099451b44SJordan Rupprecht 3199451b44SJordan Rupprecht # Completing member functions 326bf6c476SDavid Spickett self.complete_from_to( 332238dcc3SJonas Devlieghere "expr some_expr.FooNoArgs", "expr some_expr.FooNoArgsBar()" 342238dcc3SJonas Devlieghere ) 356bf6c476SDavid Spickett self.complete_from_to( 362238dcc3SJonas Devlieghere "expr some_expr.FooWithArgs", "expr some_expr.FooWithArgsBar(" 372238dcc3SJonas Devlieghere ) 386bf6c476SDavid Spickett self.complete_from_to( 392238dcc3SJonas Devlieghere "expr some_expr.FooWithMultipleArgs", 402238dcc3SJonas Devlieghere "expr some_expr.FooWithMultipleArgsBar(", 412238dcc3SJonas Devlieghere ) 426bf6c476SDavid Spickett self.complete_from_to( 432238dcc3SJonas Devlieghere "expr some_expr.FooUnderscore", "expr some_expr.FooUnderscoreBar_()" 442238dcc3SJonas Devlieghere ) 456bf6c476SDavid Spickett self.complete_from_to( 462238dcc3SJonas Devlieghere "expr some_expr.FooNumbers", "expr some_expr.FooNumbersBar1()" 472238dcc3SJonas Devlieghere ) 486bf6c476SDavid Spickett self.complete_from_to( 492238dcc3SJonas Devlieghere "expr some_expr.StaticMemberMethod", 502238dcc3SJonas Devlieghere "expr some_expr.StaticMemberMethodBar()", 512238dcc3SJonas Devlieghere ) 5299451b44SJordan Rupprecht 5399451b44SJordan Rupprecht # Completing static functions 546bf6c476SDavid Spickett self.complete_from_to( 552238dcc3SJonas Devlieghere "expr Expr::StaticMemberMethod", "expr Expr::StaticMemberMethodBar()" 562238dcc3SJonas Devlieghere ) 5799451b44SJordan Rupprecht 5899451b44SJordan Rupprecht # Completing member variables 596bf6c476SDavid Spickett self.complete_from_to( 602238dcc3SJonas Devlieghere "expr some_expr.MemberVariab", "expr some_expr.MemberVariableBar" 612238dcc3SJonas Devlieghere ) 6299451b44SJordan Rupprecht 6399451b44SJordan Rupprecht # Multiple completions 642238dcc3SJonas Devlieghere self.completions_contain( 652238dcc3SJonas Devlieghere "expr some_expr.", 662238dcc3SJonas Devlieghere [ 672238dcc3SJonas Devlieghere "some_expr.FooNumbersBar1()", 682238dcc3SJonas Devlieghere "some_expr.FooUnderscoreBar_()", 692238dcc3SJonas Devlieghere "some_expr.FooWithArgsBar(", 702238dcc3SJonas Devlieghere "some_expr.MemberVariableBar", 712238dcc3SJonas Devlieghere ], 722238dcc3SJonas Devlieghere ) 7399451b44SJordan Rupprecht 742238dcc3SJonas Devlieghere self.completions_contain( 752238dcc3SJonas Devlieghere "expr some_expr.Foo", 762238dcc3SJonas Devlieghere [ 772238dcc3SJonas Devlieghere "some_expr.FooNumbersBar1()", 782238dcc3SJonas Devlieghere "some_expr.FooUnderscoreBar_()", 792238dcc3SJonas Devlieghere "some_expr.FooWithArgsBar(", 802238dcc3SJonas Devlieghere ], 812238dcc3SJonas Devlieghere ) 8299451b44SJordan Rupprecht 832238dcc3SJonas Devlieghere self.completions_contain( 842238dcc3SJonas Devlieghere "expr ", ["static_cast", "reinterpret_cast", "dynamic_cast"] 852238dcc3SJonas Devlieghere ) 8699451b44SJordan Rupprecht 872238dcc3SJonas Devlieghere self.completions_contain( 882238dcc3SJonas Devlieghere "expr 1 + ", ["static_cast", "reinterpret_cast", "dynamic_cast"] 892238dcc3SJonas Devlieghere ) 9099451b44SJordan Rupprecht 9199451b44SJordan Rupprecht # Completion expr without spaces 9299451b44SJordan Rupprecht # This is a bit awkward looking for the user, but that's how 9399451b44SJordan Rupprecht # the completion API works at the moment. 942238dcc3SJonas Devlieghere self.completions_contain("expr 1+", ["1+some_expr", "1+static_cast"]) 9599451b44SJordan Rupprecht 9699451b44SJordan Rupprecht # Test with spaces 976bf6c476SDavid Spickett self.complete_from_to( 982238dcc3SJonas Devlieghere "expr some_expr .FooNoArgs", "expr some_expr .FooNoArgsBar()" 992238dcc3SJonas Devlieghere ) 1006bf6c476SDavid Spickett self.complete_from_to( 1012238dcc3SJonas Devlieghere "expr some_expr .FooNoArgs", "expr some_expr .FooNoArgsBar()" 1022238dcc3SJonas Devlieghere ) 1036bf6c476SDavid Spickett self.complete_from_to( 1042238dcc3SJonas Devlieghere "expr some_expr .FooNoArgs", "expr some_expr .FooNoArgsBar()" 1052238dcc3SJonas Devlieghere ) 1066bf6c476SDavid Spickett self.complete_from_to( 1072238dcc3SJonas Devlieghere "expr some_expr. FooNoArgs", "expr some_expr. FooNoArgsBar()" 1082238dcc3SJonas Devlieghere ) 1096bf6c476SDavid Spickett self.complete_from_to( 1102238dcc3SJonas Devlieghere "expr some_expr . FooNoArgs", "expr some_expr . FooNoArgsBar()" 1112238dcc3SJonas Devlieghere ) 1126bf6c476SDavid Spickett self.complete_from_to( 1132238dcc3SJonas Devlieghere "expr Expr :: StaticMemberMethod", "expr Expr :: StaticMemberMethodBar()" 1142238dcc3SJonas Devlieghere ) 1156bf6c476SDavid Spickett self.complete_from_to( 1162238dcc3SJonas Devlieghere "expr Expr ::StaticMemberMethod", "expr Expr ::StaticMemberMethodBar()" 1172238dcc3SJonas Devlieghere ) 1186bf6c476SDavid Spickett self.complete_from_to( 1192238dcc3SJonas Devlieghere "expr Expr:: StaticMemberMethod", "expr Expr:: StaticMemberMethodBar()" 1202238dcc3SJonas Devlieghere ) 12199451b44SJordan Rupprecht 12299451b44SJordan Rupprecht # Test that string literals don't break our parsing logic. 1236bf6c476SDavid Spickett self.complete_from_to( 1242238dcc3SJonas Devlieghere 'expr const char *cstr = "some_e"; char c = *cst', 1252238dcc3SJonas Devlieghere 'expr const char *cstr = "some_e"; char c = *cstr', 1262238dcc3SJonas Devlieghere ) 1276bf6c476SDavid Spickett self.complete_from_to( 1282238dcc3SJonas Devlieghere 'expr const char *cstr = "some_e" ; char c = *cst', 1292238dcc3SJonas Devlieghere 'expr const char *cstr = "some_e" ; char c = *cstr', 1302238dcc3SJonas Devlieghere ) 13199451b44SJordan Rupprecht # Requesting completions inside an incomplete string doesn't provide any 13299451b44SJordan Rupprecht # completions. 1336bf6c476SDavid Spickett self.complete_from_to( 1342238dcc3SJonas Devlieghere 'expr const char *cstr = "some_e', 'expr const char *cstr = "some_e' 1352238dcc3SJonas Devlieghere ) 13699451b44SJordan Rupprecht 13799451b44SJordan Rupprecht # Completing inside double dash should do nothing 1382238dcc3SJonas Devlieghere self.assume_no_completions("expr -i0 -- some_expr.", 10) 1392238dcc3SJonas Devlieghere self.assume_no_completions("expr -i0 -- some_expr.", 11) 14099451b44SJordan Rupprecht 14199451b44SJordan Rupprecht # Test with expr arguments 1426bf6c476SDavid Spickett self.complete_from_to( 1432238dcc3SJonas Devlieghere "expr -i0 -- some_expr .FooNoArgs", "expr -i0 -- some_expr .FooNoArgsBar()" 1442238dcc3SJonas Devlieghere ) 1456bf6c476SDavid Spickett self.complete_from_to( 1462238dcc3SJonas Devlieghere "expr -i0 -- some_expr .FooNoArgs", 1472238dcc3SJonas Devlieghere "expr -i0 -- some_expr .FooNoArgsBar()", 1482238dcc3SJonas Devlieghere ) 14999451b44SJordan Rupprecht 15099451b44SJordan Rupprecht # Addrof and deref 1516bf6c476SDavid Spickett self.complete_from_to( 1522238dcc3SJonas Devlieghere "expr (*(&some_expr)).FooNoArgs", "expr (*(&some_expr)).FooNoArgsBar()" 1532238dcc3SJonas Devlieghere ) 1546bf6c476SDavid Spickett self.complete_from_to( 1552238dcc3SJonas Devlieghere "expr (*(&some_expr)) .FooNoArgs", "expr (*(&some_expr)) .FooNoArgsBar()" 1562238dcc3SJonas Devlieghere ) 1576bf6c476SDavid Spickett self.complete_from_to( 1582238dcc3SJonas Devlieghere "expr (* (&some_expr)) .FooNoArgs", "expr (* (&some_expr)) .FooNoArgsBar()" 1592238dcc3SJonas Devlieghere ) 1606bf6c476SDavid Spickett self.complete_from_to( 1612238dcc3SJonas Devlieghere "expr (* (& some_expr)) .FooNoArgs", 1622238dcc3SJonas Devlieghere "expr (* (& some_expr)) .FooNoArgsBar()", 1632238dcc3SJonas Devlieghere ) 16499451b44SJordan Rupprecht 16599451b44SJordan Rupprecht # Addrof and deref (part 2) 1666bf6c476SDavid Spickett self.complete_from_to( 1672238dcc3SJonas Devlieghere "expr (&some_expr)->FooNoArgs", "expr (&some_expr)->FooNoArgsBar()" 1682238dcc3SJonas Devlieghere ) 1696bf6c476SDavid Spickett self.complete_from_to( 1702238dcc3SJonas Devlieghere "expr (&some_expr) ->FooNoArgs", "expr (&some_expr) ->FooNoArgsBar()" 1712238dcc3SJonas Devlieghere ) 1726bf6c476SDavid Spickett self.complete_from_to( 1732238dcc3SJonas Devlieghere "expr (&some_expr) -> FooNoArgs", "expr (&some_expr) -> FooNoArgsBar()" 1742238dcc3SJonas Devlieghere ) 1756bf6c476SDavid Spickett self.complete_from_to( 1762238dcc3SJonas Devlieghere "expr (&some_expr)-> FooNoArgs", "expr (&some_expr)-> FooNoArgsBar()" 1772238dcc3SJonas Devlieghere ) 17899451b44SJordan Rupprecht 17999451b44SJordan Rupprecht # Builtin arg 1806bf6c476SDavid Spickett self.complete_from_to("expr static_ca", "expr static_cast") 18199451b44SJordan Rupprecht 18299451b44SJordan Rupprecht # From other files 1836bf6c476SDavid Spickett self.complete_from_to( 1842238dcc3SJonas Devlieghere "expr fwd_decl_ptr->Hidden", "expr fwd_decl_ptr->HiddenMember" 1852238dcc3SJonas Devlieghere ) 18699451b44SJordan Rupprecht 18799451b44SJordan Rupprecht # Types 1886bf6c476SDavid Spickett self.complete_from_to("expr LongClassNa", "expr LongClassName") 1896bf6c476SDavid Spickett self.complete_from_to( 1902238dcc3SJonas Devlieghere "expr LongNamespaceName::NestedCla", "expr LongNamespaceName::NestedClass" 1912238dcc3SJonas Devlieghere ) 19299451b44SJordan Rupprecht 19399451b44SJordan Rupprecht # Namespaces 1946bf6c476SDavid Spickett self.complete_from_to("expr LongNamespaceNa", "expr LongNamespaceName::") 19599451b44SJordan Rupprecht 19699451b44SJordan Rupprecht # Multiple arguments 1976bf6c476SDavid Spickett self.complete_from_to( 1982238dcc3SJonas Devlieghere "expr &some_expr + &some_e", "expr &some_expr + &some_expr" 1992238dcc3SJonas Devlieghere ) 2006bf6c476SDavid Spickett self.complete_from_to( 2012238dcc3SJonas Devlieghere "expr SomeLongVarNameWithCapitals + SomeLongVarName", 2022238dcc3SJonas Devlieghere "expr SomeLongVarNameWithCapitals + SomeLongVarNameWithCapitals", 2032238dcc3SJonas Devlieghere ) 2046bf6c476SDavid Spickett self.complete_from_to( 2052238dcc3SJonas Devlieghere "expr SomeIntVar + SomeIntV", "expr SomeIntVar + SomeIntVar" 2062238dcc3SJonas Devlieghere ) 20799451b44SJordan Rupprecht 20899451b44SJordan Rupprecht # Multiple statements 2096bf6c476SDavid Spickett self.complete_from_to( 2102238dcc3SJonas Devlieghere "expr long LocalVariable = 0; LocalVaria", 2112238dcc3SJonas Devlieghere "expr long LocalVariable = 0; LocalVariable", 2122238dcc3SJonas Devlieghere ) 21399451b44SJordan Rupprecht 21499451b44SJordan Rupprecht # Custom Decls 2156bf6c476SDavid Spickett self.complete_from_to( 2162238dcc3SJonas Devlieghere "expr auto l = [](int LeftHandSide, int bx){ return LeftHandS", 2172238dcc3SJonas Devlieghere "expr auto l = [](int LeftHandSide, int bx){ return LeftHandSide", 2182238dcc3SJonas Devlieghere ) 2196bf6c476SDavid Spickett self.complete_from_to( 2202238dcc3SJonas Devlieghere "expr struct LocalStruct { long MemberName; } ; LocalStruct S; S.Mem", 2212238dcc3SJonas Devlieghere "expr struct LocalStruct { long MemberName; } ; LocalStruct S; S.MemberName", 2222238dcc3SJonas Devlieghere ) 22399451b44SJordan Rupprecht 22499451b44SJordan Rupprecht # Completing function call arguments 2256bf6c476SDavid Spickett self.complete_from_to( 2262238dcc3SJonas Devlieghere "expr some_expr.FooWithArgsBar(some_exp", 2272238dcc3SJonas Devlieghere "expr some_expr.FooWithArgsBar(some_expr", 2282238dcc3SJonas Devlieghere ) 2296bf6c476SDavid Spickett self.complete_from_to( 2302238dcc3SJonas Devlieghere "expr some_expr.FooWithArgsBar(SomeIntV", 2312238dcc3SJonas Devlieghere "expr some_expr.FooWithArgsBar(SomeIntVar", 2322238dcc3SJonas Devlieghere ) 2336bf6c476SDavid Spickett self.complete_from_to( 2342238dcc3SJonas Devlieghere "expr some_expr.FooWithMultipleArgsBar(SomeIntVar, SomeIntVa", 2352238dcc3SJonas Devlieghere "expr some_expr.FooWithMultipleArgsBar(SomeIntVar, SomeIntVar", 2362238dcc3SJonas Devlieghere ) 23799451b44SJordan Rupprecht 23899451b44SJordan Rupprecht # Function return values 2396bf6c476SDavid Spickett self.complete_from_to( 2402238dcc3SJonas Devlieghere "expr some_expr.Self().FooNoArgs", "expr some_expr.Self().FooNoArgsBar()" 2412238dcc3SJonas Devlieghere ) 2426bf6c476SDavid Spickett self.complete_from_to( 2432238dcc3SJonas Devlieghere "expr some_expr.Self() .FooNoArgs", "expr some_expr.Self() .FooNoArgsBar()" 2442238dcc3SJonas Devlieghere ) 2456bf6c476SDavid Spickett self.complete_from_to( 2462238dcc3SJonas Devlieghere "expr some_expr.Self(). FooNoArgs", "expr some_expr.Self(). FooNoArgsBar()" 2472238dcc3SJonas Devlieghere ) 24899451b44SJordan Rupprecht 249*88bf6409SMichael Buch self.complete_from_to("expr myVec.__f", "expr myVec.__func()") 250*88bf6409SMichael Buch self.complete_from_to("expr myVec._F", "expr myVec._Func()") 251*88bf6409SMichael Buch self.complete_from_to("expr myVec.__m", "expr myVec.__mem") 252*88bf6409SMichael Buch self.complete_from_to("expr myVec._M", "expr myVec._Mem") 253*88bf6409SMichael Buch 25499451b44SJordan Rupprecht def test_expr_completion_with_descriptions(self): 25599451b44SJordan Rupprecht self.build() 25699451b44SJordan Rupprecht self.main_source = "main.cpp" 25799451b44SJordan Rupprecht self.main_source_spec = lldb.SBFileSpec(self.main_source) 25854c26872SRaphael Isemann self.createTestTarget() 25999451b44SJordan Rupprecht 2602238dcc3SJonas Devlieghere (target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint( 2612238dcc3SJonas Devlieghere self, "// Break here", self.main_source_spec 2622238dcc3SJonas Devlieghere ) 26399451b44SJordan Rupprecht 2642238dcc3SJonas Devlieghere self.check_completion_with_desc( 2652238dcc3SJonas Devlieghere "expr ", 2662238dcc3SJonas Devlieghere [ 26799451b44SJordan Rupprecht # builtin types have no description. 26899451b44SJordan Rupprecht ["int", ""], 26974a51753SRaphael Isemann ["float", ""], 27074a51753SRaphael Isemann # VarDecls have their type as description. 27174a51753SRaphael Isemann ["some_expr", "Expr &"], 2722238dcc3SJonas Devlieghere ], 2732238dcc3SJonas Devlieghere enforce_order=True, 2742238dcc3SJonas Devlieghere ) 2752238dcc3SJonas Devlieghere self.check_completion_with_desc( 2762238dcc3SJonas Devlieghere "expr some_expr.", 2772238dcc3SJonas Devlieghere [ 27899451b44SJordan Rupprecht # Functions have their signature as description. 27999451b44SJordan Rupprecht ["some_expr.~Expr()", "inline ~Expr()"], 28074a51753SRaphael Isemann ["some_expr.operator=(", "inline Expr &operator=(const Expr &)"], 28199451b44SJordan Rupprecht # FieldDecls have their type as description. 28299451b44SJordan Rupprecht ["some_expr.MemberVariableBar", "int"], 2832238dcc3SJonas Devlieghere [ 2842238dcc3SJonas Devlieghere "some_expr.StaticMemberMethodBar()", 2852238dcc3SJonas Devlieghere "static int StaticMemberMethodBar()", 2862238dcc3SJonas Devlieghere ], 28774a51753SRaphael Isemann ["some_expr.Self()", "Expr &Self()"], 28874a51753SRaphael Isemann ["some_expr.FooNoArgsBar()", "int FooNoArgsBar()"], 28974a51753SRaphael Isemann ["some_expr.FooWithArgsBar(", "int FooWithArgsBar(int)"], 29074a51753SRaphael Isemann ["some_expr.FooNumbersBar1()", "int FooNumbersBar1()"], 29174a51753SRaphael Isemann ["some_expr.FooUnderscoreBar_()", "int FooUnderscoreBar_()"], 2922238dcc3SJonas Devlieghere [ 2932238dcc3SJonas Devlieghere "some_expr.FooWithMultipleArgsBar(", 2942238dcc3SJonas Devlieghere "int FooWithMultipleArgsBar(int, int)", 2952238dcc3SJonas Devlieghere ], 2962238dcc3SJonas Devlieghere ], 2972238dcc3SJonas Devlieghere enforce_order=True, 2982238dcc3SJonas Devlieghere ) 29999451b44SJordan Rupprecht 30099451b44SJordan Rupprecht def assume_no_completions(self, str_input, cursor_pos=None): 30199451b44SJordan Rupprecht interp = self.dbg.GetCommandInterpreter() 30299451b44SJordan Rupprecht match_strings = lldb.SBStringList() 30399451b44SJordan Rupprecht if cursor_pos is None: 30499451b44SJordan Rupprecht cursor_pos = len(str_input) 3052238dcc3SJonas Devlieghere num_matches = interp.HandleCompletion( 3062238dcc3SJonas Devlieghere str_input, cursor_pos, 0, -1, match_strings 3072238dcc3SJonas Devlieghere ) 30899451b44SJordan Rupprecht 30999451b44SJordan Rupprecht available_completions = [] 31099451b44SJordan Rupprecht for m in match_strings: 31199451b44SJordan Rupprecht available_completions.append(m) 31299451b44SJordan Rupprecht 31380fcecb1SJonas Devlieghere self.assertEqual( 3142238dcc3SJonas Devlieghere num_matches, 3152238dcc3SJonas Devlieghere 0, 3162238dcc3SJonas Devlieghere "Got matches, but didn't expect any: " + str(available_completions), 3172238dcc3SJonas Devlieghere ) 31899451b44SJordan Rupprecht 31999451b44SJordan Rupprecht def completions_contain(self, str_input, items): 32099451b44SJordan Rupprecht interp = self.dbg.GetCommandInterpreter() 32199451b44SJordan Rupprecht match_strings = lldb.SBStringList() 3222238dcc3SJonas Devlieghere num_matches = interp.HandleCompletion( 3232238dcc3SJonas Devlieghere str_input, len(str_input), 0, -1, match_strings 3242238dcc3SJonas Devlieghere ) 32599451b44SJordan Rupprecht common_match = match_strings.GetStringAtIndex(0) 32699451b44SJordan Rupprecht 32799451b44SJordan Rupprecht for item in items: 32899451b44SJordan Rupprecht found = False 32999451b44SJordan Rupprecht for m in match_strings: 33099451b44SJordan Rupprecht if m == item: 33199451b44SJordan Rupprecht found = True 33299451b44SJordan Rupprecht if not found: 33399451b44SJordan Rupprecht # Transform match_strings to a python list with strings 33499451b44SJordan Rupprecht available_completions = [] 33599451b44SJordan Rupprecht for m in match_strings: 33699451b44SJordan Rupprecht available_completions.append(m) 3372238dcc3SJonas Devlieghere self.assertTrue( 3382238dcc3SJonas Devlieghere found, 3392238dcc3SJonas Devlieghere "Couldn't find completion " 3402238dcc3SJonas Devlieghere + item 3412238dcc3SJonas Devlieghere + " in completions " 3422238dcc3SJonas Devlieghere + str(available_completions), 3432238dcc3SJonas Devlieghere ) 344