debug 1.4.0 → 1.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -4,72 +4,125 @@ require_relative 'color'
4
4
 
5
5
  module DEBUGGER__
6
6
  class SourceRepository
7
- SrcInfo = Struct.new(:src, :colored)
7
+ include Color
8
8
 
9
- def initialize
10
- @files = {} # filename => SrcInfo
11
- end
9
+ if RubyVM.respond_to? :keep_script_lines
10
+ # Ruby 3.1 and later
11
+ RubyVM.keep_script_lines = true
12
+ require 'objspace'
12
13
 
13
- def add iseq, src
14
- if (path = iseq.absolute_path) && File.exist?(path)
15
- add_path path
16
- elsif src
17
- add_iseq iseq, src
14
+ def initialize
15
+ # cache
16
+ @cmap = ObjectSpace::WeakMap.new
17
+ @loaded_file_map = {} # path => nil
18
18
  end
19
- end
20
19
 
21
- def all_iseq iseq, rs = []
22
- rs << iseq
23
- iseq.each_child{|ci|
24
- all_iseq(ci, rs)
25
- }
26
- rs
27
- end
20
+ def add iseq, src
21
+ # do nothing
22
+ if (path = (iseq.absolute_path || iseq.path)) && File.exist?(path)
23
+ if @loaded_file_map.has_key? path
24
+ return path, true # reloaded
25
+ else
26
+ @loaded_file_map[path] = path
27
+ return path, false
28
+ end
29
+ end
30
+ end
31
+
32
+ def get iseq
33
+ return unless iseq
28
34
 
29
- private def add_iseq iseq, src
30
- line = iseq.first_line
31
- if line > 1
32
- src = ("\n" * (line - 1)) + src
35
+ if lines = iseq.script_lines&.map(&:chomp)
36
+ lines
37
+ else
38
+ if (path = (iseq.absolute_path || iseq.path)) && File.exist?(path)
39
+ File.readlines(path, chomp: true)
40
+ else
41
+ nil
42
+ end
43
+ end
33
44
  end
34
- si = SrcInfo.new(src.lines)
35
45
 
36
- all_iseq(iseq).each{|e|
37
- e.instance_variable_set(:@debugger_si, si)
38
- e.freeze
39
- }
40
- end
46
+ def get_colored iseq
47
+ if lines = @cmap[iseq]
48
+ lines
49
+ else
50
+ if src_lines = get(iseq)
51
+ @cmap[iseq] = colorize_code(src_lines.join("\n")).lines
52
+ else
53
+ nil
54
+ end
55
+ end
56
+ end
57
+ else
58
+ # ruby 3.0 or earlier
59
+ SrcInfo = Struct.new(:src, :colored)
41
60
 
42
- private def add_path path
43
- src = File.read(path)
44
- src = src.gsub("\r\n", "\n") # CRLF -> LF
45
- @files[path] = SrcInfo.new(src.lines)
46
- rescue SystemCallError
47
- end
61
+ def initialize
62
+ @files = {} # filename => SrcInfo
63
+ end
48
64
 
49
- private def get_si iseq
50
- return unless iseq
65
+ def add iseq, src
66
+ if (path = (iseq.absolute_path || iseq.path)) && File.exist?(path)
67
+ reloaded = @files.has_key? path
68
+ add_path path
69
+ return path, reloaded
70
+ elsif src
71
+ add_iseq iseq, src
72
+ end
51
73
 
52
- if iseq.instance_variable_defined?(:@debugger_si)
53
- iseq.instance_variable_get(:@debugger_si)
54
- elsif @files.has_key?(path = iseq.absolute_path)
55
- @files[path]
56
- elsif path
57
- add_path(path)
74
+ nil
58
75
  end
59
- end
60
76
 
61
- def get iseq
62
- if si = get_si(iseq)
63
- si.src
77
+ private def all_iseq iseq, rs = []
78
+ rs << iseq
79
+ iseq.each_child{|ci|
80
+ all_iseq(ci, rs)
81
+ }
82
+ rs
64
83
  end
65
- end
66
84
 
67
- include Color
85
+ private def add_iseq iseq, src
86
+ line = iseq.first_line
87
+ if line > 1
88
+ src = ("\n" * (line - 1)) + src
89
+ end
90
+ si = SrcInfo.new(src.lines)
91
+ all_iseq(iseq).each{|e|
92
+ e.instance_variable_set(:@debugger_si, si)
93
+ e.freeze
94
+ }
95
+ end
96
+
97
+ private def add_path path
98
+ src_lines = File.readlines(path, chomp: true)
99
+ @files[path] = SrcInfo.new(src_lines)
100
+ rescue SystemCallError
101
+ end
102
+
103
+ private def get_si iseq
104
+ return unless iseq
105
+
106
+ if iseq.instance_variable_defined?(:@debugger_si)
107
+ iseq.instance_variable_get(:@debugger_si)
108
+ elsif @files.has_key?(path = (iseq.absolute_path || iseq.path))
109
+ @files[path]
110
+ elsif path
111
+ add_path(path)
112
+ end
113
+ end
114
+
115
+ def get iseq
116
+ if si = get_si(iseq)
117
+ si.src
118
+ end
119
+ end
68
120
 
69
- def get_colored iseq
70
- if si = get_si(iseq)
71
- si.colored || begin
72
- si.colored = colorize_code(si.src.join).lines
121
+ def get_colored iseq
122
+ if si = get_si(iseq)
123
+ si.colored || begin
124
+ si.colored = colorize_code(si.src.join("\n")).lines
125
+ end
73
126
  end
74
127
  end
75
128
  end