ruby/lib/syntax_suggest/display_invalid_blocks.rb
schneems f64ba0fadd
[ruby/syntax_suggest] Do not output "Syntax OK" when there's an error
Due to a problem with ripper we do not recognize `break` as invalid code. It's confusing that "Syntax OK" is output in that case.

When there's no syntax error, the algorithm should not say anything. The exception is in the CLI and that's for compatibility with `ruby -wc`

```
$ cat /tmp/break.rb
break
️ 3.1.2 🚀 /Users/rschneeman/Documents/projects/syntax_suggest (schneems/no-syntax-not-okay-break)
$ ruby -wc /tmp/break.rb
Syntax OK
```

> Note that this is invalid, running this code will raise a Syntax error.

```
$ exe/syntax_suggest /tmp/break.rb
Syntax OK
```

Close https://github.com/ruby/syntax_suggest/pull/157

d7bd8f03a2
2022-11-28 20:55:41 +09:00

83 lines
1.8 KiB
Ruby

# frozen_string_literal: true
require_relative "capture_code_context"
require_relative "display_code_with_line_numbers"
module SyntaxSuggest
# Used for formatting invalid blocks
class DisplayInvalidBlocks
attr_reader :filename
def initialize(code_lines:, blocks:, io: $stderr, filename: nil, terminal: DEFAULT_VALUE)
@io = io
@blocks = Array(blocks)
@filename = filename
@code_lines = code_lines
@terminal = terminal == DEFAULT_VALUE ? io.isatty : terminal
end
def document_ok?
@blocks.none? { |b| !b.hidden? }
end
def call
if document_ok?
return self
end
if filename
@io.puts("--> #{filename}")
@io.puts
end
@blocks.each do |block|
display_block(block)
end
self
end
private def display_block(block)
# Build explanation
explain = ExplainSyntax.new(
code_lines: block.lines
).call
# Enhance code output
# Also handles several ambiguious cases
lines = CaptureCodeContext.new(
blocks: block,
code_lines: @code_lines
).call
# Build code output
document = DisplayCodeWithLineNumbers.new(
lines: lines,
terminal: @terminal,
highlight_lines: block.lines
).call
# Output syntax error explanation
explain.errors.each do |e|
@io.puts e
end
@io.puts
# Output code
@io.puts(document)
end
private def code_with_context
lines = CaptureCodeContext.new(
blocks: @blocks,
code_lines: @code_lines
).call
DisplayCodeWithLineNumbers.new(
lines: lines,
terminal: @terminal,
highlight_lines: @invalid_lines
).call
end
end
end