1"""
2Test lldb-vscode completions request
3"""
4
5
6import lldbvscode_testcase
7import unittest2
8import vscode
9from lldbsuite.test import lldbutil
10from lldbsuite.test.decorators import *
11from lldbsuite.test.lldbtest import *
12
13class TestVSCode_variables(lldbvscode_testcase.VSCodeTestCaseBase):
14
15    mydir = TestBase.compute_mydir(__file__)
16
17    def assertEvaluate(self, expression, regex):
18        self.assertRegexpMatches(
19            self.vscode.request_evaluate(expression, context=self.context)['body']['result'],
20            regex)
21
22    def assertEvaluateFailure(self, expression):
23        self.assertNotIn('result',
24            self.vscode.request_evaluate(expression, context=self.context)['body'])
25
26    def isExpressionParsedExpected(self):
27        return self.context != "hover"
28
29    def run_test_evaluate_expressions(self, context=None):
30        """
31            Tests the evaluate expression request at different breakpoints
32        """
33        self.context = context
34        program = self.getBuildArtifact("a.out")
35        self.build_and_launch(program)
36        source = "main.cpp"
37        self.set_source_breakpoints(
38            source,
39            [
40                line_number(source, "// breakpoint 1"),
41                line_number(source, "// breakpoint 2"),
42                line_number(source, "// breakpoint 3")
43            ]
44        )
45        self.continue_to_next_stop()
46
47        # Expressions at breakpoint 1, which is in main
48        self.assertEvaluate("var1", "20")
49        self.assertEvaluate("var2", "21")
50        self.assertEvaluate("static_int", "42")
51        self.assertEvaluate("non_static_int", "43")
52        self.assertEvaluate("struct1", "my_struct @ 0x.*")
53        self.assertEvaluate("struct1.foo", "15")
54        self.assertEvaluate("struct2->foo", "16")
55
56        self.assertEvaluateFailure("var") # local variable of a_function
57        self.assertEvaluateFailure("my_struct") # type name
58        self.assertEvaluateFailure("int") # type name
59        self.assertEvaluateFailure("foo") # member of my_struct
60
61        if self.isExpressionParsedExpected():
62            self.assertEvaluate(
63                "a_function",
64                "0x.*a.out`a_function.*")
65            self.assertEvaluate("a_function(1)", "1")
66            self.assertEvaluate("var2 + struct1.foo", "36")
67            self.assertEvaluate(
68                "foo_func",
69                "0x.*a.out`foo_func.*")
70            self.assertEvaluate("foo_var", "44")
71        else:
72            self.assertEvaluateFailure("a_function")
73            self.assertEvaluateFailure("a_function(1)")
74            self.assertEvaluateFailure("var2 + struct1.foo")
75            self.assertEvaluateFailure("foo_func")
76            self.assertEvaluateFailure("foo_var")
77
78        # Expressions at breakpoint 2, which is an anonymous block
79        self.continue_to_next_stop()
80        self.assertEvaluate("var1", "20")
81        self.assertEvaluate("var2", "2") # different variable with the same name
82        self.assertEvaluate("static_int", "42")
83        self.assertEvaluate("non_static_int", "10") # different variable with the same name
84        self.assertEvaluate("struct1", "my_struct @ 0x.*")
85        self.assertEvaluate("struct1.foo", "15")
86        self.assertEvaluate("struct2->foo", "16")
87
88        if self.isExpressionParsedExpected():
89            self.assertEvaluate(
90                "a_function",
91                "0x.*a.out`a_function.*")
92            self.assertEvaluate("a_function(1)", "1")
93            self.assertEvaluate("var2 + struct1.foo", "17")
94            self.assertEvaluate(
95                "foo_func",
96                "0x.*a.out`foo_func.*")
97            self.assertEvaluate("foo_var", "44")
98        else:
99            self.assertEvaluateFailure("a_function")
100            self.assertEvaluateFailure("a_function(1)")
101            self.assertEvaluateFailure("var2 + struct1.foo")
102            self.assertEvaluateFailure("foo_func")
103            self.assertEvaluateFailure("foo_var")
104
105        # Expressions at breakpoint 3, which is inside a_function
106        self.continue_to_next_stop()
107        self.assertEvaluate("var", "42")
108        self.assertEvaluate("static_int", "42")
109        self.assertEvaluate("non_static_int", "43")
110
111        self.assertEvaluateFailure("var1")
112        self.assertEvaluateFailure("var2")
113        self.assertEvaluateFailure("struct1")
114        self.assertEvaluateFailure("struct1.foo")
115        self.assertEvaluateFailure("struct2->foo")
116        self.assertEvaluateFailure("var2 + struct1.foo")
117
118        if self.isExpressionParsedExpected():
119            self.assertEvaluate(
120                "a_function",
121                "0x.*a.out`a_function.*")
122            self.assertEvaluate("a_function(1)", "1")
123            self.assertEvaluate("var + 1", "43")
124            self.assertEvaluate(
125                "foo_func",
126                "0x.*a.out`foo_func.*")
127            self.assertEvaluate("foo_var", "44")
128        else:
129            self.assertEvaluateFailure("a_function")
130            self.assertEvaluateFailure("a_function(1)")
131            self.assertEvaluateFailure("var + 1")
132            self.assertEvaluateFailure("foo_func")
133            self.assertEvaluateFailure("foo_var")
134
135    @skipIfWindows
136    @skipIfRemote
137    def test_generic_evaluate_expressions(self):
138        # Tests context-less expression evaluations
139        self.run_test_evaluate_expressions()
140
141    @skipIfWindows
142    @skipIfRemote
143    def test_repl_evaluate_expressions(self):
144        # Tests expression evaluations that are triggered from the Debug Console
145        self.run_test_evaluate_expressions("repl")
146
147    @skipIfWindows
148    @skipIfRemote
149    def test_watch_evaluate_expressions(self):
150        # Tests expression evaluations that are triggered from a watch expression
151        self.run_test_evaluate_expressions("watch")
152
153    @skipIfWindows
154    @skipIfRemote
155    def test_hover_evaluate_expressions(self):
156        # Tests expression evaluations that are triggered when hovering on the editor
157        self.run_test_evaluate_expressions("hover")
158