2 Test the lldb command line completion mechanism for the 'expr' command.
7 from lldbsuite
.test
.decorators
import *
8 from lldbsuite
.test
.lldbtest
import *
9 from lldbsuite
.test
import lldbplatform
10 from lldbsuite
.test
import lldbutil
13 class CommandLineExprCompletionTestCase(TestBase
):
14 NO_DEBUG_INFO_TESTCASE
= True
16 def test_expr_completion(self
):
18 self
.main_source
= "main.cpp"
19 self
.main_source_spec
= lldb
.SBFileSpec(self
.main_source
)
20 self
.createTestTarget()
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")
27 (target
, process
, thread
, bkpt
) = lldbutil
.run_to_source_breakpoint(
28 self
, "// Break here", self
.main_source_spec
31 # Completing member functions
32 self
.complete_from_to(
33 "expr some_expr.FooNoArgs", "expr some_expr.FooNoArgsBar()"
35 self
.complete_from_to(
36 "expr some_expr.FooWithArgs", "expr some_expr.FooWithArgsBar("
38 self
.complete_from_to(
39 "expr some_expr.FooWithMultipleArgs",
40 "expr some_expr.FooWithMultipleArgsBar(",
42 self
.complete_from_to(
43 "expr some_expr.FooUnderscore", "expr some_expr.FooUnderscoreBar_()"
45 self
.complete_from_to(
46 "expr some_expr.FooNumbers", "expr some_expr.FooNumbersBar1()"
48 self
.complete_from_to(
49 "expr some_expr.StaticMemberMethod",
50 "expr some_expr.StaticMemberMethodBar()",
53 # Completing static functions
54 self
.complete_from_to(
55 "expr Expr::StaticMemberMethod", "expr Expr::StaticMemberMethodBar()"
58 # Completing member variables
59 self
.complete_from_to(
60 "expr some_expr.MemberVariab", "expr some_expr.MemberVariableBar"
63 # Multiple completions
64 self
.completions_contain(
67 "some_expr.FooNumbersBar1()",
68 "some_expr.FooUnderscoreBar_()",
69 "some_expr.FooWithArgsBar(",
70 "some_expr.MemberVariableBar",
74 self
.completions_contain(
77 "some_expr.FooNumbersBar1()",
78 "some_expr.FooUnderscoreBar_()",
79 "some_expr.FooWithArgsBar(",
83 self
.completions_contain(
84 "expr ", ["static_cast", "reinterpret_cast", "dynamic_cast"]
87 self
.completions_contain(
88 "expr 1 + ", ["static_cast", "reinterpret_cast", "dynamic_cast"]
91 # Completion expr without spaces
92 # This is a bit awkward looking for the user, but that's how
93 # the completion API works at the moment.
94 self
.completions_contain("expr 1+", ["1+some_expr", "1+static_cast"])
97 self
.complete_from_to(
98 "expr some_expr .FooNoArgs", "expr some_expr .FooNoArgsBar()"
100 self
.complete_from_to(
101 "expr some_expr .FooNoArgs", "expr some_expr .FooNoArgsBar()"
103 self
.complete_from_to(
104 "expr some_expr .FooNoArgs", "expr some_expr .FooNoArgsBar()"
106 self
.complete_from_to(
107 "expr some_expr. FooNoArgs", "expr some_expr. FooNoArgsBar()"
109 self
.complete_from_to(
110 "expr some_expr . FooNoArgs", "expr some_expr . FooNoArgsBar()"
112 self
.complete_from_to(
113 "expr Expr :: StaticMemberMethod", "expr Expr :: StaticMemberMethodBar()"
115 self
.complete_from_to(
116 "expr Expr ::StaticMemberMethod", "expr Expr ::StaticMemberMethodBar()"
118 self
.complete_from_to(
119 "expr Expr:: StaticMemberMethod", "expr Expr:: StaticMemberMethodBar()"
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',
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',
131 # Requesting completions inside an incomplete string doesn't provide any
133 self
.complete_from_to(
134 'expr const char *cstr = "some_e', 'expr const char *cstr = "some_e'
137 # Completing inside double dash should do nothing
138 self
.assume_no_completions("expr -i0 -- some_expr.", 10)
139 self
.assume_no_completions("expr -i0 -- some_expr.", 11)
141 # Test with expr arguments
142 self
.complete_from_to(
143 "expr -i0 -- some_expr .FooNoArgs", "expr -i0 -- some_expr .FooNoArgsBar()"
145 self
.complete_from_to(
146 "expr -i0 -- some_expr .FooNoArgs",
147 "expr -i0 -- some_expr .FooNoArgsBar()",
151 self
.complete_from_to(
152 "expr (*(&some_expr)).FooNoArgs", "expr (*(&some_expr)).FooNoArgsBar()"
154 self
.complete_from_to(
155 "expr (*(&some_expr)) .FooNoArgs", "expr (*(&some_expr)) .FooNoArgsBar()"
157 self
.complete_from_to(
158 "expr (* (&some_expr)) .FooNoArgs", "expr (* (&some_expr)) .FooNoArgsBar()"
160 self
.complete_from_to(
161 "expr (* (& some_expr)) .FooNoArgs",
162 "expr (* (& some_expr)) .FooNoArgsBar()",
165 # Addrof and deref (part 2)
166 self
.complete_from_to(
167 "expr (&some_expr)->FooNoArgs", "expr (&some_expr)->FooNoArgsBar()"
169 self
.complete_from_to(
170 "expr (&some_expr) ->FooNoArgs", "expr (&some_expr) ->FooNoArgsBar()"
172 self
.complete_from_to(
173 "expr (&some_expr) -> FooNoArgs", "expr (&some_expr) -> FooNoArgsBar()"
175 self
.complete_from_to(
176 "expr (&some_expr)-> FooNoArgs", "expr (&some_expr)-> FooNoArgsBar()"
180 self
.complete_from_to("expr static_ca", "expr static_cast")
183 self
.complete_from_to(
184 "expr fwd_decl_ptr->Hidden", "expr fwd_decl_ptr->HiddenMember"
188 self
.complete_from_to("expr LongClassNa", "expr LongClassName")
189 self
.complete_from_to(
190 "expr LongNamespaceName::NestedCla", "expr LongNamespaceName::NestedClass"
194 self
.complete_from_to("expr LongNamespaceNa", "expr LongNamespaceName::")
197 self
.complete_from_to(
198 "expr &some_expr + &some_e", "expr &some_expr + &some_expr"
200 self
.complete_from_to(
201 "expr SomeLongVarNameWithCapitals + SomeLongVarName",
202 "expr SomeLongVarNameWithCapitals + SomeLongVarNameWithCapitals",
204 self
.complete_from_to(
205 "expr SomeIntVar + SomeIntV", "expr SomeIntVar + SomeIntVar"
208 # Multiple statements
209 self
.complete_from_to(
210 "expr long LocalVariable = 0; LocalVaria",
211 "expr long LocalVariable = 0; LocalVariable",
215 self
.complete_from_to(
216 "expr auto l = [](int LeftHandSide, int bx){ return LeftHandS",
217 "expr auto l = [](int LeftHandSide, int bx){ return LeftHandSide",
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",
224 # Completing function call arguments
225 self
.complete_from_to(
226 "expr some_expr.FooWithArgsBar(some_exp",
227 "expr some_expr.FooWithArgsBar(some_expr",
229 self
.complete_from_to(
230 "expr some_expr.FooWithArgsBar(SomeIntV",
231 "expr some_expr.FooWithArgsBar(SomeIntVar",
233 self
.complete_from_to(
234 "expr some_expr.FooWithMultipleArgsBar(SomeIntVar, SomeIntVa",
235 "expr some_expr.FooWithMultipleArgsBar(SomeIntVar, SomeIntVar",
238 # Function return values
239 self
.complete_from_to(
240 "expr some_expr.Self().FooNoArgs", "expr some_expr.Self().FooNoArgsBar()"
242 self
.complete_from_to(
243 "expr some_expr.Self() .FooNoArgs", "expr some_expr.Self() .FooNoArgsBar()"
245 self
.complete_from_to(
246 "expr some_expr.Self(). FooNoArgs", "expr some_expr.Self(). FooNoArgsBar()"
249 def test_expr_completion_with_descriptions(self
):
251 self
.main_source
= "main.cpp"
252 self
.main_source_spec
= lldb
.SBFileSpec(self
.main_source
)
253 self
.createTestTarget()
255 (target
, process
, thread
, bkpt
) = lldbutil
.run_to_source_breakpoint(
256 self
, "// Break here", self
.main_source_spec
259 self
.check_completion_with_desc(
262 # builtin types have no description.
265 # VarDecls have their type as description.
266 ["some_expr", "Expr &"],
270 self
.check_completion_with_desc(
273 # Functions have their signature as description.
274 ["some_expr.~Expr()", "inline ~Expr()"],
275 ["some_expr.operator=(", "inline Expr &operator=(const Expr &)"],
276 # FieldDecls have their type as description.
277 ["some_expr.MemberVariableBar", "int"],
279 "some_expr.StaticMemberMethodBar()",
280 "static int StaticMemberMethodBar()",
282 ["some_expr.Self()", "Expr &Self()"],
283 ["some_expr.FooNoArgsBar()", "int FooNoArgsBar()"],
284 ["some_expr.FooWithArgsBar(", "int FooWithArgsBar(int)"],
285 ["some_expr.FooNumbersBar1()", "int FooNumbersBar1()"],
286 ["some_expr.FooUnderscoreBar_()", "int FooUnderscoreBar_()"],
288 "some_expr.FooWithMultipleArgsBar(",
289 "int FooWithMultipleArgsBar(int, int)",
295 def assume_no_completions(self
, str_input
, cursor_pos
=None):
296 interp
= self
.dbg
.GetCommandInterpreter()
297 match_strings
= lldb
.SBStringList()
298 if cursor_pos
is None:
299 cursor_pos
= len(str_input
)
300 num_matches
= interp
.HandleCompletion(
301 str_input
, cursor_pos
, 0, -1, match_strings
304 available_completions
= []
305 for m
in match_strings
:
306 available_completions
.append(m
)
311 "Got matches, but didn't expect any: " + str(available_completions
),
314 def completions_contain(self
, str_input
, items
):
315 interp
= self
.dbg
.GetCommandInterpreter()
316 match_strings
= lldb
.SBStringList()
317 num_matches
= interp
.HandleCompletion(
318 str_input
, len(str_input
), 0, -1, match_strings
320 common_match
= match_strings
.GetStringAtIndex(0)
324 for m
in match_strings
:
328 # Transform match_strings to a python list with strings
329 available_completions
= []
330 for m
in match_strings
:
331 available_completions
.append(m
)
334 "Couldn't find completion "
337 + str(available_completions
),