ruby-changes:63645
From: Jeremy <ko1@a...>
Date: Wed, 18 Nov 2020 14:16:13 +0900 (JST)
Subject: [ruby-changes:63645] cd0877a93e (master): Support raise_errors keyword for Ripper.{lex, tokenize, sexp, sexp_raw}
https://git.ruby-lang.org/ruby.git/commit/?id=cd0877a93e From cd0877a93e91fecb3066984b3fa2a762e6977caf Mon Sep 17 00:00:00 2001 From: Jeremy Evans <code@j...> Date: Tue, 17 Nov 2020 21:15:50 -0800 Subject: Support raise_errors keyword for Ripper.{lex,tokenize,sexp,sexp_raw} Implements [Feature #17276] diff --git a/ext/ripper/lib/ripper/lexer.rb b/ext/ripper/lib/ripper/lexer.rb index 9f613c3..e7a0787 100644 --- a/ext/ripper/lib/ripper/lexer.rb +++ b/ext/ripper/lib/ripper/lexer.rb @@ -18,8 +18,15 @@ class Ripper https://github.com/ruby/ruby/blob/trunk/ext/ripper/lib/ripper/lexer.rb#L18 # p Ripper.tokenize("def m(a) nil end") # # => ["def", " ", "m", "(", "a", ")", " ", "nil", " ", "end"] # - def Ripper.tokenize(src, filename = '-', lineno = 1) - Lexer.new(src, filename, lineno).tokenize + def Ripper.tokenize(src, filename = '-', lineno = 1, raise_errors: false) + r = Lexer.new(src, filename, lineno) + ret = r.tokenize + + if raise_errors && !r.errors.empty? + raise SyntaxError, r.errors.map(&:message).join(' ;') + end + + ret end # Tokenizes the Ruby program and returns an array of an array, @@ -41,8 +48,15 @@ class Ripper https://github.com/ruby/ruby/blob/trunk/ext/ripper/lib/ripper/lexer.rb#L48 # [[1, 12], :on_sp, " ", END ], # [[1, 13], :on_kw, "end", END ]] # - def Ripper.lex(src, filename = '-', lineno = 1) - Lexer.new(src, filename, lineno).lex + def Ripper.lex(src, filename = '-', lineno = 1, raise_errors: false) + r = Lexer.new(src, filename, lineno) + ret = r.lex + + if raise_errors && !r.errors.empty? + raise SyntaxError, r.errors.map(&:message).join(' ;') + end + + ret end class Lexer < ::Ripper #:nodoc: internal use only diff --git a/ext/ripper/lib/ripper/sexp.rb b/ext/ripper/lib/ripper/sexp.rb index e71d52c..27b86e4 100644 --- a/ext/ripper/lib/ripper/sexp.rb +++ b/ext/ripper/lib/ripper/sexp.rb @@ -28,10 +28,16 @@ class Ripper https://github.com/ruby/ruby/blob/trunk/ext/ripper/lib/ripper/sexp.rb#L28 # [:paren, [:params, [[:@ident, "a", [1, 6]]], nil, nil, nil, nil, nil, nil]], # [:bodystmt, [[:var_ref, [:@kw, "nil", [1, 9]]]], nil, nil, nil]]]] # - def Ripper.sexp(src, filename = '-', lineno = 1) + def Ripper.sexp(src, filename = '-', lineno = 1, raise_errors: false) builder = SexpBuilderPP.new(src, filename, lineno) sexp = builder.parse - sexp unless builder.error? + if builder.error? + if raise_errors + raise SyntaxError, builder.error + end + else + sexp + end end # [EXPERIMENTAL] @@ -54,13 +60,21 @@ class Ripper https://github.com/ruby/ruby/blob/trunk/ext/ripper/lib/ripper/sexp.rb#L60 # nil, # nil]]]] # - def Ripper.sexp_raw(src, filename = '-', lineno = 1) + def Ripper.sexp_raw(src, filename = '-', lineno = 1, raise_errors: false) builder = SexpBuilder.new(src, filename, lineno) sexp = builder.parse - sexp unless builder.error? + if builder.error? + if raise_errors + raise SyntaxError, builder.error + end + else + sexp + end end class SexpBuilder < ::Ripper #:nodoc: + attr_reader :error + private def dedent_element(e, width) @@ -107,6 +121,13 @@ class Ripper https://github.com/ruby/ruby/blob/trunk/ext/ripper/lib/ripper/sexp.rb#L121 end End end + + def on_error(mesg) + @error = mesg + end + remove_method :on_parse_error + alias on_parse_error on_error + alias compile_error on_error end class SexpBuilderPP < SexpBuilder #:nodoc: diff --git a/test/ripper/test_lexer.rb b/test/ripper/test_lexer.rb index 3fc4423..542db2f 100644 --- a/test/ripper/test_lexer.rb +++ b/test/ripper/test_lexer.rb @@ -145,4 +145,9 @@ class TestRipper::Lexer < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ripper/test_lexer.rb#L145 token = Ripper.lex("a( foo, bar: baz }").last assert_equal [[1, 17], :on_embexpr_end, "}", state(:EXPR_ARG)], token end + + def test_raise_errors_keyword + assert_raise(SyntaxError) { Ripper.tokenize('def req(true) end', raise_errors: true) } + assert_raise(SyntaxError) { Ripper.tokenize('def req(true) end', raise_errors: true) } + end end diff --git a/test/ripper/test_sexp.rb b/test/ripper/test_sexp.rb index 87b505a..22ee418 100644 --- a/test/ripper/test_sexp.rb +++ b/test/ripper/test_sexp.rb @@ -507,4 +507,9 @@ eot https://github.com/ruby/ruby/blob/trunk/test/ripper/test_sexp.rb#L507 assert_equal(:hshptn, hshptn[0]) assert_equal([:@label, "a:"], hshptn.dig(2, 0, 0)) end + + def test_raise_errors_keyword + assert_raise(SyntaxError) { Ripper.sexp('def req(true) end', raise_errors: true) } + assert_raise(SyntaxError) { Ripper.sexp_raw('def req(true) end', raise_errors: true) } + end end if ripper_test -- cgit v0.10.2 -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/