[前][次][番号順一覧][スレッド一覧]

ruby-changes:62340

From: aycabta <ko1@a...>
Date: Wed, 22 Jul 2020 02:42:15 +0900 (JST)
Subject: [ruby-changes:62340] 78ccab2530 (master): [ruby/irb] Suppress incomplete coding magic comment error

https://git.ruby-lang.org/ruby.git/commit/?id=78ccab2530

From 78ccab25306d15c325baa0761d9505ac23956f22 Mon Sep 17 00:00:00 2001
From: aycabta <aycabta@g...>
Date: Mon, 1 Jun 2020 08:53:07 +0900
Subject: [ruby/irb] Suppress incomplete coding magic comment error

https://github.com/ruby/irb/commit/6a457edbd1

diff --git a/lib/irb/color.rb b/lib/irb/color.rb
index d2b9674..d325c8d 100644
--- a/lib/irb/color.rb
+++ b/lib/irb/color.rb
@@ -155,27 +155,29 @@ module IRB # :nodoc: https://github.com/ruby/ruby/blob/trunk/lib/irb/color.rb#L155
         pos = [1, 0]
 
         verbose, $VERBOSE = $VERBOSE, nil
-        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
+        RubyLex.compile_with_errors_suppressed(code) do |inner_code|
+          lexer = Ripper::Lexer.new(inner_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
+                end
               end
-            end
 
-            yield(elem.event, str, elem.state)
-          end
-        else
-          lexer.parse.each do |elem|
-            yield(elem.event, elem.tok, 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
         $VERBOSE = verbose
diff --git a/lib/irb/ruby-lex.rb b/lib/irb/ruby-lex.rb
index 0c71d5e..5967cdb 100644
--- a/lib/irb/ruby-lex.rb
+++ b/lib/irb/ruby-lex.rb
@@ -30,6 +30,18 @@ class RubyLex https://github.com/ruby/ruby/blob/trunk/lib/irb/ruby-lex.rb#L30
     @prompt = nil
   end
 
+  def self.compile_with_errors_suppressed(code)
+    begin
+      result = yield code
+    rescue ArgumentError => e
+      if e.message.match?(/unknown encoding name/) && code.match?(/\A(?<shebang>#.*\n)?#\s*coding\s*:.*(?<nl>\n)?/)
+        code = code.gsub(/\A(?<shebang>#.*\n)?#\s*coding\s*:.*(?<nl>\n)?/, "\\k<shebang>#\\k<nl>")
+        retry
+      end
+    end
+    result
+  end
+
   # io functions
   def set_input(io, p = nil, &block)
     @io = io
@@ -76,7 +88,10 @@ class RubyLex https://github.com/ruby/ruby/blob/trunk/lib/irb/ruby-lex.rb#L88
 
   def ripper_lex_without_warning(code)
     verbose, $VERBOSE = $VERBOSE, nil
-    tokens = Ripper.lex(code)
+    tokens = nil
+    self.class.compile_with_errors_suppressed(code) do |inner_code|
+      tokens = Ripper.lex(inner_code)
+    end
     $VERBOSE = verbose
     tokens
   end
@@ -210,7 +225,9 @@ class RubyLex https://github.com/ruby/ruby/blob/trunk/lib/irb/ruby-lex.rb#L225
       when 'jruby'
         JRuby.compile_ir(code)
       else
-        RubyVM::InstructionSequence.compile(code)
+        self.class.compile_with_errors_suppressed(code) do |inner_code|
+          RubyVM::InstructionSequence.compile(inner_code)
+        end
       end
     rescue EncodingError
       # This is for a hash with invalid encoding symbol, {"\xAE": 1}
diff --git a/test/irb/test_ruby_lex.rb b/test/irb/test_ruby_lex.rb
index dd5a1f7..367d1e2 100644
--- a/test/irb/test_ruby_lex.rb
+++ b/test/irb/test_ruby_lex.rb
@@ -126,5 +126,18 @@ module TestIRB https://github.com/ruby/ruby/blob/trunk/test/irb/test_ruby_lex.rb#L126
         assert_indenting(lines, row.new_line_spaces, true)
       end
     end
+
+    def test_incomplete_coding_magic_comment
+      input_with_correct_indents = [
+        Row.new(%q(#coding:u), nil, 0),
+      ]
+
+      lines = []
+      input_with_correct_indents.each do |row|
+        lines << row.content
+        assert_indenting(lines, row.current_line_spaces, false)
+        assert_indenting(lines, row.new_line_spaces, true)
+      end
+    end
   end
 end
-- 
cgit v0.10.2


--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]