Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

method_source not working with Prism due to different SyntaxError messages #2734

Open
eregon opened this issue Apr 25, 2024 · 1 comment
Open
Labels
bug Something isn't working

Comments

@eregon
Copy link
Member

eregon commented Apr 25, 2024

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)?

@eregon
Copy link
Member Author

eregon commented May 24, 2024

@kddnewton Any thoughts regarding that last sentence? IIRC IRB also wanted this predicate for syntax errors.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants