Add two new pretty-printer methods

This adds two new pretty-printer methods, to support random access to
children.  The methods are implemented for the no-op array printer,
and DAP is updated to use this.

Reviewed-By: Eli Zaretskii <eliz@gnu.org>
This commit is contained in:
Tom Tromey
2023-09-08 13:18:17 -06:00
parent fb28257699
commit f35baff348
3 changed files with 43 additions and 11 deletions

View File

@@ -1828,6 +1828,22 @@ are peformed in this method and nothing is printed.
If the result is not one of these types, an exception is raised. If the result is not one of these types, an exception is raised.
@end defun @end defun
@defun pretty_printer.num_children ()
This is not a basic method, so @value{GDBN} will only ever call it for
objects derived from @code{gdb.ValuePrinter}.
If available, this method should return the number of children.
@code{None} may be returned if the number can't readily be computed.
@end defun
@defun pretty_printer.child (n)
This is not a basic method, so @value{GDBN} will only ever call it for
objects derived from @code{gdb.ValuePrinter}.
If available, this method should return the child value indicated by
@var{n}. Indices start at zero.
@end defun
@value{GDBN} provides a function which can be used to look up the @value{GDBN} provides a function which can be used to look up the
default pretty-printer for a @code{gdb.Value}: default pretty-printer for a @code{gdb.Value}:

View File

@@ -151,9 +151,9 @@ class VariableReference(BaseReference):
# This discards all laziness. This could be improved # This discards all laziness. This could be improved
# slightly by lazily evaluating children, but because this # slightly by lazily evaluating children, but because this
# code also generally needs to know the number of # code also generally needs to know the number of
# children, it probably wouldn't help much. A real fix # children, it probably wouldn't help much. Note that
# would require an update to gdb's pretty-printer protocol # this is only needed with legacy (non-ValuePrinter)
# (though of course that is probably also inadvisable). # printers.
self.child_cache = list(self.printer.children()) self.child_cache = list(self.printer.children())
return self.child_cache return self.child_cache
@@ -161,9 +161,12 @@ class VariableReference(BaseReference):
if self.count is None: if self.count is None:
return None return None
if self.count == -1: if self.count == -1:
if hasattr(self.printer, "num_children"): num_children = None
num_children = self.printer.num_children if isinstance(self.printer, gdb.ValuePrinter) and hasattr(
else: self.printer, "num_children"
):
num_children = self.printer.num_children()
if num_children is None:
num_children = len(self.cache_children()) num_children = len(self.cache_children())
self.count = num_children self.count = num_children
return self.count return self.count
@@ -193,6 +196,11 @@ class VariableReference(BaseReference):
@in_gdb_thread @in_gdb_thread
def fetch_one_child(self, idx): def fetch_one_child(self, idx):
if isinstance(self.printer, gdb.ValuePrinter) and hasattr(
self.printer, "child"
):
return self.printer.child(idx)
else:
return self.cache_children()[idx] return self.cache_children()[idx]

View File

@@ -285,11 +285,16 @@ class NoOpPointerReferencePrinter(gdb.ValuePrinter):
def __init__(self, value): def __init__(self, value):
self.__value = value self.__value = value
self.num_children = 1
def to_string(self): def to_string(self):
return self.__value.format_string(deref_refs=False) return self.__value.format_string(deref_refs=False)
def num_children(self):
return 1
def child(self, i):
return "value", self.__value.referenced_value()
def children(self): def children(self):
yield "value", self.__value.referenced_value() yield "value", self.__value.referenced_value()
@@ -313,9 +318,6 @@ class NoOpArrayPrinter(gdb.ValuePrinter):
e_values = itertools.takewhile(lambda x: x.enumval <= high, e_values) e_values = itertools.takewhile(lambda x: x.enumval <= high, e_values)
low = 0 low = 0
high = len(list(e_values)) - 1 high = len(list(e_values)) - 1
# This is a convenience to the DAP code and perhaps other
# users.
self.num_children = high - low + 1
self.__low = low self.__low = low
self.__high = high self.__high = high
@@ -325,6 +327,12 @@ class NoOpArrayPrinter(gdb.ValuePrinter):
def display_hint(self): def display_hint(self):
return "array" return "array"
def num_children(self):
return self.__high - self.__low + 1
def child(self, i):
return (self.__low + i, self.__value[self.__low + i])
def children(self): def children(self):
for i in range(self.__low, self.__high + 1): for i in range(self.__low, self.__high + 1):
yield (i, self.__value[i]) yield (i, self.__value[i])