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

ruby-changes:41326

From: nobu <ko1@a...>
Date: Fri, 1 Jan 2016 05:06:31 +0900 (JST)
Subject: [ruby-changes:41326] nobu:r53398 (trunk): parse.y: single-quote indented heredoc

nobu	2016-01-01 05:06:22 +0900 (Fri, 01 Jan 2016)

  New Revision: 53398

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=53398

  Log:
    parse.y: single-quote indented heredoc
    
    * parse.y (parser_here_document): update indent for each line in
      indented here document with single-quotes.
      [ruby-core:72479] [Bug #11871]

  Modified files:
    trunk/ChangeLog
    trunk/parse.y
    trunk/test/ruby/test_syntax.rb
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 53397)
+++ ChangeLog	(revision 53398)
@@ -1,3 +1,9 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
+Fri Jan  1 05:06:20 2016  Nobuyoshi Nakada  <nobu@r...>
+
+	* parse.y (parser_here_document): update indent for each line in
+	  indented here document with single-quotes.
+	  [ruby-core:72479] [Bug #11871]
+
 Fri Jan  1 03:26:44 2016  Nobuyoshi Nakada  <nobu@r...>
 
 	* lib/ostruct.rb (freeze): define deferred accessors before
Index: parse.y
===================================================================
--- parse.y	(revision 53397)
+++ parse.y	(revision 53398)
@@ -6215,6 +6215,32 @@ simple_re_meta(int c) https://github.com/ruby/ruby/blob/trunk/parse.y#L6215
 }
 
 static int
+parser_update_heredoc_indent(struct parser_params *parser, int c)
+{
+    if (heredoc_line_indent == -1) {
+	if (c == '\n') heredoc_line_indent = 0;
+    }
+    else {
+	if (c == ' ') {
+	    heredoc_line_indent++;
+	    return TRUE;
+	}
+	else if (c == '\t') {
+	    int w = (heredoc_line_indent / TAB_WIDTH) + 1;
+	    heredoc_line_indent = w * TAB_WIDTH;
+	    return TRUE;
+	}
+	else if (c != '\n') {
+	    if (heredoc_indent > heredoc_line_indent) {
+		heredoc_indent = heredoc_line_indent;
+	    }
+	    heredoc_line_indent = -1;
+	}
+    }
+    return FALSE;
+}
+
+static int
 parser_tokadd_string(struct parser_params *parser,
 		     int func, int term, int paren, long *nest,
 		     rb_encoding **encp)
@@ -6244,24 +6270,7 @@ parser_tokadd_string(struct parser_param https://github.com/ruby/ruby/blob/trunk/parse.y#L6270
 
     while ((c = nextc()) != -1) {
 	if (heredoc_indent > 0) {
-	    if (heredoc_line_indent == -1) {
-		if (c == '\n') heredoc_line_indent = 0;
-	    }
-	    else {
-		if (c == ' ') {
-		    heredoc_line_indent++;
-		}
-		else if (c == '\t') {
-		    int w = (heredoc_line_indent / TAB_WIDTH) + 1;
-		    heredoc_line_indent = w * TAB_WIDTH;
-		}
-		else if (c != '\n') {
-		    if (heredoc_indent > heredoc_line_indent) {
-			heredoc_indent = heredoc_line_indent;
-		    }
-		    heredoc_line_indent = -1;
-		}
-	    }
+	    parser_update_heredoc_indent(parser, c);
 	}
 
 	if (paren && c == paren) {
@@ -6881,6 +6890,14 @@ parser_here_document(struct parser_param https://github.com/ruby/ruby/blob/trunk/parse.y#L6890
 		    --pend;
 		}
 	    }
+
+	    if (heredoc_indent > 0) {
+		long i = 0;
+		while (p + i < pend && parser_update_heredoc_indent(parser, p[i]))
+		    i++;
+		heredoc_line_indent = 0;
+	    }
+
 	    if (str)
 		rb_str_cat(str, p, pend - p);
 	    else
Index: test/ruby/test_syntax.rb
===================================================================
--- test/ruby/test_syntax.rb	(revision 53397)
+++ test/ruby/test_syntax.rb	(revision 53398)
@@ -492,92 +492,92 @@ e" https://github.com/ruby/ruby/blob/trunk/test/ruby/test_syntax.rb#L492
     assert_equal(expected, actual, "#{Bug7559}: ")
   end
 
+  def assert_dedented_heredoc(expect, result, mesg = "")
+    %w[eos "eos" 'eos'].each do |eos|
+      assert_equal(eval("<<-#{eos}\n#{expect}eos\n"),
+                   eval("<<~#{eos}\n#{result}eos\n"),
+                   message(mesg) {"with #{eos}"})
+    end
+  end
+
   def test_dedented_heredoc_without_indentation
-    assert_equal(" y\nz\n", <<~eos)
- y
-z
-    eos
+    result = " y\n" \
+             "z\n"
+    expect = result
+    assert_dedented_heredoc(expect, result)
   end
 
   def test_dedented_heredoc_with_indentation
-    assert_equal(" a\nb\n", <<~eos)
-     a
-    b
-    eos
+    result = "     a\n" \
+             "    b\n"
+    expect = " a\n" \
+             "b\n"
+    assert_dedented_heredoc(expect, result)
   end
 
   def test_dedented_heredoc_with_blank_less_indented_line
     # the blank line has two leading spaces
-    result = eval("<<~eos\n" \
-                  "    a\n" \
-                  "  \n" \
-                  "    b\n" \
-                  "    eos\n")
-    assert_equal("a\n\nb\n", result)
+    result = "    a\n" \
+             "  \n" \
+             "    b\n"
+    expect = "a\n" \
+             "\n" \
+             "b\n"
+    assert_dedented_heredoc(expect, result)
   end
 
   def test_dedented_heredoc_with_blank_less_indented_line_escaped
-    result = eval("<<~eos\n" \
-                  "    a\n" \
-                  "\\ \\ \n" \
-                  "    b\n" \
-                  "    eos\n")
-    assert_equal("    a\n  \n    b\n", result)
+    result = "    a\n" \
+             "\\ \\ \n" \
+             "    b\n"
+    expect = result
+    assert_dedented_heredoc(expect, result)
   end
 
   def test_dedented_heredoc_with_blank_more_indented_line
     # the blank line has six leading spaces
-    result = eval("<<~eos\n" \
-                  "    a\n" \
-                  "      \n" \
-                  "    b\n" \
-                  "    eos\n")
-    assert_equal("a\n  \nb\n", result)
+    result = "    a\n" \
+             "      \n" \
+             "    b\n"
+    expect = "a\n" \
+             "  \n" \
+             "b\n"
+    assert_dedented_heredoc(expect, result)
   end
 
   def test_dedented_heredoc_with_blank_more_indented_line_escaped
-    result = eval("<<~eos\n" \
-                  "    a\n" \
-                  "\\ \\ \\ \\ \\ \\ \n" \
-                  "    b\n" \
-                  "    eos\n")
-    assert_equal("    a\n      \n    b\n", result)
+    result = "    a\n" \
+             "\\ \\ \\ \\ \\ \\ \n" \
+             "    b\n"
+    expect = result
+    assert_dedented_heredoc(expect, result)
   end
 
   def test_dedented_heredoc_with_empty_line
-result = eval("<<~eos\n" \
-              "      This would contain specially formatted text.\n" \
-              "\n" \
-              "      That might span many lines\n" \
-              "    eos\n")
-    assert_equal(<<-eos, result)
-This would contain specially formatted text.
-
-That might span many lines
-    eos
+    result = "      This would contain specially formatted text.\n" \
+             "\n" \
+             "      That might span many lines\n"
+    expect = 'This would contain specially formatted text.'"\n" \
+             ''"\n" \
+             'That might span many lines'"\n"
+    assert_dedented_heredoc(expect, result)
   end
 
   def test_dedented_heredoc_with_interpolated_expression
-    result = eval(" <<~eos\n" \
-                  "  #{1}a\n" \
-                  " zy\n" \
-                  "      eos\n")
-      assert_equal(<<-eos, result)
- #{1}a
-zy
-      eos
+    result = '  #{1}a'"\n" \
+             " zy\n"
+    expect = ' #{1}a'"\n" \
+             "zy\n"
+    assert_dedented_heredoc(expect, result)
   end
 
   def test_dedented_heredoc_with_interpolated_string
     w = ""
-    result = eval("<<~eos\n" \
-                  " \#{w} a\n" \
-                  "  zy\n" \
-                  "    eos\n")
-    assert_equal(<<-eos, result)
-#{w} a
- zy
-    eos
+    result = " \#{mesg} a\n" \
+             "  zy\n"
+    expect = '#{mesg} a'"\n" \
+             ' zy'"\n"
+    assert_dedented_heredoc(expect, result)
   end
 
   def test_lineno_after_heredoc

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

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