https://github.com/jimingham created https://github.com/llvm/llvm-project/pull/82428
This is a follow-on to: https://github.com/llvm/llvm-project/pull/82085 The completer for register names was missing from the argument table. I somehow missed that the only register completer test was x86_64, so that test broke. I added the completer in to the right slot in the argument table, and added a small completions test that just uses the alias register names. If we end up having a platform that doesn't define register names, we'll have to skip this test there, but it should add a sniff test for register completion that will run most everywhere. >From bec7ab45ffbad48b8794cf425a07148a0490b008 Mon Sep 17 00:00:00 2001 From: Jim Ingham <jing...@apple.com> Date: Tue, 20 Feb 2024 09:59:43 -0800 Subject: [PATCH 1/2] Revert "Revert "Centralize the handling of completion for simple argument lists. (#82085)"" This reverts commit 9ed8b272c30a01c450616f0ed8b2373d5d618ebb. --- lldb/include/lldb/Interpreter/CommandObject.h | 9 ++- .../Interpreter/CommandOptionArgumentTable.h | 21 +++--- lldb/include/lldb/lldb-enumerations.h | 3 + .../source/Commands/CommandObjectCommands.cpp | 14 ---- .../Commands/CommandObjectDWIMPrint.cpp | 6 -- lldb/source/Commands/CommandObjectDWIMPrint.h | 4 - lldb/source/Commands/CommandObjectFrame.cpp | 19 ----- .../source/Commands/CommandObjectPlatform.cpp | 75 +++++-------------- lldb/source/Commands/CommandObjectPlugin.cpp | 7 -- lldb/source/Commands/CommandObjectProcess.cpp | 19 +---- .../source/Commands/CommandObjectRegister.cpp | 7 +- lldb/source/Commands/CommandObjectSession.cpp | 7 -- .../source/Commands/CommandObjectSettings.cpp | 8 -- lldb/source/Commands/CommandObjectTarget.cpp | 29 +------ lldb/source/Commands/CommandObjectThread.cpp | 13 +--- lldb/source/Commands/CommandObjectType.cpp | 32 -------- .../Commands/CommandObjectWatchpoint.cpp | 10 --- lldb/source/Interpreter/CommandObject.cpp | 37 +++++++++ lldb/test/API/commands/help/TestHelp.py | 2 +- 19 files changed, 86 insertions(+), 236 deletions(-) diff --git a/lldb/include/lldb/Interpreter/CommandObject.h b/lldb/include/lldb/Interpreter/CommandObject.h index b99de56f534469..a326c6dc38a37a 100644 --- a/lldb/include/lldb/Interpreter/CommandObject.h +++ b/lldb/include/lldb/Interpreter/CommandObject.h @@ -242,6 +242,13 @@ class CommandObject : public std::enable_shared_from_this<CommandObject> { /// The completion request that needs to be answered. virtual void HandleCompletion(CompletionRequest &request); + /// The default version handles argument definitions that have only one + /// argument type, and use one of the argument types that have an entry in + /// the CommonCompletions. Override this if you have a more complex + /// argument setup. + /// FIXME: we should be able to extend this to more complex argument + /// definitions provided we have completers for all the argument types. + /// /// The input array contains a parsed version of the line. /// /// We've constructed the map of options and their arguments as well if that @@ -251,7 +258,7 @@ class CommandObject : public std::enable_shared_from_this<CommandObject> { /// The completion request that needs to be answered. virtual void HandleArgumentCompletion(CompletionRequest &request, - OptionElementVector &opt_element_vector) {} + OptionElementVector &opt_element_vector); bool HelpTextContainsWord(llvm::StringRef search_word, bool search_short_help = true, diff --git a/lldb/include/lldb/Interpreter/CommandOptionArgumentTable.h b/lldb/include/lldb/Interpreter/CommandOptionArgumentTable.h index d0cf54c31ca73f..ab5eff699b4cf0 100644 --- a/lldb/include/lldb/Interpreter/CommandOptionArgumentTable.h +++ b/lldb/include/lldb/Interpreter/CommandOptionArgumentTable.h @@ -243,7 +243,7 @@ static constexpr CommandObject::ArgumentTableEntry g_argument_table[] = { { lldb::eArgTypeLogCategory, "log-category", lldb::CompletionType::eNoCompletion, {}, { nullptr, false }, "The name of a category within a log channel, e.g. all (try \"log list\" to see a list of all channels and their categories." }, { lldb::eArgTypeLogChannel, "log-channel", lldb::CompletionType::eNoCompletion, {}, { nullptr, false }, "The name of a log channel, e.g. process.gdb-remote (try \"log list\" to see a list of all channels and their categories)." }, { lldb::eArgTypeMethod, "method", lldb::CompletionType::eNoCompletion, {}, { nullptr, false }, "A C++ method name." }, - { lldb::eArgTypeName, "name", lldb::eTypeCategoryNameCompletion, {}, { nullptr, false }, "Help text goes here." }, + { lldb::eArgTypeName, "name", lldb::eTypeCategoryNameCompletion, {}, { nullptr, false }, "The name of a type category." }, { lldb::eArgTypeNewPathPrefix, "new-path-prefix", lldb::CompletionType::eNoCompletion, {}, { nullptr, false }, "Help text goes here." }, { lldb::eArgTypeNumLines, "num-lines", lldb::CompletionType::eNoCompletion, {}, { nullptr, false }, "The number of lines to use." }, { lldb::eArgTypeNumberPerLine, "number-per-line", lldb::CompletionType::eNoCompletion, {}, { nullptr, false }, "The number of items per line to display." }, @@ -262,7 +262,7 @@ static constexpr CommandObject::ArgumentTableEntry g_argument_table[] = { { lldb::eArgTypeQueueName, "queue-name", lldb::CompletionType::eNoCompletion, {}, { nullptr, false }, "The name of the thread queue." }, { lldb::eArgTypeRegisterName, "register-name", lldb::CompletionType::eNoCompletion, {}, { RegisterNameHelpTextCallback, true }, nullptr }, { lldb::eArgTypeRegularExpression, "regular-expression", lldb::CompletionType::eNoCompletion, {}, { nullptr, false }, "A POSIX-compliant extended regular expression." }, - { lldb::eArgTypeRunArgs, "run-args", lldb::CompletionType::eNoCompletion, {}, { nullptr, false }, "Arguments to be passed to the target program when it starts executing." }, + { lldb::eArgTypeRunArgs, "run-args", lldb::CompletionType::eDiskFileCompletion, {}, { nullptr, false }, "Arguments to be passed to the target program when it starts executing." }, { lldb::eArgTypeRunMode, "run-mode", lldb::CompletionType::eNoCompletion, g_running_mode, { nullptr, false }, "Help text goes here." }, { lldb::eArgTypeScriptedCommandSynchronicity, "script-cmd-synchronicity", lldb::CompletionType::eNoCompletion, g_script_synchro_type, { nullptr, false }, "The synchronicity to use to run scripted commands with regard to LLDB event system." }, { lldb::eArgTypeScriptLang, "script-language", lldb::CompletionType::eNoCompletion, g_script_option_enumeration, { nullptr, false }, "The scripting language to be used for script-based commands. Supported languages are python and lua." }, @@ -270,21 +270,21 @@ static constexpr CommandObject::ArgumentTableEntry g_argument_table[] = { { lldb::eArgTypeSelector, "selector", lldb::CompletionType::eNoCompletion, {}, { nullptr, false }, "An Objective-C selector name." }, { lldb::eArgTypeSettingIndex, "setting-index", lldb::CompletionType::eNoCompletion, {}, { nullptr, false }, "An index into a settings variable that is an array (try 'settings list' to see all the possible settings variables and their types)." }, { lldb::eArgTypeSettingKey, "setting-key", lldb::CompletionType::eNoCompletion, {}, { nullptr, false }, "A key into a settings variables that is a dictionary (try 'settings list' to see all the possible settings variables and their types)." }, - { lldb::eArgTypeSettingPrefix, "setting-prefix", lldb::CompletionType::eNoCompletion, {}, { nullptr, false }, "The name of a settable internal debugger variable up to a dot ('.'), e.g. 'target.process.'" }, - { lldb::eArgTypeSettingVariableName, "setting-variable-name", lldb::CompletionType::eNoCompletion, {}, { nullptr, false }, "The name of a settable internal debugger variable. Type 'settings list' to see a complete list of such variables." }, - { lldb::eArgTypeShlibName, "shlib-name", lldb::CompletionType::eNoCompletion, {}, { nullptr, false }, "The name of a shared library." }, + { lldb::eArgTypeSettingPrefix, "setting-prefix", lldb::CompletionType::eSettingsNameCompletion, {}, { nullptr, false }, "The name of a settable internal debugger variable up to a dot ('.'), e.g. 'target.process.'" }, + { lldb::eArgTypeSettingVariableName, "setting-variable-name", lldb::CompletionType::eSettingsNameCompletion, {}, { nullptr, false }, "The name of a settable internal debugger variable. Type 'settings list' to see a complete list of such variables." }, + { lldb::eArgTypeShlibName, "shlib-name", lldb::CompletionType::eDiskFileCompletion, {}, { nullptr, false }, "The name of a shared library." }, { lldb::eArgTypeSourceFile, "source-file", lldb::eSourceFileCompletion, {}, { nullptr, false }, "The name of a source file.." }, { lldb::eArgTypeSortOrder, "sort-order", lldb::CompletionType::eNoCompletion, g_sort_option_enumeration, { nullptr, false }, "Specify a sort order when dumping lists." }, { lldb::eArgTypeStartAddress, "start-address", lldb::CompletionType::eNoCompletion, {}, { nullptr, false }, "Help text goes here." }, { lldb::eArgTypeSummaryString, "summary-string", lldb::CompletionType::eNoCompletion, {}, { SummaryStringHelpTextCallback, true }, nullptr }, { lldb::eArgTypeSymbol, "symbol", lldb::eSymbolCompletion, {}, { nullptr, false }, "Any symbol name (function name, variable, argument, etc.)" }, - { lldb::eArgTypeThreadID, "thread-id", lldb::CompletionType::eNoCompletion, {}, { nullptr, false }, "Thread ID number." }, - { lldb::eArgTypeThreadIndex, "thread-index", lldb::CompletionType::eNoCompletion, {}, { nullptr, false }, "Index into the process' list of threads." }, + { lldb::eArgTypeThreadID, "thread-id", lldb::CompletionType::eThreadIndexCompletion, {}, { nullptr, false }, "Thread ID number." }, + { lldb::eArgTypeThreadIndex, "thread-index", lldb::CompletionType::eThreadIndexCompletion, {}, { nullptr, false }, "Index into the process' list of threads." }, { lldb::eArgTypeThreadName, "thread-name", lldb::CompletionType::eNoCompletion, {}, { nullptr, false }, "The thread's name." }, { lldb::eArgTypeTypeName, "type-name", lldb::CompletionType::eNoCompletion, {}, { nullptr, false }, "A type name." }, { lldb::eArgTypeUnsignedInteger, "unsigned-integer", lldb::CompletionType::eNoCompletion, {}, { nullptr, false }, "An unsigned integer." }, { lldb::eArgTypeUnixSignal, "unix-signal", lldb::CompletionType::eNoCompletion, {}, { nullptr, false }, "A valid Unix signal name or number (e.g. SIGKILL, KILL or 9)." }, - { lldb::eArgTypeVarName, "variable-name", lldb::CompletionType::eNoCompletion, {} ,{ nullptr, false }, "The name of a variable in your program." }, + { lldb::eArgTypeVarName, "variable-name", lldb::CompletionType::eVariablePathCompletion, {} ,{ nullptr, false }, "The name of a variable in your program." }, { lldb::eArgTypeValue, "value", lldb::CompletionType::eNoCompletion, g_dependents_enumeration, { nullptr, false }, "A value could be anything, depending on where and how it is used." }, { lldb::eArgTypeWidth, "width", lldb::CompletionType::eNoCompletion, {}, { nullptr, false }, "Help text goes here." }, { lldb::eArgTypeNone, "none", lldb::CompletionType::eNoCompletion, {}, { nullptr, false }, "No help available for this." }, @@ -302,8 +302,11 @@ static constexpr CommandObject::ArgumentTableEntry g_argument_table[] = { { lldb::eArgTypeRecognizerID, "frame-recognizer-id", lldb::CompletionType::eNoCompletion, {}, { nullptr, false }, "The ID for a stack frame recognizer." }, { lldb::eArgTypeConnectURL, "process-connect-url", lldb::CompletionType::eNoCompletion, {}, { nullptr, false }, "A URL-style specification for a remote connection." }, { lldb::eArgTypeTargetID, "target-id", lldb::CompletionType::eNoCompletion, {}, { nullptr, false }, "The index ID for an lldb Target." }, - { lldb::eArgTypeStopHookID, "stop-hook-id", lldb::CompletionType::eNoCompletion, {}, { nullptr, false }, "The ID you receive when you create a stop-hook." }, + { lldb::eArgTypeStopHookID, "stop-hook-id", lldb::CompletionType::eStopHookIDCompletion, {}, { nullptr, false }, "The ID you receive when you create a stop-hook." }, { lldb::eArgTypeCompletionType, "completion-type", lldb::CompletionType::eNoCompletion, g_completion_type, { nullptr, false }, "The completion type to use when adding custom commands. If none is specified, the command won't use auto-completion." }, + { lldb::eArgTypeRemotePath, "remote-path", lldb::CompletionType::eRemoteDiskFileCompletion, {}, { nullptr, false }, "A path on the system managed by the current platform." }, + { lldb::eArgTypeRemoteFilename, "remote-filename", lldb::CompletionType::eRemoteDiskFileCompletion, {}, { nullptr, false }, "A file on the system managed by the current platform." }, + { lldb::eArgTypeModule, "module", lldb::CompletionType::eModuleCompletion, {}, { nullptr, false }, "The name of a module loaded into the current target." }, // clang-format on }; diff --git a/lldb/include/lldb/lldb-enumerations.h b/lldb/include/lldb/lldb-enumerations.h index 4640533047833b..85769071dae785 100644 --- a/lldb/include/lldb/lldb-enumerations.h +++ b/lldb/include/lldb/lldb-enumerations.h @@ -651,6 +651,9 @@ enum CommandArgumentType { eArgTypeTargetID, eArgTypeStopHookID, eArgTypeCompletionType, + eArgTypeRemotePath, + eArgTypeRemoteFilename, + eArgTypeModule, eArgTypeLastArg // Always keep this entry as the last entry in this // enumeration!! }; diff --git a/lldb/source/Commands/CommandObjectCommands.cpp b/lldb/source/Commands/CommandObjectCommands.cpp index b7cd65059b2214..7c459bdaf38022 100644 --- a/lldb/source/Commands/CommandObjectCommands.cpp +++ b/lldb/source/Commands/CommandObjectCommands.cpp @@ -63,13 +63,6 @@ class CommandObjectCommandsSource : public CommandObjectParsed { return std::string(""); } - void - HandleArgumentCompletion(CompletionRequest &request, - OptionElementVector &opt_element_vector) override { - lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks( - GetCommandInterpreter(), lldb::eDiskFileCompletion, request, nullptr); - } - Options *GetOptions() override { return &m_options; } protected: @@ -1968,13 +1961,6 @@ class CommandObjectCommandsScriptImport : public CommandObjectParsed { ~CommandObjectCommandsScriptImport() override = default; - void - HandleArgumentCompletion(CompletionRequest &request, - OptionElementVector &opt_element_vector) override { - lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks( - GetCommandInterpreter(), lldb::eDiskFileCompletion, request, nullptr); - } - Options *GetOptions() override { return &m_options; } protected: diff --git a/lldb/source/Commands/CommandObjectDWIMPrint.cpp b/lldb/source/Commands/CommandObjectDWIMPrint.cpp index 695f3d7931cd0a..fb2cc106ffd2dd 100644 --- a/lldb/source/Commands/CommandObjectDWIMPrint.cpp +++ b/lldb/source/Commands/CommandObjectDWIMPrint.cpp @@ -52,12 +52,6 @@ CommandObjectDWIMPrint::CommandObjectDWIMPrint(CommandInterpreter &interpreter) Options *CommandObjectDWIMPrint::GetOptions() { return &m_option_group; } -void CommandObjectDWIMPrint::HandleArgumentCompletion( - CompletionRequest &request, OptionElementVector &opt_element_vector) { - lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks( - GetCommandInterpreter(), lldb::eVariablePathCompletion, request, nullptr); -} - void CommandObjectDWIMPrint::DoExecute(StringRef command, CommandReturnObject &result) { m_option_group.NotifyOptionParsingStarting(&m_exe_ctx); diff --git a/lldb/source/Commands/CommandObjectDWIMPrint.h b/lldb/source/Commands/CommandObjectDWIMPrint.h index d868f8964c2ac5..01ba9c225e3301 100644 --- a/lldb/source/Commands/CommandObjectDWIMPrint.h +++ b/lldb/source/Commands/CommandObjectDWIMPrint.h @@ -39,10 +39,6 @@ class CommandObjectDWIMPrint : public CommandObjectRaw { bool WantsCompletion() override { return true; } - void - HandleArgumentCompletion(CompletionRequest &request, - OptionElementVector &opt_element_vector) override; - private: void DoExecute(llvm::StringRef command, CommandReturnObject &result) override; diff --git a/lldb/source/Commands/CommandObjectFrame.cpp b/lldb/source/Commands/CommandObjectFrame.cpp index a4d3fb66e8b552..f092d54ffe9932 100644 --- a/lldb/source/Commands/CommandObjectFrame.cpp +++ b/lldb/source/Commands/CommandObjectFrame.cpp @@ -286,16 +286,6 @@ class CommandObjectFrameSelect : public CommandObjectParsed { ~CommandObjectFrameSelect() override = default; - void - HandleArgumentCompletion(CompletionRequest &request, - OptionElementVector &opt_element_vector) override { - if (request.GetCursorIndex() != 0) - return; - - lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks( - GetCommandInterpreter(), lldb::eFrameIndexCompletion, request, nullptr); - } - Options *GetOptions() override { return &m_options; } protected: @@ -446,15 +436,6 @@ may even involve JITing and running code in the target program.)"); Options *GetOptions() override { return &m_option_group; } - void - HandleArgumentCompletion(CompletionRequest &request, - OptionElementVector &opt_element_vector) override { - // Arguments are the standard source file completer. - lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks( - GetCommandInterpreter(), lldb::eVariablePathCompletion, request, - nullptr); - } - protected: llvm::StringRef GetScopeString(VariableSP var_sp) { if (!var_sp) diff --git a/lldb/source/Commands/CommandObjectPlatform.cpp b/lldb/source/Commands/CommandObjectPlatform.cpp index 790f1dbb475358..b25c391bd4faa2 100644 --- a/lldb/source/Commands/CommandObjectPlatform.cpp +++ b/lldb/source/Commands/CommandObjectPlatform.cpp @@ -418,7 +418,7 @@ class CommandObjectPlatformMkDir : public CommandObjectParsed { : CommandObjectParsed(interpreter, "platform mkdir", "Make a new directory on the remote end.", nullptr, 0) { - CommandArgumentData thread_arg{eArgTypePath, eArgRepeatPlain}; + CommandArgumentData thread_arg{eArgTypeRemotePath, eArgRepeatPlain}; m_arguments.push_back({thread_arg}); } @@ -467,21 +467,12 @@ class CommandObjectPlatformFOpen : public CommandObjectParsed { CommandObjectPlatformFOpen(CommandInterpreter &interpreter) : CommandObjectParsed(interpreter, "platform file open", "Open a file on the remote end.", nullptr, 0) { - CommandArgumentData path_arg{eArgTypePath, eArgRepeatPlain}; + CommandArgumentData path_arg{eArgTypeRemotePath, eArgRepeatPlain}; m_arguments.push_back({path_arg}); } ~CommandObjectPlatformFOpen() override = default; - void - HandleArgumentCompletion(CompletionRequest &request, - OptionElementVector &opt_element_vector) override { - if (request.GetCursorIndex() == 0) - lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks( - GetCommandInterpreter(), lldb::eRemoteDiskFileCompletion, request, - nullptr); - } - void DoExecute(Args &args, CommandReturnObject &result) override { PlatformSP platform_sp( GetDebugger().GetPlatformList().GetSelectedPlatform()); @@ -795,7 +786,7 @@ class CommandObjectPlatformGetFile : public CommandObjectParsed { CommandArgumentData file_arg_remote, file_arg_host; // Define the first (and only) variant of this arg. - file_arg_remote.arg_type = eArgTypeFilename; + file_arg_remote.arg_type = eArgTypeRemoteFilename; file_arg_remote.arg_repetition = eArgRepeatPlain; // There is only one variant this argument could be; put it into the // argument entry. @@ -876,7 +867,7 @@ class CommandObjectPlatformGetSize : public CommandObjectParsed { CommandArgumentData file_arg_remote; // Define the first (and only) variant of this arg. - file_arg_remote.arg_type = eArgTypeFilename; + file_arg_remote.arg_type = eArgTypeRemoteFilename; file_arg_remote.arg_repetition = eArgRepeatPlain; // There is only one variant this argument could be; put it into the // argument entry. @@ -888,17 +879,6 @@ class CommandObjectPlatformGetSize : public CommandObjectParsed { ~CommandObjectPlatformGetSize() override = default; - void - HandleArgumentCompletion(CompletionRequest &request, - OptionElementVector &opt_element_vector) override { - if (request.GetCursorIndex() != 0) - return; - - lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks( - GetCommandInterpreter(), lldb::eRemoteDiskFileCompletion, request, - nullptr); - } - void DoExecute(Args &args, CommandReturnObject &result) override { // If the number of arguments is incorrect, issue an error message. if (args.GetArgumentCount() != 1) { @@ -946,7 +926,7 @@ class CommandObjectPlatformGetPermissions : public CommandObjectParsed { CommandArgumentData file_arg_remote; // Define the first (and only) variant of this arg. - file_arg_remote.arg_type = eArgTypeFilename; + file_arg_remote.arg_type = eArgTypeRemoteFilename; file_arg_remote.arg_repetition = eArgRepeatPlain; // There is only one variant this argument could be; put it into the // argument entry. @@ -958,17 +938,6 @@ class CommandObjectPlatformGetPermissions : public CommandObjectParsed { ~CommandObjectPlatformGetPermissions() override = default; - void - HandleArgumentCompletion(CompletionRequest &request, - OptionElementVector &opt_element_vector) override { - if (request.GetCursorIndex() != 0) - return; - - lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks( - GetCommandInterpreter(), lldb::eRemoteDiskFileCompletion, request, - nullptr); - } - void DoExecute(Args &args, CommandReturnObject &result) override { // If the number of arguments is incorrect, issue an error message. if (args.GetArgumentCount() != 1) { @@ -1015,7 +984,7 @@ class CommandObjectPlatformFileExists : public CommandObjectParsed { CommandArgumentData file_arg_remote; // Define the first (and only) variant of this arg. - file_arg_remote.arg_type = eArgTypeFilename; + file_arg_remote.arg_type = eArgTypeRemoteFilename; file_arg_remote.arg_repetition = eArgRepeatPlain; // There is only one variant this argument could be; put it into the // argument entry. @@ -1027,17 +996,6 @@ class CommandObjectPlatformFileExists : public CommandObjectParsed { ~CommandObjectPlatformFileExists() override = default; - void - HandleArgumentCompletion(CompletionRequest &request, - OptionElementVector &opt_element_vector) override { - if (request.GetCursorIndex() != 0) - return; - - lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks( - GetCommandInterpreter(), lldb::eRemoteDiskFileCompletion, request, - nullptr); - } - void DoExecute(Args &args, CommandReturnObject &result) override { // If the number of arguments is incorrect, issue an error message. if (args.GetArgumentCount() != 1) { @@ -1080,7 +1038,7 @@ class CommandObjectPlatformPutFile : public CommandObjectParsed { Omitting the destination places the file in the platform working directory.)"); CommandArgumentData source_arg{eArgTypePath, eArgRepeatPlain}; - CommandArgumentData path_arg{eArgTypePath, eArgRepeatOptional}; + CommandArgumentData path_arg{eArgTypeRemotePath, eArgRepeatOptional}; m_arguments.push_back({source_arg}); m_arguments.push_back({path_arg}); } @@ -1139,6 +1097,16 @@ class CommandObjectPlatformProcessLaunch : public CommandObjectParsed { m_arguments.push_back({run_arg_arg}); } + void + HandleArgumentCompletion(CompletionRequest &request, + OptionElementVector &opt_element_vector) override { + // I didn't make a type for RemoteRunArgs, but since we're going to run + // this on the remote system we should use the remote completer. + lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks( + GetCommandInterpreter(), lldb::eRemoteDiskFileCompletion, request, + nullptr); + } + ~CommandObjectPlatformProcessLaunch() override = default; Options *GetOptions() override { return &m_all_options; } @@ -1552,13 +1520,6 @@ class CommandObjectPlatformProcessInfo : public CommandObjectParsed { ~CommandObjectPlatformProcessInfo() override = default; - void - HandleArgumentCompletion(CompletionRequest &request, - OptionElementVector &opt_element_vector) override { - lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks( - GetCommandInterpreter(), lldb::eProcessIDCompletion, request, nullptr); - } - protected: void DoExecute(Args &args, CommandReturnObject &result) override { Target *target = GetDebugger().GetSelectedTarget().get(); @@ -1850,7 +1811,7 @@ class CommandObjectPlatformInstall : public CommandObjectParsed { "Install a target (bundle or executable file) to the remote end.", "platform target-install <local-thing> <remote-sandbox>", 0) { CommandArgumentData local_arg{eArgTypePath, eArgRepeatPlain}; - CommandArgumentData remote_arg{eArgTypePath, eArgRepeatPlain}; + CommandArgumentData remote_arg{eArgTypeRemotePath, eArgRepeatPlain}; m_arguments.push_back({local_arg}); m_arguments.push_back({remote_arg}); } diff --git a/lldb/source/Commands/CommandObjectPlugin.cpp b/lldb/source/Commands/CommandObjectPlugin.cpp index f22885144b09b3..da3b5f0518a690 100644 --- a/lldb/source/Commands/CommandObjectPlugin.cpp +++ b/lldb/source/Commands/CommandObjectPlugin.cpp @@ -36,13 +36,6 @@ class CommandObjectPluginLoad : public CommandObjectParsed { ~CommandObjectPluginLoad() override = default; - void - HandleArgumentCompletion(CompletionRequest &request, - OptionElementVector &opt_element_vector) override { - lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks( - GetCommandInterpreter(), lldb::eDiskFileCompletion, request, nullptr); - } - protected: void DoExecute(Args &command, CommandReturnObject &result) override { size_t argc = command.GetArgumentCount(); diff --git a/lldb/source/Commands/CommandObjectProcess.cpp b/lldb/source/Commands/CommandObjectProcess.cpp index 722b0e0c376be8..7cd5ad656f1b05 100644 --- a/lldb/source/Commands/CommandObjectProcess.cpp +++ b/lldb/source/Commands/CommandObjectProcess.cpp @@ -143,14 +143,6 @@ class CommandObjectProcessLaunch : public CommandObjectProcessLaunchOrAttach { ~CommandObjectProcessLaunch() override = default; - void - HandleArgumentCompletion(CompletionRequest &request, - OptionElementVector &opt_element_vector) override { - - lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks( - GetCommandInterpreter(), lldb::eDiskFileCompletion, request, nullptr); - } - Options *GetOptions() override { return &m_all_options; } std::optional<std::string> GetRepeatCommand(Args ¤t_command_args, @@ -1015,9 +1007,7 @@ class CommandObjectProcessLoad : public CommandObjectParsed { OptionElementVector &opt_element_vector) override { if (!m_exe_ctx.HasProcessScope()) return; - - lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks( - GetCommandInterpreter(), lldb::eDiskFileCompletion, request, nullptr); + CommandObject::HandleArgumentCompletion(request, opt_element_vector); } Options *GetOptions() override { return &m_options; } @@ -1292,13 +1282,6 @@ class CommandObjectProcessSaveCore : public CommandObjectParsed { Options *GetOptions() override { return &m_options; } - void - HandleArgumentCompletion(CompletionRequest &request, - OptionElementVector &opt_element_vector) override { - CommandCompletions::InvokeCommonCompletionCallbacks( - GetCommandInterpreter(), lldb::eDiskFileCompletion, request, nullptr); - } - class CommandOptions : public Options { public: CommandOptions() = default; diff --git a/lldb/source/Commands/CommandObjectRegister.cpp b/lldb/source/Commands/CommandObjectRegister.cpp index a4d53e5c8dd5f1..4ffdde1ee09f9f 100644 --- a/lldb/source/Commands/CommandObjectRegister.cpp +++ b/lldb/source/Commands/CommandObjectRegister.cpp @@ -80,9 +80,7 @@ class CommandObjectRegisterRead : public CommandObjectParsed { OptionElementVector &opt_element_vector) override { if (!m_exe_ctx.HasProcessScope()) return; - - lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks( - GetCommandInterpreter(), lldb::eRegisterCompletion, request, nullptr); + CommandObject::HandleArgumentCompletion(request, opt_element_vector); } Options *GetOptions() override { return &m_option_group; } @@ -440,8 +438,7 @@ different for the same register when connected to different debug servers.)"); OptionElementVector &opt_element_vector) override { if (!m_exe_ctx.HasProcessScope() || request.GetCursorIndex() != 0) return; - CommandCompletions::InvokeCommonCompletionCallbacks( - GetCommandInterpreter(), lldb::eRegisterCompletion, request, nullptr); + CommandObject::HandleArgumentCompletion(request, opt_element_vector); } protected: diff --git a/lldb/source/Commands/CommandObjectSession.cpp b/lldb/source/Commands/CommandObjectSession.cpp index d140bdfdba57b3..28506d6c59512d 100644 --- a/lldb/source/Commands/CommandObjectSession.cpp +++ b/lldb/source/Commands/CommandObjectSession.cpp @@ -28,13 +28,6 @@ class CommandObjectSessionSave : public CommandObjectParsed { ~CommandObjectSessionSave() override = default; - void - HandleArgumentCompletion(CompletionRequest &request, - OptionElementVector &opt_element_vector) override { - lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks( - GetCommandInterpreter(), lldb::eDiskFileCompletion, request, nullptr); - } - protected: void DoExecute(Args &args, CommandReturnObject &result) override { llvm::StringRef file_path; diff --git a/lldb/source/Commands/CommandObjectSettings.cpp b/lldb/source/Commands/CommandObjectSettings.cpp index 5fb7dcc80279fd..0cf3d1daf7f528 100644 --- a/lldb/source/Commands/CommandObjectSettings.cpp +++ b/lldb/source/Commands/CommandObjectSettings.cpp @@ -262,14 +262,6 @@ class CommandObjectSettingsShow : public CommandObjectParsed { ~CommandObjectSettingsShow() override = default; - void - HandleArgumentCompletion(CompletionRequest &request, - OptionElementVector &opt_element_vector) override { - lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks( - GetCommandInterpreter(), lldb::eSettingsNameCompletion, request, - nullptr); - } - protected: void DoExecute(Args &args, CommandReturnObject &result) override { result.SetStatus(eReturnStatusSuccessFinishResult); diff --git a/lldb/source/Commands/CommandObjectTarget.cpp b/lldb/source/Commands/CommandObjectTarget.cpp index c3ecdb7700c256..4e006e4bb0e0fc 100644 --- a/lldb/source/Commands/CommandObjectTarget.cpp +++ b/lldb/source/Commands/CommandObjectTarget.cpp @@ -257,13 +257,6 @@ class CommandObjectTargetCreate : public CommandObjectParsed { Options *GetOptions() override { return &m_option_group; } - void - HandleArgumentCompletion(CompletionRequest &request, - OptionElementVector &opt_element_vector) override { - lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks( - GetCommandInterpreter(), lldb::eDiskFileCompletion, request, nullptr); - } - protected: void DoExecute(Args &command, CommandReturnObject &result) override { const size_t argc = command.GetArgumentCount(); @@ -2789,13 +2782,6 @@ class CommandObjectTargetModulesAdd : public CommandObjectParsed { Options *GetOptions() override { return &m_option_group; } - void - HandleArgumentCompletion(CompletionRequest &request, - OptionElementVector &opt_element_vector) override { - lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks( - GetCommandInterpreter(), lldb::eDiskFileCompletion, request, nullptr); - } - protected: OptionGroupOptions m_option_group; OptionGroupUUID m_uuid_option_group; @@ -3233,7 +3219,7 @@ class CommandObjectTargetModulesList : public CommandObjectParsed { : CommandObjectParsed( interpreter, "target modules list", "List current executable and dependent shared library images.") { - CommandArgumentData module_arg{eArgTypeShlibName, eArgRepeatStar}; + CommandArgumentData module_arg{eArgTypeModule, eArgRepeatStar}; m_arguments.push_back({module_arg}); } @@ -4343,13 +4329,6 @@ class CommandObjectTargetSymbolsAdd : public CommandObjectParsed { ~CommandObjectTargetSymbolsAdd() override = default; - void - HandleArgumentCompletion(CompletionRequest &request, - OptionElementVector &opt_element_vector) override { - lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks( - GetCommandInterpreter(), lldb::eDiskFileCompletion, request, nullptr); - } - Options *GetOptions() override { return &m_option_group; } protected: @@ -5195,8 +5174,7 @@ class CommandObjectTargetStopHookDelete : public CommandObjectParsed { OptionElementVector &opt_element_vector) override { if (request.GetCursorIndex()) return; - lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks( - GetCommandInterpreter(), lldb::eStopHookIDCompletion, request, nullptr); + CommandObject::HandleArgumentCompletion(request, opt_element_vector); } protected: @@ -5251,8 +5229,7 @@ class CommandObjectTargetStopHookEnableDisable : public CommandObjectParsed { OptionElementVector &opt_element_vector) override { if (request.GetCursorIndex()) return; - lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks( - GetCommandInterpreter(), lldb::eStopHookIDCompletion, request, nullptr); + CommandObject::HandleArgumentCompletion(request, opt_element_vector); } protected: diff --git a/lldb/source/Commands/CommandObjectThread.cpp b/lldb/source/Commands/CommandObjectThread.cpp index a1e7e3f11361e7..52e493b13c61ca 100644 --- a/lldb/source/Commands/CommandObjectThread.cpp +++ b/lldb/source/Commands/CommandObjectThread.cpp @@ -403,10 +403,7 @@ class CommandObjectThreadStepWithTypeAndScope : public CommandObjectParsed { OptionElementVector &opt_element_vector) override { if (request.GetCursorIndex()) return; - - lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks( - GetCommandInterpreter(), lldb::eThreadIndexCompletion, request, - nullptr); + CommandObject::HandleArgumentCompletion(request, opt_element_vector); } Options *GetOptions() override { return &m_all_options; } @@ -663,14 +660,6 @@ class CommandObjectThreadContinue : public CommandObjectParsed { ~CommandObjectThreadContinue() override = default; - void - HandleArgumentCompletion(CompletionRequest &request, - OptionElementVector &opt_element_vector) override { - lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks( - GetCommandInterpreter(), lldb::eThreadIndexCompletion, request, - nullptr); - } - void DoExecute(Args &command, CommandReturnObject &result) override { bool synchronous_execution = m_interpreter.GetSynchronous(); diff --git a/lldb/source/Commands/CommandObjectType.cpp b/lldb/source/Commands/CommandObjectType.cpp index f76420f3cc6837..036b8e9d9def13 100644 --- a/lldb/source/Commands/CommandObjectType.cpp +++ b/lldb/source/Commands/CommandObjectType.cpp @@ -1758,14 +1758,6 @@ class CommandObjectTypeCategoryDefine : public CommandObjectParsed { ~CommandObjectTypeCategoryDefine() override = default; - void - HandleArgumentCompletion(CompletionRequest &request, - OptionElementVector &opt_element_vector) override { - lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks( - GetCommandInterpreter(), lldb::eTypeCategoryNameCompletion, request, - nullptr); - } - protected: void DoExecute(Args &command, CommandReturnObject &result) override { const size_t argc = command.GetArgumentCount(); @@ -1859,14 +1851,6 @@ class CommandObjectTypeCategoryEnable : public CommandObjectParsed { ~CommandObjectTypeCategoryEnable() override = default; - void - HandleArgumentCompletion(CompletionRequest &request, - OptionElementVector &opt_element_vector) override { - lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks( - GetCommandInterpreter(), lldb::eTypeCategoryNameCompletion, request, - nullptr); - } - protected: void DoExecute(Args &command, CommandReturnObject &result) override { const size_t argc = command.GetArgumentCount(); @@ -1926,14 +1910,6 @@ class CommandObjectTypeCategoryDelete : public CommandObjectParsed { ~CommandObjectTypeCategoryDelete() override = default; - void - HandleArgumentCompletion(CompletionRequest &request, - OptionElementVector &opt_element_vector) override { - lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks( - GetCommandInterpreter(), lldb::eTypeCategoryNameCompletion, request, - nullptr); - } - protected: void DoExecute(Args &command, CommandReturnObject &result) override { const size_t argc = command.GetArgumentCount(); @@ -2033,14 +2009,6 @@ class CommandObjectTypeCategoryDisable : public CommandObjectParsed { ~CommandObjectTypeCategoryDisable() override = default; - void - HandleArgumentCompletion(CompletionRequest &request, - OptionElementVector &opt_element_vector) override { - lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks( - GetCommandInterpreter(), lldb::eTypeCategoryNameCompletion, request, - nullptr); - } - protected: void DoExecute(Args &command, CommandReturnObject &result) override { const size_t argc = command.GetArgumentCount(); diff --git a/lldb/source/Commands/CommandObjectWatchpoint.cpp b/lldb/source/Commands/CommandObjectWatchpoint.cpp index 438a16c50bd67f..5b74b1ae43accc 100644 --- a/lldb/source/Commands/CommandObjectWatchpoint.cpp +++ b/lldb/source/Commands/CommandObjectWatchpoint.cpp @@ -831,16 +831,6 @@ corresponding to the byte size of the data type."); ~CommandObjectWatchpointSetVariable() override = default; - void - HandleArgumentCompletion(CompletionRequest &request, - OptionElementVector &opt_element_vector) override { - if (request.GetCursorIndex() != 0) - return; - lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks( - GetCommandInterpreter(), lldb::eVariablePathCompletion, request, - nullptr); - } - Options *GetOptions() override { return &m_option_group; } protected: diff --git a/lldb/source/Interpreter/CommandObject.cpp b/lldb/source/Interpreter/CommandObject.cpp index 6ed0fd1f1ddbd9..93c53e89f7d1ae 100644 --- a/lldb/source/Interpreter/CommandObject.cpp +++ b/lldb/source/Interpreter/CommandObject.cpp @@ -305,6 +305,43 @@ void CommandObject::HandleCompletion(CompletionRequest &request) { } } +void CommandObject::HandleArgumentCompletion( + CompletionRequest &request, OptionElementVector &opt_element_vector) { + size_t num_arg_entries = GetNumArgumentEntries(); + if (num_arg_entries != 1) + return; + + CommandArgumentEntry *entry_ptr = GetArgumentEntryAtIndex(0); + if (!entry_ptr) { + assert(entry_ptr && "We said there was one entry, but there wasn't."); + return; // Not worth crashing if asserts are off... + } + + CommandArgumentEntry &entry = *entry_ptr; + // For now, we only handle the simple case of one homogenous argument type. + if (entry.size() != 1) + return; + + // Look up the completion type, and if it has one, invoke it: + const CommandObject::ArgumentTableEntry *arg_entry = + FindArgumentDataByType(entry[0].arg_type); + const ArgumentRepetitionType repeat = entry[0].arg_repetition; + + if (arg_entry == nullptr || arg_entry->completion_type == lldb::eNoCompletion) + return; + + // FIXME: This should be handled higher in the Command Parser. + // Check the case where this command only takes one argument, and don't do + // the completion if we aren't on the first entry: + if (repeat == eArgRepeatPlain && request.GetCursorIndex() != 0) + return; + + lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks( + GetCommandInterpreter(), arg_entry->completion_type, request, nullptr); + +} + + bool CommandObject::HelpTextContainsWord(llvm::StringRef search_word, bool search_short_help, bool search_long_help, diff --git a/lldb/test/API/commands/help/TestHelp.py b/lldb/test/API/commands/help/TestHelp.py index 95ffdb3cc8b18b..f0f5bcb3218011 100644 --- a/lldb/test/API/commands/help/TestHelp.py +++ b/lldb/test/API/commands/help/TestHelp.py @@ -104,7 +104,7 @@ def test_help_image_du_line_should_work(self): def test_help_image_list_shows_positional_args(self): """Command 'help image list' should describe positional args.""" # 'image' is an alias for 'target modules'. - self.expect("help image list", substrs=["<shlib-name> [...]"]) + self.expect("help image list", substrs=["<module> [...]"]) @no_debug_info_test def test_help_target_variable_syntax(self): >From 9a430ce7c8065f21abef474d233a6b41937563ac Mon Sep 17 00:00:00 2001 From: Jim Ingham <jing...@apple.com> Date: Tue, 20 Feb 2024 14:07:35 -0800 Subject: [PATCH 2/2] The register common completer was missing from g_argument_table. I didn't notice the register test was x86_64 only. I added the element to get this to pass, and also added a test that just does completion on the alias register names so it will run everywhere. --- .../Interpreter/CommandOptionArgumentTable.h | 2 +- .../completion/TestCompletion.py | 21 +++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/lldb/include/lldb/Interpreter/CommandOptionArgumentTable.h b/lldb/include/lldb/Interpreter/CommandOptionArgumentTable.h index ab5eff699b4cf0..9248e2ac814461 100644 --- a/lldb/include/lldb/Interpreter/CommandOptionArgumentTable.h +++ b/lldb/include/lldb/Interpreter/CommandOptionArgumentTable.h @@ -260,7 +260,7 @@ static constexpr CommandObject::ArgumentTableEntry g_argument_table[] = { { lldb::eArgTypePythonFunction, "python-function", lldb::CompletionType::eNoCompletion, {}, { nullptr, false }, "The name of a Python function." }, { lldb::eArgTypePythonScript, "python-script", lldb::CompletionType::eNoCompletion, {}, { nullptr, false }, "Source code written in Python." }, { lldb::eArgTypeQueueName, "queue-name", lldb::CompletionType::eNoCompletion, {}, { nullptr, false }, "The name of the thread queue." }, - { lldb::eArgTypeRegisterName, "register-name", lldb::CompletionType::eNoCompletion, {}, { RegisterNameHelpTextCallback, true }, nullptr }, + { lldb::eArgTypeRegisterName, "register-name", lldb::CompletionType::eRegisterCompletion, {}, { RegisterNameHelpTextCallback, true }, nullptr }, { lldb::eArgTypeRegularExpression, "regular-expression", lldb::CompletionType::eNoCompletion, {}, { nullptr, false }, "A POSIX-compliant extended regular expression." }, { lldb::eArgTypeRunArgs, "run-args", lldb::CompletionType::eDiskFileCompletion, {}, { nullptr, false }, "Arguments to be passed to the target program when it starts executing." }, { lldb::eArgTypeRunMode, "run-mode", lldb::CompletionType::eNoCompletion, g_running_mode, { nullptr, false }, "Help text goes here." }, diff --git a/lldb/test/API/functionalities/completion/TestCompletion.py b/lldb/test/API/functionalities/completion/TestCompletion.py index f71bc73928f0f4..b4681062a7d4e8 100644 --- a/lldb/test/API/functionalities/completion/TestCompletion.py +++ b/lldb/test/API/functionalities/completion/TestCompletion.py @@ -787,6 +787,27 @@ def test_register_read_and_write_on_x86(self): # register write can only take exact one register name as argument self.complete_from_to("register write rbx ", []) + def test_register_read_and_write_generic(self): + """Test the completion of the commands register read and write on x86""" + + self.build() + self.main_source_spec = lldb.SBFileSpec("main.cpp") + lldbutil.run_to_source_breakpoint(self, "// Break here", self.main_source_spec) + + # test cases for register read + self.complete_from_to("register read f", ["fp"]) + # register read can take multiple register names as arguments + self.complete_from_to("register read sp ", ["sp", "fp"]) + # complete with prefix '$' + self.complete_from_to("register read sp $", ["$sp", "$fp"]) + self.complete_from_to("register read $x0 ", ["sp", "fp"]) + + # test cases for register write + self.complete_from_to("register write ", ["fp", "sp"]) + self.complete_from_to("register write f", ["fp"]) + # register write can only take exact one register name as argument + self.complete_from_to("register write fp ", []) + def test_common_completion_target_stophook_ids(self): subcommands = ["delete", "enable", "disable"] _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits