зеркало из https://github.com/github/ruby.git
[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:
Родитель
1912bf5461
Коммит
3becc4a105
17
parse.y
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
|
||||
|
|
Загрузка…
Ссылка в новой задаче