Skip to content

Commit 91a0a6a

Browse files
authored
+ ruby34.y: reject return in singleton class (#1048)
This tracks upstream commit ruby/ruby@e642ddf
1 parent 510eba0 commit 91a0a6a

File tree

3 files changed

+48
-5
lines changed

3 files changed

+48
-5
lines changed

lib/parser/context.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ class Context
2424
in_class
2525
in_block
2626
in_lambda
27+
cant_return
2728
]
2829

2930
def initialize
@@ -38,6 +39,7 @@ def reset
3839
@in_class = false
3940
@in_block = false
4041
@in_lambda = false
42+
@cant_return = false
4143
end
4244

4345
attr_accessor(*FLAGS)

lib/parser/ruby34.y

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -366,6 +366,7 @@ rule
366366

367367
result = [ val[0], @context.dup ]
368368
@context.in_def = true
369+
@context.cant_return = false
369370
}
370371

371372
defn_head: k_def def_name
@@ -1319,6 +1320,7 @@ rule
13191320
| k_class cpath superclass
13201321
{
13211322
@context.in_class = true
1323+
@context.cant_return = true
13221324
local_push
13231325
}
13241326
bodystmt kEND
@@ -1334,11 +1336,13 @@ rule
13341336
13351337
local_pop
13361338
@context.in_class = ctx.in_class
1339+
@context.cant_return = ctx.cant_return
13371340
}
13381341
| k_class tLSHFT expr_value term
13391342
{
13401343
@context.in_def = false
13411344
@context.in_class = false
1345+
@context.cant_return = true
13421346
local_push
13431347
}
13441348
bodystmt kEND
@@ -1350,10 +1354,12 @@ rule
13501354
local_pop
13511355
@context.in_def = ctx.in_def
13521356
@context.in_class = ctx.in_class
1357+
@context.cant_return = ctx.cant_return
13531358
}
13541359
| k_module cpath
13551360
{
13561361
@context.in_class = true
1362+
@context.cant_return = true
13571363
local_push
13581364
}
13591365
bodystmt kEND
@@ -1367,6 +1373,7 @@ rule
13671373
13681374
local_pop
13691375
@context.in_class = ctx.in_class
1376+
@context.cant_return = ctx.cant_return
13701377
}
13711378
| defn_head f_arglist bodystmt kEND
13721379
{
@@ -1425,7 +1432,7 @@ rule
14251432
14261433
k_return: kRETURN
14271434
{
1428-
if @context.in_class && !@context.in_def && !(context.in_block || context.in_lambda)
1435+
if @context.cant_return && !(context.in_block || context.in_lambda)
14291436
diagnostic :error, :invalid_return, nil, val[0]
14301437
end
14311438
}

test/test_parser.rb

Lines changed: 38 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6805,15 +6805,29 @@ def test_context_class
68056805
%q{class A; get_context; end},
68066806
%q{class A < B; get_context; end}
68076807
].each do |code|
6808-
assert_context([:in_class], code, ALL_VERSIONS)
6808+
assert_context([:in_class], code, ALL_VERSIONS - SINCE_3_4)
6809+
assert_context([:in_class, :cant_return], code, SINCE_3_4)
68096810
end
68106811
end
68116812

68126813
def test_context_module
68136814
assert_context(
68146815
[:in_class],
68156816
%q{module M; get_context; end},
6816-
ALL_VERSIONS)
6817+
ALL_VERSIONS - SINCE_3_4)
6818+
assert_context(
6819+
[:in_class, :cant_return],
6820+
%q{module M; get_context; end},
6821+
SINCE_3_4)
6822+
end
6823+
6824+
def test_context_sclass
6825+
[
6826+
%q{class << foo; get_context; end},
6827+
%q{class A; class << self; get_context; end; end}
6828+
].each do |code|
6829+
assert_context([:cant_return], code, SINCE_3_4)
6830+
end
68176831
end
68186832

68196833
def test_context_def
@@ -6900,15 +6914,21 @@ def test_return_in_class
69006914
SINCE_2_5)
69016915

69026916
[
6903-
%q{class << foo; return; end},
69046917
%q{def m; return; end},
69056918
%q{tap { return }},
6906-
%q{class A; class << self; return; end; end},
6919+
%q{class A; class << self; def m; return; end; end; end},
69076920
%q{class A; def m; return; end; end},
69086921
].each do |code|
69096922
refute_diagnoses(code, ALL_VERSIONS)
69106923
end
69116924

6925+
[
6926+
%q{class << foo; return; end},
6927+
%q{class A; class << self; return; end; end},
6928+
].each do |code|
6929+
refute_diagnoses(code, ALL_VERSIONS - SINCE_3_4)
6930+
end
6931+
69126932
[
69136933
%q{-> do return end},
69146934
%q{class A; -> do return end; end},
@@ -6917,6 +6937,20 @@ def test_return_in_class
69176937
end
69186938
end
69196939

6940+
def test_return_in_sclass_since_34
6941+
assert_diagnoses(
6942+
[:error, :invalid_return, {}],
6943+
%q{class << foo; return; end},
6944+
%q{ ^^^^^^ location},
6945+
SINCE_3_4)
6946+
6947+
assert_diagnoses(
6948+
[:error, :invalid_return, {}],
6949+
%q{class A; class << self; return; end; end},
6950+
%q{ ^^^^^^ location},
6951+
SINCE_3_4)
6952+
end
6953+
69206954
def test_method_definition_in_while_cond
69216955
assert_parses(
69226956
s(:while,

0 commit comments

Comments
 (0)