dead_end 3.0.1 → 3.0.2

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: c232ccfce002bd3a79d6a5508ea46b27684a9a0ae2bb5d6f843d49e5ba59c0ac
4
- data.tar.gz: 745847314c5c3ff09cb85b525a5d583f89c1c597e1f5b785ed54e01299bb72c4
3
+ metadata.gz: 802262fe82f2dcb82c0ca5d908852141a6fb7fe533b597f80c4d65b2e7f8b7e6
4
+ data.tar.gz: 2087ff7725c10acc2eac1278dfe6d64c1e2161ee9d4fe97bb87b33aecc73d468
5
5
  SHA512:
6
- metadata.gz: c49f5b58a7a2f222606a01efc3256a2a0eceade66ff6e46f7c15172cf972a48aa4b6d55212eb714ad69dde1b6d80e91cf8589a9b7026ad2b3e9baafabb8c2e6c
7
- data.tar.gz: f70fc9947a92d8de2d8f05e08ab803a791c9fc396f03a0bed812b0a88bdb74af33658b23ebdf148adbc716cc41870bee8fabe57c3ae62bd6c9e9b063717f0bbc
6
+ metadata.gz: 25b2a17f9901cbdf5d8a7c3085a931b95f70eda6a51661664c5b859a3f06b21e9fe4aa926e1d93e54f04b05bd4b27e67bfaa6ef84d61fcd0eacbf9929882bc43
7
+ data.tar.gz: f9aeb83c9d39c05d03be3f0e84c4c2fc86246a61f6b77b6185f2f0a25ec91885ed3d727e7ecf41948a11b5efd3d0b51aef3824103f83800e23734675a33bbed2
data/CHANGELOG.md CHANGED
@@ -1,11 +1,17 @@
1
1
  ## HEAD (unreleased)
2
2
 
3
+ ## 3.0.2
4
+
5
+ - Fix windows filename detection (https://github.com/zombocom/dead_end/pull/114)
6
+ - Update links on readme and code of conduct (https://github.com/zombocom/dead_end/pull/107)
7
+
3
8
  ## 3.0.1
4
9
 
5
10
  - Fix CLI parsing when flags come before filename (https://github.com/zombocom/dead_end/pull/102)
6
11
 
7
12
  ## 3.0.0
8
13
 
14
+ - [Breaking] CLI now outputs to STDOUT instead of STDERR (https://github.com/zombocom/dead_end/pull/98)
9
15
  - [Breaking] Remove previously deprecated `require "dead_end/fyi"` interface (https://github.com/zombocom/dead_end/pull/94)
10
16
  - Fix double output bug (https://github.com/zombocom/dead_end/pull/99)
11
17
  - Fix bug causing poor results (fix #95, fix #88) (https://github.com/zombocom/dead_end/pull/96)
data/CODE_OF_CONDUCT.md CHANGED
@@ -68,7 +68,7 @@ members of the project's leadership.
68
68
  ## Attribution
69
69
 
70
70
  This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71
- available at [https://contributor-covenant.org/version/1/4][version]
71
+ available at [https://contributor-covenant.org/version/1/4/code-of-conduct/][version]
72
72
 
73
73
  [homepage]: https://contributor-covenant.org
74
- [version]: https://contributor-covenant.org/version/1/4/
74
+ [version]: https://contributor-covenant.org/version/1/4/code-of-conduct/
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- dead_end (3.0.1)
4
+ dead_end (3.0.2)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
data/README.md CHANGED
@@ -45,6 +45,13 @@ To get the CLI and manually search for syntax errors (but not automatically anno
45
45
 
46
46
  This gives you the CLI command `$ dead_end` for more info run `$ dead_end --help`.
47
47
 
48
+ ## Editor integration
49
+
50
+ An extension is available for VSCode:
51
+
52
+ - Extension: https://marketplace.visualstudio.com/items?itemName=Zombocom.dead-end-vscode
53
+ - GitHub: https://github.com/zombocom/dead_end-vscode
54
+
48
55
  ## What syntax errors does it handle?
49
56
 
50
57
  Dead end will fire against all syntax errors and can isolate any syntax error. In addition, dead_end attempts to produce human readable descriptions of what needs to be done to resolve the issue. For example:
@@ -195,7 +202,7 @@ $ qcachegrind tmp/last/profile.callgrind.out.<numbers>
195
202
 
196
203
  ## Contributing
197
204
 
198
- Bug reports and pull requests are welcome on GitHub at https://github.com/zombocom/dead_end. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/zombocom/dead_end/blob/master/CODE_OF_CONDUCT.md).
205
+ Bug reports and pull requests are welcome on GitHub at https://github.com/zombocom/dead_end. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/zombocom/dead_end/blob/main/CODE_OF_CONDUCT.md).
199
206
 
200
207
 
201
208
  ## License
@@ -204,4 +211,4 @@ The gem is available as open source under the terms of the [MIT License](https:/
204
211
 
205
212
  ## Code of Conduct
206
213
 
207
- Everyone interacting in the DeadEnd project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/zombocom/dead_end/blob/master/CODE_OF_CONDUCT.md).
214
+ Everyone interacting in the DeadEnd project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/zombocom/dead_end/blob/main/CODE_OF_CONDUCT.md).
@@ -85,8 +85,8 @@ module DeadEnd
85
85
  #
86
86
  class CleanDocument
87
87
  def initialize(source:)
88
- @source = clean_sweep(source: source)
89
- @document = CodeLine.from_source(@source)
88
+ lines = clean_sweep(source: source)
89
+ @document = CodeLine.from_source(lines.join, lines: lines)
90
90
  end
91
91
 
92
92
  # Call all of the document "cleaners"
@@ -161,7 +161,7 @@ module DeadEnd
161
161
  else
162
162
  line
163
163
  end
164
- end.join
164
+ end
165
165
  end
166
166
 
167
167
  # Smushes all heredoc lines into one line
@@ -54,6 +54,8 @@ module DeadEnd
54
54
  @code_lines = code_lines
55
55
  @frontier = InsertionSort.new
56
56
  @unvisited_lines = @code_lines.sort_by(&:indent_index)
57
+ @visited_lines = {}
58
+
57
59
  @has_run = false
58
60
  @check_next = true
59
61
  end
@@ -128,7 +130,13 @@ module DeadEnd
128
130
  end
129
131
 
130
132
  def register_indent_block(block)
131
- @unvisited_lines -= block.lines
133
+ block.lines.each do |line|
134
+ next if @visited_lines[line]
135
+ @visited_lines[line] = true
136
+
137
+ index = @unvisited_lines.bsearch_index { |l| line.indent_index <=> l.indent_index }
138
+ @unvisited_lines.delete_at(index)
139
+ end
132
140
  self
133
141
  end
134
142
 
@@ -26,9 +26,10 @@ module DeadEnd
26
26
 
27
27
  # Returns an array of CodeLine objects
28
28
  # from the source string
29
- def self.from_source(source)
30
- lex_array_for_line = LexAll.new(source: source).each_with_object(Hash.new { |h, k| h[k] = [] }) { |lex, hash| hash[lex.line] << lex }
31
- source.lines.map.with_index do |line, index|
29
+ def self.from_source(source, lines: nil)
30
+ lines ||= source.lines
31
+ lex_array_for_line = LexAll.new(source: source, source_lines: lines).each_with_object(Hash.new { |h, k| h[k] = [] }) { |lex, hash| hash[lex.line] << lex }
32
+ lines.map.with_index do |line, index|
32
33
  CodeLine.new(
33
34
  line: line,
34
35
  index: index,
@@ -42,28 +43,20 @@ module DeadEnd
42
43
  @lex = lex
43
44
  @line = line
44
45
  @index = index
45
- @original = line.freeze
46
+ @original = line
46
47
  @line_number = @index + 1
48
+ strip_line = line.dup
49
+ strip_line.lstrip!
47
50
 
48
- if line.strip.empty?
51
+ if strip_line.empty?
49
52
  @empty = true
50
53
  @indent = 0
51
54
  else
52
55
  @empty = false
53
- @indent = SpaceCount.indent(line)
56
+ @indent = line.length - strip_line.length
54
57
  end
55
58
 
56
- kw_count = 0
57
- end_count = 0
58
- @lex.each do |lex|
59
- kw_count += 1 if lex.is_kw?
60
- end_count += 1 if lex.is_end?
61
- end
62
-
63
- kw_count -= oneliner_method_count
64
-
65
- @is_kw = (kw_count - end_count) > 0
66
- @is_end = (end_count - kw_count) > 0
59
+ set_kw_end
67
60
  end
68
61
 
69
62
  # Used for stable sort via indentation level
@@ -179,8 +172,7 @@ module DeadEnd
179
172
  #
180
173
  # For some reason this introduces `on_ignore_newline` but with BEG type
181
174
  def ignore_newline_not_beg?
182
- lex_value = lex.detect { |l| l.type == :on_ignored_nl }
183
- !!(lex_value && !lex_value.expr_beg?)
175
+ @ignore_newline_not_beg
184
176
  end
185
177
 
186
178
  # Determines if the given line has a trailing slash
@@ -206,11 +198,22 @@ module DeadEnd
206
198
  #
207
199
  # ENDFN -> BEG (token = '=' ) -> END
208
200
  #
209
- private def oneliner_method_count
201
+ private def set_kw_end
210
202
  oneliner_count = 0
211
203
  in_oneliner_def = nil
212
204
 
205
+ kw_count = 0
206
+ end_count = 0
207
+
208
+ @ignore_newline_not_beg = false
213
209
  @lex.each do |lex|
210
+ kw_count += 1 if lex.is_kw?
211
+ end_count += 1 if lex.is_end?
212
+
213
+ if lex.type == :on_ignored_nl
214
+ @ignore_newline_not_beg = !lex.expr_beg?
215
+ end
216
+
214
217
  if in_oneliner_def.nil?
215
218
  in_oneliner_def = :ENDFN if lex.state.allbits?(Ripper::EXPR_ENDFN)
216
219
  elsif lex.state.allbits?(Ripper::EXPR_ENDFN)
@@ -227,7 +230,10 @@ module DeadEnd
227
230
  end
228
231
  end
229
232
 
230
- oneliner_count
233
+ kw_count -= oneliner_count
234
+
235
+ @is_kw = (kw_count - end_count) > 0
236
+ @is_end = (end_count - kw_count) > 0
231
237
  end
232
238
  end
233
239
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module DeadEnd
2
4
  # Ripper.lex is not guaranteed to lex the entire source document
3
5
  #
@@ -8,20 +10,22 @@ module DeadEnd
8
10
  class LexAll
9
11
  include Enumerable
10
12
 
11
- def initialize(source:)
12
- @lex = Ripper.lex(source)
13
- lineno = @lex.last.first.first + 1
14
- source_lines = source.lines
15
- last_lineno = source_lines.count
13
+ def initialize(source:, source_lines: nil)
14
+ @lex = Ripper::Lexer.new(source, "-", 1).parse.sort_by(&:pos)
15
+ lineno = @lex.last.pos.first + 1
16
+ source_lines ||= source.lines
17
+ last_lineno = source_lines.length
16
18
 
17
19
  until lineno >= last_lineno
18
20
  lines = source_lines[lineno..-1]
19
21
 
20
- @lex.concat(Ripper.lex(lines.join, "-", lineno + 1))
21
- lineno = @lex.last.first.first + 1
22
+ @lex.concat(
23
+ Ripper::Lexer.new(lines.join, "-", lineno + 1).parse.sort_by(&:pos)
24
+ )
25
+ lineno = @lex.last.pos.first + 1
22
26
  end
23
27
 
24
- @lex.map! { |(line, _), type, token, state| LexValue.new(line, type, token, state) }
28
+ @lex.map! { |elem| LexValue.new(elem.pos.first, elem.event, elem.tok, elem.state) }
25
29
  end
26
30
 
27
31
  def to_a
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module DeadEnd
2
4
  # Value object for accessing lex values
3
5
  #
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DeadEnd
4
+ # Converts a SyntaxError message to a path
5
+ #
6
+ # Handles the case where the filename has a colon in it
7
+ # such as on a windows file system: https://github.com/zombocom/dead_end/issues/111
8
+ #
9
+ # Example:
10
+ #
11
+ # message = "/tmp/scratch:2:in `require_relative': /private/tmp/bad.rb:1: syntax error, unexpected `end' (SyntaxError)"
12
+ # puts PathnameFromMessage.new(message).call.name
13
+ # # => "/tmp/scratch.rb"
14
+ #
15
+ class PathnameFromMessage
16
+ attr_reader :name
17
+
18
+ def initialize(message, io: $stderr)
19
+ @line = message.lines.first
20
+ @parts = @line.split(":")
21
+ @guess = []
22
+ @name = nil
23
+ @io = io
24
+ end
25
+
26
+ def call
27
+ until stop?
28
+ @guess << @parts.shift
29
+ @name = Pathname(@guess.join(":"))
30
+ end
31
+
32
+ if @parts.empty?
33
+ @io.puts "DeadEnd: could not find filename from #{@line.inspect}"
34
+ @name = nil
35
+ end
36
+
37
+ self
38
+ end
39
+
40
+ def stop?
41
+ return true if @parts.empty?
42
+ return false if @guess.empty?
43
+
44
+ @name&.exist?
45
+ end
46
+ end
47
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module DeadEnd
4
- VERSION = "3.0.1"
4
+ VERSION = "3.0.2"
5
5
  end
data/lib/dead_end.rb CHANGED
@@ -17,12 +17,14 @@ module DeadEnd
17
17
  TIMEOUT_DEFAULT = ENV.fetch("DEAD_END_TIMEOUT", 1).to_i
18
18
 
19
19
  def self.handle_error(e)
20
- filename = e.message.split(":").first
20
+ file = PathnameFromMessage.new(e.message).call.name
21
+ raise e unless file
22
+
21
23
  $stderr.sync = true
22
24
 
23
25
  call(
24
- source: Pathname(filename).read,
25
- filename: filename
26
+ source: file.read,
27
+ filename: file
26
28
  )
27
29
 
28
30
  raise e
@@ -139,21 +141,24 @@ module DeadEnd
139
141
  end
140
142
  end
141
143
 
142
- require_relative "dead_end/code_line"
143
- require_relative "dead_end/code_block"
144
+ # Integration
145
+ require_relative "dead_end/cli"
146
+ require_relative "dead_end/auto"
147
+
148
+ # Core logic
144
149
  require_relative "dead_end/code_search"
145
150
  require_relative "dead_end/code_frontier"
151
+ require_relative "dead_end/explain_syntax"
146
152
  require_relative "dead_end/clean_document"
147
153
 
154
+ # Helpers
148
155
  require_relative "dead_end/lex_all"
156
+ require_relative "dead_end/code_line"
157
+ require_relative "dead_end/code_block"
149
158
  require_relative "dead_end/block_expand"
159
+ require_relative "dead_end/ripper_errors"
150
160
  require_relative "dead_end/insertion_sort"
151
161
  require_relative "dead_end/around_block_scan"
152
- require_relative "dead_end/ripper_errors"
162
+ require_relative "dead_end/pathname_from_message"
153
163
  require_relative "dead_end/display_invalid_blocks"
154
164
  require_relative "dead_end/parse_blocks_from_indent_line"
155
-
156
- require_relative "dead_end/explain_syntax"
157
-
158
- require_relative "dead_end/auto"
159
- require_relative "dead_end/cli"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dead_end
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.0.1
4
+ version: 3.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - schneems
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-11-04 00:00:00.000000000 Z
11
+ date: 2021-11-12 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: When you get an "unexpected end" in your syntax this gem helps you find
14
14
  it
@@ -54,6 +54,7 @@ files:
54
54
  - lib/dead_end/lex_all.rb
55
55
  - lib/dead_end/lex_value.rb
56
56
  - lib/dead_end/parse_blocks_from_indent_line.rb
57
+ - lib/dead_end/pathname_from_message.rb
57
58
  - lib/dead_end/ripper_errors.rb
58
59
  - lib/dead_end/version.rb
59
60
  homepage: https://github.com/zombocom/dead_end.git