diff options
author | yui-knk <spiketeika@gmail.com> | 2022-10-01 17:19:34 +0900 |
---|---|---|
committer | Yuichiro Kaneko <spiketeika@gmail.com> | 2022-10-08 17:59:11 +0900 |
commit | 4f24f3ea94e43d1021fdd8548480f130f5112b99 (patch) | |
tree | 8cfe7d2e7dd0dcdabc31aa7a781858b9364a1291 /parse.y | |
parent | 342d4c16d963408905fd08118d1908fe197f2364 (diff) | |
download | ruby-4f24f3ea94e43d1021fdd8548480f130f5112b99.tar.gz |
Treat "end" as reserved word with consideration of indent
"end" after "." or "::" is treated as local variable or method,
see `EXPR_DOT_bit` for detail.
However this "changes" where `bar` method is defined. In the example
below it is not module Z but class Foo.
```
module Z
class Foo
foo.
end
def bar
end
end
```
[Feature #19013]
Diffstat (limited to 'parse.y')
-rw-r--r-- | parse.y | 37 |
1 files changed, 36 insertions, 1 deletions
@@ -438,6 +438,13 @@ pop_end_expect_token_localtions(struct parser_params *p) rb_ary_pop(p->end_expect_token_localtions); debug_end_expect_token_localtions(p, "pop_end_expect_token_localtions"); } + +static VALUE +peek_end_expect_token_localtions(struct parser_params *p) +{ + if(NIL_P(p->end_expect_token_localtions)) return Qnil; + return rb_ary_last(0, 0, p->end_expect_token_localtions); +} #endif RBIMPL_ATTR_NONNULL((1, 2, 3)) @@ -9285,6 +9292,7 @@ parse_ident(struct parser_params *p, int c, int cmd_state) int mb = ENC_CODERANGE_7BIT; const enum lex_state_e last_state = p->lex.state; ID ident; + int enforce_keyword_end = 0; do { if (!ISASCII(c)) mb = ENC_CODERANGE_UNKNOWN; @@ -9314,7 +9322,34 @@ parse_ident(struct parser_params *p, int c, int cmd_state) return tLABEL; } } - if (mb == ENC_CODERANGE_7BIT && !IS_lex_state(EXPR_DOT)) { + +#ifndef RIPPER + if (!NIL_P(peek_end_expect_token_localtions(p))) { + VALUE end_loc; + int lineno, column; + int beg_pos = (int)(p->lex.ptok - p->lex.pbeg); + + end_loc = peek_end_expect_token_localtions(p); + lineno = NUM2INT(rb_ary_entry(end_loc, 0)); + column = NUM2INT(rb_ary_entry(end_loc, 1)); + + if (p->debug) { + rb_parser_printf(p, "enforce_keyword_end check. current: (%d, %d), peek: (%d, %d)\n", + p->ruby_sourceline, beg_pos, lineno, column); + } + + if ((p->ruby_sourceline > lineno) && (beg_pos <= column)) { + const struct kwtable *kw; + + if ((IS_lex_state(EXPR_DOT)) && (kw = rb_reserved_word(tok(p), toklen(p))) && (kw && kw->id[0] == keyword_end)) { + if (p->debug) rb_parser_printf(p, "enforce_keyword_end is enabled\n"); + enforce_keyword_end = 1; + } + } + } +#endif + + if (mb == ENC_CODERANGE_7BIT && (!IS_lex_state(EXPR_DOT) || enforce_keyword_end)) { const struct kwtable *kw; /* See if it is a reserved word. */ |