Skip to content

Commit

Permalink
More specific error messages
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
schneems committed Nov 12, 2020
1 parent 8e0e097 commit a0ea931
Show file tree
Hide file tree
Showing 6 changed files with 49 additions and 13 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
## HEAD (unreleased)

- "Unmatched end" and "missing end" not generate different error text instructions (https://github.com/zombocom/syntax_search/pull/10)

## 0.1.1

- Fire search on both unexpected end-of-input and unexected end (https://github.com/zombocom/syntax_search/pull/8)
Expand Down
24 changes: 22 additions & 2 deletions lib/syntax_search.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ def self.handle_error(e, search_source_on_error: SEARCH_SOURCE_ON_ERROR_DEFAULT)
self.call(
source: Pathname(filename).read,
filename: filename,
terminal: true
terminal: true,
)
end

Expand All @@ -40,6 +40,7 @@ def self.call(source: , filename: , terminal: false, record_dir: nil)
blocks: blocks,
filename: filename,
terminal: terminal,
invalid_type: invalid_type(source),
io: $stderr
).call
end
Expand Down Expand Up @@ -122,11 +123,30 @@ def self.valid?(source)

Parser::CurrentRuby.parse(source)
true
rescue Parser::SyntaxError
rescue Parser::SyntaxError => e
yield e if block_given?
false
ensure
$stderr = stderr if stderr
end

def self.invalid_type(source)
message = nil
self.valid?(source) do |error|
message = error.message
end

case message
when nil
:none
when /token kEND/
:unmatched_end
when /token \$end/ #
:missing_end
else
raise "Unexpected message #{message}"
end
end
end

require_relative "syntax_search/code_line"
Expand Down
28 changes: 21 additions & 7 deletions lib/syntax_search/display_invalid_blocks.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ module SyntaxErrorSearch
class DisplayInvalidBlocks
attr_reader :filename

def initialize(blocks:, io: $stderr, filename: nil, terminal: false)
def initialize(blocks:, io: $stderr, filename: nil, terminal: false, invalid_type: :unmatched_end)
@terminal = terminal
@filename = filename
@io = io
Expand All @@ -16,6 +16,7 @@ def initialize(blocks:, io: $stderr, filename: nil, terminal: false)
@digit_count = @code_lines.last&.line_number.to_s.length

@invalid_line_hash = @lines.each_with_object({}) {|line, h| h[line] = true }
@invalid_type = invalid_type
end

def call
Expand All @@ -33,15 +34,28 @@ def call
end

private def found_invalid_blocks
@io.puts <<~EOM
case @invalid_type
when :missing_end
@io.puts <<~EOM
SyntaxErrorSearch: A syntax error was detected
SyntaxSearch: Missing `end` detected
This code has an unmatched `end` this is caused by either
missing a syntax keyword (`def`, `do`, etc.) or inclusion
of an extra `end` line
This code has a missing `end`. Ensure that all
syntax keywords (`def`, `do`, etc.) have a matching `end`.
EOM
when :unmatched_end
@io.puts <<~EOM
SyntaxSearch: Unmatched `end` detected
This code has an unmatched `end`. Ensure that all `end` lines
in your code have a matching syntax keyword (`def`, `do`, etc.)
and that you don't have any extra `end` lines.
EOM
end

EOM
@io.puts("file: #{filename}") if filename
@io.puts <<~EOM
simplified:
Expand Down
2 changes: 1 addition & 1 deletion spec/unit/display_invalid_blocks_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ def hai
)
display.call
expect(io.string).to include("❯ 2 def hello")
expect(io.string).to include("A syntax error was detected")
expect(io.string).to include("SyntaxSearch")
end

it " wraps code with github style codeblocks" do
Expand Down
4 changes: 2 additions & 2 deletions spec/unit/exe_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ def exe(cmd)
ruby_file = fixtures_dir.join("this_project_extra_def.rb.txt")
out = exe("#{ruby_file} --no-terminal")

expect(out.strip).to include("A syntax error was detected")
expect(out.strip).to include("Missing `end` detected")
expect(out.strip).to include("❯ 36 def filename")
end

Expand All @@ -37,7 +37,7 @@ def exe(cmd)

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

expect(out.strip).to include("A syntax error was detected")
expect(out.strip).to include("Unmatched `end` detected")
expect(tmp_dir).to_not be_empty
end
end
Expand Down
2 changes: 1 addition & 1 deletion spec/unit/syntax_search_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ module SyntaxErrorSearch

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

expect(out).to include("This code has an unmatched")
expect(out).to include("Unmatched `end` detected")
expect(out).to include("Run `$ syntax_search")
expect($?.success?).to be_falsey
end
Expand Down

0 comments on commit a0ea931

Please sign in to comment.