diff --git a/lib/irb/nesting_parser.rb b/lib/irb/nesting_parser.rb index 23eeeaf6cf..5aa940cc28 100644 --- a/lib/irb/nesting_parser.rb +++ b/lib/irb/nesting_parser.rb @@ -12,6 +12,8 @@ module IRB skip = false last_tok, state, args = opens.last case state + when :in_alias_undef + skip = t.event == :on_kw when :in_unquoted_symbol unless IGNORE_TOKENS.include?(t.event) opens.pop @@ -130,6 +132,10 @@ module IRB opens.pop opens << [t, nil] end + when 'alias' + opens << [t, :in_alias_undef, 2] + when 'undef' + opens << [t, :in_alias_undef, 1] when 'elsif', 'else', 'when' opens.pop opens << [t, nil] @@ -174,6 +180,10 @@ module IRB pending_heredocs.reverse_each { |t| opens << [t, nil] } pending_heredocs = [] end + if opens.last && opens.last[1] == :in_alias_undef && !IGNORE_TOKENS.include?(t.event) && t.event != :on_heredoc_end + tok, state, arg = opens.pop + opens << [tok, state, arg - 1] if arg >= 1 + end yield t, opens if block_given? end opens.map(&:first) + pending_heredocs.reverse diff --git a/lib/irb/ruby-lex.rb b/lib/irb/ruby-lex.rb index 4bce2aa6b2..754acfad05 100644 --- a/lib/irb/ruby-lex.rb +++ b/lib/irb/ruby-lex.rb @@ -290,7 +290,7 @@ module IRB when :on_embdoc_beg indent_level = 0 else - indent_level += 1 + indent_level += 1 unless t.tok == 'alias' || t.tok == 'undef' end end indent_level diff --git a/test/irb/test_nesting_parser.rb b/test/irb/test_nesting_parser.rb index ea3a23aaf5..2482d40081 100644 --- a/test/irb/test_nesting_parser.rb +++ b/test/irb/test_nesting_parser.rb @@ -280,6 +280,44 @@ module TestIRB end end + def test_undef_alias + codes = [ + 'undef foo', + 'alias foo bar', + 'undef !', + 'alias + -', + 'alias $a $b', + 'undef do', + 'alias do do', + 'undef :do', + 'alias :do :do', + 'undef :"#{alias do do}"', + 'alias :"#{undef do}" do', + 'alias do :"#{undef do}"' + ] + code_with_comment = <<~EOS + undef # + # + do # + alias # + # + do # + # + do # + EOS + code_with_heredoc = <<~EOS + <<~A; alias + A + :"#{<<~A}" + A + do + EOS + [*codes, code_with_comment, code_with_heredoc].each do |code| + opens = IRB::NestingParser.open_tokens(IRB::RubyLex.ripper_lex_without_warning('(' + code + "\nif")) + assert_equal(%w[( if], opens.map(&:tok)) + end + end + def test_case_in if Gem::Version.new(RUBY_VERSION) < Gem::Version.new('2.7.0') pend 'This test requires ruby version that supports case-in syntax'