aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog7
-rw-r--r--parse.y17
-rw-r--r--test/ruby/test_keyword.rb10
3 files changed, 30 insertions, 4 deletions
diff --git a/ChangeLog b/ChangeLog
index d7bd7b60f0..ba86ab5dd5 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+Tue Mar 25 16:47:36 2014 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * parse.y (lex_state_e, parser_params, f_arglist, parser_yylex):
+ separate EXPR_LABELARG from EXPR_BEG and let newline significant,
+ so that required keyword argument can place at the end of
+ argument list without parentheses. [ruby-core:61658] [Bug #9669]
+
Mon Mar 24 22:19:56 2014 Nobuyoshi Nakada <nobu@ruby-lang.org>
* parse.y (ripper_initialize): filename can not be modified.
diff --git a/parse.y b/parse.y
index 67f182a51b..b3bbef1a51 100644
--- a/parse.y
+++ b/parse.y
@@ -74,6 +74,7 @@ enum lex_state_bits {
EXPR_DOT_bit, /* right after `.' or `::', no reserved words. */
EXPR_CLASS_bit, /* immediate after `class', no here document. */
EXPR_VALUE_bit, /* alike EXPR_BEG but label is disallowed. */
+ EXPR_LABELARG_bit, /* ignore significant, +/- is a sign. */
EXPR_MAX_STATE
};
/* examine combinations */
@@ -90,7 +91,8 @@ enum lex_state_e {
DEF_EXPR(DOT),
DEF_EXPR(CLASS),
DEF_EXPR(VALUE),
- EXPR_BEG_ANY = (EXPR_BEG | EXPR_VALUE | EXPR_MID | EXPR_CLASS),
+ DEF_EXPR(LABELARG),
+ EXPR_BEG_ANY = (EXPR_BEG | EXPR_VALUE | EXPR_MID | EXPR_CLASS | EXPR_LABELARG),
EXPR_ARG_ANY = (EXPR_ARG | EXPR_CMDARG),
EXPR_END_ANY = (EXPR_END | EXPR_ENDARG | EXPR_ENDFN)
};
@@ -244,6 +246,7 @@ struct parser_params {
int parser_brace_nest;
int parser_compile_for_eval;
VALUE parser_cur_mid;
+ int parser_in_kwarg;
int parser_in_defined;
char *parser_tokenbuf;
int parser_tokidx;
@@ -4402,9 +4405,14 @@ f_arglist : '(' f_args rparen
lex_state = EXPR_BEG;
command_start = TRUE;
}
- | f_args term
+ | {
+ $<num>$ = parser->parser_in_kwarg;
+ parser->parser_in_kwarg = 1;
+ }
+ f_args term
{
- $$ = $1;
+ parser->parser_in_kwarg = $<num>1;
+ $$ = $2;
lex_state = EXPR_BEG;
command_start = TRUE;
}
@@ -8147,7 +8155,7 @@ parser_yylex(struct parser_params *parser)
if (IS_LABEL_POSSIBLE()) {
if (IS_LABEL_SUFFIX(0)) {
- lex_state = EXPR_BEG;
+ lex_state = EXPR_LABELARG;
nextc();
set_yylval_name(TOK_INTERN());
return tLABEL;
@@ -10861,6 +10869,7 @@ parser_initialize(struct parser_params *parser)
parser->parser_in_single = 0;
parser->parser_in_def = 0;
parser->parser_in_defined = 0;
+ parser->parser_in_kwarg = 0;
parser->parser_compile_for_eval = 0;
parser->parser_cur_mid = 0;
parser->parser_tokenbuf = NULL;
diff --git a/test/ruby/test_keyword.rb b/test/ruby/test_keyword.rb
index 625146b0ba..75b8f58a98 100644
--- a/test/ruby/test_keyword.rb
+++ b/test/ruby/test_keyword.rb
@@ -325,6 +325,16 @@ class TestKeywordArguments < Test::Unit::TestCase
assert_equal([[:keyreq, :a], [:keyrest, :b]], o.method(:bar).parameters, feature7701)
assert_raise_with_message(ArgumentError, /missing keyword/, bug8139) {o.bar(c: bug8139)}
assert_raise_with_message(ArgumentError, /missing keyword/, bug8139) {o.bar}
+
+ bug9669 = '[ruby-core:61658] [Bug #9669]'
+ assert_nothing_raised(SyntaxError, bug9669) do
+ eval(<<-'end;', nil, __FILE__, __LINE__)
+ def bug9669.foo a:
+ return a
+ end
+ end;
+ end
+ assert_equal(42, bug9669.foo(a: 42))
end
def test_block_required_keyword