[前][次][番号順一覧][スレッド一覧]

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/

[前][次][番号順一覧][スレッド一覧]