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:
parent
88411d350e
commit
1808029061
7 changed files with 93 additions and 49 deletions
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.")
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue