1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

Support raise_errors keyword for Ripper.{lex,tokenize,sexp,sexp_raw}

Implements [Feature #17276]
This commit is contained in:
Jeremy Evans 2020-11-17 21:15:50 -08:00 committed by GitHub
parent a776032ef1
commit cd0877a93e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
Notes: git 2020-11-18 14:16:15 +09:00
Merged: https://github.com/ruby/ruby/pull/3774

Merged-By: jeremyevans <code@jeremyevans.net>
4 changed files with 53 additions and 8 deletions

View file

@ -18,8 +18,15 @@ class Ripper
# 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
# [[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

View file

@ -28,10 +28,16 @@ class Ripper
# [: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
# 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
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:

View file

@ -145,4 +145,9 @@ class TestRipper::Lexer < Test::Unit::TestCase
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

View file

@ -507,4 +507,9 @@ eot
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