1""" 2Test the lldb command line completion mechanism for the 'expr' command. 3""" 4 5 6import lldb 7from lldbsuite.test.decorators import * 8from lldbsuite.test.lldbtest import * 9from lldbsuite.test import lldbplatform 10from lldbsuite.test import lldbutil 11 12class CommandLineExprCompletionTestCase(TestBase): 13 14 mydir = TestBase.compute_mydir(__file__) 15 16 NO_DEBUG_INFO_TESTCASE = True 17 18 def test_expr_completion(self): 19 self.build() 20 self.main_source = "main.cpp" 21 self.main_source_spec = lldb.SBFileSpec(self.main_source) 22 self.createTestTarget() 23 24 # Try the completion before we have a context to complete on. 25 self.assume_no_completions('expr some_expr') 26 self.assume_no_completions('expr ') 27 self.assume_no_completions('expr f') 28 29 30 (target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint(self, 31 '// Break here', self.main_source_spec) 32 33 # Completing member functions 34 self.complete_exactly('expr some_expr.FooNoArgs', 35 'expr some_expr.FooNoArgsBar()') 36 self.complete_exactly('expr some_expr.FooWithArgs', 37 'expr some_expr.FooWithArgsBar(') 38 self.complete_exactly('expr some_expr.FooWithMultipleArgs', 39 'expr some_expr.FooWithMultipleArgsBar(') 40 self.complete_exactly('expr some_expr.FooUnderscore', 41 'expr some_expr.FooUnderscoreBar_()') 42 self.complete_exactly('expr some_expr.FooNumbers', 43 'expr some_expr.FooNumbersBar1()') 44 self.complete_exactly('expr some_expr.StaticMemberMethod', 45 'expr some_expr.StaticMemberMethodBar()') 46 47 # Completing static functions 48 self.complete_exactly('expr Expr::StaticMemberMethod', 49 'expr Expr::StaticMemberMethodBar()') 50 51 # Completing member variables 52 self.complete_exactly('expr some_expr.MemberVariab', 53 'expr some_expr.MemberVariableBar') 54 55 # Multiple completions 56 self.completions_contain('expr some_expr.', 57 ['some_expr.FooNumbersBar1()', 58 'some_expr.FooUnderscoreBar_()', 59 'some_expr.FooWithArgsBar(', 60 'some_expr.MemberVariableBar']) 61 62 self.completions_contain('expr some_expr.Foo', 63 ['some_expr.FooNumbersBar1()', 64 'some_expr.FooUnderscoreBar_()', 65 'some_expr.FooWithArgsBar(']) 66 67 self.completions_contain('expr ', 68 ['static_cast', 69 'reinterpret_cast', 70 'dynamic_cast']) 71 72 self.completions_contain('expr 1 + ', 73 ['static_cast', 74 'reinterpret_cast', 75 'dynamic_cast']) 76 77 # Completion expr without spaces 78 # This is a bit awkward looking for the user, but that's how 79 # the completion API works at the moment. 80 self.completions_contain('expr 1+', 81 ['1+some_expr', "1+static_cast"]) 82 83 # Test with spaces 84 self.complete_exactly('expr some_expr .FooNoArgs', 85 'expr some_expr .FooNoArgsBar()') 86 self.complete_exactly('expr some_expr .FooNoArgs', 87 'expr some_expr .FooNoArgsBar()') 88 self.complete_exactly('expr some_expr .FooNoArgs', 89 'expr some_expr .FooNoArgsBar()') 90 self.complete_exactly('expr some_expr. FooNoArgs', 91 'expr some_expr. FooNoArgsBar()') 92 self.complete_exactly('expr some_expr . FooNoArgs', 93 'expr some_expr . FooNoArgsBar()') 94 self.complete_exactly('expr Expr :: StaticMemberMethod', 95 'expr Expr :: StaticMemberMethodBar()') 96 self.complete_exactly('expr Expr ::StaticMemberMethod', 97 'expr Expr ::StaticMemberMethodBar()') 98 self.complete_exactly('expr Expr:: StaticMemberMethod', 99 'expr Expr:: StaticMemberMethodBar()') 100 101 # Test that string literals don't break our parsing logic. 102 self.complete_exactly('expr const char *cstr = "some_e"; char c = *cst', 103 'expr const char *cstr = "some_e"; char c = *cstr') 104 self.complete_exactly('expr const char *cstr = "some_e" ; char c = *cst', 105 'expr const char *cstr = "some_e" ; char c = *cstr') 106 # Requesting completions inside an incomplete string doesn't provide any 107 # completions. 108 self.complete_exactly('expr const char *cstr = "some_e', 109 'expr const char *cstr = "some_e') 110 111 # Completing inside double dash should do nothing 112 self.assume_no_completions('expr -i0 -- some_expr.', 10) 113 self.assume_no_completions('expr -i0 -- some_expr.', 11) 114 115 # Test with expr arguments 116 self.complete_exactly('expr -i0 -- some_expr .FooNoArgs', 117 'expr -i0 -- some_expr .FooNoArgsBar()') 118 self.complete_exactly('expr -i0 -- some_expr .FooNoArgs', 119 'expr -i0 -- some_expr .FooNoArgsBar()') 120 121 # Addrof and deref 122 self.complete_exactly('expr (*(&some_expr)).FooNoArgs', 123 'expr (*(&some_expr)).FooNoArgsBar()') 124 self.complete_exactly('expr (*(&some_expr)) .FooNoArgs', 125 'expr (*(&some_expr)) .FooNoArgsBar()') 126 self.complete_exactly('expr (* (&some_expr)) .FooNoArgs', 127 'expr (* (&some_expr)) .FooNoArgsBar()') 128 self.complete_exactly('expr (* (& some_expr)) .FooNoArgs', 129 'expr (* (& some_expr)) .FooNoArgsBar()') 130 131 # Addrof and deref (part 2) 132 self.complete_exactly('expr (&some_expr)->FooNoArgs', 133 'expr (&some_expr)->FooNoArgsBar()') 134 self.complete_exactly('expr (&some_expr) ->FooNoArgs', 135 'expr (&some_expr) ->FooNoArgsBar()') 136 self.complete_exactly('expr (&some_expr) -> FooNoArgs', 137 'expr (&some_expr) -> FooNoArgsBar()') 138 self.complete_exactly('expr (&some_expr)-> FooNoArgs', 139 'expr (&some_expr)-> FooNoArgsBar()') 140 141 # Builtin arg 142 self.complete_exactly('expr static_ca', 143 'expr static_cast') 144 145 # From other files 146 self.complete_exactly('expr fwd_decl_ptr->Hidden', 147 'expr fwd_decl_ptr->HiddenMember') 148 149 150 # Types 151 self.complete_exactly('expr LongClassNa', 152 'expr LongClassName') 153 self.complete_exactly('expr LongNamespaceName::NestedCla', 154 'expr LongNamespaceName::NestedClass') 155 156 # Namespaces 157 self.complete_exactly('expr LongNamespaceNa', 158 'expr LongNamespaceName::') 159 160 # Multiple arguments 161 self.complete_exactly('expr &some_expr + &some_e', 162 'expr &some_expr + &some_expr') 163 self.complete_exactly('expr SomeLongVarNameWithCapitals + SomeLongVarName', 164 'expr SomeLongVarNameWithCapitals + SomeLongVarNameWithCapitals') 165 self.complete_exactly('expr SomeIntVar + SomeIntV', 166 'expr SomeIntVar + SomeIntVar') 167 168 # Multiple statements 169 self.complete_exactly('expr long LocalVariable = 0; LocalVaria', 170 'expr long LocalVariable = 0; LocalVariable') 171 172 # Custom Decls 173 self.complete_exactly('expr auto l = [](int LeftHandSide, int bx){ return LeftHandS', 174 'expr auto l = [](int LeftHandSide, int bx){ return LeftHandSide') 175 self.complete_exactly('expr struct LocalStruct { long MemberName; } ; LocalStruct S; S.Mem', 176 'expr struct LocalStruct { long MemberName; } ; LocalStruct S; S.MemberName') 177 178 # Completing function call arguments 179 self.complete_exactly('expr some_expr.FooWithArgsBar(some_exp', 180 'expr some_expr.FooWithArgsBar(some_expr') 181 self.complete_exactly('expr some_expr.FooWithArgsBar(SomeIntV', 182 'expr some_expr.FooWithArgsBar(SomeIntVar') 183 self.complete_exactly('expr some_expr.FooWithMultipleArgsBar(SomeIntVar, SomeIntVa', 184 'expr some_expr.FooWithMultipleArgsBar(SomeIntVar, SomeIntVar') 185 186 # Function return values 187 self.complete_exactly('expr some_expr.Self().FooNoArgs', 188 'expr some_expr.Self().FooNoArgsBar()') 189 self.complete_exactly('expr some_expr.Self() .FooNoArgs', 190 'expr some_expr.Self() .FooNoArgsBar()') 191 self.complete_exactly('expr some_expr.Self(). FooNoArgs', 192 'expr some_expr.Self(). FooNoArgsBar()') 193 194 def test_expr_completion_with_descriptions(self): 195 self.build() 196 self.main_source = "main.cpp" 197 self.main_source_spec = lldb.SBFileSpec(self.main_source) 198 self.createTestTarget() 199 200 (target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint(self, 201 '// Break here', self.main_source_spec) 202 203 self.check_completion_with_desc("expr ", [ 204 # builtin types have no description. 205 ["int", ""], 206 ["float", ""], 207 # VarDecls have their type as description. 208 ["some_expr", "Expr &"], 209 ], enforce_order = True) 210 self.check_completion_with_desc("expr some_expr.", [ 211 # Functions have their signature as description. 212 ["some_expr.~Expr()", "inline ~Expr()"], 213 ["some_expr.operator=(", "inline Expr &operator=(const Expr &)"], 214 # FieldDecls have their type as description. 215 ["some_expr.MemberVariableBar", "int"], 216 ["some_expr.StaticMemberMethodBar()", "static int StaticMemberMethodBar()"], 217 ["some_expr.Self()", "Expr &Self()"], 218 ["some_expr.FooNoArgsBar()", "int FooNoArgsBar()"], 219 ["some_expr.FooWithArgsBar(", "int FooWithArgsBar(int)"], 220 ["some_expr.FooNumbersBar1()", "int FooNumbersBar1()"], 221 ["some_expr.FooUnderscoreBar_()", "int FooUnderscoreBar_()"], 222 ["some_expr.FooWithMultipleArgsBar(", "int FooWithMultipleArgsBar(int, int)"], 223 ], enforce_order = True) 224 225 def assume_no_completions(self, str_input, cursor_pos = None): 226 interp = self.dbg.GetCommandInterpreter() 227 match_strings = lldb.SBStringList() 228 if cursor_pos is None: 229 cursor_pos = len(str_input) 230 num_matches = interp.HandleCompletion(str_input, cursor_pos, 0, -1, match_strings) 231 232 available_completions = [] 233 for m in match_strings: 234 available_completions.append(m) 235 236 self.assertEquals(num_matches, 0, "Got matches, but didn't expect any: " + str(available_completions)) 237 238 def completions_contain(self, str_input, items): 239 interp = self.dbg.GetCommandInterpreter() 240 match_strings = lldb.SBStringList() 241 num_matches = interp.HandleCompletion(str_input, len(str_input), 0, -1, match_strings) 242 common_match = match_strings.GetStringAtIndex(0) 243 244 for item in items: 245 found = False 246 for m in match_strings: 247 if m == item: 248 found = True 249 if not found: 250 # Transform match_strings to a python list with strings 251 available_completions = [] 252 for m in match_strings: 253 available_completions.append(m) 254 self.assertTrue(found, "Couldn't find completion " + item + " in completions " + str(available_completions)) 255