summaryrefslogtreecommitdiffstats
path: root/lldb/packages/Python/lldbsuite/test/commands/expression/completion/TestExprCompletion.py
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/packages/Python/lldbsuite/test/commands/expression/completion/TestExprCompletion.py')
-rw-r--r--lldb/packages/Python/lldbsuite/test/commands/expression/completion/TestExprCompletion.py255
1 files changed, 255 insertions, 0 deletions
diff --git a/lldb/packages/Python/lldbsuite/test/commands/expression/completion/TestExprCompletion.py b/lldb/packages/Python/lldbsuite/test/commands/expression/completion/TestExprCompletion.py
new file mode 100644
index 00000000000..33a423c806b
--- /dev/null
+++ b/lldb/packages/Python/lldbsuite/test/commands/expression/completion/TestExprCompletion.py
@@ -0,0 +1,255 @@
+"""
+Test the lldb command line completion mechanism for the 'expr' command.
+"""
+
+from __future__ import print_function
+
+import lldb
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbplatform
+from lldbsuite.test import lldbutil
+
+class CommandLineExprCompletionTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ NO_DEBUG_INFO_TESTCASE = True
+
+ def test_expr_completion(self):
+ self.build()
+ self.main_source = "main.cpp"
+ self.main_source_spec = lldb.SBFileSpec(self.main_source)
+ self.dbg.CreateTarget(self.getBuildArtifact("a.out"))
+
+ # Try the completion before we have a context to complete on.
+ self.assume_no_completions('expr some_expr')
+ self.assume_no_completions('expr ')
+ self.assume_no_completions('expr f')
+
+
+ (target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint(self,
+ '// Break here', self.main_source_spec)
+
+ # Completing member functions
+ self.complete_exactly('expr some_expr.FooNoArgs',
+ 'expr some_expr.FooNoArgsBar()')
+ self.complete_exactly('expr some_expr.FooWithArgs',
+ 'expr some_expr.FooWithArgsBar(')
+ self.complete_exactly('expr some_expr.FooWithMultipleArgs',
+ 'expr some_expr.FooWithMultipleArgsBar(')
+ self.complete_exactly('expr some_expr.FooUnderscore',
+ 'expr some_expr.FooUnderscoreBar_()')
+ self.complete_exactly('expr some_expr.FooNumbers',
+ 'expr some_expr.FooNumbersBar1()')
+ self.complete_exactly('expr some_expr.StaticMemberMethod',
+ 'expr some_expr.StaticMemberMethodBar()')
+
+ # Completing static functions
+ self.complete_exactly('expr Expr::StaticMemberMethod',
+ 'expr Expr::StaticMemberMethodBar()')
+
+ # Completing member variables
+ self.complete_exactly('expr some_expr.MemberVariab',
+ 'expr some_expr.MemberVariableBar')
+
+ # Multiple completions
+ self.completions_contain('expr some_expr.',
+ ['some_expr.FooNumbersBar1()',
+ 'some_expr.FooUnderscoreBar_()',
+ 'some_expr.FooWithArgsBar(',
+ 'some_expr.MemberVariableBar'])
+
+ self.completions_contain('expr some_expr.Foo',
+ ['some_expr.FooNumbersBar1()',
+ 'some_expr.FooUnderscoreBar_()',
+ 'some_expr.FooWithArgsBar('])
+
+ self.completions_contain('expr ',
+ ['static_cast',
+ 'reinterpret_cast',
+ 'dynamic_cast'])
+
+ self.completions_contain('expr 1 + ',
+ ['static_cast',
+ 'reinterpret_cast',
+ 'dynamic_cast'])
+
+ # Completion expr without spaces
+ # This is a bit awkward looking for the user, but that's how
+ # the completion API works at the moment.
+ self.completions_contain('expr 1+',
+ ['1+some_expr', "1+static_cast"])
+
+ # Test with spaces
+ self.complete_exactly('expr some_expr .FooNoArgs',
+ 'expr some_expr .FooNoArgsBar()')
+ self.complete_exactly('expr some_expr .FooNoArgs',
+ 'expr some_expr .FooNoArgsBar()')
+ self.complete_exactly('expr some_expr .FooNoArgs',
+ 'expr some_expr .FooNoArgsBar()')
+ self.complete_exactly('expr some_expr. FooNoArgs',
+ 'expr some_expr. FooNoArgsBar()')
+ self.complete_exactly('expr some_expr . FooNoArgs',
+ 'expr some_expr . FooNoArgsBar()')
+ self.complete_exactly('expr Expr :: StaticMemberMethod',
+ 'expr Expr :: StaticMemberMethodBar()')
+ self.complete_exactly('expr Expr ::StaticMemberMethod',
+ 'expr Expr ::StaticMemberMethodBar()')
+ self.complete_exactly('expr Expr:: StaticMemberMethod',
+ 'expr Expr:: StaticMemberMethodBar()')
+
+ # Test that string literals don't break our parsing logic.
+ self.complete_exactly('expr const char *cstr = "some_e"; char c = *cst',
+ 'expr const char *cstr = "some_e"; char c = *cstr')
+ self.complete_exactly('expr const char *cstr = "some_e" ; char c = *cst',
+ 'expr const char *cstr = "some_e" ; char c = *cstr')
+ # Requesting completions inside an incomplete string doesn't provide any
+ # completions.
+ self.complete_exactly('expr const char *cstr = "some_e',
+ 'expr const char *cstr = "some_e')
+
+ # Completing inside double dash should do nothing
+ self.assume_no_completions('expr -i0 -- some_expr.', 10)
+ self.assume_no_completions('expr -i0 -- some_expr.', 11)
+
+ # Test with expr arguments
+ self.complete_exactly('expr -i0 -- some_expr .FooNoArgs',
+ 'expr -i0 -- some_expr .FooNoArgsBar()')
+ self.complete_exactly('expr -i0 -- some_expr .FooNoArgs',
+ 'expr -i0 -- some_expr .FooNoArgsBar()')
+
+ # Addrof and deref
+ self.complete_exactly('expr (*(&some_expr)).FooNoArgs',
+ 'expr (*(&some_expr)).FooNoArgsBar()')
+ self.complete_exactly('expr (*(&some_expr)) .FooNoArgs',
+ 'expr (*(&some_expr)) .FooNoArgsBar()')
+ self.complete_exactly('expr (* (&some_expr)) .FooNoArgs',
+ 'expr (* (&some_expr)) .FooNoArgsBar()')
+ self.complete_exactly('expr (* (& some_expr)) .FooNoArgs',
+ 'expr (* (& some_expr)) .FooNoArgsBar()')
+
+ # Addrof and deref (part 2)
+ self.complete_exactly('expr (&some_expr)->FooNoArgs',
+ 'expr (&some_expr)->FooNoArgsBar()')
+ self.complete_exactly('expr (&some_expr) ->FooNoArgs',
+ 'expr (&some_expr) ->FooNoArgsBar()')
+ self.complete_exactly('expr (&some_expr) -> FooNoArgs',
+ 'expr (&some_expr) -> FooNoArgsBar()')
+ self.complete_exactly('expr (&some_expr)-> FooNoArgs',
+ 'expr (&some_expr)-> FooNoArgsBar()')
+
+ # Builtin arg
+ self.complete_exactly('expr static_ca',
+ 'expr static_cast')
+
+ # From other files
+ self.complete_exactly('expr fwd_decl_ptr->Hidden',
+ 'expr fwd_decl_ptr->HiddenMember')
+
+
+ # Types
+ self.complete_exactly('expr LongClassNa',
+ 'expr LongClassName')
+ self.complete_exactly('expr LongNamespaceName::NestedCla',
+ 'expr LongNamespaceName::NestedClass')
+
+ # Namespaces
+ self.complete_exactly('expr LongNamespaceNa',
+ 'expr LongNamespaceName::')
+
+ # Multiple arguments
+ self.complete_exactly('expr &some_expr + &some_e',
+ 'expr &some_expr + &some_expr')
+ self.complete_exactly('expr SomeLongVarNameWithCapitals + SomeLongVarName',
+ 'expr SomeLongVarNameWithCapitals + SomeLongVarNameWithCapitals')
+ self.complete_exactly('expr SomeIntVar + SomeIntV',
+ 'expr SomeIntVar + SomeIntVar')
+
+ # Multiple statements
+ self.complete_exactly('expr long LocalVariable = 0; LocalVaria',
+ 'expr long LocalVariable = 0; LocalVariable')
+
+ # Custom Decls
+ self.complete_exactly('expr auto l = [](int LeftHandSide, int bx){ return LeftHandS',
+ 'expr auto l = [](int LeftHandSide, int bx){ return LeftHandSide')
+ self.complete_exactly('expr struct LocalStruct { long MemberName; } ; LocalStruct S; S.Mem',
+ 'expr struct LocalStruct { long MemberName; } ; LocalStruct S; S.MemberName')
+
+ # Completing function call arguments
+ self.complete_exactly('expr some_expr.FooWithArgsBar(some_exp',
+ 'expr some_expr.FooWithArgsBar(some_expr')
+ self.complete_exactly('expr some_expr.FooWithArgsBar(SomeIntV',
+ 'expr some_expr.FooWithArgsBar(SomeIntVar')
+ self.complete_exactly('expr some_expr.FooWithMultipleArgsBar(SomeIntVar, SomeIntVa',
+ 'expr some_expr.FooWithMultipleArgsBar(SomeIntVar, SomeIntVar')
+
+ # Function return values
+ self.complete_exactly('expr some_expr.Self().FooNoArgs',
+ 'expr some_expr.Self().FooNoArgsBar()')
+ self.complete_exactly('expr some_expr.Self() .FooNoArgs',
+ 'expr some_expr.Self() .FooNoArgsBar()')
+ self.complete_exactly('expr some_expr.Self(). FooNoArgs',
+ 'expr some_expr.Self(). FooNoArgsBar()')
+
+ def test_expr_completion_with_descriptions(self):
+ self.build()
+ self.main_source = "main.cpp"
+ self.main_source_spec = lldb.SBFileSpec(self.main_source)
+ self.dbg.CreateTarget(self.getBuildArtifact("a.out"))
+
+ (target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint(self,
+ '// Break here', self.main_source_spec)
+
+ self.check_completion_with_desc("expr ", [
+ # VarDecls have their type as description.
+ ["some_expr", "Expr &"],
+ # builtin types have no description.
+ ["int", ""],
+ ["float", ""]
+ ])
+ self.check_completion_with_desc("expr some_expr.", [
+ # Functions have their signature as description.
+ ["some_expr.Self()", "Expr &Self()"],
+ ["some_expr.operator=(", "inline Expr &operator=(const Expr &)"],
+ ["some_expr.FooNumbersBar1()", "int FooNumbersBar1()"],
+ ["some_expr.StaticMemberMethodBar()", "static int StaticMemberMethodBar()"],
+ ["some_expr.FooWithArgsBar(", "int FooWithArgsBar(int)"],
+ ["some_expr.FooNoArgsBar()", "int FooNoArgsBar()"],
+ ["some_expr.FooUnderscoreBar_()", "int FooUnderscoreBar_()"],
+ ["some_expr.FooWithMultipleArgsBar(", "int FooWithMultipleArgsBar(int, int)"],
+ ["some_expr.~Expr()", "inline ~Expr()"],
+ # FieldDecls have their type as description.
+ ["some_expr.MemberVariableBar", "int"],
+ ])
+
+ def assume_no_completions(self, str_input, cursor_pos = None):
+ interp = self.dbg.GetCommandInterpreter()
+ match_strings = lldb.SBStringList()
+ if cursor_pos is None:
+ cursor_pos = len(str_input)
+ num_matches = interp.HandleCompletion(str_input, cursor_pos, 0, -1, match_strings)
+
+ available_completions = []
+ for m in match_strings:
+ available_completions.append(m)
+
+ self.assertEquals(num_matches, 0, "Got matches, but didn't expect any: " + str(available_completions))
+
+ def completions_contain(self, str_input, items):
+ interp = self.dbg.GetCommandInterpreter()
+ match_strings = lldb.SBStringList()
+ num_matches = interp.HandleCompletion(str_input, len(str_input), 0, -1, match_strings)
+ common_match = match_strings.GetStringAtIndex(0)
+
+ for item in items:
+ found = False
+ for m in match_strings:
+ if m == item:
+ found = True
+ if not found:
+ # Transform match_strings to a python list with strings
+ available_completions = []
+ for m in match_strings:
+ available_completions.append(m)
+ self.assertTrue(found, "Couldn't find completion " + item + " in completions " + str(available_completions))
OpenPOWER on IntegriCloud