]>
git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - gdb/python/lib/gdb/dap/evaluate.py
1 # Copyright 2022-2024 Free Software Foundation, Inc.
3 # This program is free software; you can redistribute it and/or modify
4 # it under the terms of the GNU General Public License as published by
5 # the Free Software Foundation; either version 3 of the License, or
6 # (at your option) any later version.
8 # This program is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # GNU General Public License for more details.
13 # You should have received a copy of the GNU General Public License
14 # along with this program. If not, see <http://www.gnu.org/licenses/>.
18 # This is deprecated in 3.9, but required in older versions.
19 from typing
import Optional
21 from .frames
import select_frame
22 from .server
import capability
, request
, client_bool_capability
23 from .startup
import in_gdb_thread
, parse_and_eval
, DAPException
24 from .varref
import find_variable
, VariableReference
, apply_format
27 class EvaluateResult(VariableReference
):
28 def __init__(self
, value
):
29 super().__init
__(None, value
, "result")
32 # Helper function to evaluate an expression in a certain frame.
34 def _evaluate(expr
, frame_id
, value_format
):
35 with
apply_format(value_format
):
37 if frame_id
is not None:
38 select_frame(frame_id
)
39 global_context
= False
40 val
= parse_and_eval(expr
, global_context
=global_context
)
41 ref
= EvaluateResult(val
)
42 return ref
.to_object()
45 # Like _evaluate but ensure that the expression cannot cause side
48 def _eval_for_hover(expr
, frame_id
, value_format
):
49 with gdb
.with_parameter("may-write-registers", "off"):
50 with gdb
.with_parameter("may-write-memory", "off"):
51 with gdb
.with_parameter("may-call-functions", "off"):
52 return _evaluate(expr
, frame_id
, value_format
)
55 class _SetResult(VariableReference
):
56 def __init__(self
, value
):
57 super().__init
__(None, value
, "value")
60 # Helper function to evaluate a gdb command in a certain frame.
62 def _repl(command
, frame_id
):
63 if frame_id
is not None:
64 select_frame(frame_id
)
65 val
= gdb
.execute(command
, from_tty
=True, to_string
=True)
68 "variablesReference": 0,
73 @capability("supportsEvaluateForHovers")
74 @capability("supportsValueFormattingOptions")
78 frameId
: Optional
[int] = None,
79 context
: str = "variables",
83 if context
in ("watch", "variables"):
84 # These seem to be expression-like.
85 return _evaluate(expression
, frameId
, format
)
86 elif context
== "hover":
87 return _eval_for_hover(expression
, frameId
, format
)
88 elif context
== "repl":
89 # Ignore the format for repl evaluation.
90 return _repl(expression
, frameId
)
92 raise DAPException('unknown evaluate context "' + context
+ '"')
96 # Note that we ignore the 'filter' field. That seems to be
97 # specific to javascript.
99 *, variablesReference
: int, start
: int = 0, count
: int = 0, format
=None, **args
101 # This behavior was clarified here:
102 # https://github.com/microsoft/debug-adapter-protocol/pull/394
103 if not client_bool_capability("supportsVariablePaging"):
106 with
apply_format(format
):
107 var
= find_variable(variablesReference
)
108 children
= var
.fetch_children(start
, count
)
109 return {"variables": [x
.to_object() for x
in children
]}
112 @capability("supportsSetExpression")
113 @request("setExpression")
115 *, expression
: str, value
: str, frameId
: Optional
[int] = None, format
=None, **args
117 with
apply_format(format
):
118 global_context
= True
119 if frameId
is not None:
120 select_frame(frameId
)
121 global_context
= False
122 lhs
= parse_and_eval(expression
, global_context
=global_context
)
123 rhs
= parse_and_eval(value
, global_context
=global_context
)
125 return _SetResult(lhs
).to_object()
128 @capability("supportsSetVariable")
129 @request("setVariable")
131 *, variablesReference
: int, name
: str, value
: str, format
=None, **args
133 with
apply_format(format
):
134 var
= find_variable(variablesReference
)
135 lhs
= var
.find_child_by_name(name
)
136 rhs
= parse_and_eval(value
)
138 return lhs
.to_object()