diff options
author | Nobuyoshi Nakada <nobu@ruby-lang.org> | 2023-09-13 13:34:30 +0900 |
---|---|---|
committer | Nobuyoshi Nakada <nobu@ruby-lang.org> | 2023-09-28 16:23:51 +0900 |
commit | b5e23d3e3b5ff2f5328aa43a2392ebe7c951a222 (patch) | |
tree | 408005ab7b1b51f2a04bd3a15142361937683208 | |
parent | ad96962173c824aeb4ecdd1d9a2e98eaa23a7536 (diff) |
Syntax check of `yield` in the parser
-rw-r--r-- | parse.y | 15 | ||||
-rw-r--r-- | test/prism/parse_test.rb | 2 | ||||
-rw-r--r-- | test/ruby/test_ast.rb | 28 | ||||
-rw-r--r-- | test/ruby/test_rubyoptions.rb | 3 |
4 files changed, 43 insertions, 5 deletions
@@ -2697,7 +2697,7 @@ command : fcall command_args %prec tLOWEST /*% %*/ /*% ripper: super!($2) %*/ } - | keyword_yield command_args + | k_yield command_args { /*%%%*/ $$ = new_yield(p, $2, &@$); @@ -3797,21 +3797,21 @@ primary : literal /*% %*/ /*% ripper: return0! %*/ } - | keyword_yield '(' call_args rparen + | k_yield '(' call_args rparen { /*%%%*/ $$ = new_yield(p, $3, &@$); /*% %*/ /*% ripper: yield!(paren!($3)) %*/ } - | keyword_yield '(' rparen + | k_yield '(' rparen { /*%%%*/ $$ = NEW_YIELD(0, &@$); /*% %*/ /*% ripper: yield!(paren!(args_new!)) %*/ } - | keyword_yield + | k_yield { /*%%%*/ $$ = NEW_YIELD(0, &@$); @@ -4294,6 +4294,13 @@ k_return : keyword_return } ; +k_yield : keyword_yield + { + if (!p->ctxt.in_defined && !p->ctxt.in_def && !dyna_in_block(p)) + yyerror1(&@1, "Invalid yield"); + } + ; + then : term | keyword_then | term keyword_then diff --git a/test/prism/parse_test.rb b/test/prism/parse_test.rb index 65128bf5a7..3c0d584a12 100644 --- a/test/prism/parse_test.rb +++ b/test/prism/parse_test.rb @@ -89,7 +89,7 @@ module Prism src = source case relative - when /break|next|redo|if|unless|rescue|control|keywords|retry/ + when /break|next|redo|if|unless|rescue|control|keywords|retry|yield|\/args_assocs/ # Uncaught syntax errors: Invalid break, Invalid next src = "->do\nrescue\n#{src}\nend" ripper_should_match = false diff --git a/test/ruby/test_ast.rb b/test/ruby/test_ast.rb index 70ebd22a98..76fd2b3783 100644 --- a/test/ruby/test_ast.rb +++ b/test/ruby/test_ast.rb @@ -285,6 +285,34 @@ class TestAst < Test::Unit::TestCase assert_parse("begin rescue; END {defined? retry}; end") end + def test_invalid_yield + msg = /Invalid yield/ + assert_invalid_parse(msg, "yield") + assert_invalid_parse(msg, "class C; yield; end") + assert_invalid_parse(msg, "BEGIN {yield}") + assert_invalid_parse(msg, "END {yield}") + + assert_invalid_parse(msg, "yield true") + assert_invalid_parse(msg, "class C; yield true; end") + assert_invalid_parse(msg, "BEGIN {yield true}") + assert_invalid_parse(msg, "END {yield true}") + + assert_parse("!defined?(yield)") + assert_parse("class C; defined?(yield); end") + assert_parse("BEGIN {defined?(yield)}") + assert_parse("END {defined?(yield)}") + + assert_parse("!defined?(yield true)") + assert_parse("class C; defined?(yield true); end") + assert_parse("BEGIN {defined?(yield true)}") + assert_parse("END {defined?(yield true)}") + + assert_parse("!defined? yield") + assert_parse("class C; defined? yield; end") + assert_parse("BEGIN {defined? yield}") + assert_parse("END {defined? yield}") + end + def test_node_id_for_location exception = begin raise diff --git a/test/ruby/test_rubyoptions.rb b/test/ruby/test_rubyoptions.rb index a2f738d9a5..b2e2e7bb6c 100644 --- a/test/ruby/test_rubyoptions.rb +++ b/test/ruby/test_rubyoptions.rb @@ -373,14 +373,17 @@ class TestRubyOptions < Test::Unit::TestCase assert_in_out_err(%w(-cw -e next), "", [], ["-e:1: Invalid next", :*]) assert_in_out_err(%w(-cw -e redo), "", [], ["-e:1: Invalid redo", :*]) assert_in_out_err(%w(-cw -e retry), "", [], ["-e:1: Invalid retry", :*]) + assert_in_out_err(%w(-cw -e yield), "", [], ["-e:1: Invalid yield", :*]) assert_in_out_err(%w(-cw -e begin -e break -e end), "", [], ["-e:2: Invalid break", :*]) assert_in_out_err(%w(-cw -e begin -e next -e end), "", [], ["-e:2: Invalid next", :*]) assert_in_out_err(%w(-cw -e begin -e redo -e end), "", [], ["-e:2: Invalid redo", :*]) assert_in_out_err(%w(-cw -e begin -e retry -e end), "", [], ["-e:2: Invalid retry", :*]) + assert_in_out_err(%w(-cw -e begin -e yield -e end), "", [], ["-e:2: Invalid yield", :*]) assert_in_out_err(%w(-cw -e !defined?(break)), "", ["Syntax OK"], []) assert_in_out_err(%w(-cw -e !defined?(next)), "", ["Syntax OK"], []) assert_in_out_err(%w(-cw -e !defined?(redo)), "", ["Syntax OK"], []) assert_in_out_err(%w(-cw -e !defined?(retry)), "", ["Syntax OK"], []) + assert_in_out_err(%w(-cw -e !defined?(yield)), "", ["Syntax OK"], []) assert_in_out_err(%w(-n -cw -e break), "", ["Syntax OK"], []) assert_in_out_err(%w(-n -cw -e next), "", ["Syntax OK"], []) assert_in_out_err(%w(-n -cw -e redo), "", ["Syntax OK"], []) |