diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index b17f4434f..4ddb48ea7 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -11,7 +11,7 @@ jobs: uses: ruby/actions/.github/workflows/ruby_versions.yml@master with: engine: cruby-truffleruby - min_version: 2.6 + min_version: 2.7 irb: needs: ruby-versions @@ -48,7 +48,6 @@ jobs: ruby: ${{ fromJson(needs.ruby-versions.outputs.versions) }} with_latest_reline: [true, false] exclude: - - ruby: 2.6 - ruby: truffleruby - ruby: truffleruby-head fail-fast: false diff --git a/irb.gemspec b/irb.gemspec index 20c187f37..e62429ca7 100644 --- a/irb.gemspec +++ b/irb.gemspec @@ -39,7 +39,7 @@ Gem::Specification.new do |spec| spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) } spec.require_paths = ["lib"] - spec.required_ruby_version = Gem::Requirement.new(">= 2.6") + spec.required_ruby_version = Gem::Requirement.new(">= 2.7") spec.add_dependency "reline", ">= 0.3.0" end diff --git a/lib/irb.rb b/lib/irb.rb index f9f39a1de..13fbbbad2 100644 --- a/lib/irb.rb +++ b/lib/irb.rb @@ -560,7 +560,6 @@ def eval_input @scanner.each_top_level_statement do |line, line_no| signal_status(:IN_EVAL) do begin - line.untaint if RUBY_VERSION < '2.7' if IRB.conf[:MEASURE] && IRB.conf[:MEASURE_CALLBACKS].empty? IRB.set_measure_callback end diff --git a/lib/irb/cmd/nop.rb b/lib/irb/cmd/nop.rb index 2e112d170..fc6231f0a 100644 --- a/lib/irb/cmd/nop.rb +++ b/lib/irb/cmd/nop.rb @@ -30,20 +30,11 @@ def string_literal?(args) end end - if RUBY_VERSION >= "2.7.0" - def self.execute(conf, *opts, **kwargs, &block) - command = new(conf) - command.execute(*opts, **kwargs, &block) - rescue CommandArgumentError => e - puts e.message - end - else - def self.execute(conf, *opts, &block) - command = new(conf) - command.execute(*opts, &block) - rescue CommandArgumentError => e - puts e.message - end + def self.execute(conf, *opts, **kwargs, &block) + command = new(conf) + command.execute(*opts, **kwargs, &block) + rescue CommandArgumentError => e + puts e.message end def initialize(conf) diff --git a/lib/irb/cmd/show_source.rb b/lib/irb/cmd/show_source.rb index eb21533b5..f4925a831 100644 --- a/lib/irb/cmd/show_source.rb +++ b/lib/irb/cmd/show_source.rb @@ -27,7 +27,7 @@ def find_source(str, irb_context) when /\A[A-Z]\w*(::[A-Z]\w*)*\z/ # Const::Name eval(str, irb_context.workspace.binding) # trigger autoload base = irb_context.workspace.binding.receiver.yield_self { |r| r.is_a?(Module) ? r : Object } - file, line = base.const_source_location(str) if base.respond_to?(:const_source_location) # Ruby 2.7+ + file, line = base.const_source_location(str) when /\A(?[A-Z]\w*(::[A-Z]\w*)*)#(?[^ :.]+)\z/ # Class#method owner = eval(Regexp.last_match[:owner], irb_context.workspace.binding) method = Regexp.last_match[:method] diff --git a/lib/irb/color.rb b/lib/irb/color.rb index 52d624091..fa99ed6fd 100644 --- a/lib/irb/color.rb +++ b/lib/irb/color.rb @@ -197,15 +197,9 @@ def scan(code, allow_last_error:) end end - if lexer.respond_to?(:scan) # Ruby 2.7+ - lexer.scan.each do |elem| - next if allow_last_error and /meets end of file|unexpected end-of-input/ =~ elem.message - on_scan.call(elem) - end - else - lexer.parse.sort_by(&:pos).each do |elem| - on_scan.call(elem) - end + lexer.scan.each do |elem| + next if allow_last_error and /meets end of file|unexpected end-of-input/ =~ elem.message + on_scan.call(elem) end # yield uncolorable DATA section yield(nil, inner_code.byteslice(byte_pos...inner_code.bytesize), nil) if byte_pos < inner_code.bytesize diff --git a/lib/irb/completion.rb b/lib/irb/completion.rb index 6a7e04264..84f4c4e35 100644 --- a/lib/irb/completion.rb +++ b/lib/irb/completion.rb @@ -58,19 +58,11 @@ def defined? do BASIC_WORD_BREAK_CHARACTERS = " \t\n`><=;|&{(" - def self.absolute_path?(p) # TODO Remove this method after 2.6 EOL. - if File.respond_to?(:absolute_path?) - File.absolute_path?(p) - else - File.absolute_path(p) == p - end - end - GEM_PATHS = if defined?(Gem::Specification) Gem::Specification.latest_specs(true).map { |s| s.require_paths.map { |p| - if absolute_path?(p) + if File.absolute_path?(p) p else File.join(s.full_gem_path, p) diff --git a/lib/irb/ext/loader.rb b/lib/irb/ext/loader.rb index 0a599ee80..1ab8a4e32 100644 --- a/lib/irb/ext/loader.rb +++ b/lib/irb/ext/loader.rb @@ -24,31 +24,8 @@ def irb_load(fn, priv = nil) load_file(path, priv) end - if File.respond_to?(:absolute_path?) - def absolute_path?(path) - File.absolute_path?(path) - end - else - separator = - if File::ALT_SEPARATOR - "[#{Regexp.quote(File::SEPARATOR + File::ALT_SEPARATOR)}]" - else - File::SEPARATOR - end - ABSOLUTE_PATH_PATTERN = # :nodoc: - case Dir.pwd - when /\A\w:/, /\A#{separator}{2}/ - /\A(?:\w:|#{separator})#{separator}/ - else - /\A#{separator}/ - end - def absolute_path?(path) - ABSOLUTE_PATH_PATTERN =~ path - end - end - def search_file_from_ruby_path(fn) # :nodoc: - if absolute_path?(fn) + if File.absolute_path?(fn) return fn if File.exist?(fn) return nil end diff --git a/lib/irb/extend-command.rb b/lib/irb/extend-command.rb index 4018eb13a..8e985274b 100644 --- a/lib/irb/extend-command.rb +++ b/lib/irb/extend-command.rb @@ -256,13 +256,12 @@ def self.def_extend_command(cmd_name, cmd_class, load_file = nil, *aliases) end if load_file - kwargs = ", **kwargs" if RUBY_VERSION >= "2.7.0" line = __LINE__; eval %[ - def #{cmd_name}(*opts#{kwargs}, &b) + def #{cmd_name}(*opts, **kwargs, &b) Kernel.require_relative "#{load_file}" arity = ::IRB::ExtendCommand::#{cmd_class}.instance_method(:execute).arity args = (1..(arity < 0 ? ~arity : arity)).map {|i| "arg" + i.to_s } - args << "*opts#{kwargs}" if arity < 0 + args << "*opts, **kwargs" if arity < 0 args << "&block" args = args.join(", ") line = __LINE__; eval %[ @@ -273,7 +272,7 @@ def self.#{cmd_name}_(\#{args}) end end ], nil, __FILE__, line - __send__ :#{cmd_name}_, *opts#{kwargs}, &b + __send__ :#{cmd_name}_, *opts, **kwargs, &b end ], nil, __FILE__, line else diff --git a/lib/irb/inspector.rb b/lib/irb/inspector.rb index bdfa282f0..ee3b19efd 100644 --- a/lib/irb/inspector.rb +++ b/lib/irb/inspector.rb @@ -98,8 +98,7 @@ def inspect_value(v) puts "An error occurred when inspecting the object: #{e.inspect}" begin - # TODO: change this to bind_call when we drop support for Ruby 2.6 - puts "Result of Kernel#inspect: #{KERNEL_INSPECT.bind(v).call}" + puts "Result of Kernel#inspect: #{KERNEL_INSPECT.bind_call(v)}" '' rescue => e puts "An error occurred when running Kernel#inspect: #{e.inspect}" diff --git a/lib/irb/ruby-lex.rb b/lib/irb/ruby-lex.rb index 9e4a7b28f..a156f3707 100644 --- a/lib/irb/ruby-lex.rb +++ b/lib/irb/ruby-lex.rb @@ -148,19 +148,15 @@ def self.ripper_lex_without_warning(code, context: nil) compile_with_errors_suppressed(code, line_no: line_no) do |inner_code, line_no| lexer = Ripper::Lexer.new(inner_code, '-', line_no) - if lexer.respond_to?(:scan) # Ruby 2.7+ - lexer.scan.each_with_object([]) do |t, tokens| - next if t.pos.first == 0 - prev_tk = tokens.last - position_overlapped = prev_tk && t.pos[0] == prev_tk.pos[0] && t.pos[1] < prev_tk.pos[1] + prev_tk.tok.bytesize - if position_overlapped - tokens[-1] = t if ERROR_TOKENS.include?(prev_tk.event) && !ERROR_TOKENS.include?(t.event) - else - tokens << t - end + lexer.scan.each_with_object([]) do |t, tokens| + next if t.pos.first == 0 + prev_tk = tokens.last + position_overlapped = prev_tk && t.pos[0] == prev_tk.pos[0] && t.pos[1] < prev_tk.pos[1] + prev_tk.tok.bytesize + if position_overlapped + tokens[-1] = t if ERROR_TOKENS.include?(prev_tk.event) && !ERROR_TOKENS.include?(t.event) + else + tokens << t end - else - lexer.parse.reject { |it| it.pos.first == 0 }.sort_by(&:pos) end end ensure diff --git a/test/irb/test_cmd.rb b/test/irb/test_cmd.rb index ef864fb5c..66328b89b 100644 --- a/test/irb/test_cmd.rb +++ b/test/irb/test_cmd.rb @@ -855,9 +855,6 @@ def test_edit_with_non_existing_path end def test_edit_with_constant - # const_source_location is supported after Ruby 2.7 - omit if Gem::Version.new(RUBY_VERSION) < Gem::Version.new('2.7.0') - out, err = execute_lines( "edit IRB::Irb" ) diff --git a/test/irb/test_color.rb b/test/irb/test_color.rb index fbcb283a6..652396c89 100644 --- a/test/irb/test_color.rb +++ b/test/irb/test_color.rb @@ -109,14 +109,11 @@ def test_colorize_code "< "#{RED}<= 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", - "< "#{RED}< "#{MAGENTA}#{BOLD}4.5#{CLEAR}#{RED}#{REVERSE}.6#{CLEAR}", + "\e[0m\n" => "#{RED}#{REVERSE}^[#{CLEAR}[#{BLUE}#{BOLD}0#{CLEAR}#{RED}#{REVERSE}m#{CLEAR}\n", + "< "#{RED}<= Gem::Version.new('3.0.0') @@ -136,18 +133,9 @@ def test_colorize_code }) end else - if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('2.7.0') - tests.merge!({ - "[1]]]\u0013" => "[#{BLUE}#{BOLD}1#{CLEAR}]#{RED}#{REVERSE}]#{CLEAR}]^S", - "def req(true) end" => "#{GREEN}def#{CLEAR} #{BLUE}#{BOLD}req#{CLEAR}(#{RED}#{REVERSE}true#{CLEAR}) end", - }) - else - tests.merge!({ - "[1]]]\u0013" => "[#{BLUE}#{BOLD}1#{CLEAR}]]]^S", - "def req(true) end" => "#{GREEN}def#{CLEAR} #{BLUE}#{BOLD}req#{CLEAR}(#{CYAN}#{BOLD}true#{CLEAR}) end", - }) - end tests.merge!({ + "[1]]]\u0013" => "[#{BLUE}#{BOLD}1#{CLEAR}]#{RED}#{REVERSE}]#{CLEAR}]^S", + "def req(true) end" => "#{GREEN}def#{CLEAR} #{BLUE}#{BOLD}req#{CLEAR}(#{RED}#{REVERSE}true#{CLEAR}) end", "nil = 1" => "#{CYAN}#{BOLD}nil#{CLEAR} = #{BLUE}#{BOLD}1#{CLEAR}", "alias $x $1" => "#{GREEN}alias#{CLEAR} #{GREEN}#{BOLD}$x#{CLEAR} $1", "class bad; end" => "#{GREEN}class#{CLEAR} bad; #{GREEN}end#{CLEAR}", @@ -184,10 +172,6 @@ def test_colorize_code_with_local_variables end def test_colorize_code_complete_true - unless complete_option_supported? - pend '`complete: true` is the same as `complete: false` in Ruby 2.6-' - end - # `complete: true` behaviors. Warn end-of-file. { "'foo' + 'bar" => "#{RED}#{BOLD}'#{CLEAR}#{RED}foo#{CLEAR}#{RED}#{BOLD}'#{CLEAR} + #{RED}#{BOLD}'#{CLEAR}#{RED}#{REVERSE}bar#{CLEAR}", @@ -216,16 +200,6 @@ def test_colorize_code_complete_false assert_equal_with_term(code, code, complete: false, colorable: false) assert_equal_with_term(result, code, complete: false, tty: false, colorable: true) - - unless complete_option_supported? - assert_equal_with_term(result, code, complete: true) - - assert_equal_with_term(code, code, complete: true, tty: false) - - assert_equal_with_term(code, code, complete: true, colorable: false) - - assert_equal_with_term(result, code, complete: true, tty: false, colorable: true) - end end end @@ -251,11 +225,6 @@ def test_inspect_colorable private - # `complete: true` is the same as `complete: false` in Ruby 2.6- - def complete_option_supported? - Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('2.7.0') - end - def with_term(tty: true) stdout = $stdout io = StringIO.new diff --git a/test/irb/test_color_printer.rb b/test/irb/test_color_printer.rb index 41a7345bd..a717940d8 100644 --- a/test/irb/test_color_printer.rb +++ b/test/irb/test_color_printer.rb @@ -38,9 +38,6 @@ def teardown IRBTestColorPrinter = Struct.new(:a) def test_color_printer - unless ripper_lexer_scan_supported? - pend 'Ripper::Lexer#scan is supported in Ruby 2.7+' - end { 1 => "#{BLUE}#{BOLD}1#{CLEAR}\n", "a\nb" => %[#{RED}#{BOLD}"#{CLEAR}#{RED}a\\nb#{CLEAR}#{RED}#{BOLD}"#{CLEAR}\n], @@ -55,10 +52,6 @@ def test_color_printer private - def ripper_lexer_scan_supported? - Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('2.7.0') - end - def with_term stdout = $stdout io = StringIO.new diff --git a/test/irb/test_context.rb b/test/irb/test_context.rb index 783b19b97..c4ca56aba 100644 --- a/test/irb/test_context.rb +++ b/test/irb/test_context.rb @@ -185,7 +185,6 @@ def inspect end def test_object_inspection_prints_useful_info_when_kernel_inspect_also_errored - omit if RUBY_VERSION < '2.7' verbose, $VERBOSE = $VERBOSE, nil main = Object.new main.singleton_class.module_eval <<~RUBY diff --git a/test/irb/test_ruby_lex.rb b/test/irb/test_ruby_lex.rb index d9b1418cb..1657d0fc6 100644 --- a/test/irb/test_ruby_lex.rb +++ b/test/irb/test_ruby_lex.rb @@ -613,9 +613,6 @@ def test_oneliner_def_in_multiple_lines end def test_broken_heredoc - if Gem::Version.new(RUBY_VERSION) < Gem::Version.new('2.7.0') - pend 'This test needs Ripper::Lexer#scan to take broken tokens' - end input_with_correct_indents = [ Row.new(%q(def foo), nil, 2, 1), Row.new(%q( <<~Q), 2, 2, 1), @@ -721,10 +718,6 @@ def test_dyanmic_prompt_with_blank_line end def test_broken_percent_literal - if Gem::Version.new(RUBY_VERSION) < Gem::Version.new('2.7.0') - pend 'This test needs Ripper::Lexer#scan to take broken tokens' - end - tokens = RubyLex.ripper_lex_without_warning('%wwww') pos_to_index = {} tokens.each_with_index { |t, i| @@ -734,10 +727,6 @@ def test_broken_percent_literal end def test_broken_percent_literal_in_method - if Gem::Version.new(RUBY_VERSION) < Gem::Version.new('2.7.0') - pend 'This test needs Ripper::Lexer#scan to take broken tokens' - end - tokens = RubyLex.ripper_lex_without_warning(<<~EOC.chomp) def foo %wwww @@ -751,10 +740,6 @@ def foo end def test_unterminated_code - if Gem::Version.new(RUBY_VERSION) < Gem::Version.new('2.7.0') - pend 'This test needs Ripper::Lexer#scan to take broken tokens' - end - ['do', '<