From f5ca3ff4dbcf5c140a77d1de5ff3fe3eed2d558d Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Thu, 26 Nov 2020 20:14:34 +0900 Subject: [PATCH] Store all kinds of syntax errors [Bug #17345] --- ext/ripper/lib/ripper/lexer.rb | 4 +++- test/ripper/test_lexer.rb | 32 +++++++++++++++++++++++++++++--- 2 files changed, 32 insertions(+), 4 deletions(-) diff --git a/ext/ripper/lib/ripper/lexer.rb b/ext/ripper/lib/ripper/lexer.rb index 287bd4fdb6..9ada47927b 100644 --- a/ext/ripper/lib/ripper/lexer.rb +++ b/ext/ripper/lib/ripper/lexer.rb @@ -191,7 +191,9 @@ class Ripper def on_error(mesg) @errors.push Elem.new([lineno(), column()], __callee__, token(), state(), mesg) end - alias on_parse_error on_error + PARSER_EVENTS.grep(/_error\z/) do |e| + alias_method "on_#{e}", :on_error + end alias compile_error on_error (SCANNER_EVENTS.map {|event|:"on_#{event}"} - private_instance_methods(false)).each do |event| diff --git a/test/ripper/test_lexer.rb b/test/ripper/test_lexer.rb index 73941d162a..05a70d3449 100644 --- a/test/ripper/test_lexer.rb +++ b/test/ripper/test_lexer.rb @@ -146,15 +146,41 @@ class TestRipper::Lexer < Test::Unit::TestCase assert_equal [[1, 17], :on_embexpr_end, "}", state(:EXPR_ARG)], token end + BAD_CODE = { + parse_error: 'def req(true) end', + assign_error: 'begin; nil = 1; end', + alias_error: 'begin; alias $x $1; end', + class_name_error: 'class bad; end', + param_error: 'def req(@a) end', + } + def test_raise_errors_keyword - assert_raise(SyntaxError) { Ripper.tokenize('def req(true) end', raise_errors: true) } + all_assertions do |all| + BAD_CODE.each do |err, code| + all.for(err) do + assert_raise(SyntaxError) { Ripper.tokenize(code, raise_errors: true) } + end + end + end end def test_tokenize_with_syntax_error - assert_equal "end", Ripper.tokenize("def req(true) end").last + all_assertions do |all| + BAD_CODE.each do |err, code| + all.for(err) do + assert_equal "end", Ripper.tokenize(code).last + end + end + end end def test_lex_with_syntax_error - assert_equal [[1, 14], :on_kw, "end", state(:EXPR_END)], Ripper.lex("def req(true) end").last + all_assertions do |all| + BAD_CODE.each do |err, code| + all.for(err) do + assert_equal [[1, code.size-3], :on_kw, "end", state(:EXPR_END)], Ripper.lex(code).last + end + end + end end end