xref: /llvm-project/lldb/test/API/commands/expression/fixits/TestFixIts.py (revision 06bb7df81c0ba01f7efab76779e2eb7d76615e3d)
1"""
2Test calling an expression with errors that a FixIt can fix.
3"""
4
5import lldb
6from lldbsuite.test.decorators import *
7from lldbsuite.test.lldbtest import *
8from lldbsuite.test import lldbutil
9
10
11class ExprCommandWithFixits(TestBase):
12
13    mydir = TestBase.compute_mydir(__file__)
14
15    def test_with_dummy_target(self):
16        """Test calling expressions in the dummy target with errors that can be fixed by the FixIts."""
17
18        # Enable fix-its as they were intentionally disabled by TestBase.setUp.
19        self.runCmd("settings set target.auto-apply-fixits true")
20
21        ret_val = lldb.SBCommandReturnObject()
22        result = self.dbg.GetCommandInterpreter().HandleCommand("expression ((1 << 16) - 1))", ret_val)
23        self.assertEqual(result, lldb.eReturnStatusSuccessFinishResult, "The expression was successful.")
24        self.assertTrue("Fix-it applied" in ret_val.GetError(), "Found the applied FixIt.")
25
26    def test_with_target(self):
27        """Test calling expressions with errors that can be fixed by the FixIts."""
28        self.build()
29        (target, process, self.thread, bkpt) = lldbutil.run_to_source_breakpoint(self,
30                                        'Stop here to evaluate expressions',
31                                         lldb.SBFileSpec("main.cpp"))
32
33        options = lldb.SBExpressionOptions()
34        options.SetAutoApplyFixIts(True)
35
36        top_level_options = lldb.SBExpressionOptions()
37        top_level_options.SetAutoApplyFixIts(True)
38        top_level_options.SetTopLevel(True)
39
40        frame = self.thread.GetFrameAtIndex(0)
41
42        # Try with one error:
43        value = frame.EvaluateExpression("my_pointer.first", options)
44        self.assertTrue(value.IsValid())
45        self.assertTrue(value.GetError().Success())
46        self.assertEquals(value.GetValueAsUnsigned(), 10)
47
48        # Try with one error in a top-level expression.
49        # The Fix-It changes "ptr.m" to "ptr->m".
50        expr = "struct X { int m; }; X x; X *ptr = &x; int m = ptr.m;"
51        value = frame.EvaluateExpression(expr, top_level_options)
52        # A successfully parsed top-level expression will yield an error
53        # that there is 'no value'. If a parsing error would have happened we
54        # would get a different error kind, so let's check the error kind here.
55        self.assertEquals(value.GetError().GetCString(), "error: No value")
56
57        # Try with two errors:
58        two_error_expression = "my_pointer.second->a"
59        value = frame.EvaluateExpression(two_error_expression, options)
60        self.assertTrue(value.IsValid())
61        self.assertTrue(value.GetError().Success())
62        self.assertEquals(value.GetValueAsUnsigned(), 20)
63
64        # Now turn off the fixits, and the expression should fail:
65        options.SetAutoApplyFixIts(False)
66        value = frame.EvaluateExpression(two_error_expression, options)
67        self.assertTrue(value.IsValid())
68        self.assertTrue(value.GetError().Fail())
69        error_string = value.GetError().GetCString()
70        self.assertTrue(
71            error_string.find("fixed expression suggested:") != -1,
72            "Fix was suggested")
73        self.assertTrue(
74            error_string.find("my_pointer->second.a") != -1,
75            "Fix was right")
76