error_highlight 0.2.0 → 0.3.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5eb06bb7a0af000c582a2ae98fb4401652556c10cd756a1cba8d68951c4b60b9
4
- data.tar.gz: 4fd7da0b60979f72f250c5044af20a8d7badd37776d2b6e7ba75b960f72e0a90
3
+ metadata.gz: 39dd627c1efbe9ac9572d6173babe5dd142d46c7f5e012dc86941216d2f82c29
4
+ data.tar.gz: f1f74a8453bf72581f2153762094a439620d1abcbdca93e648bf14827f26728c
5
5
  SHA512:
6
- metadata.gz: 475126fb1511ea9e9c25d966c778931c4d2b51ae91658703c0f7d625f536788afad4645b1ae4ddecafb5e9a7a4cb99ed84f88a04c58035e9e968db1c2e2ba715
7
- data.tar.gz: df639b399fbb96cb0afcb71f78263268558e689eb058f9a1da2f5a7ccb87e682697e1580eadc702c78c801380cf1e7823e0a668b19fd526a9314bc0975e14d9a
6
+ metadata.gz: 11a923c3ffb586b7662af28d595e11d4b0a890d9f45a168e4442bdc77257ca230c0fca37cc905ed011b23b2ba934dcf7b4d14e02523999fa60f7056c5b7f1637
7
+ data.tar.gz: 2268b2f56399e14923cee50f2a9625edfcc6db914d044a639ddc98066141266ab17774f1d5c95af55f8a1c05d4ea2e02804758cd219fc98b2a8df768c345b694
data/README.md CHANGED
@@ -29,7 +29,7 @@ def extract_value(data)
29
29
  end
30
30
  ```
31
31
 
32
- When `data` is `{ :results => [] }`, the following error messsage is shown:
32
+ When `data` is `{ :results => [] }`, the following error message is shown:
33
33
 
34
34
  ```
35
35
  $ ruby test.rb
@@ -55,13 +55,13 @@ test.rb:2:in `extract_value': undefined method `[]' for nil:NilClass (NoMethodEr
55
55
 
56
56
  *Note: This API is experimental, may change in future.*
57
57
 
58
- You can use the `ErrorHighlight.spot` method to get the spnippet data.
59
- Note that the argument must be a RubyVM::AbstractSyntaxTree::Node object that is created with `save_script_lines: true` option (which is available since Ruby 3.1).
58
+ You can use the `ErrorHighlight.spot` method to get the snippet data.
59
+ Note that the argument must be a RubyVM::AbstractSyntaxTree::Node object that is created with `keep_script_lines: true` option (which is available since Ruby 3.1).
60
60
 
61
61
  ```ruby
62
62
  class Dummy
63
63
  def test(_dummy_arg)
64
- node = RubyVM::AbstractSyntaxTree.of(caller_locations.first, save_script_lines: true)
64
+ node = RubyVM::AbstractSyntaxTree.of(caller_locations.first, keep_script_lines: true)
65
65
  ErrorHighlight.spot(node)
66
66
  end
67
67
  end
@@ -18,7 +18,7 @@ Gem::Specification.new do |spec|
18
18
  spec.homepage = "https://github.com/ruby/error_highlight"
19
19
 
20
20
  spec.license = "MIT"
21
- spec.required_ruby_version = Gem::Requirement.new(">= 3.1.0")
21
+ spec.required_ruby_version = Gem::Requirement.new(">= 3.1.0.dev")
22
22
 
23
23
  spec.files = Dir.chdir(File.expand_path(__dir__)) do
24
24
  `git ls-files -z`.split("\x0").reject { |f| f.match(%r{\A(?:test|spec|features)/}) }
@@ -21,6 +21,9 @@ module ErrorHighlight
21
21
  end
22
22
 
23
23
  class Spotter
24
+ class NonAscii < Exception; end
25
+ private_constant :NonAscii
26
+
24
27
  def initialize(node, point_type: :name, name: nil)
25
28
  @node = node
26
29
  @point_type = point_type
@@ -31,7 +34,15 @@ module ErrorHighlight
31
34
  @multiline = false # Allow multiline spot
32
35
 
33
36
  @fetch = -> (lineno, last_lineno = lineno) do
34
- @node.script_lines[lineno - 1 .. last_lineno - 1].join("")
37
+ snippet = @node.script_lines[lineno - 1 .. last_lineno - 1].join("")
38
+ snippet += "\n" unless snippet.end_with?("\n")
39
+
40
+ # It require some work to support Unicode (or multibyte) characters.
41
+ # Tentatively, we stop highlighting if the code snippet has non-ascii characters.
42
+ # See https://github.com/ruby/error_highlight/issues/4
43
+ raise NonAscii unless snippet.ascii_only?
44
+
45
+ snippet
35
46
  end
36
47
  end
37
48
 
@@ -115,6 +126,9 @@ module ErrorHighlight
115
126
  else
116
127
  return nil
117
128
  end
129
+
130
+ rescue NonAscii
131
+ nil
118
132
  end
119
133
 
120
134
  private
@@ -134,7 +148,7 @@ module ErrorHighlight
134
148
  nd_recv, mid, nd_args = @node.children
135
149
  lineno = nd_recv.last_lineno
136
150
  lines = @fetch[lineno, @node.last_lineno]
137
- if mid == :[] && lines.match(/\G\s*(\[(?:\s*\])?)/, nd_recv.last_column)
151
+ if mid == :[] && lines.match(/\G[\s)]*(\[(?:\s*\])?)/, nd_recv.last_column)
138
152
  @beg_column = $~.begin(1)
139
153
  @snippet = lines[/.*\n/]
140
154
  @beg_lineno = @end_lineno = lineno
@@ -143,11 +157,11 @@ module ErrorHighlight
143
157
  @end_column = $~.end(0)
144
158
  end
145
159
  else
146
- if lines.match(/\G\s*?\[\s*\]/, nd_recv.last_column)
160
+ if lines.match(/\G[\s)]*?\[\s*\]/, nd_recv.last_column)
147
161
  @end_column = $~.end(0)
148
162
  end
149
163
  end
150
- elsif lines.match(/\G\s*?(\&?\.)(\s*?)(#{ Regexp.quote(mid) }).*\n/, nd_recv.last_column)
164
+ elsif lines.match(/\G[\s)]*?(\&?\.)(\s*?)(#{ Regexp.quote(mid) }).*\n/, nd_recv.last_column)
151
165
  lines = $` + $&
152
166
  @beg_column = $~.begin($2.include?("\n") ? 3 : 1)
153
167
  @end_column = $~.end(3)
@@ -193,16 +207,16 @@ module ErrorHighlight
193
207
  nd_recv, mid, nd_args = @node.children
194
208
  *nd_args, _nd_last_arg, _nil = nd_args.children
195
209
  fetch_line(nd_recv.last_lineno)
196
- if mid == :[]= && @snippet.match(/\G\s*(\[)/, nd_recv.last_column)
210
+ if mid == :[]= && @snippet.match(/\G[\s)]*(\[)/, nd_recv.last_column)
197
211
  @beg_column = $~.begin(1)
198
212
  args_last_column = $~.end(0)
199
213
  if nd_args.last && nd_recv.last_lineno == nd_args.last.last_lineno
200
214
  args_last_column = nd_args.last.last_column
201
215
  end
202
- if @snippet.match(/\s*\]\s*=/, args_last_column)
216
+ if @snippet.match(/[\s)]*\]\s*=/, args_last_column)
203
217
  @end_column = $~.end(0)
204
218
  end
205
- elsif @snippet.match(/\G\s*(\.\s*#{ Regexp.quote(mid.to_s.sub(/=\z/, "")) }\s*=)/, nd_recv.last_column)
219
+ elsif @snippet.match(/\G[\s)]*(\.\s*#{ Regexp.quote(mid.to_s.sub(/=\z/, "")) }\s*=)/, nd_recv.last_column)
206
220
  @beg_column = $~.begin(1)
207
221
  @end_column = $~.end(1)
208
222
  end
@@ -218,7 +232,7 @@ module ErrorHighlight
218
232
  def spot_attrasgn_for_args
219
233
  nd_recv, mid, nd_args = @node.children
220
234
  fetch_line(nd_recv.last_lineno)
221
- if mid == :[]= && @snippet.match(/\G\s*\[/, nd_recv.last_column)
235
+ if mid == :[]= && @snippet.match(/\G[\s)]*\[/, nd_recv.last_column)
222
236
  @beg_column = $~.end(0)
223
237
  if nd_recv.last_lineno == nd_args.last_lineno
224
238
  @end_column = nd_args.last_column
@@ -240,7 +254,7 @@ module ErrorHighlight
240
254
  fetch_line(nd_recv.last_lineno)
241
255
  if nd_arg
242
256
  # binary operator
243
- if @snippet.match(/\G\s*(#{ Regexp.quote(op) })/, nd_recv.last_column)
257
+ if @snippet.match(/\G[\s)]*(#{ Regexp.quote(op) })/, nd_recv.last_column)
244
258
  @beg_column = $~.begin(1)
245
259
  @end_column = $~.end(1)
246
260
  end
@@ -316,7 +330,7 @@ module ErrorHighlight
316
330
  def spot_op_asgn1_for_name
317
331
  nd_recv, op, nd_args, _nd_rhs = @node.children
318
332
  fetch_line(nd_recv.last_lineno)
319
- if @snippet.match(/\G\s*(\[)/, nd_recv.last_column)
333
+ if @snippet.match(/\G[\s)]*(\[)/, nd_recv.last_column)
320
334
  bracket_beg_column = $~.begin(1)
321
335
  args_last_column = $~.end(0)
322
336
  if nd_args && nd_recv.last_lineno == nd_args.last_lineno
@@ -363,7 +377,7 @@ module ErrorHighlight
363
377
  def spot_op_asgn2_for_name
364
378
  nd_recv, _qcall, attr, op, _nd_rhs = @node.children
365
379
  fetch_line(nd_recv.last_lineno)
366
- if @snippet.match(/\G\s*(\.)\s*#{ Regexp.quote(attr) }()\s*(#{ Regexp.quote(op) })(=)/, nd_recv.last_column)
380
+ if @snippet.match(/\G[\s)]*(\.)\s*#{ Regexp.quote(attr) }()\s*(#{ Regexp.quote(op) })(=)/, nd_recv.last_column)
367
381
  case @name
368
382
  when attr
369
383
  @beg_column = $~.begin(1)
@@ -16,7 +16,7 @@ module ErrorHighlight
16
16
 
17
17
  loc = locs.first
18
18
  begin
19
- node = RubyVM::AbstractSyntaxTree.of(loc, save_script_lines: true)
19
+ node = RubyVM::AbstractSyntaxTree.of(loc, keep_script_lines: true)
20
20
  opts = {}
21
21
 
22
22
  case self
@@ -29,7 +29,9 @@ module ErrorHighlight
29
29
 
30
30
  spot = ErrorHighlight.spot(node, **opts)
31
31
 
32
- rescue Errno::ENOENT
32
+ rescue SyntaxError
33
+ rescue SystemCallError # file not found or something
34
+ rescue ArgumentError # eval'ed code
33
35
  end
34
36
 
35
37
  if spot
@@ -1,9 +1,10 @@
1
1
  module ErrorHighlight
2
2
  class DefaultFormatter
3
- def message_for(spot)
3
+ def self.message_for(spot)
4
4
  # currently only a one-line code snippet is supported
5
5
  if spot[:first_lineno] == spot[:last_lineno]
6
- marker = " " * spot[:first_column] + "^" * (spot[:last_column] - spot[:first_column])
6
+ indent = spot[:snippet][0...spot[:first_column]].gsub(/[^\t]/, " ")
7
+ marker = indent + "^" * (spot[:last_column] - spot[:first_column])
7
8
 
8
9
  "\n\n#{ spot[:snippet] }#{ marker }"
9
10
  else
@@ -13,12 +14,10 @@ module ErrorHighlight
13
14
  end
14
15
 
15
16
  def self.formatter
16
- @@formatter
17
+ Ractor.current[:__error_highlight_formatter__] || DefaultFormatter
17
18
  end
18
19
 
19
20
  def self.formatter=(formatter)
20
- @@formatter = formatter
21
+ Ractor.current[:__error_highlight_formatter__] = formatter
21
22
  end
22
-
23
- self.formatter = DefaultFormatter.new
24
23
  end
@@ -1,3 +1,3 @@
1
1
  module ErrorHighlight
2
- VERSION = "0.2.0"
2
+ VERSION = "0.3.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: error_highlight
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yusuke Endoh
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-06-30 00:00:00.000000000 Z
11
+ date: 2021-12-23 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: The gem enhances Exception#message by adding a short explanation where
14
14
  the exception is raised
@@ -42,14 +42,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
42
42
  requirements:
43
43
  - - ">="
44
44
  - !ruby/object:Gem::Version
45
- version: 3.1.0
45
+ version: 3.1.0.dev
46
46
  required_rubygems_version: !ruby/object:Gem::Requirement
47
47
  requirements:
48
48
  - - ">="
49
49
  - !ruby/object:Gem::Version
50
50
  version: '0'
51
51
  requirements: []
52
- rubygems_version: 3.2.15
52
+ rubygems_version: 3.3.1
53
53
  signing_key:
54
54
  specification_version: 4
55
55
  summary: Shows a one-line code snippet with an underline in the error backtrace