debug 1.3.4 → 1.6.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -4,74 +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
- begin
44
- src = File.read(path)
45
- src = src.gsub("\r\n", "\n") # CRLF -> LF
46
- @files[path] = SrcInfo.new(src.lines)
47
- rescue SystemCallError
61
+ def initialize
62
+ @files = {} # filename => SrcInfo
48
63
  end
49
- end
50
64
 
51
- private def get_si iseq
52
- 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
73
+
74
+ nil
75
+ end
53
76
 
54
- if iseq.instance_variable_defined?(:@debugger_si)
55
- iseq.instance_variable_get(:@debugger_si)
56
- elsif @files.has_key?(path = iseq.absolute_path)
57
- @files[path]
58
- elsif path
59
- add_path(path)
77
+ private def all_iseq iseq, rs = []
78
+ rs << iseq
79
+ iseq.each_child{|ci|
80
+ all_iseq(ci, rs)
81
+ }
82
+ rs
60
83
  end
61
- end
62
84
 
63
- def get iseq
64
- if si = get_si(iseq)
65
- si.src
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
+ }
66
95
  end
67
- end
68
96
 
69
- include Color
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
70
120
 
71
- def get_colored iseq
72
- if si = get_si(iseq)
73
- si.colored || begin
74
- 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
75
126
  end
76
127
  end
77
128
  end