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