prism
prism copied to clipboard
method_source not working with Prism due to different SyntaxError messages
Running https://github.com/banister/method_source 's test suite passes on ruby master but fails with RUBYOPT=--parser=prism bundle exec rake:
Failures:
1) MethodSource::CodeHelpers should not raise an error on broken lines: def\na\n(); end
Failure/Error: eval("BEGIN{throw :valid}\n#{str}")
SyntaxError:
(eval at /home/eregon/code/method_source/lib/method_source/code_helpers.rb:71):3: syntax errors found (SyntaxError)
1 | BEGIN{throw :valid}
> 2 | def
| ^ expected an `end` to close the `def` statement
| ^ expected a delimiter to close the parameters
> 3 |
| ^ unexpected end of file, assuming it is closing the parent top level context
| ^ unexpected end of file; expected a method name
# ./lib/method_source/code_helpers.rb:71:in 'Kernel#eval'
# ./lib/method_source/code_helpers.rb:71:in 'block in MethodSource::CodeHelpers#complete_expression?'
# ./lib/method_source/code_helpers.rb:70:in 'Kernel#catch'
# ./lib/method_source/code_helpers.rb:70:in 'MethodSource::CodeHelpers#complete_expression?'
# ./spec/method_source/code_helpers_spec.rb:22:in 'block (4 levels) in <top (required)>'
# ./spec/method_source/code_helpers_spec.rb:21:in 'Integer#upto'
# ./spec/method_source/code_helpers_spec.rb:21:in 'block (3 levels) in <top (required)>'
2) MethodSource::CodeHelpers should not raise an error on broken lines: p = <<FOO\nlots\nand\nlots of\nfoo\nFOO
Failure/Error: eval("BEGIN{throw :valid}\n#{str}")
SyntaxError:
(eval at /home/eregon/code/method_source/lib/method_source/code_helpers.rb:71):3: syntax error found (SyntaxError)
1 | BEGIN{throw :valid}
2 | p = <<FOO
> 3 |
| ^ could not find a terminator for the heredoc
# ./lib/method_source/code_helpers.rb:71:in 'Kernel#eval'
# ./lib/method_source/code_helpers.rb:71:in 'block in MethodSource::CodeHelpers#complete_expression?'
# ./lib/method_source/code_helpers.rb:70:in 'Kernel#catch'
# ./lib/method_source/code_helpers.rb:70:in 'MethodSource::CodeHelpers#complete_expression?'
# ./spec/method_source/code_helpers_spec.rb:22:in 'block (4 levels) in <top (required)>'
# ./spec/method_source/code_helpers_spec.rb:21:in 'Integer#upto'
# ./spec/method_source/code_helpers_spec.rb:21:in 'block (3 levels) in <top (required)>'
3) MethodSource::CodeHelpers should not raise an error on broken lines: [\n:lets,\n'list',\n[/nested/\n], things ]
Failure/Error: eval("BEGIN{throw :valid}\n#{str}")
SyntaxError:
(eval at /home/eregon/code/method_source/lib/method_source/code_helpers.rb:71):2: syntax error found (SyntaxError)
1 | BEGIN{throw :valid}
> 2 | [
| ^ expected a `]` to close the array
3 |
# ./lib/method_source/code_helpers.rb:71:in 'Kernel#eval'
# ./lib/method_source/code_helpers.rb:71:in 'block in MethodSource::CodeHelpers#complete_expression?'
# ./lib/method_source/code_helpers.rb:70:in 'Kernel#catch'
# ./lib/method_source/code_helpers.rb:70:in 'MethodSource::CodeHelpers#complete_expression?'
# ./spec/method_source/code_helpers_spec.rb:22:in 'block (4 levels) in <top (required)>'
# ./spec/method_source/code_helpers_spec.rb:21:in 'Integer#upto'
# ./spec/method_source/code_helpers_spec.rb:21:in 'block (3 levels) in <top (required)>'
4) MethodSource::CodeHelpers should not raise an error on broken lines: abc =~ /hello\n/
Failure/Error: eval("BEGIN{throw :valid}\n#{str}")
SyntaxError:
(eval at /home/eregon/code/method_source/lib/method_source/code_helpers.rb:71):2: syntax error found (SyntaxError)
1 | BEGIN{throw :valid}
> 2 | abc =~ /hello
| ^ expected a closing delimiter for the regular expression
3 |
# ./lib/method_source/code_helpers.rb:71:in 'Kernel#eval'
# ./lib/method_source/code_helpers.rb:71:in 'block in MethodSource::CodeHelpers#complete_expression?'
# ./lib/method_source/code_helpers.rb:70:in 'Kernel#catch'
# ./lib/method_source/code_helpers.rb:70:in 'MethodSource::CodeHelpers#complete_expression?'
# ./spec/method_source/code_helpers_spec.rb:22:in 'block (4 levels) in <top (required)>'
# ./spec/method_source/code_helpers_spec.rb:21:in 'Integer#upto'
# ./spec/method_source/code_helpers_spec.rb:21:in 'block (3 levels) in <top (required)>'
5) MethodSource::CodeHelpers should not raise an error on broken lines: issue = %W/\n343/
Failure/Error: eval("BEGIN{throw :valid}\n#{str}")
SyntaxError:
(eval at /home/eregon/code/method_source/lib/method_source/code_helpers.rb:71):2: syntax error found (SyntaxError)
1 | BEGIN{throw :valid}
> 2 | issue = %W/
| ^~~ expected a closing delimiter for the `%W` list
3 |
# ./lib/method_source/code_helpers.rb:71:in 'Kernel#eval'
# ./lib/method_source/code_helpers.rb:71:in 'block in MethodSource::CodeHelpers#complete_expression?'
# ./lib/method_source/code_helpers.rb:70:in 'Kernel#catch'
# ./lib/method_source/code_helpers.rb:70:in 'MethodSource::CodeHelpers#complete_expression?'
# ./spec/method_source/code_helpers_spec.rb:22:in 'block (4 levels) in <top (required)>'
# ./spec/method_source/code_helpers_spec.rb:21:in 'Integer#upto'
# ./spec/method_source/code_helpers_spec.rb:21:in 'block (3 levels) in <top (required)>'
6) MethodSource::CodeHelpers should not raise an error on broken lines: puts 1, 2,\n3
Failure/Error: eval("BEGIN{throw :valid}\n#{str}")
SyntaxError:
(eval at /home/eregon/code/method_source/lib/method_source/code_helpers.rb:71):2: syntax error found (SyntaxError)
1 | BEGIN{throw :valid}
> 2 | puts 1, 2,
| ^ expected an argument
3 |
# ./lib/method_source/code_helpers.rb:71:in 'Kernel#eval'
# ./lib/method_source/code_helpers.rb:71:in 'block in MethodSource::CodeHelpers#complete_expression?'
# ./lib/method_source/code_helpers.rb:70:in 'Kernel#catch'
# ./lib/method_source/code_helpers.rb:70:in 'MethodSource::CodeHelpers#complete_expression?'
# ./spec/method_source/code_helpers_spec.rb:22:in 'block (4 levels) in <top (required)>'
# ./spec/method_source/code_helpers_spec.rb:21:in 'Integer#upto'
# ./spec/method_source/code_helpers_spec.rb:21:in 'block (3 levels) in <top (required)>'
7) MethodSource Methods should return source for an *_evaled method
Failure/Error: raise SourceNotFoundError, "Could not parse source for #{name}: #{e.message}"
MethodSource::SourceNotFoundError:
Could not parse source for hello_name: (eval at /home/eregon/code/method_source/lib/method_source/code_helpers.rb:71):3: syntax errors found
1 | BEGIN{throw :valid}
2 | def hello_#{name}(*args)
> 3 |
| ^ expected an `end` to close the `def` statement
| ^ unexpected end of file, assuming it is closing the parent top level context
# ./lib/method_source.rb:29:in 'MethodSource.source_helper'
# ./lib/method_source.rb:115:in 'MethodSource::MethodExtensions#source'
# ./spec/method_source_spec.rb:75:in 'block (3 levels) in <top (required)>'
# ------------------
# --- Caused by: ---
# SyntaxError:
# (eval at /home/eregon/code/method_source/lib/method_source/code_helpers.rb:71):3: syntax errors found (SyntaxError)
# 1 | BEGIN{throw :valid}
# 2 | def hello_#{name}(*args)
# > 3 |
# | ^ expected an `end` to close the `def` statement
#
# | ^ unexpected end of file, assuming it is closing the parent top level context
# ./lib/method_source/code_helpers.rb:71:in 'Kernel#eval'
Finished in 0.00674 seconds (files took 0.04986 seconds to load)
36 examples, 7 failures
Failed examples:
rspec './spec/method_source/code_helpers_spec.rb[1:2]' # MethodSource::CodeHelpers should not raise an error on broken lines: def\na\n(); end
rspec './spec/method_source/code_helpers_spec.rb[1:3]' # MethodSource::CodeHelpers should not raise an error on broken lines: p = <<FOO\nlots\nand\nlots of\nfoo\nFOO
rspec './spec/method_source/code_helpers_spec.rb[1:4]' # MethodSource::CodeHelpers should not raise an error on broken lines: [\n:lets,\n'list',\n[/nested/\n], things ]
rspec './spec/method_source/code_helpers_spec.rb[1:5]' # MethodSource::CodeHelpers should not raise an error on broken lines: abc =~ /hello\n/
rspec './spec/method_source/code_helpers_spec.rb[1:6]' # MethodSource::CodeHelpers should not raise an error on broken lines: issue = %W/\n343/
rspec './spec/method_source/code_helpers_spec.rb[1:9]' # MethodSource::CodeHelpers should not raise an error on broken lines: puts 1, 2,\n3
rspec ./spec/method_source_spec.rb:74 # MethodSource Methods should return source for an *_evaled method
Because of https://github.com/banister/method_source/blob/06f21c66380c64ff05c8031c0208eef240da0e83/lib/method_source/code_helpers.rb#L125-L131
Is there a better way with Prism to find "subsets of SyntaxErrors that can be fixed by adding more input to the buffer" than matching messages (which seems very brittle)?
@kddnewton Any thoughts regarding that last sentence? IIRC IRB also wanted this predicate for syntax errors.
To answer your question — there is not currently a way. I think that discussion is still taking place here: https://bugs.ruby-lang.org/issues/20024.