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 +4 -4
- data/CHANGELOG.md +6 -0
- data/CODE_OF_CONDUCT.md +2 -2
- data/Gemfile.lock +1 -1
- data/README.md +9 -2
- data/lib/dead_end/clean_document.rb +3 -3
- data/lib/dead_end/code_frontier.rb +9 -1
- data/lib/dead_end/code_line.rb +27 -21
- data/lib/dead_end/lex_all.rb +12 -8
- data/lib/dead_end/lex_value.rb +2 -0
- data/lib/dead_end/pathname_from_message.rb +47 -0
- data/lib/dead_end/version.rb +1 -1
- data/lib/dead_end.rb +16 -11
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 802262fe82f2dcb82c0ca5d908852141a6fb7fe533b597f80c4d65b2e7f8b7e6
|
4
|
+
data.tar.gz: 2087ff7725c10acc2eac1278dfe6d64c1e2161ee9d4fe97bb87b33aecc73d468
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
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/
|
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/
|
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
|
-
|
89
|
-
@document = CodeLine.from_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
|
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
|
-
|
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
|
|
data/lib/dead_end/code_line.rb
CHANGED
@@ -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
|
-
|
31
|
-
source
|
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
|
46
|
+
@original = line
|
46
47
|
@line_number = @index + 1
|
48
|
+
strip_line = line.dup
|
49
|
+
strip_line.lstrip!
|
47
50
|
|
48
|
-
if
|
51
|
+
if strip_line.empty?
|
49
52
|
@empty = true
|
50
53
|
@indent = 0
|
51
54
|
else
|
52
55
|
@empty = false
|
53
|
-
@indent =
|
56
|
+
@indent = line.length - strip_line.length
|
54
57
|
end
|
55
58
|
|
56
|
-
|
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
|
-
|
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
|
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
|
data/lib/dead_end/lex_all.rb
CHANGED
@@ -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.
|
13
|
-
lineno = @lex.last.
|
14
|
-
source_lines
|
15
|
-
last_lineno = source_lines.
|
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(
|
21
|
-
|
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! { |
|
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
|
data/lib/dead_end/lex_value.rb
CHANGED
@@ -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
|
data/lib/dead_end/version.rb
CHANGED
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
|
-
|
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:
|
25
|
-
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
|
-
|
143
|
-
require_relative "dead_end/
|
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/
|
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.
|
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-
|
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
|