Skip to content

Commit 5cc4655

Browse files
committed
Share variable inspection logic between CDP and DAP
1 parent 0f7907a commit 5cc4655

File tree

3 files changed

+98
-75
lines changed

3 files changed

+98
-75
lines changed
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
# frozen_string_literal: true
2+
3+
module DEBUGGER__
4+
module Mirrors
5+
class VariableInspector
6+
class Member
7+
attr_reader :name, :value
8+
9+
def initialize(name:, value:, internal: false)
10+
@name = name
11+
@value = value
12+
@is_internal = internal
13+
end
14+
15+
def internal?
16+
@is_internal
17+
end
18+
19+
def self.internal name:, value:
20+
new(name:, value:, internal: true)
21+
end
22+
end
23+
24+
def indexed_members_of obj, start:, count:
25+
(start ... (start + count)).map { |i| Member.new(name: i.to_s, value: obj[i]) }
26+
end
27+
28+
def named_members_of obj
29+
members = case obj
30+
when Array then obj.map.with_index { |o, i| Member.new(name: i.to_s, value: o) }
31+
when Hash then obj.map { |k, v| Member.new(name: value_inspect(k), value: v) }
32+
when Struct then obj.members.map { |name| Member.new(name:, value: obj[name]) }
33+
when String
34+
members = [
35+
Member.internal(name: '#length', value: obj.length),
36+
Member.internal(name: '#encoding', value: obj.encoding),
37+
]
38+
if defined?(DEBUGGER__::NaiveString)
39+
printed_str = value_inspect(obj)
40+
members << Member.internal(name: "#dump", value: DEBUGGER__::NaiveString.new(obj)) if printed_str.end_with?('...')
41+
end
42+
members
43+
when Class, Module then [Member.internal(name: "%ancestors", value: obj.ancestors[1..])]
44+
when Range then [Member.internal(name: "#begin", value: obj.begin), Member.internal(name: "#end", value: obj.end)]
45+
else []
46+
end
47+
48+
unless defined?(DEBUGGER__::NaiveString) && DEBUGGER__::NaiveString === obj
49+
members += M_INSTANCE_VARIABLES.bind_call(obj).sort.map{|iv|
50+
Member.new(name: iv, value: M_INSTANCE_VARIABLE_GET.bind_call(obj, iv))
51+
}
52+
members.unshift Member.internal(name: '#class', value: M_CLASS.bind_call(obj))
53+
end
54+
55+
members
56+
end
57+
58+
private
59+
60+
MAX_LENGTH = 180
61+
62+
def value_inspect obj, short: true
63+
# TODO: max length should be configurable?
64+
str = DEBUGGER__.safe_inspect obj, short: short, max_length: MAX_LENGTH
65+
66+
if str.encoding == Encoding::UTF_8
67+
str.scrub
68+
else
69+
str.encode(Encoding::UTF_8, invalid: :replace, undef: :replace)
70+
end
71+
end
72+
end
73+
end
74+
end

lib/debug/server_cdp.rb

Lines changed: 14 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1113,46 +1113,25 @@ def process_cdp args
11131113
event! :protocol_result, :scope, req, vars
11141114
when :properties
11151115
oid = args.shift
1116-
result = []
1117-
prop = []
11181116

11191117
if obj = @obj_map[oid]
1120-
case obj
1121-
when Array
1122-
result = obj.map.with_index{|o, i|
1123-
variable i.to_s, o
1124-
}
1125-
when Hash
1126-
result = obj.map{|k, v|
1127-
variable(k, v)
1128-
}
1129-
when Struct
1130-
result = obj.members.map{|m|
1131-
variable(m, obj[m])
1132-
}
1133-
when String
1134-
prop = [
1135-
internalProperty('#length', obj.length),
1136-
internalProperty('#encoding', obj.encoding)
1137-
]
1138-
when Class, Module
1139-
result = obj.instance_variables.map{|iv|
1140-
variable(iv, obj.instance_variable_get(iv))
1141-
}
1142-
prop = [internalProperty('%ancestors', obj.ancestors[1..])]
1143-
when Range
1144-
prop = [
1145-
internalProperty('#begin', obj.begin),
1146-
internalProperty('#end', obj.end),
1147-
]
1118+
members = Mirrors::VariableInspector.new.named_members_of(obj)
1119+
1120+
result = members.filter_map do |member|
1121+
next if member.internal?
1122+
variable(member.name, member.value)
11481123
end
11491124

1150-
result += M_INSTANCE_VARIABLES.bind_call(obj).map{|iv|
1151-
variable(iv, M_INSTANCE_VARIABLE_GET.bind_call(obj, iv))
1152-
}
1153-
prop += [internalProperty('#class', M_CLASS.bind_call(obj))]
1125+
internal_properties = members.filter_map do |member|
1126+
next unless member.internal?
1127+
internalProperty(member.name, member.value)
1128+
end
1129+
else
1130+
result = []
1131+
internal_properties = []
11541132
end
1155-
event! :protocol_result, :properties, req, result: result, internalProperties: prop
1133+
1134+
event! :protocol_result, :properties, req, result: result, internalProperties: internal_properties
11561135
when :exception
11571136
oid = args.shift
11581137
exc = nil

lib/debug/server_dap.rb

Lines changed: 10 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -776,7 +776,7 @@ class ThreadClient
776776
MAX_LENGTH = 180
777777

778778
def value_inspect obj, short: true
779-
# TODO: max length should be configuarable?
779+
# TODO: max length should be configurable?
780780
str = DEBUGGER__.safe_inspect obj, short: short, max_length: MAX_LENGTH
781781

782782
if str.encoding == Encoding::UTF_8
@@ -875,48 +875,18 @@ def process_dap args
875875
vid = args.shift
876876
obj = @var_map[vid]
877877
if obj
878-
case req.dig('arguments', 'filter')
878+
members = case req.dig('arguments', 'filter')
879879
when 'indexed'
880-
start = req.dig('arguments', 'start') || 0
881-
count = req.dig('arguments', 'count') || obj.size
882-
vars = (start ... (start + count)).map{|i|
883-
variable(i.to_s, obj[i])
884-
}
880+
Mirrors::VariableInspector.new.indexed_members_of(
881+
obj,
882+
start: req.dig('arguments', 'start') || 0,
883+
count: req.dig('arguments', 'count') || obj.size,
884+
)
885885
else
886-
vars = []
887-
888-
case obj
889-
when Hash
890-
vars = obj.map{|k, v|
891-
variable(value_inspect(k), v,)
892-
}
893-
when Struct
894-
vars = obj.members.map{|m|
895-
variable(m, obj[m])
896-
}
897-
when String
898-
vars = [
899-
variable('#length', obj.length),
900-
variable('#encoding', obj.encoding),
901-
]
902-
printed_str = value_inspect(obj)
903-
vars << variable('#dump', NaiveString.new(obj)) if printed_str.end_with?('...')
904-
when Class, Module
905-
vars << variable('%ancestors', obj.ancestors[1..])
906-
when Range
907-
vars = [
908-
variable('#begin', obj.begin),
909-
variable('#end', obj.end),
910-
]
911-
end
912-
913-
unless NaiveString === obj
914-
vars += M_INSTANCE_VARIABLES.bind_call(obj).sort.map{|iv|
915-
variable(iv, M_INSTANCE_VARIABLE_GET.bind_call(obj, iv))
916-
}
917-
vars.unshift variable('#class', M_CLASS.bind_call(obj))
918-
end
886+
Mirrors::VariableInspector.new.named_members_of(obj)
919887
end
888+
889+
vars = members.map { |member| variable(member.name, member.value) }
920890
end
921891
event! :protocol_result, :variable, req, variables: (vars || []), tid: self.id
922892

0 commit comments

Comments
 (0)