summaryrefslogtreecommitdiffstats
path: root/lldb/packages/Python/lldbsuite/test
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/packages/Python/lldbsuite/test')
-rw-r--r--lldb/packages/Python/lldbsuite/test/expression_command/completion/.categories1
-rw-r--r--lldb/packages/Python/lldbsuite/test/expression_command/completion/Makefile5
-rw-r--r--lldb/packages/Python/lldbsuite/test/expression_command/completion/TestExprCompletion.py227
-rw-r--r--lldb/packages/Python/lldbsuite/test/expression_command/completion/main.cpp35
-rw-r--r--lldb/packages/Python/lldbsuite/test/expression_command/completion/other.cpp4
-rw-r--r--lldb/packages/Python/lldbsuite/test/functionalities/completion/TestCompletion.py36
-rw-r--r--lldb/packages/Python/lldbsuite/test/lldbtest.py40
7 files changed, 312 insertions, 36 deletions
diff --git a/lldb/packages/Python/lldbsuite/test/expression_command/completion/.categories b/lldb/packages/Python/lldbsuite/test/expression_command/completion/.categories
new file mode 100644
index 00000000000..3a3f4df6416
--- /dev/null
+++ b/lldb/packages/Python/lldbsuite/test/expression_command/completion/.categories
@@ -0,0 +1 @@
+cmdline
diff --git a/lldb/packages/Python/lldbsuite/test/expression_command/completion/Makefile b/lldb/packages/Python/lldbsuite/test/expression_command/completion/Makefile
new file mode 100644
index 00000000000..6fc26a9193f
--- /dev/null
+++ b/lldb/packages/Python/lldbsuite/test/expression_command/completion/Makefile
@@ -0,0 +1,5 @@
+LEVEL = ../../make
+
+CXX_SOURCES := main.cpp other.cpp
+
+include $(LEVEL)/Makefile.rules
diff --git a/lldb/packages/Python/lldbsuite/test/expression_command/completion/TestExprCompletion.py b/lldb/packages/Python/lldbsuite/test/expression_command/completion/TestExprCompletion.py
new file mode 100644
index 00000000000..2ebc239fa08
--- /dev/null
+++ b/lldb/packages/Python/lldbsuite/test/expression_command/completion/TestExprCompletion.py
@@ -0,0 +1,227 @@
+"""
+Test the lldb command line completion mechanism for the 'expr' command.
+"""
+
+from __future__ import print_function
+
+import random
+import os
+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
+
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24489")
+ 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 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))
diff --git a/lldb/packages/Python/lldbsuite/test/expression_command/completion/main.cpp b/lldb/packages/Python/lldbsuite/test/expression_command/completion/main.cpp
new file mode 100644
index 00000000000..908bebbebff
--- /dev/null
+++ b/lldb/packages/Python/lldbsuite/test/expression_command/completion/main.cpp
@@ -0,0 +1,35 @@
+namespace LongNamespaceName { class NestedClass { long m; }; }
+
+// Defined in other.cpp, we only have a forward declaration here.
+struct ForwardDecl;
+extern ForwardDecl fwd_decl;
+
+class LongClassName { long i ; };
+
+class Expr {
+public:
+ int FooNoArgsBar() { return 1; }
+ int FooWithArgsBar(int i) { return i; }
+ int FooWithMultipleArgsBar(int i, int j) { return i + j; }
+ int FooUnderscoreBar_() { return 4; }
+ int FooNumbersBar1() { return 8; }
+ int MemberVariableBar = 0;
+ Expr &Self() { return *this; }
+ static int StaticMemberMethodBar() { return 82; }
+};
+
+int main()
+{
+ LongClassName a;
+ LongNamespaceName::NestedClass NestedFoo;
+ long SomeLongVarNameWithCapitals = 44;
+ int SomeIntVar = 33;
+ Expr some_expr;
+ some_expr.FooNoArgsBar();
+ some_expr.FooWithArgsBar(1);
+ some_expr.FooUnderscoreBar_();
+ some_expr.FooNumbersBar1();
+ Expr::StaticMemberMethodBar();
+ ForwardDecl *fwd_decl_ptr = &fwd_decl;
+ return 0; // Break here
+}
diff --git a/lldb/packages/Python/lldbsuite/test/expression_command/completion/other.cpp b/lldb/packages/Python/lldbsuite/test/expression_command/completion/other.cpp
new file mode 100644
index 00000000000..1f8a488639b
--- /dev/null
+++ b/lldb/packages/Python/lldbsuite/test/expression_command/completion/other.cpp
@@ -0,0 +1,4 @@
+struct ForwardDecl {
+ long HiddenMemberName;
+};
+ForwardDecl fwd_decl;
diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/completion/TestCompletion.py b/lldb/packages/Python/lldbsuite/test/functionalities/completion/TestCompletion.py
index 5971e5a673d..7302660d6cf 100644
--- a/lldb/packages/Python/lldbsuite/test/functionalities/completion/TestCompletion.py
+++ b/lldb/packages/Python/lldbsuite/test/functionalities/completion/TestCompletion.py
@@ -281,39 +281,3 @@ class CommandLineCompletionTestCase(TestBase):
self.complete_from_to('breakpoint set -n Fo',
'breakpoint set -n Foo::Bar(int,\\ int)',
turn_off_re_match=True)
-
- def complete_from_to(self, str_input, patterns, turn_off_re_match=False):
- """Test that the completion mechanism completes str_input to patterns,
- where patterns could be a pattern-string or a list of pattern-strings"""
- # Patterns should not be None in order to proceed.
- self.assertFalse(patterns is None)
- # And should be either a string or list of strings. Check for list type
- # below, if not, make a list out of the singleton string. If patterns
- # is not a string or not a list of strings, there'll be runtime errors
- # later on.
- if not isinstance(patterns, list):
- patterns = [patterns]
-
- 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)
- if num_matches == 0:
- compare_string = str_input
- else:
- if common_match != None and len(common_match) > 0:
- compare_string = str_input + common_match
- else:
- compare_string = ""
- for idx in range(1, num_matches+1):
- compare_string += match_strings.GetStringAtIndex(idx) + "\n"
-
- for p in patterns:
- if turn_off_re_match:
- self.expect(
- compare_string, msg=COMPLETION_MSG(
- str_input, p, match_strings), exe=False, substrs=[p])
- else:
- self.expect(
- compare_string, msg=COMPLETION_MSG(
- str_input, p, match_strings), exe=False, patterns=[p])
diff --git a/lldb/packages/Python/lldbsuite/test/lldbtest.py b/lldb/packages/Python/lldbsuite/test/lldbtest.py
index e7316af9e89..cee4d34101a 100644
--- a/lldb/packages/Python/lldbsuite/test/lldbtest.py
+++ b/lldb/packages/Python/lldbsuite/test/lldbtest.py
@@ -2145,6 +2145,46 @@ class TestBase(Base):
return match_object
+
+ def complete_exactly(self, str_input, patterns):
+ self.complete_from_to(str_input, patterns, True)
+
+ def complete_from_to(self, str_input, patterns, turn_off_re_match=False):
+ """Test that the completion mechanism completes str_input to patterns,
+ where patterns could be a pattern-string or a list of pattern-strings"""
+ # Patterns should not be None in order to proceed.
+ self.assertFalse(patterns is None)
+ # And should be either a string or list of strings. Check for list type
+ # below, if not, make a list out of the singleton string. If patterns
+ # is not a string or not a list of strings, there'll be runtime errors
+ # later on.
+ if not isinstance(patterns, list):
+ patterns = [patterns]
+
+ 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)
+ if num_matches == 0:
+ compare_string = str_input
+ else:
+ if common_match != None and len(common_match) > 0:
+ compare_string = str_input + common_match
+ else:
+ compare_string = ""
+ for idx in range(1, num_matches+1):
+ compare_string += match_strings.GetStringAtIndex(idx) + "\n"
+
+ for p in patterns:
+ if turn_off_re_match:
+ self.expect(
+ compare_string, msg=COMPLETION_MSG(
+ str_input, p, match_strings), exe=False, substrs=[p])
+ else:
+ self.expect(
+ compare_string, msg=COMPLETION_MSG(
+ str_input, p, match_strings), exe=False, patterns=[p])
+
def expect(
self,
str,
OpenPOWER on IntegriCloud