[Lldb-commits] [lldb] [lldb] Fix `po` alias by printing fix-its to the console. (PR #68452)

Pete Lawrence via lldb-commits lldb-commits at lists.llvm.org
Fri Oct 6 14:17:34 PDT 2023


https://github.com/PortalPete created https://github.com/llvm/llvm-project/pull/68452

The `po` alias now matches the behavior of the `expression` command when the it can apply a Fix-It to an expression.
Modifications

- Add has `m_fixed_expression` to the `CommandObjectDWIMPrint` class a `protected` member that stores the post Fix-It expression, just like the `CommandObjectExpression` class.
- Converted messages to present tense.
- Add test cases that confirms a Fix-It for a C++ expression for both `po` and `expressions`

rdar://115317419

>From 1d0ac08d38a33ae70687f7b125367c39fbcf92f3 Mon Sep 17 00:00:00 2001
From: Pete Lawrence <plawrence at apple.com>
Date: Thu, 5 Oct 2023 14:22:35 -1000
Subject: [PATCH] Modify `po` alias to match outward FixIt behavior with
 `expression`.

- Fix `po` alias so that it prints out a message when applying a FixIt, just like the `expression` command.
- Add test cases for applying a FixIt with both `expression` command and `po` alias.
- Reword console messages for readability.
---
 .../Commands/CommandObjectDWIMPrint.cpp       | 11 +++++++-
 lldb/source/Commands/CommandObjectDWIMPrint.h |  4 +++
 .../Commands/CommandObjectExpression.cpp      |  6 ++---
 .../source/Commands/CommandObjectExpression.h |  4 ++-
 .../API/lang/cpp/dwim-print-fixit/Makefile    |  3 +++
 .../dwim-print-fixit/TestCppDWIMPrintFixIt.py | 27 +++++++++++++++++++
 .../API/lang/cpp/dwim-print-fixit/main.cpp    |  6 +++++
 .../API/lang/cpp/expression-fixit/Makefile    |  3 +++
 .../TestCppExpressionFixIt.py                 | 26 ++++++++++++++++++
 .../API/lang/cpp/expression-fixit/main.cpp    |  6 +++++
 10 files changed, 91 insertions(+), 5 deletions(-)
 create mode 100644 lldb/test/API/lang/cpp/dwim-print-fixit/Makefile
 create mode 100644 lldb/test/API/lang/cpp/dwim-print-fixit/TestCppDWIMPrintFixIt.py
 create mode 100644 lldb/test/API/lang/cpp/dwim-print-fixit/main.cpp
 create mode 100644 lldb/test/API/lang/cpp/expression-fixit/Makefile
 create mode 100644 lldb/test/API/lang/cpp/expression-fixit/TestCppExpressionFixIt.py
 create mode 100644 lldb/test/API/lang/cpp/expression-fixit/main.cpp

diff --git a/lldb/source/Commands/CommandObjectDWIMPrint.cpp b/lldb/source/Commands/CommandObjectDWIMPrint.cpp
index 7b168eab9e02d44..8a5be3e1cd1c36e 100644
--- a/lldb/source/Commands/CommandObjectDWIMPrint.cpp
+++ b/lldb/source/Commands/CommandObjectDWIMPrint.cpp
@@ -173,7 +173,16 @@ bool CommandObjectDWIMPrint::DoExecute(StringRef command,
     auto *exe_scope = m_exe_ctx.GetBestExecutionContextScope();
     ValueObjectSP valobj_sp;
     ExpressionResults expr_result =
-        target.EvaluateExpression(expr, exe_scope, valobj_sp, eval_options);
+        target.EvaluateExpression(expr, exe_scope, valobj_sp, eval_options, &m_fixed_expression);
+    
+    // Only mention Fix-Its if the command applies them.
+    // The compiler errors can address any parsing issues after applying Fix-It(s).
+    if (!m_fixed_expression.empty() && target.GetEnableNotifyAboutFixIts()) {
+      Stream &error_stream = result.GetErrorStream();
+      error_stream.Printf("  Applying Fix-It to expression, changing it to:\n    %s\n",
+                          m_fixed_expression.c_str());
+    }
+
     if (expr_result == eExpressionCompleted) {
       if (verbosity != eDWIMPrintVerbosityNone) {
         StringRef flags;
diff --git a/lldb/source/Commands/CommandObjectDWIMPrint.h b/lldb/source/Commands/CommandObjectDWIMPrint.h
index 3fc6c01d4729707..b4e68495b17af07 100644
--- a/lldb/source/Commands/CommandObjectDWIMPrint.h
+++ b/lldb/source/Commands/CommandObjectDWIMPrint.h
@@ -43,6 +43,10 @@ class CommandObjectDWIMPrint : public CommandObjectRaw {
   HandleArgumentCompletion(CompletionRequest &request,
                            OptionElementVector &opt_element_vector) override;
 
+protected:
+  /// Stores the expression after applying any Fix-Its.
+  std::string m_fixed_expression;
+
 private:
   bool DoExecute(llvm::StringRef command, CommandReturnObject &result) override;
 
diff --git a/lldb/source/Commands/CommandObjectExpression.cpp b/lldb/source/Commands/CommandObjectExpression.cpp
index e7e6e3820b99133..82283d0fe6a0935 100644
--- a/lldb/source/Commands/CommandObjectExpression.cpp
+++ b/lldb/source/Commands/CommandObjectExpression.cpp
@@ -439,10 +439,10 @@ bool CommandObjectExpression::EvaluateExpression(llvm::StringRef expr,
   ExpressionResults success = target.EvaluateExpression(
       expr, frame, result_valobj_sp, eval_options, &m_fixed_expression);
 
-  // We only tell you about the FixIt if we applied it.  The compiler errors
-  // will suggest the FixIt if it parsed.
+  // Only mention Fix-Its if the command applies them.
+  // The compiler errors can address any parsing issues after applying Fix-It(s).
   if (!m_fixed_expression.empty() && target.GetEnableNotifyAboutFixIts()) {
-    error_stream.Printf("  Fix-it applied, fixed expression was: \n    %s\n",
+    error_stream.Printf("  Applying Fix-It to expression, changing it to:\n    %s\n",
                         m_fixed_expression.c_str());
   }
 
diff --git a/lldb/source/Commands/CommandObjectExpression.h b/lldb/source/Commands/CommandObjectExpression.h
index b2b8fc73a1ee831..276da559fb4dbd6 100644
--- a/lldb/source/Commands/CommandObjectExpression.h
+++ b/lldb/source/Commands/CommandObjectExpression.h
@@ -99,7 +99,9 @@ class CommandObjectExpression : public CommandObjectRaw,
   CommandOptions m_command_options;
   uint32_t m_expr_line_count;
   std::string m_expr_lines;       // Multi-line expression support
-  std::string m_fixed_expression; // Holds the current expression's fixed text.
+
+  /// Stores the expression after applying any Fix-Its.
+  std::string m_fixed_expression;
 };
 
 } // namespace lldb_private
diff --git a/lldb/test/API/lang/cpp/dwim-print-fixit/Makefile b/lldb/test/API/lang/cpp/dwim-print-fixit/Makefile
new file mode 100644
index 000000000000000..99998b20bcb0502
--- /dev/null
+++ b/lldb/test/API/lang/cpp/dwim-print-fixit/Makefile
@@ -0,0 +1,3 @@
+CXX_SOURCES := main.cpp
+
+include Makefile.rules
diff --git a/lldb/test/API/lang/cpp/dwim-print-fixit/TestCppDWIMPrintFixIt.py b/lldb/test/API/lang/cpp/dwim-print-fixit/TestCppDWIMPrintFixIt.py
new file mode 100644
index 000000000000000..ad92d0216126965
--- /dev/null
+++ b/lldb/test/API/lang/cpp/dwim-print-fixit/TestCppDWIMPrintFixIt.py
@@ -0,0 +1,27 @@
+"""
+Tests whether the do-what-I-mean (DWIM) print `po` alias applies FixIts like `expr` does
+"""
+import lldb
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+
+class CPP_DWIM_Fixit_TestCase(TestBase):
+    def test_with_run_command(self):
+        "Confirm that the `po` command (alias) applies a FixIt " \
+        "and prints it out to the console, " \
+        "just like the `expression` command."
+        
+        self.build()
+        lldbutil.run_to_source_breakpoint(
+            self, "// break here", lldb.SBFileSpec("main.cpp")
+        )
+
+        self.expect(
+            "po class C { int i; void f() { []() { ++i; }(); } }",
+            error = True,
+            substrs=["Applying Fix-It to expression",
+                "changing it to:",
+                "class C { int i; void f() { [this]() { ++i; }(); } }"],
+        )
diff --git a/lldb/test/API/lang/cpp/dwim-print-fixit/main.cpp b/lldb/test/API/lang/cpp/dwim-print-fixit/main.cpp
new file mode 100644
index 000000000000000..3ead9e4957a632f
--- /dev/null
+++ b/lldb/test/API/lang/cpp/dwim-print-fixit/main.cpp
@@ -0,0 +1,6 @@
+int main()
+{
+  long foo = 1234;
+
+  return 0; // break here
+}
diff --git a/lldb/test/API/lang/cpp/expression-fixit/Makefile b/lldb/test/API/lang/cpp/expression-fixit/Makefile
new file mode 100644
index 000000000000000..99998b20bcb0502
--- /dev/null
+++ b/lldb/test/API/lang/cpp/expression-fixit/Makefile
@@ -0,0 +1,3 @@
+CXX_SOURCES := main.cpp
+
+include Makefile.rules
diff --git a/lldb/test/API/lang/cpp/expression-fixit/TestCppExpressionFixIt.py b/lldb/test/API/lang/cpp/expression-fixit/TestCppExpressionFixIt.py
new file mode 100644
index 000000000000000..7517d911723d851
--- /dev/null
+++ b/lldb/test/API/lang/cpp/expression-fixit/TestCppExpressionFixIt.py
@@ -0,0 +1,26 @@
+"""
+Tests whether the expression command applies FixIts
+"""
+import lldb
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+
+class CPP_Expression_FixIt_TestCase(TestBase):
+    def test_with_run_command(self):
+        "Confirm that the `expression` command applies a FixIt " \
+        "and prints it out to the console."
+        
+        self.build()
+        lldbutil.run_to_source_breakpoint(
+            self, "// break here", lldb.SBFileSpec("main.cpp")
+        )
+
+        self.expect(
+            "expr -l c++ -- class C { int i; void f() { []() { ++i; }(); } }",
+            error = True,
+            substrs=["Applying Fix-It to expression",
+                "changing it to:",
+                "class C { int i; void f() { [this]() { ++i; }(); } }"],
+        )
diff --git a/lldb/test/API/lang/cpp/expression-fixit/main.cpp b/lldb/test/API/lang/cpp/expression-fixit/main.cpp
new file mode 100644
index 000000000000000..3ead9e4957a632f
--- /dev/null
+++ b/lldb/test/API/lang/cpp/expression-fixit/main.cpp
@@ -0,0 +1,6 @@
+int main()
+{
+  long foo = 1234;
+
+  return 0; // break here
+}



More information about the lldb-commits mailing list