parse.y: fix interpolated string literal dedent

* parse.y (heredoc_dedent): fix interpolated string literal dedent,
  remove indentations from only nodes with the newline flag.
  [ruby-core:85983] [Bug #14584]

* parse.y (here_document): set the newline flag on literal string
  nodes starting at the beginning of line.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62724 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
nobu 2018-03-11 12:19:08 +00:00
parent e1a60b2db9
commit f2b094a522
2 changed files with 18 additions and 5 deletions

17
parse.y
View File

@ -6017,7 +6017,6 @@ static NODE *
heredoc_dedent(struct parser_params *p, NODE *root) heredoc_dedent(struct parser_params *p, NODE *root)
{ {
NODE *node, *str_node, *prev_node; NODE *node, *str_node, *prev_node;
int bol = TRUE;
int indent = p->heredoc_indent; int indent = p->heredoc_indent;
VALUE prev_lit = 0; VALUE prev_lit = 0;
@ -6030,8 +6029,9 @@ heredoc_dedent(struct parser_params *p, NODE *root)
while (str_node) { while (str_node) {
VALUE lit = str_node->nd_lit; VALUE lit = str_node->nd_lit;
if (bol) dedent_string(lit, indent); if (str_node->flags & NODE_FL_NEWLINE) {
bol = TRUE; dedent_string(lit, indent);
}
if (!prev_lit) { if (!prev_lit) {
prev_lit = lit; prev_lit = lit;
} }
@ -6055,7 +6055,6 @@ heredoc_dedent(struct parser_params *p, NODE *root)
if ((str_node = node->nd_head) != 0) { if ((str_node = node->nd_head) != 0) {
enum node_type type = nd_type(str_node); enum node_type type = nd_type(str_node);
if (type == NODE_STR || type == NODE_DSTR) break; if (type == NODE_STR || type == NODE_DSTR) break;
bol = FALSE;
prev_lit = 0; prev_lit = 0;
str_node = 0; str_node = 0;
} }
@ -6204,6 +6203,7 @@ here_document(struct parser_params *p, rb_strterm_heredoc_t *here)
long len; long len;
VALUE str = 0; VALUE str = 0;
rb_encoding *enc = p->enc; rb_encoding *enc = p->enc;
int bol;
eos = RSTRING_PTR(here->term); eos = RSTRING_PTR(here->term);
len = RSTRING_LEN(here->term) - 2; /* here->term includes term_len and func */ len = RSTRING_LEN(here->term) - 2; /* here->term includes term_len and func */
@ -6242,7 +6242,8 @@ here_document(struct parser_params *p, rb_strterm_heredoc_t *here)
p->lex.strterm = 0; p->lex.strterm = 0;
return 0; return 0;
} }
if (was_bol(p) && whole_match_p(p, eos, len, indent)) { bol = was_bol(p);
if (bol && whole_match_p(p, eos, len, indent)) {
dispatch_heredoc_end(p); dispatch_heredoc_end(p);
heredoc_restore(p, &p->lex.strterm->u.heredoc); heredoc_restore(p, &p->lex.strterm->u.heredoc);
p->lex.strterm = 0; p->lex.strterm = 0;
@ -6317,6 +6318,9 @@ here_document(struct parser_params *p, rb_strterm_heredoc_t *here)
flush_str: flush_str:
set_yylval_str(str); set_yylval_str(str);
add_mark_object(p, str); add_mark_object(p, str);
#ifndef RIPPER
if (bol) yylval.node->flags |= NODE_FL_NEWLINE;
#endif
flush_string_content(p, enc); flush_string_content(p, enc);
return tSTRING_CONTENT; return tSTRING_CONTENT;
} }
@ -6339,6 +6343,9 @@ here_document(struct parser_params *p, rb_strterm_heredoc_t *here)
p->lex.strterm = NEW_STRTERM(func | STR_FUNC_TERM, 0, 0); p->lex.strterm = NEW_STRTERM(func | STR_FUNC_TERM, 0, 0);
set_yylval_str(str); set_yylval_str(str);
add_mark_object(p, str); add_mark_object(p, str);
#ifndef RIPPER
if (bol) yylval.node->flags |= NODE_FL_NEWLINE;
#endif
return tSTRING_CONTENT; return tSTRING_CONTENT;
} }

View File

@ -667,6 +667,12 @@ e"
assert_dedented_heredoc(expected, result) assert_dedented_heredoc(expected, result)
end end
def test_dedented_heredoc_expr_string
result = ' one#{" two "}'"\n"
expected = 'one#{" two "}'"\n"
assert_dedented_heredoc(expected, result)
end
def test_lineno_after_heredoc def test_lineno_after_heredoc
bug7559 = '[ruby-dev:46737]' bug7559 = '[ruby-dev:46737]'
expected, _, actual = __LINE__, <<eom, __LINE__ expected, _, actual = __LINE__, <<eom, __LINE__