[Bug #19291] Rewind to the previous line

When rewinding looking ahead after newline token, also reset the last
line string, the pointers to it, and the location, not only the line
number.
This commit is contained in:
Nobuyoshi Nakada 2023-01-02 00:27:25 +09:00
Родитель 1912bf5461
Коммит 3becc4a105
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 7CD2805BFA3770C6
3 изменённых файлов: 20 добавлений и 4 удалений

17
parse.y
Просмотреть файл

@ -7028,6 +7028,14 @@ add_delayed_token(struct parser_params *p, const char *tok, const char *end, int
}
}
static void
set_lastline(struct parser_params *p, VALUE v)
{
p->lex.pbeg = p->lex.pcur = RSTRING_PTR(v);
p->lex.pend = p->lex.pcur + RSTRING_LEN(v);
p->lex.lastline = v;
}
static int
nextline(struct parser_params *p, int set_encoding)
{
@ -7065,10 +7073,8 @@ nextline(struct parser_params *p, int set_encoding)
p->heredoc_end = 0;
}
p->ruby_sourceline++;
p->lex.pbeg = p->lex.pcur = RSTRING_PTR(v);
p->lex.pend = p->lex.pcur + RSTRING_LEN(v);
set_lastline(p, v);
token_flush(p);
p->lex.lastline = v;
return 0;
}
@ -9850,6 +9856,7 @@ parser_yylex(struct parser_params *p)
/* fall through */
case '\n':
p->token_seen = token_seen;
VALUE prevline = p->lex.lastline;
c = (IS_lex_state(EXPR_BEG|EXPR_CLASS|EXPR_FNAME|EXPR_DOT) &&
!IS_lex_state(EXPR_LABELED));
if (c || IS_lex_state_all(EXPR_ARG|EXPR_LABELED)) {
@ -9887,10 +9894,12 @@ parser_yylex(struct parser_params *p)
default:
p->ruby_sourceline--;
p->lex.nextline = p->lex.lastline;
set_lastline(p, prevline);
case -1: /* EOF no decrement*/
lex_goto_eol(p);
if (c != -1) {
p->lex.ptok = p->lex.pcur;
token_flush(p);
RUBY_SET_YYLLOC(*p->yylloc);
}
goto normal_newline;
}

Просмотреть файл

@ -995,4 +995,10 @@ class TestRipper::ScannerEvents < Test::Unit::TestCase
assert_equal ['U'], scan('tstring_content', '/\\xU/') {|*e| err = e}
assert_equal [:on_parse_error, "invalid hex escape", "\\x"], err
end
def test_error_token
src = "{a:,aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n""hello}"
err = scan('parse_error', src) {|*e| break e}
assert_equal "", err[2]
end
end if ripper_test

Просмотреть файл

@ -14,6 +14,7 @@ class TestParse < Test::Unit::TestCase
def test_error_line
assert_syntax_error('------,,', /\n\z/, 'Message to pipe should end with a newline')
assert_syntax_error("{hello\n world}", /hello/)
end
def test_else_without_rescue