1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

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]

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@53398 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
nobu 2015-12-31 20:06:22 +00:00
parent d6c769a5fe
commit b1796737cf
3 changed files with 99 additions and 76 deletions

View file

@ -1,3 +1,9 @@
Fri Jan 1 05:06:20 2016 Nobuyoshi Nakada <nobu@ruby-lang.org>
* 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@ruby-lang.org> Fri Jan 1 03:26:44 2016 Nobuyoshi Nakada <nobu@ruby-lang.org>
* lib/ostruct.rb (freeze): define deferred accessors before * lib/ostruct.rb (freeze): define deferred accessors before

53
parse.y
View file

@ -6214,6 +6214,32 @@ simple_re_meta(int c)
} }
} }
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 static int
parser_tokadd_string(struct parser_params *parser, parser_tokadd_string(struct parser_params *parser,
int func, int term, int paren, long *nest, int func, int term, int paren, long *nest,
@ -6244,24 +6270,7 @@ parser_tokadd_string(struct parser_params *parser,
while ((c = nextc()) != -1) { while ((c = nextc()) != -1) {
if (heredoc_indent > 0) { if (heredoc_indent > 0) {
if (heredoc_line_indent == -1) { parser_update_heredoc_indent(parser, c);
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;
}
}
} }
if (paren && c == paren) { if (paren && c == paren) {
@ -6881,6 +6890,14 @@ parser_here_document(struct parser_params *parser, NODE *here)
--pend; --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) if (str)
rb_str_cat(str, p, pend - p); rb_str_cat(str, p, pend - p);
else else

View file

@ -492,92 +492,92 @@ e"
assert_equal(expected, actual, "#{Bug7559}: ") assert_equal(expected, actual, "#{Bug7559}: ")
end 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 def test_dedented_heredoc_without_indentation
assert_equal(" y\nz\n", <<~eos) result = " y\n" \
y "z\n"
z expect = result
eos assert_dedented_heredoc(expect, result)
end end
def test_dedented_heredoc_with_indentation def test_dedented_heredoc_with_indentation
assert_equal(" a\nb\n", <<~eos) result = " a\n" \
a " b\n"
b expect = " a\n" \
eos "b\n"
assert_dedented_heredoc(expect, result)
end end
def test_dedented_heredoc_with_blank_less_indented_line def test_dedented_heredoc_with_blank_less_indented_line
# the blank line has two leading spaces # the blank line has two leading spaces
result = eval("<<~eos\n" \ result = " a\n" \
" a\n" \ " \n" \
" \n" \ " b\n"
" b\n" \ expect = "a\n" \
" eos\n") "\n" \
assert_equal("a\n\nb\n", result) "b\n"
assert_dedented_heredoc(expect, result)
end end
def test_dedented_heredoc_with_blank_less_indented_line_escaped def test_dedented_heredoc_with_blank_less_indented_line_escaped
result = eval("<<~eos\n" \ result = " a\n" \
" a\n" \ "\\ \\ \n" \
"\\ \\ \n" \ " b\n"
" b\n" \ expect = result
" eos\n") assert_dedented_heredoc(expect, result)
assert_equal(" a\n \n b\n", result)
end end
def test_dedented_heredoc_with_blank_more_indented_line def test_dedented_heredoc_with_blank_more_indented_line
# the blank line has six leading spaces # the blank line has six leading spaces
result = eval("<<~eos\n" \ result = " a\n" \
" a\n" \ " \n" \
" \n" \ " b\n"
" b\n" \ expect = "a\n" \
" eos\n") " \n" \
assert_equal("a\n \nb\n", result) "b\n"
assert_dedented_heredoc(expect, result)
end end
def test_dedented_heredoc_with_blank_more_indented_line_escaped def test_dedented_heredoc_with_blank_more_indented_line_escaped
result = eval("<<~eos\n" \ result = " a\n" \
" a\n" \ "\\ \\ \\ \\ \\ \\ \n" \
"\\ \\ \\ \\ \\ \\ \n" \ " b\n"
" b\n" \ expect = result
" eos\n") assert_dedented_heredoc(expect, result)
assert_equal(" a\n \n b\n", result)
end end
def test_dedented_heredoc_with_empty_line def test_dedented_heredoc_with_empty_line
result = eval("<<~eos\n" \ result = " This would contain specially formatted text.\n" \
" This would contain specially formatted text.\n" \ "\n" \
"\n" \ " That might span many lines\n"
" That might span many lines\n" \ expect = 'This would contain specially formatted text.'"\n" \
" eos\n") ''"\n" \
assert_equal(<<-eos, result) 'That might span many lines'"\n"
This would contain specially formatted text. assert_dedented_heredoc(expect, result)
That might span many lines
eos
end end
def test_dedented_heredoc_with_interpolated_expression def test_dedented_heredoc_with_interpolated_expression
result = eval(" <<~eos\n" \ result = ' #{1}a'"\n" \
" #{1}a\n" \ " zy\n"
" zy\n" \ expect = ' #{1}a'"\n" \
" eos\n") "zy\n"
assert_equal(<<-eos, result) assert_dedented_heredoc(expect, result)
#{1}a
zy
eos
end end
def test_dedented_heredoc_with_interpolated_string def test_dedented_heredoc_with_interpolated_string
w = "" w = ""
result = eval("<<~eos\n" \ result = " \#{mesg} a\n" \
" \#{w} a\n" \ " zy\n"
" zy\n" \ expect = '#{mesg} a'"\n" \
" eos\n") ' zy'"\n"
assert_equal(<<-eos, result) assert_dedented_heredoc(expect, result)
#{w} a
zy
eos
end end
def test_lineno_after_heredoc def test_lineno_after_heredoc