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

Pete Lawrence via lldb-commits lldb-commits at lists.llvm.org
Wed Oct 11 17:12:24 PDT 2023


https://github.com/PortalPete updated https://github.com/llvm/llvm-project/pull/68755

>From b0dfcb5b88fa206ebf238f04061d17003dddd5a6 Mon Sep 17 00:00:00 2001
From: Pete Lawrence <34425917+PortalPete at users.noreply.github.com>
Date: Tue, 10 Oct 2023 10:59:58 -1000
Subject: [PATCH] [lldb] Fix `po` alias by printing fix-its to the console.

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
---
 .../Commands/CommandObjectDWIMPrint.cpp       | 15 ++++++-
 .../Commands/CommandObjectExpression.cpp      |  8 ++--
 .../commands/expression/fixits/TestFixIts.py  |  8 +++-
 .../API/lang/cpp/expression-fixit/Makefile    |  3 ++
 .../TestCppExpressionFixIt.py                 | 26 +++++++++++
 .../API/lang/cpp/expression-fixit/main.cpp    |  5 +++
 lldb/test/API/lang/cpp/fixits/Makefile        |  3 ++
 .../test/API/lang/cpp/fixits/TestCppFixIts.py | 44 +++++++++++++++++++
 lldb/test/API/lang/cpp/fixits/main.cpp        |  5 +++
 9 files changed, 109 insertions(+), 8 deletions(-)
 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
 create mode 100644 lldb/test/API/lang/cpp/fixits/Makefile
 create mode 100644 lldb/test/API/lang/cpp/fixits/TestCppFixIts.py
 create mode 100644 lldb/test/API/lang/cpp/fixits/main.cpp

diff --git a/lldb/source/Commands/CommandObjectDWIMPrint.cpp b/lldb/source/Commands/CommandObjectDWIMPrint.cpp
index 7b168eab9e02d44..bdc17c9cffc779a 100644
--- a/lldb/source/Commands/CommandObjectDWIMPrint.cpp
+++ b/lldb/source/Commands/CommandObjectDWIMPrint.cpp
@@ -172,8 +172,19 @@ 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);
+    std::string fixed_expression;
+
+    ExpressionResults expr_result = target.EvaluateExpression(
+        expr, exe_scope, valobj_sp, eval_options, &fixed_expression);
+
+    // Only mention Fix-Its if the expression evaluator applied them.
+    // Compiler errors refer to the final expression after applying Fix-It(s).
+    if (!fixed_expression.empty() && target.GetEnableNotifyAboutFixIts()) {
+      Stream &error_stream = result.GetErrorStream();
+      error_stream << "  Evaluated this expression after applying Fix-It(s):\n";
+      error_stream << "    " << fixed_expression << "\n";
+    }
+
     if (expr_result == eExpressionCompleted) {
       if (verbosity != eDWIMPrintVerbosityNone) {
         StringRef flags;
diff --git a/lldb/source/Commands/CommandObjectExpression.cpp b/lldb/source/Commands/CommandObjectExpression.cpp
index e7e6e3820b99133..2834be660abaf53 100644
--- a/lldb/source/Commands/CommandObjectExpression.cpp
+++ b/lldb/source/Commands/CommandObjectExpression.cpp
@@ -439,11 +439,11 @@ 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 expression evaluator applied them.
+  // Compiler errors refer to the final expression after applying Fix-It(s).
   if (!m_fixed_expression.empty() && target.GetEnableNotifyAboutFixIts()) {
-    error_stream.Printf("  Fix-it applied, fixed expression was: \n    %s\n",
-                        m_fixed_expression.c_str());
+    error_stream << "  Evaluated this expression after applying Fix-It(s):\n";
+    error_stream << "    " << m_fixed_expression << "\n";
   }
 
   if (result_valobj_sp) {
diff --git a/lldb/test/API/commands/expression/fixits/TestFixIts.py b/lldb/test/API/commands/expression/fixits/TestFixIts.py
index 3bdeb84b4e79726..38b242838c828f1 100644
--- a/lldb/test/API/commands/expression/fixits/TestFixIts.py
+++ b/lldb/test/API/commands/expression/fixits/TestFixIts.py
@@ -22,7 +22,9 @@ def test_with_dummy_target(self):
         self.assertEqual(
             result, lldb.eReturnStatusSuccessFinishResult, ret_val.GetError()
         )
-        self.assertIn("Fix-it applied", ret_val.GetError())
+        self.assertIn(
+            "Evaluated this expression after applying Fix-It(s):", ret_val.GetError()
+        )
 
     def test_with_target(self):
         """Test calling expressions with errors that can be fixed by the FixIts."""
@@ -99,7 +101,9 @@ def test_with_target_error_applies_fixit(self):
         )
         self.assertEqual(result, lldb.eReturnStatusFailed, ret_val.GetError())
 
-        self.assertIn("Fix-it applied, fixed expression was:", ret_val.GetError())
+        self.assertIn(
+            "Evaluated this expression after applying Fix-It(s):", ret_val.GetError()
+        )
         self.assertIn("null_pointer->first", ret_val.GetError())
 
     # The final function call runs into SIGILL on aarch64-linux.
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..095f7d00789910a
--- /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 TestCase(TestBase):
+    def test_with_run_command(self):
+        """Confirms `expression` shows an expression after applying Fix-It(s)."""
+
+        self.build()
+        lldbutil.run_to_source_breakpoint(
+            self, "// break here", lldb.SBFileSpec("main.cpp")
+        )
+
+        self.expect(
+            "expr class C { int i; void f() { []() { ++i; }(); } }; 42",
+            error=True,
+            substrs=[
+                "Evaluated this expression after applying Fix-It(s)",
+                "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..e9cf11d18a6560d
--- /dev/null
+++ b/lldb/test/API/lang/cpp/expression-fixit/main.cpp
@@ -0,0 +1,5 @@
+int main() {
+  long foo = 1234;
+
+  return 0; // break here
+}
diff --git a/lldb/test/API/lang/cpp/fixits/Makefile b/lldb/test/API/lang/cpp/fixits/Makefile
new file mode 100644
index 000000000000000..99998b20bcb0502
--- /dev/null
+++ b/lldb/test/API/lang/cpp/fixits/Makefile
@@ -0,0 +1,3 @@
+CXX_SOURCES := main.cpp
+
+include Makefile.rules
diff --git a/lldb/test/API/lang/cpp/fixits/TestCppFixIts.py b/lldb/test/API/lang/cpp/fixits/TestCppFixIts.py
new file mode 100644
index 000000000000000..34b52f796da28be
--- /dev/null
+++ b/lldb/test/API/lang/cpp/fixits/TestCppFixIts.py
@@ -0,0 +1,44 @@
+"""
+Tests a C++ fixit for the `expr` command and
+`po` alias (aka DWIM aka "do what I mean") alias.
+"""
+import lldb
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+
+class TestCase(TestBase):
+    def test_fixit_with_dwim(self):
+        """Confirms `po` shows an expression after applying Fix-It(s)."""
+
+        self.build()
+        lldbutil.run_to_source_breakpoint(
+            self, "// break here", lldb.SBFileSpec("main.cpp")
+        )
+
+        self.expect(
+            "dwim-print -O -- class C { int i; void f() { []() { ++i; }(); } }; 42",
+            error=True,
+            substrs=[
+                "Evaluated this expression after applying Fix-It(s)",
+                "class C { int i; void f() { [this]() { ++i; }(); } }",
+            ],
+        )
+
+    def test_fixit_with_expression(self):
+        """Confirms `expression` shows an expression after applying Fix-It(s)."""
+
+        self.build()
+        lldbutil.run_to_source_breakpoint(
+            self, "// break here", lldb.SBFileSpec("main.cpp")
+        )
+
+        self.expect(
+            "expr class C { int i; void f() { []() { ++i; }(); } }; 42",
+            error=True,
+            substrs=[
+                "Evaluated this expression after applying Fix-It(s)",
+                "class C { int i; void f() { [this]() { ++i; }(); } }",
+            ],
+        )
diff --git a/lldb/test/API/lang/cpp/fixits/main.cpp b/lldb/test/API/lang/cpp/fixits/main.cpp
new file mode 100644
index 000000000000000..e9cf11d18a6560d
--- /dev/null
+++ b/lldb/test/API/lang/cpp/fixits/main.cpp
@@ -0,0 +1,5 @@
+int main() {
+  long foo = 1234;
+
+  return 0; // break here
+}



More information about the lldb-commits mailing list