error_highlight 0.3.0 → 0.5.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: 39dd627c1efbe9ac9572d6173babe5dd142d46c7f5e012dc86941216d2f82c29
4
- data.tar.gz: f1f74a8453bf72581f2153762094a439620d1abcbdca93e648bf14827f26728c
3
+ metadata.gz: eb083cc3162d22724aa838cfc6c8a6d3473436c9fa276d731c07a840bdab1466
4
+ data.tar.gz: 3fb0a3ac24c77556f3343a9da1f43de5fdbe4a6bdf70d96a468cbcae129f3a1a
5
5
  SHA512:
6
- metadata.gz: 11a923c3ffb586b7662af28d595e11d4b0a890d9f45a168e4442bdc77257ca230c0fca37cc905ed011b23b2ba934dcf7b4d14e02523999fa60f7056c5b7f1637
7
- data.tar.gz: 2268b2f56399e14923cee50f2a9625edfcc6db914d044a639ddc98066141266ab17774f1d5c95af55f8a1c05d4ea2e02804758cd219fc98b2a8df768c345b694
6
+ metadata.gz: 2d40e91d23f06e0f62db5c9945dc27c96590c0a36448e987e7d2c23b8b5947a978ba2f7918bc5d934342075d3926a525e64df159120c0c0026f19b8bc4203f4d
7
+ data.tar.gz: e7cb628e3cf5c60147a97ed96e02898ff9f444230aeed640c61c4998722e1cab6ea97149931340298ee525c72d5c2e663cc3f835fa116a9dbf22167ecad36e69
@@ -0,0 +1,6 @@
1
+ version: 2
2
+ updates:
3
+ - package-ecosystem: 'github-actions'
4
+ directory: '/'
5
+ schedule:
6
+ interval: 'weekly'
@@ -13,9 +13,9 @@ jobs:
13
13
  runs-on: ubuntu-latest
14
14
  strategy:
15
15
  matrix:
16
- ruby: [ 'ruby-head' ]
16
+ ruby: [ 'ruby-head', '3.1' ]
17
17
  steps:
18
- - uses: actions/checkout@v2
18
+ - uses: actions/checkout@v3
19
19
  - uses: ruby/setup-ruby@v1
20
20
  with:
21
21
  ruby-version: ${{ matrix.ruby }}
@@ -1,12 +1,17 @@
1
1
  require_relative "version"
2
2
 
3
3
  module ErrorHighlight
4
- # Identify the code fragment that seems associated with a given error
4
+ # Identify the code fragment at that a given exception occurred.
5
5
  #
6
- # Arguments:
7
- # node: RubyVM::AbstractSyntaxTree::Node (script_lines should be enabled)
8
- # point_type: :name | :args
9
- # name: The name associated with the NameError/NoMethodError
6
+ # Options:
7
+ #
8
+ # point_type: :name | :args
9
+ # :name (default) points the method/variable name that the exception occurred.
10
+ # :args points the arguments of the method call that the exception occurred.
11
+ #
12
+ # backtrace_location: Thread::Backtrace::Location
13
+ # It locates the code fragment of the given backtrace_location.
14
+ # By default, it uses the first frame of backtrace_locations of the given exception.
10
15
  #
11
16
  # Returns:
12
17
  # {
@@ -15,9 +20,56 @@ module ErrorHighlight
15
20
  # last_lineno: Integer,
16
21
  # last_column: Integer,
17
22
  # snippet: String,
23
+ # script_lines: [String],
18
24
  # } | nil
19
- def self.spot(...)
20
- Spotter.new(...).spot
25
+ #
26
+ # Limitations:
27
+ #
28
+ # Currently, ErrorHighlight.spot only supports a single-line code fragment.
29
+ # Therefore, if the return value is not nil, first_lineno and last_lineno will have
30
+ # the same value. If the relevant code fragment spans multiple lines
31
+ # (e.g., Array#[] of +ary[(newline)expr(newline)]+), the method will return nil.
32
+ # This restriction may be removed in the future.
33
+ def self.spot(obj, **opts)
34
+ case obj
35
+ when Exception
36
+ exc = obj
37
+ loc = opts[:backtrace_location]
38
+ opts = { point_type: opts.fetch(:point_type, :name) }
39
+
40
+ unless loc
41
+ case exc
42
+ when TypeError, ArgumentError
43
+ opts[:point_type] = :args
44
+ end
45
+
46
+ locs = exc.backtrace_locations
47
+ return nil unless locs
48
+
49
+ loc = locs.first
50
+ return nil unless loc
51
+
52
+ opts[:name] = exc.name if NameError === obj
53
+ end
54
+
55
+ return nil unless Thread::Backtrace::Location === loc
56
+
57
+ node = RubyVM::AbstractSyntaxTree.of(loc, keep_script_lines: true)
58
+
59
+ Spotter.new(node, **opts).spot
60
+
61
+ when RubyVM::AbstractSyntaxTree::Node
62
+ Spotter.new(obj, **opts).spot
63
+
64
+ else
65
+ raise TypeError, "Exception is expected"
66
+ end
67
+
68
+ rescue SyntaxError,
69
+ SystemCallError, # file not found or something
70
+ ArgumentError # eval'ed code
71
+
72
+ return nil
21
73
  end
22
74
 
23
75
  class Spotter
@@ -122,6 +174,7 @@ module ErrorHighlight
122
174
  last_lineno: @end_lineno,
123
175
  last_column: @end_column,
124
176
  snippet: @snippet,
177
+ script_lines: @node.script_lines,
125
178
  }
126
179
  else
127
180
  return nil
@@ -2,51 +2,41 @@ require_relative "formatter"
2
2
 
3
3
  module ErrorHighlight
4
4
  module CoreExt
5
- # This is a marker to let `DidYouMean::Correctable#original_message` skip
6
- # the following method definition of `to_s`.
7
- # See https://github.com/ruby/did_you_mean/pull/152
8
- SKIP_TO_S_FOR_SUPER_LOOKUP = true
9
- private_constant :SKIP_TO_S_FOR_SUPER_LOOKUP
10
-
11
- def to_s
12
- msg = super.dup
13
-
14
- locs = backtrace_locations
15
- return msg unless locs
16
-
17
- loc = locs.first
18
- begin
19
- node = RubyVM::AbstractSyntaxTree.of(loc, keep_script_lines: true)
20
- opts = {}
5
+ private def generate_snippet
6
+ spot = ErrorHighlight.spot(self)
7
+ return "" unless spot
8
+ return ErrorHighlight.formatter.message_for(spot)
9
+ end
21
10
 
22
- case self
23
- when NoMethodError, NameError
24
- opts[:point_type] = :name
25
- opts[:name] = name
26
- when TypeError, ArgumentError
27
- opts[:point_type] = :args
11
+ if Exception.method_defined?(:detailed_message)
12
+ def detailed_message(highlight: false, error_highlight: true, **)
13
+ return super unless error_highlight
14
+ snippet = generate_snippet
15
+ if highlight
16
+ snippet = snippet.gsub(/.+/) { "\e[1m" + $& + "\e[m" }
28
17
  end
29
-
30
- spot = ErrorHighlight.spot(node, **opts)
31
-
32
- rescue SyntaxError
33
- rescue SystemCallError # file not found or something
34
- rescue ArgumentError # eval'ed code
18
+ super + snippet
35
19
  end
36
-
37
- if spot
38
- points = ErrorHighlight.formatter.message_for(spot)
39
- msg << points if !msg.include?(points)
20
+ else
21
+ # This is a marker to let `DidYouMean::Correctable#original_message` skip
22
+ # the following method definition of `to_s`.
23
+ # See https://github.com/ruby/did_you_mean/pull/152
24
+ SKIP_TO_S_FOR_SUPER_LOOKUP = true
25
+ private_constant :SKIP_TO_S_FOR_SUPER_LOOKUP
26
+
27
+ def to_s
28
+ msg = super
29
+ snippet = generate_snippet
30
+ if snippet != "" && !msg.include?(snippet)
31
+ msg + snippet
32
+ else
33
+ msg
34
+ end
40
35
  end
41
-
42
- msg
43
36
  end
44
37
  end
45
38
 
46
39
  NameError.prepend(CoreExt)
47
-
48
- # The extension for TypeError/ArgumentError is temporarily disabled due to many test failures
49
-
50
- #TypeError.prepend(CoreExt)
51
- #ArgumentError.prepend(CoreExt)
40
+ TypeError.prepend(CoreExt)
41
+ ArgumentError.prepend(CoreExt)
52
42
  end
@@ -1,3 +1,3 @@
1
1
  module ErrorHighlight
2
- VERSION = "0.3.0"
2
+ VERSION = "0.5.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.3.0
4
+ version: 0.5.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-12-23 00:00:00.000000000 Z
11
+ date: 2022-11-08 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
@@ -18,6 +18,7 @@ executables: []
18
18
  extensions: []
19
19
  extra_rdoc_files: []
20
20
  files:
21
+ - ".github/dependabot.yml"
21
22
  - ".github/workflows/ruby.yml"
22
23
  - ".gitignore"
23
24
  - Gemfile
@@ -49,7 +50,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
49
50
  - !ruby/object:Gem::Version
50
51
  version: '0'
51
52
  requirements: []
52
- rubygems_version: 3.3.1
53
+ rubygems_version: 3.3.7
53
54
  signing_key:
54
55
  specification_version: 4
55
56
  summary: Shows a one-line code snippet with an underline in the error backtrace