[Lldb-commits] [lldb] 22e63cb - [lldb] tab completion for breakpoint names
Raphael Isemann via lldb-commits
lldb-commits at lists.llvm.org
Thu Aug 20 11:56:56 PDT 2020
Author: Gongyu Deng
Date: 2020-08-20T20:56:34+02:00
New Revision: 22e63cba17e5e6266b9251e3fb7032b793143d09
URL: https://github.com/llvm/llvm-project/commit/22e63cba17e5e6266b9251e3fb7032b793143d09
DIFF: https://github.com/llvm/llvm-project/commit/22e63cba17e5e6266b9251e3fb7032b793143d09.diff
LOG: [lldb] tab completion for breakpoint names
1. created a common completion for breakpoint names;
2. bound the breakpoint name common completion with eArgTypeBreakpointName;
3. implemented the dedicated completion for breakpoint read -N.
Reviewed By: JDevlieghere
Differential Revision: https://reviews.llvm.org/D80693
Added:
lldb/test/API/functionalities/completion/breakpoints.json
lldb/test/API/functionalities/completion/breakpoints_invalid.json
Modified:
lldb/include/lldb/Interpreter/CommandCompletions.h
lldb/source/Commands/CommandCompletions.cpp
lldb/source/Commands/CommandObjectBreakpoint.cpp
lldb/source/Interpreter/CommandObject.cpp
lldb/test/API/functionalities/completion/TestCompletion.py
Removed:
################################################################################
diff --git a/lldb/include/lldb/Interpreter/CommandCompletions.h b/lldb/include/lldb/Interpreter/CommandCompletions.h
index a744b3fd849d..1d8972e0ca03 100644
--- a/lldb/include/lldb/Interpreter/CommandCompletions.h
+++ b/lldb/include/lldb/Interpreter/CommandCompletions.h
@@ -44,10 +44,11 @@ class CommandCompletions {
eStopHookIDCompletion = (1u << 16),
eThreadIndexCompletion = (1u << 17),
eWatchPointIDCompletion = (1u << 18),
+ eBreakpointNameCompletion = (1u << 19),
// This item serves two purposes. It is the last element in the enum, so
// you can add custom enums starting from here in your Option class. Also
// if you & in this bit the base code will not process the option.
- eCustomCompletion = (1u << 19)
+ eCustomCompletion = (1u << 20)
};
static bool InvokeCommonCompletionCallbacks(
@@ -101,6 +102,10 @@ class CommandCompletions {
static void Breakpoints(CommandInterpreter &interpreter,
CompletionRequest &request, SearchFilter *searcher);
+ static void BreakpointNames(CommandInterpreter &interpreter,
+ CompletionRequest &request,
+ SearchFilter *searcher);
+
static void ProcessPluginNames(CommandInterpreter &interpreter,
CompletionRequest &request,
SearchFilter *searcher);
diff --git a/lldb/source/Commands/CommandCompletions.cpp b/lldb/source/Commands/CommandCompletions.cpp
index 4ed11e14b84f..109613e223c7 100644
--- a/lldb/source/Commands/CommandCompletions.cpp
+++ b/lldb/source/Commands/CommandCompletions.cpp
@@ -70,6 +70,7 @@ bool CommandCompletions::InvokeCommonCompletionCallbacks(
{eStopHookIDCompletion, CommandCompletions::StopHookIDs},
{eThreadIndexCompletion, CommandCompletions::ThreadIndexes},
{eWatchPointIDCompletion, CommandCompletions::WatchPointIDs},
+ {eBreakpointNameCompletion, CommandCompletions::BreakpointNames},
{eNoCompletion, nullptr} // This one has to be last in the list.
};
@@ -617,13 +618,26 @@ void CommandCompletions::Breakpoints(CommandInterpreter &interpreter,
}
}
+void CommandCompletions::BreakpointNames(CommandInterpreter &interpreter,
+ CompletionRequest &request,
+ SearchFilter *searcher) {
+ lldb::TargetSP target = interpreter.GetDebugger().GetSelectedTarget();
+ if (!target)
+ return;
+
+ std::vector<std::string> name_list;
+ target->GetBreakpointNames(name_list);
+
+ for (const std::string &name : name_list)
+ request.TryCompleteCurrentArg(name);
+}
+
void CommandCompletions::ProcessPluginNames(CommandInterpreter &interpreter,
CompletionRequest &request,
SearchFilter *searcher) {
PluginManager::AutoCompleteProcessName(request.GetCursorArgumentPrefix(),
request);
}
-
void CommandCompletions::DisassemblyFlavors(CommandInterpreter &interpreter,
CompletionRequest &request,
SearchFilter *searcher) {
diff --git a/lldb/source/Commands/CommandObjectBreakpoint.cpp b/lldb/source/Commands/CommandObjectBreakpoint.cpp
index b62fe6c93cd8..023ba208176a 100644
--- a/lldb/source/Commands/CommandObjectBreakpoint.cpp
+++ b/lldb/source/Commands/CommandObjectBreakpoint.cpp
@@ -2097,7 +2097,79 @@ class CommandObjectBreakpointRead : public CommandObjectParsed {
return llvm::makeArrayRef(g_breakpoint_read_options);
}
- // Instance variables to hold the values for command options.
+ void HandleOptionArgumentCompletion(
+ CompletionRequest &request, OptionElementVector &opt_element_vector,
+ int opt_element_index, CommandInterpreter &interpreter) override {
+ int opt_arg_pos = opt_element_vector[opt_element_index].opt_arg_pos;
+ int opt_defs_index = opt_element_vector[opt_element_index].opt_defs_index;
+
+ switch (GetDefinitions()[opt_defs_index].short_option) {
+ case 'f':
+ CommandCompletions::InvokeCommonCompletionCallbacks(
+ interpreter, CommandCompletions::eDiskFileCompletion, request,
+ nullptr);
+ break;
+
+ case 'N':
+ llvm::Optional<FileSpec> file_spec;
+ const llvm::StringRef dash_f("-f");
+ for (int arg_idx = 0; arg_idx < opt_arg_pos; arg_idx++) {
+ if (dash_f == request.GetParsedLine().GetArgumentAtIndex(arg_idx)) {
+ file_spec.emplace(
+ request.GetParsedLine().GetArgumentAtIndex(arg_idx + 1));
+ break;
+ }
+ }
+ if (!file_spec)
+ return;
+
+ FileSystem::Instance().Resolve(*file_spec);
+ Status error;
+ StructuredData::ObjectSP input_data_sp =
+ StructuredData::ParseJSONFromFile(*file_spec, error);
+ if (!error.Success())
+ return;
+
+ StructuredData::Array *bkpt_array = input_data_sp->GetAsArray();
+ if (!bkpt_array)
+ return;
+
+ const size_t num_bkpts = bkpt_array->GetSize();
+ for (size_t i = 0; i < num_bkpts; i++) {
+ StructuredData::ObjectSP bkpt_object_sp =
+ bkpt_array->GetItemAtIndex(i);
+ if (!bkpt_object_sp)
+ return;
+
+ StructuredData::Dictionary *bkpt_dict =
+ bkpt_object_sp->GetAsDictionary();
+ if (!bkpt_dict)
+ return;
+
+ StructuredData::ObjectSP bkpt_data_sp =
+ bkpt_dict->GetValueForKey(Breakpoint::GetSerializationKey());
+ if (!bkpt_data_sp)
+ return;
+
+ bkpt_dict = bkpt_data_sp->GetAsDictionary();
+ if (!bkpt_dict)
+ return;
+
+ StructuredData::Array *names_array;
+
+ if (!bkpt_dict->GetValueForKeyAsArray("Names", names_array))
+ return;
+
+ size_t num_names = names_array->GetSize();
+
+ for (size_t i = 0; i < num_names; i++) {
+ llvm::StringRef name;
+ if (names_array->GetItemAtIndexAsString(i, name))
+ request.TryCompleteCurrentArg(name);
+ }
+ }
+ }
+ }
std::string m_filename;
std::vector<std::string> m_names;
diff --git a/lldb/source/Interpreter/CommandObject.cpp b/lldb/source/Interpreter/CommandObject.cpp
index 6f356e448523..944cf5e58b40 100644
--- a/lldb/source/Interpreter/CommandObject.cpp
+++ b/lldb/source/Interpreter/CommandObject.cpp
@@ -1041,7 +1041,7 @@ CommandObject::ArgumentTableEntry CommandObject::g_arguments_data[] = {
{ eArgTypeBoolean, "boolean", CommandCompletions::eNoCompletion, { nullptr, false }, "A Boolean value: 'true' or 'false'" },
{ eArgTypeBreakpointID, "breakpt-id", CommandCompletions::eNoCompletion, { BreakpointIDHelpTextCallback, false }, nullptr },
{ eArgTypeBreakpointIDRange, "breakpt-id-list", CommandCompletions::eNoCompletion, { BreakpointIDRangeHelpTextCallback, false }, nullptr },
- { eArgTypeBreakpointName, "breakpoint-name", CommandCompletions::eNoCompletion, { BreakpointNameHelpTextCallback, false }, nullptr },
+ { eArgTypeBreakpointName, "breakpoint-name", CommandCompletions::eBreakpointNameCompletion, { BreakpointNameHelpTextCallback, false }, nullptr },
{ eArgTypeByteSize, "byte-size", CommandCompletions::eNoCompletion, { nullptr, false }, "Number of bytes to use." },
{ eArgTypeClassName, "class-name", CommandCompletions::eNoCompletion, { nullptr, false }, "Then name of a class from the debug information in the program." },
{ eArgTypeCommandName, "cmd-name", CommandCompletions::eNoCompletion, { nullptr, false }, "A debugger command (may be multiple words), without any options or arguments." },
diff --git a/lldb/test/API/functionalities/completion/TestCompletion.py b/lldb/test/API/functionalities/completion/TestCompletion.py
index 987ae65474ed..4922cca7b722 100644
--- a/lldb/test/API/functionalities/completion/TestCompletion.py
+++ b/lldb/test/API/functionalities/completion/TestCompletion.py
@@ -644,3 +644,21 @@ def test_complete_breakpoint_with_ids(self):
['1',
'2'])
+ def test_complete_breakpoint_with_names(self):
+ self.build()
+ target = self.dbg.CreateTarget(self.getBuildArtifact('a.out'))
+ self.assertTrue(target, VALID_TARGET)
+
+ # test breakpoint read dedicated
+ self.complete_from_to('breakpoint read -N ', 'breakpoint read -N ')
+ self.complete_from_to('breakpoint read -f breakpoints.json -N ', ['mm'])
+ self.complete_from_to('breakpoint read -f breakpoints.json -N n', 'breakpoint read -f breakpoints.json -N n')
+ self.complete_from_to('breakpoint read -f breakpoints_invalid.json -N ', 'breakpoint read -f breakpoints_invalid.json -N ')
+
+ # test common breapoint name completion
+ bp1 = target.BreakpointCreateByName('main', 'a.out')
+ self.assertTrue(bp1)
+ self.assertEqual(bp1.GetNumLocations(), 1)
+ self.complete_from_to('breakpoint set -N n', 'breakpoint set -N n')
+ self.assertTrue(bp1.AddNameWithErrorHandling("nn"))
+ self.complete_from_to('breakpoint set -N ', 'breakpoint set -N nn')
diff --git a/lldb/test/API/functionalities/completion/breakpoints.json b/lldb/test/API/functionalities/completion/breakpoints.json
new file mode 100644
index 000000000000..c9b4db3c6175
--- /dev/null
+++ b/lldb/test/API/functionalities/completion/breakpoints.json
@@ -0,0 +1,34 @@
+[
+ {
+ "Breakpoint": {
+ "BKPTOptions": {
+ "AutoContinue": false,
+ "ConditionText": "",
+ "EnabledState": true,
+ "IgnoreCount": 0,
+ "OneShotState": false
+ },
+ "BKPTResolver": {
+ "Options": {
+ "NameMask": [
+ 56
+ ],
+ "Offset": 0,
+ "SkipPrologue": true,
+ "SymbolNames": [
+ "main"
+ ]
+ },
+ "Type": "SymbolName"
+ },
+ "Hardware": false,
+ "Names": [
+ "mm"
+ ],
+ "SearchFilter": {
+ "Options": {},
+ "Type": "Unconstrained"
+ }
+ }
+ }
+]
diff --git a/lldb/test/API/functionalities/completion/breakpoints_invalid.json b/lldb/test/API/functionalities/completion/breakpoints_invalid.json
new file mode 100644
index 000000000000..86a6b63dfcab
--- /dev/null
+++ b/lldb/test/API/functionalities/completion/breakpoints_invalid.json
@@ -0,0 +1,6 @@
+[
+ {
+ "Breakpoint": {
+ }
+ }
+]
More information about the lldb-commits
mailing list