11"""
2- Test lldb-dap completions request
2+ Test lldb-dap evaluate request
33"""
44
55import re
66
77import lldbdap_testcase
88from lldbsuite .test .decorators import skipIfWindows
99from lldbsuite .test .lldbtest import line_number
10+ from typing import TypedDict , Optional
11+
12+
13+ class EvaluateResponseBody (TypedDict , total = False ):
14+ result : str
15+ variablesReference : int
16+ type : Optional [str ]
17+ memoryReference : Optional [str ]
18+ valueLocationReference : Optional [int ]
1019
1120
1221class TestDAP_evaluate (lldbdap_testcase .DAPTestCaseBase ):
13- def assertEvaluate (self , expression , regex ):
22+ def assertEvaluate (
23+ self ,
24+ expression ,
25+ result : str ,
26+ want_type = "" ,
27+ want_varref = False ,
28+ want_memref = True ,
29+ want_locref = False ,
30+ ):
31+ resp = self .dap_server .request_evaluate (expression , context = self .context )
32+ self .assertTrue (
33+ resp ["success" ], f"Failed to evaluate expression { expression !r} "
34+ )
35+ body : EvaluateResponseBody = resp ["body" ]
1436 self .assertRegex (
15- self .dap_server .request_evaluate (expression , context = self .context )["body" ][
16- "result"
17- ],
18- regex ,
37+ body ["result" ],
38+ result ,
39+ f"Unexpected 'result' for expression { expression !r} in response body { body } " ,
1940 )
41+ if want_varref :
42+ self .assertNotEqual (
43+ body ["variablesReference" ],
44+ 0 ,
45+ f"Unexpected 'variablesReference' for expression { expression !r} in response body { body } " ,
46+ )
47+ else :
48+ self .assertEqual (
49+ body ["variablesReference" ],
50+ 0 ,
51+ f"Unexpected 'variablesReference' for expression { expression !r} in response body { body } " ,
52+ )
53+ if want_type :
54+ self .assertEqual (
55+ body ["type" ],
56+ want_type ,
57+ f"Unexpected 'type' for expression { expression !r} in response body { body } " ,
58+ )
59+ if want_memref :
60+ self .assertIn (
61+ "memoryReference" ,
62+ body ,
63+ f"Unexpected 'memoryReference' for expression { expression !r} in response body { body } " ,
64+ )
65+ if want_locref :
66+ self .assertIn (
67+ "valueLocationReference" ,
68+ body ,
69+ f"Unexpected 'valueLocationReference' for expression { expression !r} in response body { body } " ,
70+ )
2071
2172 def assertEvaluateFailure (self , expression ):
2273 self .assertNotIn (
@@ -71,29 +122,39 @@ def run_test_evaluate_expressions(
71122 self .continue_to_breakpoint (breakpoint_1 )
72123
73124 # Expressions at breakpoint 1, which is in main
74- self .assertEvaluate ("var1" , "20" )
125+ self .assertEvaluate ("var1" , "20" , want_type = "int" )
75126 # Empty expression should equate to the previous expression.
76127 if context == "repl" :
77128 self .assertEvaluate ("" , "20" )
78129 else :
79130 self .assertEvaluateFailure ("" )
80- self .assertEvaluate ("var2" , "21" )
131+ self .assertEvaluate ("var2" , "21" , want_type = "int" )
81132 if context == "repl" :
82- self .assertEvaluate ("" , "21" )
83- self .assertEvaluate ("" , "21" )
84- self .assertEvaluate ("static_int" , "42" )
85- self .assertEvaluate ("non_static_int" , "43" )
86- self .assertEvaluate ("struct1.foo" , "15" )
87- self .assertEvaluate ("struct2->foo" , "16" )
133+ self .assertEvaluate ("" , "21" , want_type = "int" )
134+ self .assertEvaluate ("" , "21" , want_type = "int" )
135+ self .assertEvaluate ("static_int" , "42" , want_type = "int" )
136+ self .assertEvaluate ("non_static_int" , "43" , want_type = "int" )
137+ self .assertEvaluate ("struct1.foo" , "15" , want_type = "int" )
138+ self .assertEvaluate ("struct2->foo" , "16" , want_type = "int" )
88139
89140 if self .isResultExpandedDescription ():
90141 self .assertEvaluate (
91142 "struct1" ,
92143 r"\(my_struct\) (struct1|\$\d+) = \(foo = 15\)" ,
144+ want_type = "my_struct" ,
145+ want_varref = True ,
146+ )
147+ self .assertEvaluate (
148+ "struct2" ,
149+ r"\(my_struct \*\) (struct2|\$\d+) = 0x.*" ,
150+ want_type = "my_struct *" ,
151+ want_varref = True ,
93152 )
94- self .assertEvaluate ("struct2" , r"\(my_struct \*\) (struct2|\$\d+) = 0x.*" )
95153 self .assertEvaluate (
96- "struct3" , r"\(my_struct \*\) (struct3|\$\d+) = nullptr"
154+ "struct3" ,
155+ r"\(my_struct \*\) (struct3|\$\d+) = nullptr" ,
156+ want_type = "my_struct *" ,
157+ want_varref = True ,
97158 )
98159 else :
99160 self .assertEvaluate (
@@ -103,16 +164,22 @@ def run_test_evaluate_expressions(
103164 if enableAutoVariableSummaries
104165 else "my_struct @ 0x"
105166 ),
167+ want_varref = True ,
168+ )
169+ self .assertEvaluate (
170+ "struct2" ,
171+ "0x.* {foo:16}" if enableAutoVariableSummaries else "0x.*" ,
172+ want_varref = True ,
173+ want_type = "my_struct *" ,
106174 )
107175 self .assertEvaluate (
108- "struct2 " , "0x.* {foo:16}" if enableAutoVariableSummaries else "0x. *"
176+ "struct3 " , "0x.*0" , want_varref = True , want_type = "my_struct *"
109177 )
110- self .assertEvaluate ("struct3" , "0x.*0" )
111178
112179 if context == "repl" :
113180 # In the repl context expressions may be interpreted as lldb
114181 # commands since no variables have the same name as the command.
115- self .assertEvaluate ("list" , r".*" )
182+ self .assertEvaluate ("list" , r".*" , want_memref = False )
116183 else :
117184 self .assertEvaluateFailure ("list" ) # local variable of a_function
118185
@@ -121,10 +188,26 @@ def run_test_evaluate_expressions(
121188 self .assertEvaluateFailure ("foo" ) # member of my_struct
122189
123190 if self .isExpressionParsedExpected ():
124- self .assertEvaluate ("a_function" , "0x.*a.out`a_function.*" )
125- self .assertEvaluate ("a_function(1)" , "1" )
126- self .assertEvaluate ("var2 + struct1.foo" , "36" )
127- self .assertEvaluate ("foo_func" , "0x.*a.out`foo_func.*" )
191+ self .assertEvaluate (
192+ "a_function" ,
193+ "0x.*a.out`a_function.*" ,
194+ want_type = "int (*)(int)" ,
195+ want_varref = True ,
196+ want_memref = False ,
197+ want_locref = True ,
198+ )
199+ self .assertEvaluate (
200+ "a_function(1)" , "1" , want_memref = False , want_type = "int"
201+ )
202+ self .assertEvaluate ("var2 + struct1.foo" , "36" , want_memref = False )
203+ self .assertEvaluate (
204+ "foo_func" ,
205+ "0x.*a.out`foo_func.*" ,
206+ want_type = "int (*)()" ,
207+ want_varref = True ,
208+ want_memref = False ,
209+ want_locref = True ,
210+ )
128211 self .assertEvaluate ("foo_var" , "44" )
129212 else :
130213 self .assertEvaluateFailure ("a_function" )
@@ -145,6 +228,8 @@ def run_test_evaluate_expressions(
145228 self .assertEvaluate (
146229 "struct1" ,
147230 r"\(my_struct\) (struct1|\$\d+) = \(foo = 15\)" ,
231+ want_type = "my_struct" ,
232+ want_varref = True ,
148233 )
149234 else :
150235 self .assertEvaluate (
@@ -154,15 +239,26 @@ def run_test_evaluate_expressions(
154239 if enableAutoVariableSummaries
155240 else "my_struct @ 0x"
156241 ),
242+ want_type = "my_struct" ,
243+ want_varref = True ,
157244 )
158245 self .assertEvaluate ("struct1.foo" , "15" )
159246 self .assertEvaluate ("struct2->foo" , "16" )
160247
161248 if self .isExpressionParsedExpected ():
162- self .assertEvaluate ("a_function" , "0x.*a.out`a_function.*" )
163- self .assertEvaluate ("a_function(1)" , "1" )
164- self .assertEvaluate ("var2 + struct1.foo" , "17" )
165- self .assertEvaluate ("foo_func" , "0x.*a.out`foo_func.*" )
249+ self .assertEvaluate (
250+ "a_function" ,
251+ "0x.*a.out`a_function.*" ,
252+ want_type = "int (*)(int)" ,
253+ want_varref = True ,
254+ want_memref = False ,
255+ want_locref = True ,
256+ )
257+ self .assertEvaluate ("a_function(1)" , "1" , want_memref = False )
258+ self .assertEvaluate ("var2 + struct1.foo" , "17" , want_memref = False )
259+ self .assertEvaluate (
260+ "foo_func" , "0x.*a.out`foo_func.*" , want_varref = True , want_memref = False
261+ )
166262 self .assertEvaluate ("foo_var" , "44" )
167263 else :
168264 self .assertEvaluateFailure ("a_function" )
@@ -185,10 +281,18 @@ def run_test_evaluate_expressions(
185281 self .assertEvaluateFailure ("var2 + struct1.foo" )
186282
187283 if self .isExpressionParsedExpected ():
188- self .assertEvaluate ("a_function" , "0x.*a.out`a_function.*" )
189- self .assertEvaluate ("a_function(1)" , "1" )
190- self .assertEvaluate ("list + 1" , "43" )
191- self .assertEvaluate ("foo_func" , "0x.*a.out`foo_func.*" )
284+ self .assertEvaluate (
285+ "a_function" ,
286+ "0x.*a.out`a_function.*" ,
287+ want_varref = True ,
288+ want_memref = False ,
289+ want_locref = True ,
290+ )
291+ self .assertEvaluate ("a_function(1)" , "1" , want_memref = False )
292+ self .assertEvaluate ("list + 1" , "43" , want_memref = False )
293+ self .assertEvaluate (
294+ "foo_func" , "0x.*a.out`foo_func.*" , want_varref = True , want_memref = False
295+ )
192296 self .assertEvaluate ("foo_var" , "44" )
193297 else :
194298 self .assertEvaluateFailure ("a_function" )
@@ -199,26 +303,28 @@ def run_test_evaluate_expressions(
199303
200304 # Now we check that values are updated after stepping
201305 self .continue_to_breakpoint (breakpoint_4 )
202- self .assertEvaluate ("my_vec" , "size=2" )
306+ self .assertEvaluate ("my_vec" , "size=2" , want_varref = True )
203307 self .continue_to_breakpoint (breakpoint_5 )
204- self .assertEvaluate ("my_vec" , "size=3" )
308+ self .assertEvaluate ("my_vec" , "size=3" , want_varref = True )
205309
206- self .assertEvaluate ("my_map" , "size=2" )
310+ self .assertEvaluate ("my_map" , "size=2" , want_varref = True )
207311 self .continue_to_breakpoint (breakpoint_6 )
208- self .assertEvaluate ("my_map" , "size=3" )
312+ self .assertEvaluate ("my_map" , "size=3" , want_varref = True )
209313
210- self .assertEvaluate ("my_bool_vec" , "size=1" )
314+ self .assertEvaluate ("my_bool_vec" , "size=1" , want_varref = True )
211315 self .continue_to_breakpoint (breakpoint_7 )
212- self .assertEvaluate ("my_bool_vec" , "size=2" )
316+ self .assertEvaluate ("my_bool_vec" , "size=2" , want_varref = True )
213317
214318 self .continue_to_breakpoint (breakpoint_8 )
215319 # Test memory read, especially with 'empty' repeat commands.
216320 if context == "repl" :
217- self .assertEvaluate ("memory read -c 1 &my_ints" , ".* 05 .*\n " )
218- self .assertEvaluate ("" , ".* 0a .*\n " )
219- self .assertEvaluate ("" , ".* 0f .*\n " )
220- self .assertEvaluate ("" , ".* 14 .*\n " )
221- self .assertEvaluate ("" , ".* 19 .*\n " )
321+ self .assertEvaluate (
322+ "memory read -c 1 &my_ints" , ".* 05 .*\n " , want_memref = False
323+ )
324+ self .assertEvaluate ("" , ".* 0a .*\n " , want_memref = False )
325+ self .assertEvaluate ("" , ".* 0f .*\n " , want_memref = False )
326+ self .assertEvaluate ("" , ".* 14 .*\n " , want_memref = False )
327+ self .assertEvaluate ("" , ".* 19 .*\n " , want_memref = False )
222328
223329 self .continue_to_exit ()
224330
@@ -245,4 +351,6 @@ def test_hover_evaluate_expressions(self):
245351 @skipIfWindows
246352 def test_variable_evaluate_expressions (self ):
247353 # Tests expression evaluations that are triggered in the variable explorer
248- self .run_test_evaluate_expressions ("variable" , enableAutoVariableSummaries = True )
354+ self .run_test_evaluate_expressions (
355+ "variables" , enableAutoVariableSummaries = True
356+ )
0 commit comments