Skip to content

Commit 791ab77

Browse files
committed
More specific error messages
As mentioned in #8 (comment) there are two types of syntax errors that can be hit involving an end: - It's got and end but wasn't expecting one (unmatched end) - It needs an end but doesn't have one (missing end) To make this more clear, the output of SyntaxSearch now specializes for these two cases and gives a helpful output with more context.
1 parent 8e0e097 commit 791ab77

File tree

5 files changed

+47
-13
lines changed

5 files changed

+47
-13
lines changed

lib/syntax_search.rb

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ def self.handle_error(e, search_source_on_error: SEARCH_SOURCE_ON_ERROR_DEFAULT)
2323
self.call(
2424
source: Pathname(filename).read,
2525
filename: filename,
26-
terminal: true
26+
terminal: true,
2727
)
2828
end
2929

@@ -40,6 +40,7 @@ def self.call(source: , filename: , terminal: false, record_dir: nil)
4040
blocks: blocks,
4141
filename: filename,
4242
terminal: terminal,
43+
invalid_type: invalid_type(source),
4344
io: $stderr
4445
).call
4546
end
@@ -122,11 +123,30 @@ def self.valid?(source)
122123

123124
Parser::CurrentRuby.parse(source)
124125
true
125-
rescue Parser::SyntaxError
126+
rescue Parser::SyntaxError => e
127+
yield e if block_given?
126128
false
127129
ensure
128130
$stderr = stderr if stderr
129131
end
132+
133+
def self.invalid_type(source)
134+
message = nil
135+
self.valid?(source) do |error|
136+
message = error.message
137+
end
138+
139+
case message
140+
when nil
141+
:none
142+
when /token kEND/
143+
:unmatched_end
144+
when /token \$end/ #
145+
:missing_end
146+
else
147+
raise "Unexpected message #{message}"
148+
end
149+
end
130150
end
131151

132152
require_relative "syntax_search/code_line"

lib/syntax_search/display_invalid_blocks.rb

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ module SyntaxErrorSearch
55
class DisplayInvalidBlocks
66
attr_reader :filename
77

8-
def initialize(blocks:, io: $stderr, filename: nil, terminal: false)
8+
def initialize(blocks:, io: $stderr, filename: nil, terminal: false, invalid_type: :unmatched_end)
99
@terminal = terminal
1010
@filename = filename
1111
@io = io
@@ -16,6 +16,7 @@ def initialize(blocks:, io: $stderr, filename: nil, terminal: false)
1616
@digit_count = @code_lines.last&.line_number.to_s.length
1717

1818
@invalid_line_hash = @lines.each_with_object({}) {|line, h| h[line] = true }
19+
@invalid_type = invalid_type
1920
end
2021

2122
def call
@@ -33,15 +34,28 @@ def call
3334
end
3435

3536
private def found_invalid_blocks
36-
@io.puts <<~EOM
37+
case @invalid_type
38+
when :missing_end
39+
@io.puts <<~EOM
3740
38-
SyntaxErrorSearch: A syntax error was detected
41+
SyntaxSearch: Missing `end` detected
3942
40-
This code has an unmatched `end` this is caused by either
41-
missing a syntax keyword (`def`, `do`, etc.) or inclusion
42-
of an extra `end` line
43+
This code has a missing `end`. Ensure that all
44+
syntax keywords (`def`, `do`, etc.) have a matching `end`.
45+
46+
EOM
47+
when :unmatched_end
48+
@io.puts <<~EOM
49+
50+
SyntaxSearch: Unmatched `end` detected
51+
52+
This code has an unmatched `end`. Ensure that all `end` lines
53+
in your code have a matching syntax keyword (`def`, `do`, etc.)
54+
and that you don't have any extra `end` lines.
55+
56+
EOM
57+
end
4358

44-
EOM
4559
@io.puts("file: #{filename}") if filename
4660
@io.puts <<~EOM
4761
simplified:

spec/unit/display_invalid_blocks_spec.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ def hai
4242
)
4343
display.call
4444
expect(io.string).to include("❯ 2 def hello")
45-
expect(io.string).to include("A syntax error was detected")
45+
expect(io.string).to include("SyntaxSearch")
4646
end
4747

4848
it " wraps code with github style codeblocks" do

spec/unit/exe_spec.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ def exe(cmd)
2222
ruby_file = fixtures_dir.join("this_project_extra_def.rb.txt")
2323
out = exe("#{ruby_file} --no-terminal")
2424

25-
expect(out.strip).to include("A syntax error was detected")
25+
expect(out.strip).to include("Missing `end` detected")
2626
expect(out.strip).to include("❯ 36 def filename")
2727
end
2828

@@ -37,7 +37,7 @@ def exe(cmd)
3737

3838
out = exe("#{ruby_file} --record #{tmp_dir}")
3939

40-
expect(out.strip).to include("A syntax error was detected")
40+
expect(out.strip).to include("Unmatched `end` detected")
4141
expect(tmp_dir).to_not be_empty
4242
end
4343
end

spec/unit/syntax_search_spec.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ module SyntaxErrorSearch
3232

3333
out = `ruby -I#{lib_dir} -rsyntax_search/auto #{require_rb} 2>&1`
3434

35-
expect(out).to include("This code has an unmatched")
35+
expect(out).to include("Unmatched `end` detected")
3636
expect(out).to include("Run `$ syntax_search")
3737
expect($?.success?).to be_falsey
3838
end

0 commit comments

Comments
 (0)