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

make sync-default-gems GEM=irb

Upgrade IRB to 41ea43a4a7

Mostly backport changes.
This commit is contained in:
Takashi Kokubun 2019-06-13 00:29:45 +09:00
parent 88411d350e
commit 1808029061
No known key found for this signature in database
GPG key ID: 6FFC433B12EE23DD
7 changed files with 93 additions and 49 deletions

View file

@ -67,7 +67,7 @@ module IRB # :nodoc:
class << self
def colorable?
$stdout.tty? && (/mswin|mingw/ =~ RUBY_PLATFORM || (ENV.key?('TERM') && ENV['TERM'] != 'dumb'))
$stdout.tty? && supported? && (/mswin|mingw/ =~ RUBY_PLATFORM || (ENV.key?('TERM') && ENV['TERM'] != 'dumb'))
end
def inspect_colorable?(obj)
@ -132,24 +132,37 @@ module IRB # :nodoc:
private
# Ripper::Lexer::Elem#state is supported on Ruby 2.5+
def supported?
return @supported if defined?(@supported)
@supported = Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('2.5.0')
end
def scan(code, allow_last_error:)
pos = [1, 0]
Ripper::Lexer.new(code).scan.each do |elem|
str = elem.tok
next if allow_last_error and /meets end of file|unexpected end-of-input/ =~ elem.message
next if ([elem.pos[0], elem.pos[1] + str.bytesize] <=> pos) <= 0
lexer = Ripper::Lexer.new(code)
if lexer.respond_to?(:scan) # Ruby 2.7+
lexer.scan.each do |elem|
str = elem.tok
next if allow_last_error and /meets end of file|unexpected end-of-input/ =~ elem.message
next if ([elem.pos[0], elem.pos[1] + str.bytesize] <=> pos) <= 0
str.each_line do |line|
if line.end_with?("\n")
pos[0] += 1
pos[1] = 0
else
pos[1] += line.bytesize
str.each_line do |line|
if line.end_with?("\n")
pos[0] += 1
pos[1] = 0
else
pos[1] += line.bytesize
end
end
end
yield(elem.event, str, elem.state)
yield(elem.event, str, elem.state)
end
else
lexer.parse.each do |elem|
yield(elem.event, elem.tok, elem.state)
end
end
end

View file

@ -21,6 +21,7 @@ Gem::Specification.new do |spec|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
spec.require_paths = ["lib"]
spec.add_dependency "reline"
spec.add_development_dependency "bundler"
spec.add_development_dependency "rake"
end

View file

@ -127,7 +127,6 @@ class RubyLex
end
def process_continue
continued_bits = Ripper::EXPR_BEG | Ripper::EXPR_FNAME
# last token is always newline
if @tokens.size >= 2 and @tokens[-2][1] == :on_regexp_end
# end of regexp literal
@ -149,7 +148,7 @@ class RubyLex
return true
elsif @tokens.size >= 1 and @tokens[-1][1] == :on_heredoc_end # "EOH\n"
return false
elsif @tokens.size >= 2 and @tokens[-2][3].anybits?(continued_bits)
elsif @tokens.size >= 2 and defined?(Ripper::EXPR_BEG) and @tokens[-2][3].anybits?(Ripper::EXPR_BEG | Ripper::EXPR_FNAME)
# end of literal except for regexp
return true
end
@ -221,19 +220,21 @@ class RubyLex
$VERBOSE = verbose
end
last_lex_state = @tokens.last[3]
if last_lex_state.allbits?(Ripper::EXPR_BEG)
return false
elsif last_lex_state.allbits?(Ripper::EXPR_DOT)
return true
elsif last_lex_state.allbits?(Ripper::EXPR_CLASS)
return true
elsif last_lex_state.allbits?(Ripper::EXPR_FNAME)
return true
elsif last_lex_state.allbits?(Ripper::EXPR_VALUE)
return true
elsif last_lex_state.allbits?(Ripper::EXPR_ARG)
return false
if defined?(Ripper::EXPR_BEG)
last_lex_state = @tokens.last[3]
if last_lex_state.allbits?(Ripper::EXPR_BEG)
return false
elsif last_lex_state.allbits?(Ripper::EXPR_DOT)
return true
elsif last_lex_state.allbits?(Ripper::EXPR_CLASS)
return true
elsif last_lex_state.allbits?(Ripper::EXPR_FNAME)
return true
elsif last_lex_state.allbits?(Ripper::EXPR_VALUE)
return true
elsif last_lex_state.allbits?(Ripper::EXPR_ARG)
return false
end
end
false

View file

@ -18,13 +18,8 @@ module TestIRB
CYAN = "\e[36m"
def test_colorize_code
if Gem::Version.new(RUBY_VERSION) < Gem::Version.new('2.5.0')
assert_equal({}, IRB::Color::TOKEN_SEQ_EXPRS)
skip "this Ripper version is not supported"
end
# Common behaviors. Warn parser error, but do not warn compile error.
{
tests = {
"1" => "#{BLUE}#{BOLD}1#{CLEAR}",
"2.3" => "#{MAGENTA}#{BOLD}2.3#{CLEAR}",
"7r" => "#{BLUE}#{BOLD}7r#{CLEAR}",
@ -39,22 +34,17 @@ module TestIRB
'"foo#{a} #{b}"' => "#{RED}\"#{CLEAR}#{RED}foo#{CLEAR}#{RED}\#{#{CLEAR}a#{RED}}#{CLEAR}#{RED} #{CLEAR}#{RED}\#{#{CLEAR}b#{RED}}#{CLEAR}#{RED}\"#{CLEAR}",
'/r#{e}g/' => "#{RED}#{BOLD}/#{CLEAR}#{RED}r#{CLEAR}#{RED}\#{#{CLEAR}e#{RED}}#{CLEAR}#{RED}g#{CLEAR}#{RED}#{BOLD}/#{CLEAR}",
"'a\nb'" => "#{RED}'#{CLEAR}#{RED}a#{CLEAR}\n#{RED}b#{CLEAR}#{RED}'#{CLEAR}",
"4.5.6" => "#{MAGENTA}#{BOLD}4.5#{CLEAR}#{RED}#{REVERSE}.6#{CLEAR}",
"[1]]]\u0013" => "[1]]]^S",
"\e[0m\n" => "#{RED}#{REVERSE}^[#{CLEAR}[#{BLUE}#{BOLD}0#{CLEAR}#{RED}#{REVERSE}m#{CLEAR}\n",
"%w[a b]" => "#{RED}%w[#{CLEAR}#{RED}a#{CLEAR} #{RED}b#{CLEAR}#{RED}]#{CLEAR}",
"%i[c d]" => "#{RED}%i[#{CLEAR}#{RED}c#{CLEAR} #{RED}d#{CLEAR}#{RED}]#{CLEAR}",
"{'a': 1}" => "{#{RED}'#{CLEAR}#{RED}a#{CLEAR}#{RED}':#{CLEAR} #{BLUE}#{BOLD}1#{CLEAR}}",
":Struct" => "#{YELLOW}:#{CLEAR}#{YELLOW}Struct#{CLEAR}",
"<<EOS\nhere\nEOS" => "#{RED}<<EOS#{CLEAR}\n#{RED}here#{CLEAR}\n#{RED}EOS#{CLEAR}",
'"#{}"' => "#{RED}\"#{CLEAR}#{RED}\#{#{CLEAR}#{RED}}#{CLEAR}#{RED}\"#{CLEAR}",
':"a#{}b"' => "#{YELLOW}:\"#{CLEAR}#{YELLOW}a#{CLEAR}#{YELLOW}\#{#{CLEAR}#{YELLOW}}#{CLEAR}#{YELLOW}b#{CLEAR}#{YELLOW}\"#{CLEAR}",
':"a#{ def b; end; \'c\' + "#{ :d }" }e"' => "#{YELLOW}:\"#{CLEAR}#{YELLOW}a#{CLEAR}#{YELLOW}\#{#{CLEAR} #{GREEN}def#{CLEAR} #{BLUE}#{BOLD}b#{CLEAR}; #{GREEN}end#{CLEAR}; #{RED}'#{CLEAR}#{RED}c#{CLEAR}#{RED}'#{CLEAR} + #{RED}\"#{CLEAR}#{RED}\#{#{CLEAR} #{YELLOW}:#{CLEAR}#{YELLOW}d#{CLEAR} #{RED}}#{CLEAR}#{RED}\"#{CLEAR} #{YELLOW}}#{CLEAR}#{YELLOW}e#{CLEAR}#{YELLOW}\"#{CLEAR}",
"[__FILE__, __LINE__]" => "[#{CYAN}#{BOLD}__FILE__#{CLEAR}, #{CYAN}#{BOLD}__LINE__#{CLEAR}]",
":self" => "#{YELLOW}:#{CLEAR}#{YELLOW}self#{CLEAR}",
":class" => "#{YELLOW}:#{CLEAR}#{YELLOW}class#{CLEAR}",
":@1" => "#{YELLOW}:#{CLEAR}#{RED}#{REVERSE}@1#{CLEAR}",
"@@1" => "#{RED}#{REVERSE}@@1#{CLEAR}",
"[:end, 2]" => "[#{YELLOW}:#{CLEAR}#{YELLOW}end#{CLEAR}, #{BLUE}#{BOLD}2#{CLEAR}]",
"[:>, 3]" => "[#{YELLOW}:#{CLEAR}#{YELLOW}>#{CLEAR}, #{BLUE}#{BOLD}3#{CLEAR}]",
":Hello ? world : nil" => "#{YELLOW}:#{CLEAR}#{YELLOW}Hello#{CLEAR} ? world : #{CYAN}#{BOLD}nil#{CLEAR}",
@ -69,16 +59,37 @@ module TestIRB
"\t" => "\t", # not ^I
"foo(*%W(bar))" => "foo(*#{RED}%W(#{CLEAR}#{RED}bar#{CLEAR}#{RED})#{CLEAR})",
"$stdout" => "#{GREEN}#{BOLD}$stdout#{CLEAR}",
}.each do |code, result|
actual = with_term { IRB::Color.colorize_code(code, complete: true) }
assert_equal(result, actual, "Case: colorize_code(#{code.dump}, complete: true)\nResult: #{humanized_literal(actual)}")
}
actual = with_term { IRB::Color.colorize_code(code, complete: false) }
assert_equal(result, actual, "Case: colorize_code(#{code.dump}, complete: false)\nResult: #{humanized_literal(actual)}")
if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('2.7.0')
tests.merge!({
"4.5.6" => "#{MAGENTA}#{BOLD}4.5#{CLEAR}#{RED}#{REVERSE}.6#{CLEAR}",
"\e[0m\n" => "#{RED}#{REVERSE}^[#{CLEAR}[#{BLUE}#{BOLD}0#{CLEAR}#{RED}#{REVERSE}m#{CLEAR}\n",
"<<EOS\nhere\nEOS" => "#{RED}<<EOS#{CLEAR}\n#{RED}here#{CLEAR}\n#{RED}EOS#{CLEAR}",
":@1" => "#{YELLOW}:#{CLEAR}#{RED}#{REVERSE}@1#{CLEAR}",
"@@1" => "#{RED}#{REVERSE}@@1#{CLEAR}",
})
end
tests.each do |code, result|
if Gem::Version.new(RUBY_VERSION) < Gem::Version.new('2.5.0')
# colorize_code is supported only for Ruby 2.5+. Just return the original code in 2.4-.
actual = with_term { IRB::Color.colorize_code(code) }
assert_equal(code, actual)
else
actual = with_term { IRB::Color.colorize_code(code, complete: true) }
assert_equal(result, actual, "Case: colorize_code(#{code.dump}, complete: true)\nResult: #{humanized_literal(actual)}")
actual = with_term { IRB::Color.colorize_code(code, complete: false) }
assert_equal(result, actual, "Case: colorize_code(#{code.dump}, complete: false)\nResult: #{humanized_literal(actual)}")
end
end
end
def test_colorize_code_complete_true
unless lexer_scan_supported?
skip '`complete: true` is the same as `complete: false` in Ruby 2.6-'
end
# `complete: true` behaviors. Warn end-of-file.
{
"'foo' + 'bar" => "#{RED}'#{CLEAR}#{RED}foo#{CLEAR}#{RED}'#{CLEAR} + #{RED}'#{CLEAR}#{RED}#{REVERSE}bar#{CLEAR}",
@ -95,8 +106,19 @@ module TestIRB
"'foo' + 'bar" => "#{RED}'#{CLEAR}#{RED}foo#{CLEAR}#{RED}'#{CLEAR} + #{RED}'#{CLEAR}#{RED}bar#{CLEAR}",
"('foo" => "(#{RED}'#{CLEAR}#{RED}foo#{CLEAR}",
}.each do |code, result|
actual = with_term { IRB::Color.colorize_code(code, complete: false) }
assert_equal(result, actual, "Case: colorize_code(#{code.dump}, complete: false)\nResult: #{humanized_literal(actual)}")
if Gem::Version.new(RUBY_VERSION) < Gem::Version.new('2.5.0')
# colorize_code is supported only for Ruby 2.5+. Just return the original code in 2.4-.
actual = with_term { IRB::Color.colorize_code(code) }
assert_equal(code, actual)
else
actual = with_term { IRB::Color.colorize_code(code, complete: false) }
assert_equal(result, actual, "Case: colorize_code(#{code.dump}, complete: false)\nResult: #{humanized_literal(actual)}")
unless lexer_scan_supported?
actual = with_term { IRB::Color.colorize_code(code, complete: true) }
assert_equal(result, actual, "Case: colorize_code(#{code.dump}, complete: false)\nResult: #{humanized_literal(actual)}")
end
end
end
end
@ -120,6 +142,10 @@ module TestIRB
private
def lexer_scan_supported?
Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('2.7.0')
end
def with_term
stdout = $stdout
io = StringIO.new

View file

@ -7,7 +7,8 @@ module TestIRB
begin
require "irb/completion"
bug5938 = '[ruby-core:42244]'
cmds = %W[-W0 -rirb -rirb/completion -e IRB.setup(__FILE__)
bundle_exec = ENV.key?('BUNDLE_GEMFILE') ? ['-rbundler/setup'] : []
cmds = bundle_exec + %W[-W0 -rirb -rirb/completion -e IRB.setup(__FILE__)
-e IRB.conf[:MAIN_CONTEXT]=IRB::Irb.new.context
-e module\sFoo;def\sself.name;//;end;end
-e IRB::InputCompletor::CompletionProc.call("[1].first.")

View file

@ -5,7 +5,8 @@ module TestIRB
class TestOption < Test::Unit::TestCase
def test_end_of_option
bug4117 = '[ruby-core:33574]'
status = assert_in_out_err(%w[-W0 -rirb -e IRB.start(__FILE__) -- -f --], "", //, [], bug4117)
bundle_exec = ENV.key?('BUNDLE_GEMFILE') ? ['-rbundler/setup'] : []
status = assert_in_out_err(bundle_exec + %w[-W0 -rirb -e IRB.start(__FILE__) -- -f --], "", //, [], bug4117)
assert(status.success?, bug4117)
end
end

View file

@ -4,7 +4,8 @@ require 'test/unit'
module TestIRB
class TestRaiseNoBacktraceException < Test::Unit::TestCase
def test_raise_exception
assert_in_out_err(%w[-rirb -W0 -e IRB.start(__FILE__) -- -f --], <<-IRB, /Exception: foo/, [])
bundle_exec = ENV.key?('BUNDLE_GEMFILE') ? ['-rbundler/setup'] : []
assert_in_out_err(bundle_exec + %w[-rirb -W0 -e IRB.start(__FILE__) -- -f --], <<-IRB, /Exception: foo/, [])
e = Exception.new("foo")
def e.backtrace; nil; end
raise e