dead_end 3.0.1 → 3.0.2

Sign up to get free protection for your applications and to get access to all the features.
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