https://github.com/medismailben created 
https://github.com/llvm/llvm-project/pull/209400

This patch improves `scripting extension list` in three ways.

First, it groups the output by `ScriptedExtension`: instead of one row per 
registered plugin instance, one entry per extension is printed with a combined 
`Language` field.

Second, it colorizes and visually separates the output. Each entry is preceded 
by a dimmed dashed separator; field labels are printed in bold green, the 
extension name value in bold cyan as a mini-heading, and `None` usage values 
are dimmed, all via the same `ansi::FormatAnsiTerminalCodes(..., use_color)` 
idiom `Breakpoint::GetDescription` uses elsewhere, gracefully no-op when color 
is disabled or unsupported. `ScriptedInterfaceUsages::Dump` takes an optional 
`use_color` parameter so its own `API Usages:` / `Command Interpreter Usages:` 
labels can match.

Third, it adds `-j`/`--json` to emit a JSON array of `{name, description, 
languages, api_usages, command_interpreter_usages}` per extension, mirroring 
`plugin list`'s existing `-j`. `DoExecute` now computes the extension grouping 
once and branches into `OutputJsonFormat` or `OutputTextFormat`, sharing a 
`GetLanguagesForExtension` helper. It also accepts optional positional 
`<extension-name>` arguments to filter the listing to specific extensions 
(matched via the same case-insensitive `ScriptInterpreter::StringToExtension` 
used by `scripting extension generate`), with completion wired up via 
`eScriptedExtensionCompletion`.

Also fix a latent lifetime bug in the shared language-collection helper so it 
owns its `std::string` values instead of holding `StringRef`s to temporaries; 
the JSON path made it observable.

>From 4ead739172a9485d428e9a08bd9739a3333af6a6 Mon Sep 17 00:00:00 2001
From: Med Ismail Bennani <[email protected]>
Date: Mon, 13 Jul 2026 13:57:32 -0700
Subject: [PATCH] [lldb/script] Improve `scripting extension list` output and
 filtering

This patch improves `scripting extension list` in three ways.

First, it groups the output by `ScriptedExtension`: instead of one row
per registered plugin instance, one entry per extension is printed with
a combined `Language` field.

Second, it colorizes and visually separates the output. Each entry is
preceded by a dimmed dashed separator; field labels are printed in bold
green, the extension name value in bold cyan as a mini-heading, and
`None` usage values are dimmed, all via the same
`ansi::FormatAnsiTerminalCodes(..., use_color)` idiom
`Breakpoint::GetDescription` uses elsewhere, gracefully no-op when color
is disabled or unsupported. `ScriptedInterfaceUsages::Dump` takes an
optional `use_color` parameter so its own `API Usages:` /
`Command Interpreter Usages:` labels can match.

Third, it adds `-j`/`--json` to emit a JSON array of
`{name, description, languages, api_usages, command_interpreter_usages}`
per extension, mirroring `plugin list`'s existing `-j`. `DoExecute` now
computes the extension grouping once and branches into
`OutputJsonFormat` or `OutputTextFormat`, sharing a
`GetLanguagesForExtension` helper. It also accepts optional positional
`<extension-name>` arguments to filter the listing to specific
extensions (matched via the same case-insensitive
`ScriptInterpreter::StringToExtension` used by `scripting extension
generate`), with completion wired up via `eScriptedExtensionCompletion`.

Also fix a latent lifetime bug in the shared language-collection helper
so it owns its `std::string` values instead of holding `StringRef`s to
temporaries; the JSON path made it observable.

Signed-off-by: Med Ismail Bennani <[email protected]>
---
 .../Interfaces/ScriptedInterfaceUsages.h      |   2 +-
 .../lldb/Interpreter/ScriptInterpreter.h      |   5 +
 .../Commands/CommandObjectScripting.cpp       | 191 +++++++++++++++---
 lldb/source/Commands/Options.td               |   3 +
 .../Interfaces/ScriptedInterfaceUsages.cpp    |  14 +-
 lldb/source/Interpreter/ScriptInterpreter.cpp |  45 +++++
 .../command-scripting-extension-list.test     | 101 ++++-----
 7 files changed, 279 insertions(+), 82 deletions(-)

diff --git a/lldb/include/lldb/Interpreter/Interfaces/ScriptedInterfaceUsages.h 
b/lldb/include/lldb/Interpreter/Interfaces/ScriptedInterfaceUsages.h
index d958e782d86bd..48f38eb70bdb3 100644
--- a/lldb/include/lldb/Interpreter/Interfaces/ScriptedInterfaceUsages.h
+++ b/lldb/include/lldb/Interpreter/Interfaces/ScriptedInterfaceUsages.h
@@ -32,7 +32,7 @@ class ScriptedInterfaceUsages {
 
   enum class UsageKind { CommandInterpreter, API };
 
-  void Dump(Stream &s, UsageKind kind) const;
+  void Dump(Stream &s, UsageKind kind, bool use_color = false) const;
 
 private:
   std::vector<llvm::StringRef> m_command_interpreter_usages;
diff --git a/lldb/include/lldb/Interpreter/ScriptInterpreter.h 
b/lldb/include/lldb/Interpreter/ScriptInterpreter.h
index 7ab098f177a80..2b9cb8f7bb866 100644
--- a/lldb/include/lldb/Interpreter/ScriptInterpreter.h
+++ b/lldb/include/lldb/Interpreter/ScriptInterpreter.h
@@ -526,6 +526,11 @@ class ScriptInterpreter : public PluginInterface {
 
   static lldb::ScriptLanguage StringToLanguage(const llvm::StringRef &string);
 
+  static llvm::StringLiteral
+  ExtensionToString(lldb::ScriptedExtension extension);
+
+  static lldb::ScriptedExtension StringToExtension(llvm::StringRef string);
+
   lldb::ScriptLanguage GetLanguage() { return m_script_lang; }
 
   virtual lldb::ScriptedProcessInterfaceUP CreateScriptedProcessInterface() {
diff --git a/lldb/source/Commands/CommandObjectScripting.cpp 
b/lldb/source/Commands/CommandObjectScripting.cpp
index 21400a62d697f..851e501a714c8 100644
--- a/lldb/source/Commands/CommandObjectScripting.cpp
+++ b/lldb/source/Commands/CommandObjectScripting.cpp
@@ -18,8 +18,11 @@
 #include "lldb/Interpreter/Interfaces/ScriptedInterfaceUsages.h"
 #include "lldb/Interpreter/OptionArgParser.h"
 #include "lldb/Interpreter/ScriptInterpreter.h"
+#include "lldb/Utility/AnsiTerminal.h"
 #include "lldb/Utility/Args.h"
 
+#include "llvm/ADT/StringMap.h"
+
 using namespace lldb;
 using namespace lldb_private;
 
@@ -138,12 +141,23 @@ class CommandObjectScriptingExtensionList : public 
CommandObjectParsed {
       : CommandObjectParsed(
             interpreter, "scripting extension list",
             "List all the available scripting extension templates. ",
-            "scripting template list [--language <scripting-language> --]") {}
+            "scripting extension list [--language <scripting-language> --] "
+            "[--json --] [<extension-name> ...]") {
+    AddSimpleArgumentList(eArgTypeScriptedExtension, eArgRepeatStar);
+  }
 
   ~CommandObjectScriptingExtensionList() override = default;
 
   Options *GetOptions() override { return &m_options; }
 
+  void HandleArgumentCompletion(
+      CompletionRequest &request,
+      OptionElementVector &opt_element_vector) override {
+    lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks(
+        GetCommandInterpreter(), lldb::eScriptedExtensionCompletion, request,
+        nullptr);
+  }
+
   class CommandOptions : public Options {
   public:
     CommandOptions() = default;
@@ -162,6 +176,9 @@ class CommandObjectScriptingExtensionList : public 
CommandObjectParsed {
           error = Status::FromErrorStringWithFormatv(
               "unrecognized value for language '{0}'", option_arg);
         break;
+      case 'j':
+        m_json_format = true;
+        break;
       default:
         llvm_unreachable("Unimplemented option");
       }
@@ -171,6 +188,7 @@ class CommandObjectScriptingExtensionList : public 
CommandObjectParsed {
 
     void OptionParsingStarting(ExecutionContext *execution_context) override {
       m_language = lldb::eScriptLanguageDefault;
+      m_json_format = false;
     }
 
     llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
@@ -178,53 +196,164 @@ class CommandObjectScriptingExtensionList : public 
CommandObjectParsed {
     }
 
     lldb::ScriptLanguage m_language = lldb::eScriptLanguageDefault;
+    bool m_json_format = false;
   };
 
 protected:
   void DoExecute(Args &command, CommandReturnObject &result) override {
-    Stream &s = result.GetOutputStream();
-    s.Printf("Available scripted extension templates:");
+    llvm::StringMap<std::vector<size_t>> grouped_by_extension;
+    for (size_t i = 0; i < PluginManager::GetNumScriptedInterfaces(); i++) {
+      lldb::ScriptedExtension extension =
+          PluginManager::GetScriptedInterfaceExtensionAtIndex(i);
+      if (extension == eScriptedExtensionInvalid)
+        continue;
+
+      llvm::StringLiteral extension_name =
+          ScriptInterpreter::ExtensionToString(extension);
+      if (grouped_by_extension.contains(extension_name))
+        grouped_by_extension[extension_name].push_back(i);
+      else
+        grouped_by_extension[extension_name] = {i};
+    }
 
-    auto print_field = [&s](llvm::StringRef key, llvm::StringRef value) {
-      if (!value.empty()) {
-        s.IndentMore();
-        s.Indent();
-        s << key << ": " << value << '\n';
-        s.IndentLess();
+    if (command.GetArgumentCount() > 0) {
+      llvm::StringMap<std::vector<size_t>> filtered;
+      for (const Args::ArgEntry &arg : command.entries()) {
+        lldb::ScriptedExtension extension =
+            ScriptInterpreter::StringToExtension(arg.ref());
+        if (extension == eScriptedExtensionInvalid) {
+          result.AppendErrorWithFormat(
+              "no scripted extension named '%s'", arg.c_str());
+          return;
+        }
+        llvm::StringLiteral extension_name =
+            ScriptInterpreter::ExtensionToString(extension);
+        auto it = grouped_by_extension.find(extension_name);
+        if (it != grouped_by_extension.end())
+          filtered[extension_name] = it->second;
       }
-    };
+      grouped_by_extension = std::move(filtered);
+    }
 
-    size_t num_listed_interface = 0;
-    size_t num_extensions = PluginManager::GetNumScriptedInterfaces();
-    for (size_t i = 0; i < num_extensions; i++) {
-      llvm::StringRef plugin_name =
-          PluginManager::GetScriptedInterfaceNameAtIndex(i);
-      if (plugin_name.empty())
-        break;
+    if (m_options.m_json_format)
+      OutputJsonFormat(grouped_by_extension, result);
+    else
+      OutputTextFormat(grouped_by_extension, result);
+  }
 
+private:
+  std::vector<std::string>
+  GetLanguagesForExtension(const std::vector<size_t> &indices) {
+    std::vector<std::string> languages;
+    for (const size_t idx : indices) {
       lldb::ScriptLanguage lang =
-          PluginManager::GetScriptedInterfaceLanguageAtIndex(i);
+          PluginManager::GetScriptedInterfaceLanguageAtIndex(idx);
       if (lang != m_options.m_language)
         continue;
+      languages.push_back(ScriptInterpreter::LanguageToString(lang));
+    }
+    return languages;
+  }
+
+  void
+  OutputJsonFormat(const llvm::StringMap<std::vector<size_t>> 
&grouped_by_extension,
+                   CommandReturnObject &result) {
+    llvm::json::Array extensions;
+    for (const auto &extension_pair : grouped_by_extension) {
+      llvm::StringRef desc =
+          PluginManager::GetScriptedInterfaceDescriptionAtIndex(
+              extension_pair.second[0]);
+      ScriptedInterfaceUsages usages =
+          PluginManager::GetScriptedInterfaceUsagesAtIndex(
+              extension_pair.second[0]);
+
+      // llvm::json::Value's StringRef constructor does not copy the
+      // underlying characters, so every string handed to the JSON structure
+      // below must be an owned std::string -- otherwise it dangles by the
+      // time the object tree is serialized at the end of this function.
+      llvm::json::Array languages;
+      for (const std::string &lang : 
GetLanguagesForExtension(extension_pair.second))
+        languages.push_back(lang);
+
+      llvm::json::Array api_usages;
+      for (llvm::StringRef usage : usages.GetSBAPIUsages())
+        api_usages.push_back(usage.str());
+
+      llvm::json::Array cmd_usages;
+      for (llvm::StringRef usage : usages.GetCommandInterpreterUsages())
+        cmd_usages.push_back(usage.str());
+
+      extensions.push_back(llvm::json::Object{
+          {"name", extension_pair.first().str()},
+          {"description", desc.str()},
+          {"languages", std::move(languages)},
+          {"api_usages", std::move(api_usages)},
+          {"command_interpreter_usages", std::move(cmd_usages)},
+      });
+    }
+
+    std::string str;
+    llvm::raw_string_ostream os(str);
+    os << llvm::formatv("{0:2}", llvm::json::Value(std::move(extensions)));
+    result.AppendMessage(str);
+    result.SetStatus(eReturnStatusSuccessFinishResult);
+  }
+
+  void
+  OutputTextFormat(const llvm::StringMap<std::vector<size_t>> 
&grouped_by_extension,
+                   CommandReturnObject &result) {
+    Stream &s = result.GetOutputStream();
+    const bool use_color = s.AsRawOstream().colors_enabled();
+    auto ansi_code = [use_color](llvm::StringRef code) {
+      return ansi::FormatAnsiTerminalCodes(code, use_color);
+    };
+    const std::string label_color = ansi_code("${ansi.fg.green}${ansi.bold}");
+    const std::string name_color = ansi_code("${ansi.fg.cyan}${ansi.bold}");
+    const std::string sep_color = ansi_code("${ansi.faint}");
+    const std::string reset = ansi_code("${ansi.normal}");
+    const std::string separator(
+        std::min<uint64_t>(GetDebugger().GetTerminalWidth(), 80), '-');
 
-      if (!num_listed_interface)
-        s.EOL();
+    s.Printf("Available scripted extension templates:");
 
+    auto print_field = [&](llvm::StringRef key, llvm::StringRef value,
+                           const std::string &value_color = std::string()) {
+      if (value.empty())
+        return;
+      s.IndentMore();
+      s.Indent();
+      s << label_color << key << ": " << reset;
+      if (!value_color.empty())
+        s << value_color << value << reset;
+      else
+        s << value;
+      s << '\n';
+      s.IndentLess();
+    };
+
+    size_t num_listed_interface = 0;
+    for (const auto &extension_pair : grouped_by_extension) {
       num_listed_interface++;
 
+      s.EOL();
+      s << sep_color << separator << reset;
+      s.EOL();
+
       llvm::StringRef desc =
-          PluginManager::GetScriptedInterfaceDescriptionAtIndex(i);
+          PluginManager::GetScriptedInterfaceDescriptionAtIndex(
+              extension_pair.second[0]);
       ScriptedInterfaceUsages usages =
-          PluginManager::GetScriptedInterfaceUsagesAtIndex(i);
+          PluginManager::GetScriptedInterfaceUsagesAtIndex(
+              extension_pair.second[0]);
 
-      print_field("Name", plugin_name);
-      print_field("Language", ScriptInterpreter::LanguageToString(lang));
+      print_field("Name", extension_pair.first(), name_color);
       print_field("Description", desc);
-      usages.Dump(s, ScriptedInterfaceUsages::UsageKind::API);
-      usages.Dump(s, ScriptedInterfaceUsages::UsageKind::CommandInterpreter);
-
-      if (i != num_extensions - 1)
-        s.EOL();
+      print_field("Language",
+                  llvm::join(GetLanguagesForExtension(extension_pair.second),
+                             ""));
+      usages.Dump(s, ScriptedInterfaceUsages::UsageKind::API, use_color);
+      usages.Dump(s, ScriptedInterfaceUsages::UsageKind::CommandInterpreter,
+                 use_color);
     }
 
     if (!num_listed_interface)
@@ -261,8 +390,8 @@ 
CommandObjectMultiwordScripting::CommandObjectMultiwordScripting(
   LoadSubCommand("run",
                  CommandObjectSP(new CommandObjectScriptingRun(interpreter)));
   LoadSubCommand("extension",
-                 CommandObjectSP(new CommandObjectMultiwordScriptingExtension(
-                     interpreter)));
+                 CommandObjectSP(
+                     new 
CommandObjectMultiwordScriptingExtension(interpreter)));
 }
 
 CommandObjectMultiwordScripting::~CommandObjectMultiwordScripting() = default;
diff --git a/lldb/source/Commands/Options.td b/lldb/source/Commands/Options.td
index 7e6e2c173d67f..bd6fa8efad0a5 100644
--- a/lldb/source/Commands/Options.td
+++ b/lldb/source/Commands/Options.td
@@ -1582,6 +1582,9 @@ let Command = "scripting extension list" in {
         Desc<"Specify the scripting "
              " language. If none is specified the default scripting language "
              "is used.">;
+  def scripting_extension_list_json
+      : Option<"json", "j">,
+        Desc<"Output the scripted extension list in json format.">;
 }
 
 let Command = "source info" in {
diff --git a/lldb/source/Interpreter/Interfaces/ScriptedInterfaceUsages.cpp 
b/lldb/source/Interpreter/Interfaces/ScriptedInterfaceUsages.cpp
index 05d7a5d852f8c..3fcbe20182960 100644
--- a/lldb/source/Interpreter/Interfaces/ScriptedInterfaceUsages.cpp
+++ b/lldb/source/Interpreter/Interfaces/ScriptedInterfaceUsages.cpp
@@ -8,20 +8,28 @@
 
 #include "lldb/Interpreter/Interfaces/ScriptedInterfaceUsages.h"
 
+#include "lldb/Utility/AnsiTerminal.h"
+
 using namespace lldb;
 using namespace lldb_private;
 
-void ScriptedInterfaceUsages::Dump(Stream &s, UsageKind kind) const {
+void ScriptedInterfaceUsages::Dump(Stream &s, UsageKind kind,
+                                   bool use_color) const {
+  const std::string label =
+      ansi::FormatAnsiTerminalCodes("${ansi.fg.green}${ansi.bold}", use_color);
+  const std::string dim = ansi::FormatAnsiTerminalCodes("${ansi.faint}", 
use_color);
+  const std::string reset = ansi::FormatAnsiTerminalCodes("${ansi.normal}", 
use_color);
+
   s.IndentMore();
   s.Indent();
   llvm::StringRef usage_kind =
       (kind == UsageKind::CommandInterpreter) ? "Command Interpreter" : "API";
-  s << usage_kind << " Usages:";
+  s << label << usage_kind << " Usages:" << reset;
   const std::vector<llvm::StringRef> &usages =
       (kind == UsageKind::CommandInterpreter) ? GetCommandInterpreterUsages()
                                               : GetSBAPIUsages();
   if (usages.empty())
-    s << " None\n";
+    s << ' ' << dim << "None" << reset << '\n';
   else if (usages.size() == 1)
     s << " " << usages.front() << '\n';
   else {
diff --git a/lldb/source/Interpreter/ScriptInterpreter.cpp 
b/lldb/source/Interpreter/ScriptInterpreter.cpp
index 8dafb7f823e70..8420782b02814 100644
--- a/lldb/source/Interpreter/ScriptInterpreter.cpp
+++ b/lldb/source/Interpreter/ScriptInterpreter.cpp
@@ -16,6 +16,7 @@
 #include "lldb/Utility/Stream.h"
 #include "lldb/Utility/StringList.h"
 #include "lldb/ValueObject/ValueObject.h"
+#include "llvm/ADT/StringSwitch.h"
 #if defined(_WIN32)
 #include "lldb/Host/windows/ConnectionGenericFileWindows.h"
 #endif
@@ -188,6 +189,50 @@ ScriptInterpreter::StringToLanguage(const llvm::StringRef 
&language) {
   return eScriptLanguageUnknown;
 }
 
+llvm::StringLiteral
+ScriptInterpreter::ExtensionToString(lldb::ScriptedExtension extension) {
+  switch (extension) {
+  case eScriptedExtensionInvalid:
+    return "Invalid";
+  case eScriptedExtensionOperatingSystem:
+    return "OperatingSystem";
+  case eScriptedExtensionScriptedPlatform:
+    return "ScriptedPlatform";
+  case eScriptedExtensionScriptedProcess:
+    return "ScriptedProcess";
+  case eScriptedExtensionScriptedBreakpointResolver:
+    return "ScriptedBreakpointResolver";
+  case eScriptedExtensionScriptedThreadPlan:
+    return "ScriptedThreadPlan";
+  case eScriptedExtensionScriptedFrameProvider:
+    return "ScriptedFrameProvider";
+  case eScriptedExtensionScriptedHook:
+    return "ScriptedHook";
+  case eScriptedExtensionScriptedThread:
+    return "ScriptedThread";
+  case eScriptedExtensionScriptedFrame:
+    return "ScriptedFrame";
+  }
+  llvm_unreachable("unhandled ScriptedExtension");
+}
+
+lldb::ScriptedExtension
+ScriptInterpreter::StringToExtension(llvm::StringRef string) {
+  return llvm::StringSwitch<lldb::ScriptedExtension>(string)
+      .CaseLower("OperatingSystem", eScriptedExtensionOperatingSystem)
+      .CaseLower("ScriptedPlatform", eScriptedExtensionScriptedPlatform)
+      .CaseLower("ScriptedProcess", eScriptedExtensionScriptedProcess)
+      .CaseLower("ScriptedBreakpointResolver",
+                 eScriptedExtensionScriptedBreakpointResolver)
+      .CaseLower("ScriptedThreadPlan", eScriptedExtensionScriptedThreadPlan)
+      .CaseLower("ScriptedFrameProvider",
+                 eScriptedExtensionScriptedFrameProvider)
+      .CaseLower("ScriptedHook", eScriptedExtensionScriptedHook)
+      .CaseLower("ScriptedThread", eScriptedExtensionScriptedThread)
+      .CaseLower("ScriptedFrame", eScriptedExtensionScriptedFrame)
+      .Default(eScriptedExtensionInvalid);
+}
+
 Status ScriptInterpreter::SetBreakpointCommandCallback(
     std::vector<std::reference_wrapper<BreakpointOptions>> &bp_options_vec,
     const char *callback_text) {
diff --git a/lldb/test/Shell/Commands/command-scripting-extension-list.test 
b/lldb/test/Shell/Commands/command-scripting-extension-list.test
index 8ca183a609671..880d4035516de 100644
--- a/lldb/test/Shell/Commands/command-scripting-extension-list.test
+++ b/lldb/test/Shell/Commands/command-scripting-extension-list.test
@@ -2,53 +2,60 @@
 # RUN: %lldb -s %s -o exit | FileCheck %s
 
 scripting extension list
-# CHECK:Available scripted extension templates:
-
-# CHECK:  Name: OperatingSystemPythonInterface
-# CHECK-NEXT:  Language: Python
-# CHECK-NEXT:  Description: Mock thread state
-# CHECK-NEXT:  API Usages: None
-# CHECK-NEXT:  Command Interpreter Usages:
-# CHECK-NEXT:    settings set target.process.python-os-plugin-path 
<script-path>
-# CHECK-NEXT:    settings set 
process.experimental.os-plugin-reports-all-threads [0/1]
-
-# CHECK:  Name: ScriptedPlatformPythonInterface
-# CHECK-NEXT:  Language: Python
-# CHECK-NEXT:  Description: Mock platform and interact with its processes.
-# CHECK-NEXT:  API Usages: None
-# CHECK-NEXT:  Command Interpreter Usages: None
-
-# CHECK:  Name: ScriptedProcessPythonInterface
-# CHECK-NEXT:  Language: Python
-# CHECK-NEXT:  Description: Mock process state
-# CHECK-NEXT:  API Usages:
-# CHECK-NEXT:    SBAttachInfo.SetScriptedProcessClassName
-# CHECK-NEXT:    SBAttachInfo.SetScriptedProcessDictionary
-# CHECK-NEXT:    SBTarget.Attach
-# CHECK-NEXT:    SBLaunchInfo.SetScriptedProcessClassName
-# CHECK-NEXT:    SBLaunchInfo.SetScriptedProcessDictionary
-# CHECK-NEXT:    SBTarget.Launch
-# CHECK-NEXT:  Command Interpreter Usages:
-# CHECK-NEXT:    process attach -C <script-name> [-k key -v value ...]
-# CHECK-NEXT:    process launch -C <script-name> [-k key -v value ...]
-
-# CHECK:  Name: ScriptedThreadPlanPythonInterface
-# CHECK-NEXT:  Language: Python
-# CHECK-NEXT:  Description: Alter thread stepping logic and stop reason
-# CHECK-NEXT:  API Usages: SBThread.StepUsingScriptedThreadPlan
-# CHECK-NEXT:  Command Interpreter Usages: thread step-scripted -C 
<script-name> [-k key -v value ...]
-
-# CHECK:  Name: ScriptedThreadPythonInterface
-# CHECK-NEXT:  Language: Python
-# CHECK-NEXT:  Description: Provide thread state for a scripted process.
-# CHECK-NEXT:  API Usages: None
-# CHECK-NEXT:  Command Interpreter Usages: None
-
-# CHECK:  Name: ScriptedFramePythonInterface
-# CHECK-NEXT:  Language: Python
-# CHECK-NEXT:  Description: Provide frame state for scripted threads and frame 
providers.
-# CHECK-NEXT:  API Usages: None
-# CHECK-NEXT:  Command Interpreter Usages: None
+# CHECK: Available scripted extension templates:
+
+# The extensions are grouped by lldb::ScriptedExtension in a hash map, so
+# groups are not printed in a fixed order across builds. Match each group's
+# fields with CHECK-DAG instead of CHECK-NEXT.
+# CHECK-DAG: Name: OperatingSystem
+# CHECK-DAG: Language: Python
+# CHECK-DAG: Description: Mock thread state
+# CHECK-DAG: settings set target.process.python-os-plugin-path <script-path>
+# CHECK-DAG: settings set process.experimental.os-plugin-reports-all-threads 
[0/1]
+
+# CHECK-DAG: Name: ScriptedPlatform
+# CHECK-DAG: Description: Mock platform and interact with its processes.
+
+# CHECK-DAG: Name: ScriptedProcess
+# CHECK-DAG: Description: Mock process state
+# CHECK-DAG: SBAttachInfo.SetScriptedProcessClassName
+# CHECK-DAG: SBAttachInfo.SetScriptedProcessDictionary
+# CHECK-DAG: SBTarget.Attach
+# CHECK-DAG: SBLaunchInfo.SetScriptedProcessClassName
+# CHECK-DAG: SBLaunchInfo.SetScriptedProcessDictionary
+# CHECK-DAG: SBTarget.Launch
+# CHECK-DAG: process attach -C <script-name> [-k key -v value ...]
+# CHECK-DAG: process launch -C <script-name> [-k key -v value ...]
+
+# CHECK-DAG: Name: ScriptedThreadPlan
+# CHECK-DAG: Description: Alter thread stepping logic and stop reason
+# CHECK-DAG: SBThread.StepUsingScriptedThreadPlan
+# CHECK-DAG: thread step-scripted -C <script-name> [-k key -v value ...]
+
+# CHECK-DAG: Name: ScriptedBreakpointResolver
+# CHECK-DAG: Description: Create a breakpoint that chooses locations based on 
user-created callbacks
+# CHECK-DAG: SBTarget.BreakpointCreateFromScript
+# CHECK-DAG: breakpoint set -P classname [-k key -v value ...]
+
+# CHECK-DAG: Name: ScriptedFrameProvider
+# CHECK-DAG: Description: Provide scripted stack frames for threads
+# CHECK-DAG: SBTarget.RegisterScriptedFrameProvider
+# CHECK-DAG: SBTarget.RemoveScriptedFrameProvider
+# CHECK-DAG: SBTarget.ClearScriptedFrameProvider
+# CHECK-DAG: target frame-provider register -C <script-name> [-k key -v value 
...]
+# CHECK-DAG: target frame-provider list
+# CHECK-DAG: target frame-provider remove <provider-name>
+# CHECK-DAG: target frame-provider clear
+
+# CHECK-DAG: Name: ScriptedHook
+# CHECK-DAG: Description: Perform actions on target lifecycle events (module 
load/unload, process stop).
+# CHECK-DAG: target hook add -P <script-name> [-k key -v value ...]
+
+# CHECK-DAG: Name: ScriptedThread
+# CHECK-DAG: Description: Provide thread state for a scripted process.
+
+# CHECK-DAG: Name: ScriptedFrame
+# CHECK-DAG: Description: Provide frame state for scripted threads and frame 
providers.
 
 scripting extension list -l lua
 # CHECK: Available scripted extension templates: None

_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to