parser 2.6.5.0 → 2.7.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +34 -0
- data/README.md +7 -0
- data/doc/AST_FORMAT.md +346 -20
- data/lib/parser.rb +3 -1
- data/lib/parser/ast/processor.rb +15 -0
- data/lib/parser/base.rb +19 -0
- data/lib/parser/builders/default.rb +245 -12
- data/lib/parser/context.rb +4 -0
- data/lib/parser/current.rb +4 -4
- data/lib/parser/current_arg_stack.rb +43 -0
- data/lib/parser/lexer.rl +93 -94
- data/lib/parser/lexer/dedenter.rb +48 -49
- data/lib/parser/{lexer/max_numparam_stack.rb → max_numparam_stack.rb} +10 -4
- data/lib/parser/messages.rb +34 -29
- data/lib/parser/meta.rb +6 -2
- data/lib/parser/ruby27.y +488 -35
- data/lib/parser/static_environment.rb +10 -0
- data/lib/parser/variables_stack.rb +32 -0
- data/lib/parser/version.rb +1 -1
- data/test/helper.rb +1 -0
- data/test/test_lexer.rb +7 -66
- data/test/test_parser.rb +1776 -123
- metadata +5 -3
@@ -3,6 +3,8 @@
|
|
3
3
|
module Parser
|
4
4
|
|
5
5
|
class StaticEnvironment
|
6
|
+
FORWARD_ARGS = :FORWARD_ARGS
|
7
|
+
|
6
8
|
def initialize
|
7
9
|
reset
|
8
10
|
end
|
@@ -41,6 +43,14 @@ module Parser
|
|
41
43
|
def declared?(name)
|
42
44
|
@variables.include?(name.to_sym)
|
43
45
|
end
|
46
|
+
|
47
|
+
def declare_forward_args
|
48
|
+
declare(FORWARD_ARGS)
|
49
|
+
end
|
50
|
+
|
51
|
+
def declared_forward_args?
|
52
|
+
declared?(FORWARD_ARGS)
|
53
|
+
end
|
44
54
|
end
|
45
55
|
|
46
56
|
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Parser
|
4
|
+
|
5
|
+
class VariablesStack
|
6
|
+
def initialize
|
7
|
+
@stack = []
|
8
|
+
push
|
9
|
+
end
|
10
|
+
|
11
|
+
def push
|
12
|
+
@stack << Set.new
|
13
|
+
end
|
14
|
+
|
15
|
+
def pop
|
16
|
+
@stack.pop
|
17
|
+
end
|
18
|
+
|
19
|
+
def reset
|
20
|
+
@stack.clear
|
21
|
+
end
|
22
|
+
|
23
|
+
def declare(name)
|
24
|
+
@stack.last << name.to_sym
|
25
|
+
end
|
26
|
+
|
27
|
+
def declared?(name)
|
28
|
+
@stack.last.include?(name.to_sym)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
data/lib/parser/version.rb
CHANGED
data/test/helper.rb
CHANGED
data/test/test_lexer.rb
CHANGED
@@ -1507,6 +1507,13 @@ class TestLexer < Minitest::Test
|
|
1507
1507
|
assert_scanned "||", :tOROP, "||", [0, 2]
|
1508
1508
|
end
|
1509
1509
|
|
1510
|
+
def test_or2__after_27
|
1511
|
+
setup_lexer(27)
|
1512
|
+
assert_scanned("||",
|
1513
|
+
:tPIPE, "|", [0, 1],
|
1514
|
+
:tPIPE, "|", [1, 2])
|
1515
|
+
end
|
1516
|
+
|
1510
1517
|
def test_or2_equals
|
1511
1518
|
assert_scanned "||=", :tOP_ASGN, "||", [0, 3]
|
1512
1519
|
end
|
@@ -3562,51 +3569,6 @@ class TestLexer < Minitest::Test
|
|
3562
3569
|
:tIDENTIFIER, 're', [1, 3])
|
3563
3570
|
end
|
3564
3571
|
|
3565
|
-
def test_meth_ref
|
3566
|
-
setup_lexer(27)
|
3567
|
-
|
3568
|
-
assert_scanned('foo.:bar',
|
3569
|
-
:tIDENTIFIER, 'foo', [0, 3],
|
3570
|
-
:tMETHREF, '.:', [3, 5],
|
3571
|
-
:tIDENTIFIER, 'bar', [5, 8])
|
3572
|
-
|
3573
|
-
assert_scanned('foo .:bar',
|
3574
|
-
:tIDENTIFIER, 'foo', [0, 3],
|
3575
|
-
:tMETHREF, '.:', [4, 6],
|
3576
|
-
:tIDENTIFIER, 'bar', [6, 9])
|
3577
|
-
end
|
3578
|
-
|
3579
|
-
def test_meth_ref_unary_op
|
3580
|
-
setup_lexer(27)
|
3581
|
-
|
3582
|
-
assert_scanned('foo.:+',
|
3583
|
-
:tIDENTIFIER, 'foo', [0, 3],
|
3584
|
-
:tMETHREF, '.:', [3, 5],
|
3585
|
-
:tPLUS, '+', [5, 6])
|
3586
|
-
|
3587
|
-
assert_scanned('foo.:-@',
|
3588
|
-
:tIDENTIFIER, 'foo', [0, 3],
|
3589
|
-
:tMETHREF, '.:', [3, 5],
|
3590
|
-
:tUMINUS, '-@', [5, 7])
|
3591
|
-
end
|
3592
|
-
|
3593
|
-
def test_meth_ref_unsupported_newlines
|
3594
|
-
# MRI emits exactly the same sequence of tokens,
|
3595
|
-
# the error happens later in the parser
|
3596
|
-
|
3597
|
-
assert_scanned('foo. :+',
|
3598
|
-
:tIDENTIFIER, 'foo', [0, 3],
|
3599
|
-
:tDOT, '.', [3, 4],
|
3600
|
-
:tCOLON, ':', [5, 6],
|
3601
|
-
:tUPLUS, '+', [6, 7])
|
3602
|
-
|
3603
|
-
assert_scanned('foo.: +',
|
3604
|
-
:tIDENTIFIER, 'foo', [0, 3],
|
3605
|
-
:tDOT, '.', [3, 4],
|
3606
|
-
:tCOLON, ':', [4, 5],
|
3607
|
-
:tPLUS, '+', [6, 7])
|
3608
|
-
end
|
3609
|
-
|
3610
3572
|
def lex_numbered_parameter(input)
|
3611
3573
|
@lex.max_numparam_stack.push
|
3612
3574
|
|
@@ -3643,25 +3605,4 @@ class TestLexer < Minitest::Test
|
|
3643
3605
|
end
|
3644
3606
|
end
|
3645
3607
|
|
3646
|
-
def test_numbered_args_before_27
|
3647
|
-
setup_lexer(26)
|
3648
|
-
refute_scanned_numbered_parameter('@1')
|
3649
|
-
end
|
3650
|
-
|
3651
|
-
def test_numbered_args_27
|
3652
|
-
setup_lexer(27)
|
3653
|
-
assert_scanned_numbered_parameter('@1')
|
3654
|
-
assert_equal(@lex.max_numparam, 1)
|
3655
|
-
|
3656
|
-
setup_lexer(27)
|
3657
|
-
assert_scanned_numbered_parameter('@9')
|
3658
|
-
assert_equal(@lex.max_numparam, 9)
|
3659
|
-
|
3660
|
-
setup_lexer(27)
|
3661
|
-
refute_scanned_numbered_parameter('@10', :too_large_numparam)
|
3662
|
-
|
3663
|
-
setup_lexer(27)
|
3664
|
-
refute_scanned_numbered_parameter('@01', :leading_zero_in_numparam)
|
3665
|
-
end
|
3666
|
-
|
3667
3608
|
end
|
data/test/test_parser.rb
CHANGED
@@ -324,7 +324,7 @@ class TestParser < Minitest::Test
|
|
324
324
|
assert_parses(
|
325
325
|
s(:send, nil, :p,
|
326
326
|
s(:dstr,
|
327
|
-
s(:str, "
|
327
|
+
s(:str, "\tx\n"),
|
328
328
|
s(:str, "y\n"))),
|
329
329
|
%Q{p <<~E\n\tx\n y\nE},
|
330
330
|
%q{},
|
@@ -432,6 +432,14 @@ class TestParser < Minitest::Test
|
|
432
432
|
SINCE_2_3)
|
433
433
|
end
|
434
434
|
|
435
|
+
def test_parser_bug_640
|
436
|
+
assert_parses(
|
437
|
+
s(:str, "bazqux\n"),
|
438
|
+
%Q{<<~FOO\n baz\\\n qux\nFOO},
|
439
|
+
%q{},
|
440
|
+
SINCE_2_3)
|
441
|
+
end
|
442
|
+
|
435
443
|
# Symbols
|
436
444
|
|
437
445
|
def test_symbol_plain
|
@@ -2168,7 +2176,7 @@ class TestParser < Minitest::Test
|
|
2168
2176
|
s(:lvar, :var)),
|
2169
2177
|
%q{def f(var = defined?(var)) var end},
|
2170
2178
|
%q{},
|
2171
|
-
SINCE_2_1)
|
2179
|
+
SINCE_2_7 - SINCE_2_1)
|
2172
2180
|
|
2173
2181
|
assert_parses(
|
2174
2182
|
s(:def, :f,
|
@@ -2176,7 +2184,7 @@ class TestParser < Minitest::Test
|
|
2176
2184
|
s(:lvar, :var)),
|
2177
2185
|
%q{def f(var: defined?(var)) var end},
|
2178
2186
|
%q{},
|
2179
|
-
SINCE_2_1)
|
2187
|
+
SINCE_2_7 - SINCE_2_1)
|
2180
2188
|
|
2181
2189
|
assert_parses(
|
2182
2190
|
s(:block,
|
@@ -2477,7 +2485,7 @@ class TestParser < Minitest::Test
|
|
2477
2485
|
%Q{|;\na\n|},
|
2478
2486
|
SINCE_2_0)
|
2479
2487
|
|
2480
|
-
# tOROP
|
2488
|
+
# tOROP before 2.7 / tPIPE+tPIPE after
|
2481
2489
|
assert_parses_blockargs(
|
2482
2490
|
s(:args),
|
2483
2491
|
%q{||})
|
@@ -7214,52 +7222,6 @@ class TestParser < Minitest::Test
|
|
7214
7222
|
end
|
7215
7223
|
end
|
7216
7224
|
|
7217
|
-
def test_meth_ref__27
|
7218
|
-
assert_parses(
|
7219
|
-
s(:meth_ref, s(:lvar, :foo), :bar),
|
7220
|
-
%q{foo.:bar},
|
7221
|
-
%q{ ^^ dot
|
7222
|
-
| ~~~ selector
|
7223
|
-
|~~~~~~~~ expression},
|
7224
|
-
SINCE_2_7)
|
7225
|
-
|
7226
|
-
assert_parses(
|
7227
|
-
s(:meth_ref, s(:lvar, :foo), :+@),
|
7228
|
-
%q{foo.:+@},
|
7229
|
-
%q{ ^^ dot
|
7230
|
-
| ~~ selector
|
7231
|
-
|~~~~~~~ expression},
|
7232
|
-
SINCE_2_7)
|
7233
|
-
end
|
7234
|
-
|
7235
|
-
def test_meth_ref__before_27
|
7236
|
-
assert_diagnoses(
|
7237
|
-
[:error, :unexpected_token, { :token => 'tCOLON' }],
|
7238
|
-
%q{foo.:bar},
|
7239
|
-
%q{ ^ location },
|
7240
|
-
ALL_VERSIONS - SINCE_2_7)
|
7241
|
-
|
7242
|
-
assert_diagnoses(
|
7243
|
-
[:error, :unexpected_token, { :token => 'tCOLON' }],
|
7244
|
-
%q{foo.:+@},
|
7245
|
-
%q{ ^ location },
|
7246
|
-
ALL_VERSIONS - SINCE_2_7)
|
7247
|
-
end
|
7248
|
-
|
7249
|
-
def test_meth_ref_unsupported_newlines
|
7250
|
-
assert_diagnoses(
|
7251
|
-
[:error, :unexpected_token, { :token => 'tCOLON' }],
|
7252
|
-
%Q{foo. :+},
|
7253
|
-
%q{ ^ location},
|
7254
|
-
SINCE_2_7)
|
7255
|
-
|
7256
|
-
assert_diagnoses(
|
7257
|
-
[:error, :unexpected_token, { :token => 'tCOLON' }],
|
7258
|
-
%Q{foo.: +},
|
7259
|
-
%q{ ^ location},
|
7260
|
-
SINCE_2_7)
|
7261
|
-
end
|
7262
|
-
|
7263
7225
|
def test_unterimated_heredoc_id__27
|
7264
7226
|
assert_diagnoses(
|
7265
7227
|
[:error, :unterminated_heredoc_id],
|
@@ -7282,29 +7244,20 @@ class TestParser < Minitest::Test
|
|
7282
7244
|
end
|
7283
7245
|
end
|
7284
7246
|
|
7285
|
-
def test_numbered_args_before_27
|
7286
|
-
assert_diagnoses(
|
7287
|
-
[:error, :ivar_name, { :name => '@1' }],
|
7288
|
-
%q{m { @1 }},
|
7289
|
-
%q{ ^^ location},
|
7290
|
-
ALL_VERSIONS - SINCE_2_7
|
7291
|
-
)
|
7292
|
-
end
|
7293
|
-
|
7294
7247
|
def test_numbered_args_after_27
|
7295
7248
|
assert_parses(
|
7296
7249
|
s(:numblock,
|
7297
7250
|
s(:send, nil, :m),
|
7298
7251
|
9,
|
7299
7252
|
s(:send,
|
7300
|
-
s(:
|
7301
|
-
s(:
|
7302
|
-
%q{m {
|
7253
|
+
s(:lvar, :_1), :+,
|
7254
|
+
s(:lvar, :_9))),
|
7255
|
+
%q{m { _1 + _9 }},
|
7303
7256
|
%q{^^^^^^^^^^^^^ expression
|
7304
|
-
| ^^ name (send/2.
|
7305
|
-
| ^^ expression (send/2.
|
7306
|
-
| ^^ name (send/2.
|
7307
|
-
| ^^ expression (send/2.
|
7257
|
+
| ^^ name (send/2.lvar/1)
|
7258
|
+
| ^^ expression (send/2.lvar/1)
|
7259
|
+
| ^^ name (send/2.lvar/2)
|
7260
|
+
| ^^ expression (send/2.lvar/2)},
|
7308
7261
|
SINCE_2_7)
|
7309
7262
|
|
7310
7263
|
assert_parses(
|
@@ -7312,14 +7265,14 @@ class TestParser < Minitest::Test
|
|
7312
7265
|
s(:send, nil, :m),
|
7313
7266
|
9,
|
7314
7267
|
s(:send,
|
7315
|
-
s(:
|
7316
|
-
s(:
|
7317
|
-
%q{m do
|
7268
|
+
s(:lvar, :_1), :+,
|
7269
|
+
s(:lvar, :_9))),
|
7270
|
+
%q{m do _1 + _9 end},
|
7318
7271
|
%q{^^^^^^^^^^^^^^^^ expression
|
7319
|
-
| ^^ name (send/2.
|
7320
|
-
| ^^ expression (send/2.
|
7321
|
-
| ^^ name (send/2.
|
7322
|
-
| ^^ expression (send/2.
|
7272
|
+
| ^^ name (send/2.lvar/1)
|
7273
|
+
| ^^ expression (send/2.lvar/1)
|
7274
|
+
| ^^ name (send/2.lvar/2)
|
7275
|
+
| ^^ expression (send/2.lvar/2)},
|
7323
7276
|
SINCE_2_7)
|
7324
7277
|
|
7325
7278
|
# Lambdas
|
@@ -7329,14 +7282,14 @@ class TestParser < Minitest::Test
|
|
7329
7282
|
s(:lambda),
|
7330
7283
|
9,
|
7331
7284
|
s(:send,
|
7332
|
-
s(:
|
7333
|
-
s(:
|
7334
|
-
%q{-> {
|
7285
|
+
s(:lvar, :_1), :+,
|
7286
|
+
s(:lvar, :_9))),
|
7287
|
+
%q{-> { _1 + _9}},
|
7335
7288
|
%q{^^^^^^^^^^^^^ expression
|
7336
|
-
| ^^ name (send.
|
7337
|
-
| ^^ expression (send.
|
7338
|
-
| ^^ name (send.
|
7339
|
-
| ^^ expression (send.
|
7289
|
+
| ^^ name (send.lvar/1)
|
7290
|
+
| ^^ expression (send.lvar/1)
|
7291
|
+
| ^^ name (send.lvar/2)
|
7292
|
+
| ^^ expression (send.lvar/2)},
|
7340
7293
|
SINCE_2_7)
|
7341
7294
|
|
7342
7295
|
assert_parses(
|
@@ -7344,14 +7297,14 @@ class TestParser < Minitest::Test
|
|
7344
7297
|
s(:lambda),
|
7345
7298
|
9,
|
7346
7299
|
s(:send,
|
7347
|
-
s(:
|
7348
|
-
s(:
|
7349
|
-
%q{-> do
|
7300
|
+
s(:lvar, :_1), :+,
|
7301
|
+
s(:lvar, :_9))),
|
7302
|
+
%q{-> do _1 + _9 end},
|
7350
7303
|
%q{^^^^^^^^^^^^^^^^^ expression
|
7351
|
-
| ^^ name (send.
|
7352
|
-
| ^^ expression (send.
|
7353
|
-
| ^^ name (send.
|
7354
|
-
| ^^ expression (send.
|
7304
|
+
| ^^ name (send.lvar/1)
|
7305
|
+
| ^^ expression (send.lvar/1)
|
7306
|
+
| ^^ name (send.lvar/2)
|
7307
|
+
| ^^ expression (send.lvar/2)},
|
7355
7308
|
SINCE_2_7)
|
7356
7309
|
end
|
7357
7310
|
|
@@ -7360,37 +7313,37 @@ class TestParser < Minitest::Test
|
|
7360
7313
|
|
7361
7314
|
assert_diagnoses(
|
7362
7315
|
[:error, :ordinary_param_defined],
|
7363
|
-
%q{m { ||
|
7316
|
+
%q{m { || _1 } },
|
7364
7317
|
%q{ ^^ location},
|
7365
7318
|
SINCE_2_7)
|
7366
7319
|
|
7367
7320
|
assert_diagnoses(
|
7368
7321
|
[:error, :ordinary_param_defined],
|
7369
|
-
%q{m { |a|
|
7322
|
+
%q{m { |a| _1 } },
|
7370
7323
|
%q{ ^^ location},
|
7371
7324
|
SINCE_2_7)
|
7372
7325
|
|
7373
7326
|
assert_diagnoses(
|
7374
7327
|
[:error, :ordinary_param_defined],
|
7375
|
-
%q{m do ||
|
7328
|
+
%q{m do || _1 end },
|
7376
7329
|
%q{ ^^ location},
|
7377
7330
|
SINCE_2_7)
|
7378
7331
|
|
7379
7332
|
assert_diagnoses(
|
7380
7333
|
[:error, :ordinary_param_defined],
|
7381
|
-
%q{m do |a, b|
|
7334
|
+
%q{m do |a, b| _1 end },
|
7382
7335
|
%q{ ^^ location},
|
7383
7336
|
SINCE_2_7)
|
7384
7337
|
|
7385
7338
|
assert_diagnoses(
|
7386
7339
|
[:error, :ordinary_param_defined],
|
7387
|
-
%q{m { |x =
|
7340
|
+
%q{m { |x = _1| }},
|
7388
7341
|
%q{ ^^ location},
|
7389
7342
|
SINCE_2_7)
|
7390
7343
|
|
7391
7344
|
assert_diagnoses(
|
7392
7345
|
[:error, :ordinary_param_defined],
|
7393
|
-
%q{m { |x:
|
7346
|
+
%q{m { |x: _1| }},
|
7394
7347
|
%q{ ^^ location},
|
7395
7348
|
SINCE_2_7)
|
7396
7349
|
|
@@ -7398,77 +7351,161 @@ class TestParser < Minitest::Test
|
|
7398
7351
|
|
7399
7352
|
assert_diagnoses(
|
7400
7353
|
[:error, :ordinary_param_defined],
|
7401
|
-
%q{->() {
|
7354
|
+
%q{->() { _1 } },
|
7402
7355
|
%q{ ^^ location},
|
7403
7356
|
SINCE_2_7)
|
7404
7357
|
|
7405
7358
|
assert_diagnoses(
|
7406
7359
|
[:error, :ordinary_param_defined],
|
7407
|
-
%q{->(a) {
|
7360
|
+
%q{->(a) { _1 } },
|
7408
7361
|
%q{ ^^ location},
|
7409
7362
|
SINCE_2_7)
|
7410
7363
|
|
7411
7364
|
assert_diagnoses(
|
7412
7365
|
[:error, :ordinary_param_defined],
|
7413
|
-
%q{->() do
|
7366
|
+
%q{->() do _1 end },
|
7414
7367
|
%q{ ^^ location},
|
7415
7368
|
SINCE_2_7)
|
7416
7369
|
|
7417
7370
|
assert_diagnoses(
|
7418
7371
|
[:error, :ordinary_param_defined],
|
7419
|
-
%q{->(a, b) do
|
7372
|
+
%q{->(a, b) do _1 end},
|
7420
7373
|
%q{ ^^ location},
|
7421
7374
|
SINCE_2_7)
|
7422
7375
|
|
7423
7376
|
assert_diagnoses(
|
7424
7377
|
[:error, :ordinary_param_defined],
|
7425
|
-
%q{->(x
|
7378
|
+
%q{->(x=_1) {}},
|
7426
7379
|
%q{ ^^ location},
|
7427
7380
|
SINCE_2_7)
|
7428
7381
|
|
7429
7382
|
assert_diagnoses(
|
7430
7383
|
[:error, :ordinary_param_defined],
|
7431
|
-
%q{->(x:
|
7384
|
+
%q{->(x: _1) {}},
|
7432
7385
|
%q{ ^^ location},
|
7433
7386
|
SINCE_2_7)
|
7434
7387
|
|
7435
7388
|
assert_diagnoses(
|
7436
7389
|
[:error, :ordinary_param_defined],
|
7437
|
-
%q{proc {|;a|
|
7390
|
+
%q{proc {|;a| _1}},
|
7438
7391
|
%q{ ^^ location},
|
7439
7392
|
SINCE_2_7)
|
7440
7393
|
|
7441
7394
|
assert_diagnoses(
|
7442
7395
|
[:error, :ordinary_param_defined],
|
7443
|
-
"proc {|\n|
|
7396
|
+
"proc {|\n| _1}",
|
7444
7397
|
%q{ ^^ location},
|
7445
7398
|
SINCE_2_7)
|
7446
7399
|
end
|
7447
7400
|
|
7448
7401
|
def test_numparam_outside_block
|
7402
|
+
assert_parses(
|
7403
|
+
s(:class,
|
7404
|
+
s(:const, nil, :A), nil,
|
7405
|
+
s(:send, nil, :_1)),
|
7406
|
+
%q{class A; _1; end},
|
7407
|
+
%q{},
|
7408
|
+
SINCE_2_7)
|
7409
|
+
|
7410
|
+
assert_parses(
|
7411
|
+
s(:module,
|
7412
|
+
s(:const, nil, :A),
|
7413
|
+
s(:send, nil, :_1)),
|
7414
|
+
%q{module A; _1; end},
|
7415
|
+
%q{},
|
7416
|
+
SINCE_2_7)
|
7417
|
+
|
7418
|
+
assert_parses(
|
7419
|
+
s(:sclass,
|
7420
|
+
s(:lvar, :foo),
|
7421
|
+
s(:send, nil, :_1)),
|
7422
|
+
%q{class << foo; _1; end},
|
7423
|
+
%q{},
|
7424
|
+
SINCE_2_7)
|
7425
|
+
|
7426
|
+
assert_parses(
|
7427
|
+
s(:defs,
|
7428
|
+
s(:self), :m,
|
7429
|
+
s(:args),
|
7430
|
+
s(:send, nil, :_1)),
|
7431
|
+
%q{def self.m; _1; end},
|
7432
|
+
%q{},
|
7433
|
+
SINCE_2_7)
|
7434
|
+
|
7435
|
+
assert_parses(
|
7436
|
+
s(:send, nil, :_1),
|
7437
|
+
%q{_1},
|
7438
|
+
%q{},
|
7439
|
+
SINCE_2_7)
|
7440
|
+
end
|
7441
|
+
|
7442
|
+
def test_assignment_to_numparams
|
7443
|
+
assert_parses(
|
7444
|
+
s(:block,
|
7445
|
+
s(:send, nil, :proc),
|
7446
|
+
s(:args),
|
7447
|
+
s(:lvasgn, :_1,
|
7448
|
+
s(:nil))),
|
7449
|
+
%q{proc {_1 = nil}},
|
7450
|
+
%q{},
|
7451
|
+
SINCE_2_7)
|
7452
|
+
|
7449
7453
|
assert_diagnoses(
|
7450
|
-
[:error, :
|
7451
|
-
%q{
|
7452
|
-
%q{
|
7454
|
+
[:error, :cant_assign_to_numparam, { :name => '_1' }],
|
7455
|
+
%q{proc {_1; _1 = nil}},
|
7456
|
+
%q{ ^^ location},
|
7453
7457
|
SINCE_2_7)
|
7454
7458
|
|
7455
7459
|
assert_diagnoses(
|
7456
|
-
[:error, :
|
7457
|
-
%q{
|
7460
|
+
[:error, :cant_assign_to_numparam, { :name => '_1' }],
|
7461
|
+
%q{proc {_1; _1, foo = [nil, nil]}},
|
7458
7462
|
%q{ ^^ location},
|
7459
7463
|
SINCE_2_7)
|
7460
7464
|
|
7461
7465
|
assert_diagnoses(
|
7462
|
-
[:error, :
|
7463
|
-
%q{
|
7464
|
-
%q{
|
7466
|
+
[:error, :cant_assign_to_numparam, { :name => '_1' }],
|
7467
|
+
%q{proc {_9; _1 = nil}},
|
7468
|
+
%q{ ^^ location},
|
7465
7469
|
SINCE_2_7)
|
7466
7470
|
|
7467
7471
|
assert_diagnoses(
|
7468
|
-
[:error, :
|
7469
|
-
%q{
|
7470
|
-
%q{
|
7472
|
+
[:error, :cant_assign_to_numparam, { :name => '_9' }],
|
7473
|
+
%q{proc {_1; _9 = nil}},
|
7474
|
+
%q{ ^^ location},
|
7475
|
+
SINCE_2_7)
|
7476
|
+
|
7477
|
+
refute_diagnoses(
|
7478
|
+
%q{proc { _1 = nil; _1}},
|
7479
|
+
SINCE_2_7)
|
7480
|
+
end
|
7481
|
+
|
7482
|
+
def test_numparams_in_nested_blocks
|
7483
|
+
assert_diagnoses(
|
7484
|
+
[:error, :numparam_used_in_outer_scope],
|
7485
|
+
%q{foo { _1; bar { _2 }; }},
|
7486
|
+
%q{ ^^ location},
|
7471
7487
|
SINCE_2_7)
|
7488
|
+
|
7489
|
+
assert_diagnoses(
|
7490
|
+
[:error, :numparam_used_in_outer_scope],
|
7491
|
+
%q{-> { _1; -> { _2 }; }},
|
7492
|
+
%q{ ^^ location},
|
7493
|
+
SINCE_2_7)
|
7494
|
+
|
7495
|
+
[
|
7496
|
+
['class A', 'end'],
|
7497
|
+
['class << foo', 'end'],
|
7498
|
+
['def m', 'end'],
|
7499
|
+
['def self.m', 'end']
|
7500
|
+
].each do |open_scope, close_scope|
|
7501
|
+
refute_diagnoses(
|
7502
|
+
"proc { _1; #{open_scope}; proc { _2 }; #{close_scope}; }",
|
7503
|
+
SINCE_2_7)
|
7504
|
+
|
7505
|
+
refute_diagnoses(
|
7506
|
+
"-> { _1; #{open_scope}; -> { _2 }; #{close_scope}; }",
|
7507
|
+
SINCE_2_7)
|
7508
|
+
end
|
7472
7509
|
end
|
7473
7510
|
|
7474
7511
|
def test_ruby_bug_15789
|
@@ -7480,9 +7517,9 @@ class TestParser < Minitest::Test
|
|
7480
7517
|
s(:optarg, :a,
|
7481
7518
|
s(:numblock,
|
7482
7519
|
s(:lambda), 1,
|
7483
|
-
s(:
|
7520
|
+
s(:lvar, :_1)))),
|
7484
7521
|
s(:lvar, :a))),
|
7485
|
-
%q{m ->(a = ->{
|
7522
|
+
%q{m ->(a = ->{_1}) {a}},
|
7486
7523
|
%q{},
|
7487
7524
|
SINCE_2_7)
|
7488
7525
|
|
@@ -7494,9 +7531,9 @@ class TestParser < Minitest::Test
|
|
7494
7531
|
s(:kwoptarg, :a,
|
7495
7532
|
s(:numblock,
|
7496
7533
|
s(:lambda), 1,
|
7497
|
-
s(:
|
7534
|
+
s(:lvar, :_1)))),
|
7498
7535
|
s(:lvar, :a))),
|
7499
|
-
%q{m ->(a: ->{
|
7536
|
+
%q{m ->(a: ->{_1}) {a}},
|
7500
7537
|
%q{},
|
7501
7538
|
SINCE_2_7)
|
7502
7539
|
end
|
@@ -7613,13 +7650,6 @@ class TestParser < Minitest::Test
|
|
7613
7650
|
%Q{a #\n#\n&.foo\n},
|
7614
7651
|
%q{},
|
7615
7652
|
SINCE_2_7)
|
7616
|
-
|
7617
|
-
assert_parses(
|
7618
|
-
s(:meth_ref,
|
7619
|
-
s(:send, nil, :a), :foo),
|
7620
|
-
%Q{a #\n#\n.:foo\n},
|
7621
|
-
%q{},
|
7622
|
-
SINCE_2_7)
|
7623
7653
|
end
|
7624
7654
|
|
7625
7655
|
def test_comments_before_leading_dot__before_27
|
@@ -7641,4 +7671,1627 @@ class TestParser < Minitest::Test
|
|
7641
7671
|
%q{ ^ location},
|
7642
7672
|
ALL_VERSIONS - SINCE_2_7)
|
7643
7673
|
end
|
7674
|
+
|
7675
|
+
def test_circular_argument_reference_error
|
7676
|
+
assert_diagnoses(
|
7677
|
+
[:error, :circular_argument_reference, { :var_name => 'foo' }],
|
7678
|
+
%q{def m(foo = foo) end},
|
7679
|
+
%q{ ^^^ location},
|
7680
|
+
SINCE_2_7)
|
7681
|
+
|
7682
|
+
assert_diagnoses(
|
7683
|
+
[:error, :circular_argument_reference, { :var_name => 'foo' }],
|
7684
|
+
%q{def m(foo: foo) end},
|
7685
|
+
%q{ ^^^ location},
|
7686
|
+
SINCE_2_7)
|
7687
|
+
|
7688
|
+
assert_diagnoses(
|
7689
|
+
[:error, :circular_argument_reference, { :var_name => 'foo' }],
|
7690
|
+
%q{m { |foo = foo| } },
|
7691
|
+
%q{ ^^^ location},
|
7692
|
+
SINCE_2_7)
|
7693
|
+
|
7694
|
+
assert_diagnoses(
|
7695
|
+
[:error, :circular_argument_reference, { :var_name => 'foo' }],
|
7696
|
+
%q{m { |foo: foo| } },
|
7697
|
+
%q{ ^^^ location},
|
7698
|
+
SINCE_2_7)
|
7699
|
+
|
7700
|
+
# Traversing
|
7701
|
+
|
7702
|
+
assert_diagnoses(
|
7703
|
+
[:error, :circular_argument_reference, { :var_name => 'foo' }],
|
7704
|
+
%q{def m(foo = class << foo; end) end},
|
7705
|
+
%q{ ^^^ location},
|
7706
|
+
SINCE_2_7)
|
7707
|
+
|
7708
|
+
assert_diagnoses(
|
7709
|
+
[:error, :circular_argument_reference, { :var_name => 'foo' }],
|
7710
|
+
%q{def m(foo = def foo.m; end); end},
|
7711
|
+
%q{ ^^^ location},
|
7712
|
+
SINCE_2_7)
|
7713
|
+
|
7714
|
+
assert_diagnoses(
|
7715
|
+
[:error, :circular_argument_reference, { :var_name => 'foo' }],
|
7716
|
+
%q{m { |foo = proc { 1 + foo }| } },
|
7717
|
+
%q{ ^^^ location},
|
7718
|
+
SINCE_2_7)
|
7719
|
+
|
7720
|
+
# Valid cases
|
7721
|
+
|
7722
|
+
[
|
7723
|
+
'm { |foo = class A; foo; end| }',
|
7724
|
+
'm { |foo = class << self; foo; end| }',
|
7725
|
+
'm { |foo = def m(foo = bar); foo; end| }',
|
7726
|
+
'm { |foo = def m(bar = foo); foo; end| }',
|
7727
|
+
'm { |foo = def self.m(bar = foo); foo; end| }',
|
7728
|
+
'def m(foo = def m; foo; end) end',
|
7729
|
+
'def m(foo = def self.m; foo; end) end',
|
7730
|
+
'm { |foo = proc { |bar| 1 + foo }| }',
|
7731
|
+
'm { |foo = proc { || 1 + foo }| }'
|
7732
|
+
].each do |code|
|
7733
|
+
refute_diagnoses(code, SINCE_2_7)
|
7734
|
+
end
|
7735
|
+
end
|
7736
|
+
|
7737
|
+
def test_forward_args
|
7738
|
+
assert_parses(
|
7739
|
+
s(:def, :foo,
|
7740
|
+
s(:forward_args),
|
7741
|
+
s(:send, nil, :bar,
|
7742
|
+
s(:forwarded_args))),
|
7743
|
+
%q{def foo(...); bar(...); end},
|
7744
|
+
%q{ ~ begin (forward_args)
|
7745
|
+
| ~~~~~ expression (forward_args)
|
7746
|
+
| ~ end (forward_args)
|
7747
|
+
| ~~~ expression (send.forwarded_args)},
|
7748
|
+
SINCE_2_7)
|
7749
|
+
|
7750
|
+
assert_parses(
|
7751
|
+
s(:def, :foo,
|
7752
|
+
s(:forward_args),
|
7753
|
+
s(:super,
|
7754
|
+
s(:forwarded_args))),
|
7755
|
+
%q{def foo(...); super(...); end},
|
7756
|
+
%q{ ~ begin (forward_args)
|
7757
|
+
| ~~~~~ expression (forward_args)
|
7758
|
+
| ~ end (forward_args)
|
7759
|
+
| ~~~ expression (super.forwarded_args)},
|
7760
|
+
SINCE_2_7)
|
7761
|
+
|
7762
|
+
assert_parses(
|
7763
|
+
s(:def, :foo,
|
7764
|
+
s(:forward_args),
|
7765
|
+
nil),
|
7766
|
+
%q{def foo(...); end},
|
7767
|
+
%q{},
|
7768
|
+
SINCE_2_7)
|
7769
|
+
|
7770
|
+
assert_diagnoses(
|
7771
|
+
[:error, :block_and_blockarg],
|
7772
|
+
%q{def foo(...) bar(...) { }; end},
|
7773
|
+
%q{ ^^^ location
|
7774
|
+
| ~ highlights (0)},
|
7775
|
+
SINCE_2_7)
|
7776
|
+
|
7777
|
+
assert_diagnoses(
|
7778
|
+
[:error, :unexpected_token, { :token => 'tBDOT3' }],
|
7779
|
+
%q{foo do |...| end},
|
7780
|
+
%q{ ^^^ location},
|
7781
|
+
SINCE_2_7)
|
7782
|
+
|
7783
|
+
assert_diagnoses(
|
7784
|
+
[:error, :unexpected_token, { :token => 'tBDOT3' }],
|
7785
|
+
%q{foo { |...| }},
|
7786
|
+
%q{ ^^^ location},
|
7787
|
+
SINCE_2_7)
|
7788
|
+
|
7789
|
+
assert_diagnoses(
|
7790
|
+
[:error, :unexpected_token, { :token => 'tBDOT3' }],
|
7791
|
+
%q{def foo(x,y,z); bar(...); end},
|
7792
|
+
%q{ ^^^ location},
|
7793
|
+
SINCE_2_7)
|
7794
|
+
|
7795
|
+
assert_diagnoses(
|
7796
|
+
[:error, :unexpected_token, { :token => 'tBDOT3' }],
|
7797
|
+
%q{def foo(x,y,z); super(...); end},
|
7798
|
+
%q{ ^^^ location},
|
7799
|
+
SINCE_2_7)
|
7800
|
+
|
7801
|
+
assert_diagnoses(
|
7802
|
+
[:error, :unexpected_token, { :token => 'tDOT3' }],
|
7803
|
+
%q{->... {}},
|
7804
|
+
%q{ ^^^ location},
|
7805
|
+
SINCE_2_7)
|
7806
|
+
|
7807
|
+
assert_diagnoses(
|
7808
|
+
[:error, :unexpected_token, { :token => 'tBDOT3' }],
|
7809
|
+
%q{->(...) {}},
|
7810
|
+
%q{ ^^^ location},
|
7811
|
+
SINCE_2_7)
|
7812
|
+
|
7813
|
+
# Here and below the parser asssumes that
|
7814
|
+
# it can be a beginningless range, so the error comes after reducing right paren
|
7815
|
+
assert_diagnoses(
|
7816
|
+
[:error, :unexpected_token, { :token => 'tRPAREN' }],
|
7817
|
+
%q{def foo(...); yield(...); end},
|
7818
|
+
%q{ ^ location},
|
7819
|
+
SINCE_2_7)
|
7820
|
+
|
7821
|
+
assert_diagnoses(
|
7822
|
+
[:error, :unexpected_token, { :token => 'tRPAREN' }],
|
7823
|
+
%q{def foo(...); return(...); end},
|
7824
|
+
%q{ ^ location},
|
7825
|
+
SINCE_2_7)
|
7826
|
+
|
7827
|
+
assert_diagnoses(
|
7828
|
+
[:error, :unexpected_token, { :token => 'tRPAREN' }],
|
7829
|
+
%q{def foo(...); a = (...); end},
|
7830
|
+
%q{ ^ location},
|
7831
|
+
SINCE_2_7)
|
7832
|
+
|
7833
|
+
assert_diagnoses(
|
7834
|
+
[:error, :unexpected_token, { :token => 'tRBRACK' }],
|
7835
|
+
%q{def foo(...); [...]; end},
|
7836
|
+
%q{ ^ location},
|
7837
|
+
SINCE_2_7)
|
7838
|
+
|
7839
|
+
assert_diagnoses(
|
7840
|
+
[:error, :unexpected_token, { :token => 'tRBRACK' }],
|
7841
|
+
%q{def foo(...) bar[...]; end},
|
7842
|
+
%q{ ^ location},
|
7843
|
+
SINCE_2_7)
|
7844
|
+
|
7845
|
+
assert_diagnoses(
|
7846
|
+
[:error, :unexpected_token, { :token => 'tRBRACK' }],
|
7847
|
+
%q{def foo(...) bar[...] = x; end},
|
7848
|
+
%q{ ^ location},
|
7849
|
+
SINCE_2_7)
|
7850
|
+
|
7851
|
+
assert_diagnoses(
|
7852
|
+
[:error, :unexpected_token, { :token => 'tRPAREN' }],
|
7853
|
+
%q{def foo(...) defined?(...); end},
|
7854
|
+
%q{ ^ location},
|
7855
|
+
SINCE_2_7)
|
7856
|
+
|
7857
|
+
assert_diagnoses(
|
7858
|
+
[:error, :unexpected_token, { :token => 'tDOT3' }],
|
7859
|
+
%q{def foo ...; end},
|
7860
|
+
%q{ ^^^ location},
|
7861
|
+
SINCE_2_7)
|
7862
|
+
end
|
7863
|
+
|
7864
|
+
def test_erange_without_parentheses_at_eol
|
7865
|
+
assert_diagnoses(
|
7866
|
+
[:warning, :triple_dot_at_eol],
|
7867
|
+
%Q{1...\n2},
|
7868
|
+
%q{ ^^^ location},
|
7869
|
+
SINCE_2_7)
|
7870
|
+
|
7871
|
+
refute_diagnoses('(1...)', SINCE_2_7)
|
7872
|
+
refute_diagnoses("(1...\n)", SINCE_2_7)
|
7873
|
+
refute_diagnoses("[1...\n]", SINCE_2_7)
|
7874
|
+
refute_diagnoses("{a: 1...\n2}", SINCE_2_7)
|
7875
|
+
end
|
7876
|
+
|
7877
|
+
def test_embedded_document_with_eof
|
7878
|
+
refute_diagnoses("=begin\n""=end", SINCE_2_7)
|
7879
|
+
refute_diagnoses("=begin\n""=end\0", SINCE_2_7)
|
7880
|
+
refute_diagnoses("=begin\n""=end\C-d", SINCE_2_7)
|
7881
|
+
refute_diagnoses("=begin\n""=end\C-z", SINCE_2_7)
|
7882
|
+
|
7883
|
+
assert_diagnoses(
|
7884
|
+
[:fatal, :embedded_document],
|
7885
|
+
"=begin\n",
|
7886
|
+
%q{},
|
7887
|
+
SINCE_2_7)
|
7888
|
+
|
7889
|
+
assert_diagnoses(
|
7890
|
+
[:fatal, :embedded_document],
|
7891
|
+
"=begin",
|
7892
|
+
%q{},
|
7893
|
+
SINCE_2_7)
|
7894
|
+
end
|
7895
|
+
|
7896
|
+
def test_interp_digit_var
|
7897
|
+
# '#@1'
|
7898
|
+
assert_parses(
|
7899
|
+
s(:str, '#@1'),
|
7900
|
+
%q{ '#@1' },
|
7901
|
+
%q{},
|
7902
|
+
ALL_VERSIONS)
|
7903
|
+
|
7904
|
+
assert_parses(
|
7905
|
+
s(:str, '#@@1'),
|
7906
|
+
%q{ '#@@1' },
|
7907
|
+
%q{},
|
7908
|
+
ALL_VERSIONS)
|
7909
|
+
|
7910
|
+
# <<-'HERE'
|
7911
|
+
# #@1
|
7912
|
+
# HERE
|
7913
|
+
assert_parses(
|
7914
|
+
s(:str, '#@1' + "\n"),
|
7915
|
+
%q{<<-'HERE'!#@1!HERE}.gsub('!', "\n"),
|
7916
|
+
%q{},
|
7917
|
+
ALL_VERSIONS)
|
7918
|
+
|
7919
|
+
assert_parses(
|
7920
|
+
s(:str, '#@@1' + "\n"),
|
7921
|
+
%q{<<-'HERE'!#@@1!HERE}.gsub('!', "\n"),
|
7922
|
+
%q{},
|
7923
|
+
ALL_VERSIONS)
|
7924
|
+
|
7925
|
+
# %q{#@1}
|
7926
|
+
assert_parses(
|
7927
|
+
s(:str, '#@1'),
|
7928
|
+
%q{ %q{#@1} },
|
7929
|
+
%q{},
|
7930
|
+
ALL_VERSIONS)
|
7931
|
+
|
7932
|
+
assert_parses(
|
7933
|
+
s(:str, '#@@1'),
|
7934
|
+
%q{ %q{#@@1} },
|
7935
|
+
%q{},
|
7936
|
+
ALL_VERSIONS)
|
7937
|
+
|
7938
|
+
# "#@1"
|
7939
|
+
assert_diagnoses(
|
7940
|
+
[:error, :ivar_name, { :name => '@1' }],
|
7941
|
+
%q{ "#@1" },
|
7942
|
+
%q{ ^^ location},
|
7943
|
+
ALL_VERSIONS - SINCE_2_7)
|
7944
|
+
|
7945
|
+
assert_diagnoses(
|
7946
|
+
[:error, :cvar_name, { :name => '@@1' }],
|
7947
|
+
%q{ "#@@1" },
|
7948
|
+
%q{ ^^^ location},
|
7949
|
+
ALL_VERSIONS - SINCE_2_7)
|
7950
|
+
|
7951
|
+
assert_parses(
|
7952
|
+
s(:str, '#@1'),
|
7953
|
+
%q{ "#@1" },
|
7954
|
+
%q{},
|
7955
|
+
SINCE_2_7)
|
7956
|
+
|
7957
|
+
assert_parses(
|
7958
|
+
s(:str, '#@@1'),
|
7959
|
+
%q{ "#@@1" },
|
7960
|
+
%q{},
|
7961
|
+
SINCE_2_7)
|
7962
|
+
|
7963
|
+
# <<-"HERE"
|
7964
|
+
# #@1
|
7965
|
+
# HERE
|
7966
|
+
assert_diagnoses(
|
7967
|
+
[:error, :ivar_name, { :name => '@1' }],
|
7968
|
+
%q{ <<-"HERE"!#@1!HERE }.gsub('!', "\n"),
|
7969
|
+
%q{ ^^ location},
|
7970
|
+
ALL_VERSIONS - SINCE_2_7)
|
7971
|
+
|
7972
|
+
assert_diagnoses(
|
7973
|
+
[:error, :cvar_name, { :name => '@@1' }],
|
7974
|
+
%q{ <<-"HERE"!#@@1!HERE }.gsub('!', "\n"),
|
7975
|
+
%q{ ^^^ location},
|
7976
|
+
ALL_VERSIONS - SINCE_2_7)
|
7977
|
+
|
7978
|
+
assert_parses(
|
7979
|
+
s(:str, '#@1' + "\n"),
|
7980
|
+
%q{<<-"HERE"!#@1!HERE}.gsub('!', "\n"),
|
7981
|
+
%q{},
|
7982
|
+
SINCE_2_7)
|
7983
|
+
|
7984
|
+
assert_parses(
|
7985
|
+
s(:str, '#@@1' + "\n"),
|
7986
|
+
%q{<<-"HERE"!#@@1!HERE}.gsub('!', "\n"),
|
7987
|
+
%q{},
|
7988
|
+
SINCE_2_7)
|
7989
|
+
|
7990
|
+
# %{#@1}
|
7991
|
+
assert_diagnoses(
|
7992
|
+
[:error, :ivar_name, { :name => '@1' }],
|
7993
|
+
%q{ %{#@1} },
|
7994
|
+
%q{ ^^ location},
|
7995
|
+
ALL_VERSIONS - SINCE_2_7)
|
7996
|
+
|
7997
|
+
assert_diagnoses(
|
7998
|
+
[:error, :cvar_name, { :name => '@@1' }],
|
7999
|
+
%q{ %{#@@1} },
|
8000
|
+
%q{ ^^^ location},
|
8001
|
+
ALL_VERSIONS - SINCE_2_7)
|
8002
|
+
|
8003
|
+
assert_parses(
|
8004
|
+
s(:str, '#@1'),
|
8005
|
+
%q{ %{#@1} },
|
8006
|
+
%q{},
|
8007
|
+
SINCE_2_7)
|
8008
|
+
|
8009
|
+
assert_parses(
|
8010
|
+
s(:str, '#@@1'),
|
8011
|
+
%q{ %{#@@1} },
|
8012
|
+
%q{},
|
8013
|
+
SINCE_2_7)
|
8014
|
+
|
8015
|
+
# %Q{#@1}
|
8016
|
+
assert_diagnoses(
|
8017
|
+
[:error, :ivar_name, { :name => '@1' }],
|
8018
|
+
%q{ %Q{#@1} },
|
8019
|
+
%q{ ^^ location},
|
8020
|
+
ALL_VERSIONS - SINCE_2_7)
|
8021
|
+
|
8022
|
+
assert_diagnoses(
|
8023
|
+
[:error, :cvar_name, { :name => '@@1' }],
|
8024
|
+
%q{ %Q{#@@1} },
|
8025
|
+
%q{ ^^^ location},
|
8026
|
+
ALL_VERSIONS - SINCE_2_7)
|
8027
|
+
|
8028
|
+
assert_parses(
|
8029
|
+
s(:str, '#@1'),
|
8030
|
+
%q{ %Q{#@1} },
|
8031
|
+
%q{},
|
8032
|
+
SINCE_2_7)
|
8033
|
+
|
8034
|
+
assert_parses(
|
8035
|
+
s(:str, '#@@1'),
|
8036
|
+
%q{ %Q{#@@1} },
|
8037
|
+
%q{},
|
8038
|
+
SINCE_2_7)
|
8039
|
+
|
8040
|
+
# %w[#@1]
|
8041
|
+
assert_parses(
|
8042
|
+
s(:array,
|
8043
|
+
s(:str, '#@1')),
|
8044
|
+
%q{ %w[ #@1 ] },
|
8045
|
+
%q{},
|
8046
|
+
ALL_VERSIONS)
|
8047
|
+
|
8048
|
+
assert_parses(
|
8049
|
+
s(:array,
|
8050
|
+
s(:str, '#@@1')),
|
8051
|
+
%q{ %w[ #@@1 ] },
|
8052
|
+
%q{},
|
8053
|
+
ALL_VERSIONS)
|
8054
|
+
|
8055
|
+
# %W[#@1]
|
8056
|
+
assert_diagnoses(
|
8057
|
+
[:error, :ivar_name, { :name => '@1' }],
|
8058
|
+
%q{ %W[#@1] },
|
8059
|
+
%q{ ^^ location},
|
8060
|
+
ALL_VERSIONS - SINCE_2_7)
|
8061
|
+
|
8062
|
+
assert_diagnoses(
|
8063
|
+
[:error, :cvar_name, { :name => '@@1' }],
|
8064
|
+
%q{ %W[#@@1] },
|
8065
|
+
%q{ ^^^ location},
|
8066
|
+
ALL_VERSIONS - SINCE_2_7)
|
8067
|
+
|
8068
|
+
assert_parses(
|
8069
|
+
s(:array,
|
8070
|
+
s(:str, '#@1')),
|
8071
|
+
%q{ %W[#@1] },
|
8072
|
+
%q{},
|
8073
|
+
SINCE_2_7)
|
8074
|
+
|
8075
|
+
assert_parses(
|
8076
|
+
s(:array,
|
8077
|
+
s(:str, '#@@1')),
|
8078
|
+
%q{ %W[#@@1] },
|
8079
|
+
%q{},
|
8080
|
+
SINCE_2_7)
|
8081
|
+
|
8082
|
+
# %i[#@1]
|
8083
|
+
assert_parses(
|
8084
|
+
s(:array,
|
8085
|
+
s(:sym, :'#@1')),
|
8086
|
+
%q{ %i[ #@1 ] },
|
8087
|
+
%q{},
|
8088
|
+
SINCE_2_0)
|
8089
|
+
|
8090
|
+
assert_parses(
|
8091
|
+
s(:array,
|
8092
|
+
s(:sym, :'#@@1')),
|
8093
|
+
%q{ %i[ #@@1 ] },
|
8094
|
+
%q{},
|
8095
|
+
SINCE_2_0)
|
8096
|
+
|
8097
|
+
# %I[#@1]
|
8098
|
+
assert_diagnoses(
|
8099
|
+
[:error, :ivar_name, { :name => '@1' }],
|
8100
|
+
%q{ %I[#@1] },
|
8101
|
+
%q{ ^^ location},
|
8102
|
+
SINCE_2_0 - SINCE_2_7)
|
8103
|
+
|
8104
|
+
assert_diagnoses(
|
8105
|
+
[:error, :cvar_name, { :name => '@@1' }],
|
8106
|
+
%q{ %I[#@@1] },
|
8107
|
+
%q{ ^^^ location},
|
8108
|
+
SINCE_2_0 - SINCE_2_7)
|
8109
|
+
|
8110
|
+
assert_parses(
|
8111
|
+
s(:array,
|
8112
|
+
s(:sym, :'#@1')),
|
8113
|
+
%q{ %I[#@1] },
|
8114
|
+
%q{},
|
8115
|
+
SINCE_2_7)
|
8116
|
+
|
8117
|
+
assert_parses(
|
8118
|
+
s(:array,
|
8119
|
+
s(:sym, :'#@@1')),
|
8120
|
+
%q{ %I[#@@1] },
|
8121
|
+
%q{},
|
8122
|
+
SINCE_2_7)
|
8123
|
+
|
8124
|
+
# :'#@1'
|
8125
|
+
assert_parses(
|
8126
|
+
s(:sym, :'#@1'),
|
8127
|
+
%q{ :'#@1' },
|
8128
|
+
%q{},
|
8129
|
+
ALL_VERSIONS)
|
8130
|
+
|
8131
|
+
assert_parses(
|
8132
|
+
s(:sym, :'#@@1'),
|
8133
|
+
%q{ :'#@@1' },
|
8134
|
+
%q{},
|
8135
|
+
ALL_VERSIONS)
|
8136
|
+
|
8137
|
+
# %s{#@1}
|
8138
|
+
assert_parses(
|
8139
|
+
s(:sym, :'#@1'),
|
8140
|
+
%q{ %s{#@1} },
|
8141
|
+
%q{},
|
8142
|
+
ALL_VERSIONS)
|
8143
|
+
|
8144
|
+
assert_parses(
|
8145
|
+
s(:sym, :'#@@1'),
|
8146
|
+
%q{ %s{#@@1} },
|
8147
|
+
%q{},
|
8148
|
+
ALL_VERSIONS)
|
8149
|
+
|
8150
|
+
# :"#@1"
|
8151
|
+
assert_diagnoses(
|
8152
|
+
[:error, :ivar_name, { :name => '@1' }],
|
8153
|
+
%q{ :"#@1" },
|
8154
|
+
%q{ ^^ location},
|
8155
|
+
ALL_VERSIONS - SINCE_2_7)
|
8156
|
+
|
8157
|
+
assert_diagnoses(
|
8158
|
+
[:error, :cvar_name, { :name => '@@1' }],
|
8159
|
+
%q{ :"#@@1" },
|
8160
|
+
%q{ ^^^ location},
|
8161
|
+
ALL_VERSIONS - SINCE_2_7)
|
8162
|
+
|
8163
|
+
assert_parses(
|
8164
|
+
s(:sym, :'#@1'),
|
8165
|
+
%q{ :"#@1" },
|
8166
|
+
%q{},
|
8167
|
+
SINCE_2_7)
|
8168
|
+
|
8169
|
+
assert_parses(
|
8170
|
+
s(:sym, :'#@@1'),
|
8171
|
+
%q{ :"#@@1" },
|
8172
|
+
%q{},
|
8173
|
+
SINCE_2_7)
|
8174
|
+
|
8175
|
+
# /#@1/
|
8176
|
+
assert_diagnoses(
|
8177
|
+
[:error, :ivar_name, { :name => '@1' }],
|
8178
|
+
%q{ /#@1/ },
|
8179
|
+
%q{ ^^ location},
|
8180
|
+
ALL_VERSIONS - SINCE_2_7)
|
8181
|
+
|
8182
|
+
assert_diagnoses(
|
8183
|
+
[:error, :cvar_name, { :name => '@@1' }],
|
8184
|
+
%q{ /#@@1/ },
|
8185
|
+
%q{ ^^^ location},
|
8186
|
+
ALL_VERSIONS - SINCE_2_7)
|
8187
|
+
|
8188
|
+
assert_parses(
|
8189
|
+
s(:regexp,
|
8190
|
+
s(:str, '#@1'),
|
8191
|
+
s(:regopt)),
|
8192
|
+
%q{ /#@1/ },
|
8193
|
+
%q{},
|
8194
|
+
SINCE_2_7)
|
8195
|
+
|
8196
|
+
assert_parses(
|
8197
|
+
s(:regexp,
|
8198
|
+
s(:str, '#@@1'),
|
8199
|
+
s(:regopt)),
|
8200
|
+
%q{ /#@@1/ },
|
8201
|
+
%q{},
|
8202
|
+
SINCE_2_7)
|
8203
|
+
|
8204
|
+
# %r{#@1}
|
8205
|
+
assert_diagnoses(
|
8206
|
+
[:error, :ivar_name, { :name => '@1' }],
|
8207
|
+
%q{ %r{#@1} },
|
8208
|
+
%q{ ^^ location},
|
8209
|
+
ALL_VERSIONS - SINCE_2_7)
|
8210
|
+
|
8211
|
+
assert_diagnoses(
|
8212
|
+
[:error, :cvar_name, { :name => '@@1' }],
|
8213
|
+
%q{ %r{#@@1} },
|
8214
|
+
%q{ ^^^ location},
|
8215
|
+
ALL_VERSIONS - SINCE_2_7)
|
8216
|
+
|
8217
|
+
assert_parses(
|
8218
|
+
s(:regexp,
|
8219
|
+
s(:str, '#@1'),
|
8220
|
+
s(:regopt)),
|
8221
|
+
%q{ %r{#@1} },
|
8222
|
+
%q{},
|
8223
|
+
SINCE_2_7)
|
8224
|
+
|
8225
|
+
assert_parses(
|
8226
|
+
s(:regexp,
|
8227
|
+
s(:str, '#@@1'),
|
8228
|
+
s(:regopt)),
|
8229
|
+
%q{ %r{#@@1} },
|
8230
|
+
%q{},
|
8231
|
+
SINCE_2_7)
|
8232
|
+
|
8233
|
+
# %x{#@1}
|
8234
|
+
assert_diagnoses(
|
8235
|
+
[:error, :ivar_name, { :name => '@1' }],
|
8236
|
+
%q{ %x{#@1} },
|
8237
|
+
%q{ ^^ location},
|
8238
|
+
ALL_VERSIONS - SINCE_2_7)
|
8239
|
+
|
8240
|
+
assert_diagnoses(
|
8241
|
+
[:error, :cvar_name, { :name => '@@1' }],
|
8242
|
+
%q{ %x{#@@1} },
|
8243
|
+
%q{ ^^^ location},
|
8244
|
+
ALL_VERSIONS - SINCE_2_7)
|
8245
|
+
|
8246
|
+
assert_parses(
|
8247
|
+
s(:xstr,
|
8248
|
+
s(:str, '#@1')),
|
8249
|
+
%q{ %x{#@1} },
|
8250
|
+
%q{},
|
8251
|
+
SINCE_2_7)
|
8252
|
+
|
8253
|
+
assert_parses(
|
8254
|
+
s(:xstr,
|
8255
|
+
s(:str, '#@@1')),
|
8256
|
+
%q{ %x{#@@1} },
|
8257
|
+
%q{},
|
8258
|
+
SINCE_2_7)
|
8259
|
+
|
8260
|
+
# `#@1`
|
8261
|
+
assert_diagnoses(
|
8262
|
+
[:error, :ivar_name, { :name => '@1' }],
|
8263
|
+
%q{ `#@1` },
|
8264
|
+
%q{ ^^ location},
|
8265
|
+
ALL_VERSIONS - SINCE_2_7)
|
8266
|
+
|
8267
|
+
assert_diagnoses(
|
8268
|
+
[:error, :cvar_name, { :name => '@@1' }],
|
8269
|
+
%q{ `#@@1` },
|
8270
|
+
%q{ ^^^ location},
|
8271
|
+
ALL_VERSIONS - SINCE_2_7)
|
8272
|
+
|
8273
|
+
assert_parses(
|
8274
|
+
s(:xstr,
|
8275
|
+
s(:str, '#@1')),
|
8276
|
+
%q{ `#@1` },
|
8277
|
+
%q{},
|
8278
|
+
SINCE_2_7)
|
8279
|
+
|
8280
|
+
assert_parses(
|
8281
|
+
s(:xstr,
|
8282
|
+
s(:str, '#@@1')),
|
8283
|
+
%q{ `#@@1` },
|
8284
|
+
%q{},
|
8285
|
+
SINCE_2_7)
|
8286
|
+
|
8287
|
+
# <<-`HERE`
|
8288
|
+
# #@1
|
8289
|
+
# HERE
|
8290
|
+
assert_diagnoses(
|
8291
|
+
[:error, :ivar_name, { :name => '@1' }],
|
8292
|
+
%q{ <<-`HERE`!#@1!HERE }.gsub('!', "\n"),
|
8293
|
+
%q{ ^^ location},
|
8294
|
+
ALL_VERSIONS - SINCE_2_7)
|
8295
|
+
|
8296
|
+
assert_diagnoses(
|
8297
|
+
[:error, :cvar_name, { :name => '@@1' }],
|
8298
|
+
%q{ <<-`HERE`!#@@1!HERE }.gsub('!', "\n"),
|
8299
|
+
%q{ ^^^ location},
|
8300
|
+
ALL_VERSIONS - SINCE_2_7)
|
8301
|
+
|
8302
|
+
assert_parses(
|
8303
|
+
s(:xstr,
|
8304
|
+
s(:str, '#@1' + "\n")),
|
8305
|
+
%q{<<-`HERE`!#@1!HERE}.gsub('!', "\n"),
|
8306
|
+
%q{},
|
8307
|
+
SINCE_2_7)
|
8308
|
+
|
8309
|
+
assert_parses(
|
8310
|
+
s(:xstr,
|
8311
|
+
s(:str, '#@@1' + "\n")),
|
8312
|
+
%q{<<-`HERE`!#@@1!HERE}.gsub('!', "\n"),
|
8313
|
+
%q{},
|
8314
|
+
SINCE_2_7)
|
8315
|
+
end
|
8316
|
+
|
8317
|
+
def assert_parses_pattern_match(ast, code, source_maps = '', versions = SINCE_2_7)
|
8318
|
+
case_pre = "case foo; "
|
8319
|
+
source_maps_offset = case_pre.length
|
8320
|
+
source_maps_prefix = ' ' * source_maps_offset
|
8321
|
+
source_maps = source_maps
|
8322
|
+
.lines
|
8323
|
+
.map { |line| source_maps_prefix + line.sub(/^\s*\|/, '') }
|
8324
|
+
.join("\n")
|
8325
|
+
|
8326
|
+
assert_parses(
|
8327
|
+
s(:case_match,
|
8328
|
+
s(:lvar, :foo),
|
8329
|
+
ast,
|
8330
|
+
nil),
|
8331
|
+
"#{case_pre}#{code}; end",
|
8332
|
+
source_maps,
|
8333
|
+
SINCE_2_7
|
8334
|
+
)
|
8335
|
+
end
|
8336
|
+
|
8337
|
+
def test_pattern_matching_single_match
|
8338
|
+
assert_parses_pattern_match(
|
8339
|
+
s(:in_pattern,
|
8340
|
+
s(:match_var, :x),
|
8341
|
+
nil,
|
8342
|
+
s(:lvar, :x)),
|
8343
|
+
%q{in x then x},
|
8344
|
+
%q{~~ keyword (in_pattern)
|
8345
|
+
|~~~~~~~~~~~ expression (in_pattern)
|
8346
|
+
| ~~~~ begin (in_pattern)
|
8347
|
+
| ~ expression (in_pattern.match_var)
|
8348
|
+
| ~ name (in_pattern.match_var)}
|
8349
|
+
)
|
8350
|
+
end
|
8351
|
+
|
8352
|
+
def test_pattern_matching_no_body
|
8353
|
+
assert_parses_pattern_match(
|
8354
|
+
s(:in_pattern,
|
8355
|
+
s(:int, 1), nil, nil),
|
8356
|
+
%q{in 1}
|
8357
|
+
)
|
8358
|
+
end
|
8359
|
+
|
8360
|
+
def test_pattern_matching_if_unless_modifiers
|
8361
|
+
assert_parses_pattern_match(
|
8362
|
+
s(:in_pattern,
|
8363
|
+
s(:match_var, :x),
|
8364
|
+
s(:if_guard, s(:true)),
|
8365
|
+
s(:nil)
|
8366
|
+
),
|
8367
|
+
%q{in x if true; nil},
|
8368
|
+
%q{~~ keyword (in_pattern)
|
8369
|
+
|~~~~~~~~~~~~~~~~~ expression (in_pattern)
|
8370
|
+
| ~ begin (in_pattern)
|
8371
|
+
| ~~ keyword (in_pattern.if_guard)
|
8372
|
+
| ~~~~~~~ expression (in_pattern.if_guard)}
|
8373
|
+
)
|
8374
|
+
|
8375
|
+
assert_parses_pattern_match(
|
8376
|
+
s(:in_pattern,
|
8377
|
+
s(:match_var, :x),
|
8378
|
+
s(:unless_guard, s(:true)),
|
8379
|
+
s(:nil)
|
8380
|
+
),
|
8381
|
+
%q{in x unless true; nil},
|
8382
|
+
%q{~~ keyword (in_pattern)
|
8383
|
+
|~~~~~~~~~~~~~~~~~~~~~ expression (in_pattern)
|
8384
|
+
| ~ begin (in_pattern)
|
8385
|
+
| ~~~~~~ keyword (in_pattern.unless_guard)
|
8386
|
+
| ~~~~~~~~~~~ expression (in_pattern.unless_guard)}
|
8387
|
+
)
|
8388
|
+
end
|
8389
|
+
|
8390
|
+
def test_pattern_matching_pin_variable
|
8391
|
+
assert_parses_pattern_match(
|
8392
|
+
s(:in_pattern,
|
8393
|
+
s(:pin, s(:lvar, :foo)),
|
8394
|
+
nil,
|
8395
|
+
s(:nil)),
|
8396
|
+
%q{in ^foo then nil},
|
8397
|
+
%q{ ~ selector (in_pattern.pin)
|
8398
|
+
| ~~~~ expression (in_pattern.pin)
|
8399
|
+
| ~~~ name (in_pattern.pin.lvar)}
|
8400
|
+
)
|
8401
|
+
end
|
8402
|
+
|
8403
|
+
def test_pattern_matching_implicit_array_match
|
8404
|
+
assert_parses_pattern_match(
|
8405
|
+
s(:in_pattern,
|
8406
|
+
s(:array_pattern_with_tail,
|
8407
|
+
s(:match_var, :x)),
|
8408
|
+
nil,
|
8409
|
+
s(:nil)),
|
8410
|
+
%q{in x, then nil},
|
8411
|
+
%q{ ~ expression (in_pattern.array_pattern_with_tail)}
|
8412
|
+
)
|
8413
|
+
|
8414
|
+
assert_parses_pattern_match(
|
8415
|
+
s(:in_pattern,
|
8416
|
+
s(:array_pattern,
|
8417
|
+
s(:match_rest,
|
8418
|
+
s(:match_var, :x))),
|
8419
|
+
nil,
|
8420
|
+
s(:nil)),
|
8421
|
+
%q{in *x then nil},
|
8422
|
+
%q{ ~~ expression (in_pattern.array_pattern)
|
8423
|
+
| ~ operator (in_pattern.array_pattern.match_rest)
|
8424
|
+
| ~ name (in_pattern.array_pattern.match_rest.match_var)}
|
8425
|
+
)
|
8426
|
+
|
8427
|
+
assert_parses_pattern_match(
|
8428
|
+
s(:in_pattern,
|
8429
|
+
s(:array_pattern,
|
8430
|
+
s(:match_rest)),
|
8431
|
+
nil,
|
8432
|
+
s(:nil)),
|
8433
|
+
%q{in * then nil},
|
8434
|
+
%q{ ~ expression (in_pattern.array_pattern)
|
8435
|
+
| ~ operator (in_pattern.array_pattern.match_rest)}
|
8436
|
+
)
|
8437
|
+
|
8438
|
+
assert_parses_pattern_match(
|
8439
|
+
s(:in_pattern,
|
8440
|
+
s(:array_pattern,
|
8441
|
+
s(:match_var, :x),
|
8442
|
+
s(:match_var, :y)),
|
8443
|
+
nil,
|
8444
|
+
s(:nil)),
|
8445
|
+
%q{in x, y then nil},
|
8446
|
+
%q{ ~~~~ expression (in_pattern.array_pattern)}
|
8447
|
+
)
|
8448
|
+
|
8449
|
+
assert_parses_pattern_match(
|
8450
|
+
s(:in_pattern,
|
8451
|
+
s(:array_pattern_with_tail,
|
8452
|
+
s(:match_var, :x),
|
8453
|
+
s(:match_var, :y)),
|
8454
|
+
nil,
|
8455
|
+
s(:nil)),
|
8456
|
+
%q{in x, y, then nil},
|
8457
|
+
%q{ ~~~~ expression (in_pattern.array_pattern_with_tail)}
|
8458
|
+
)
|
8459
|
+
|
8460
|
+
assert_parses_pattern_match(
|
8461
|
+
s(:in_pattern,
|
8462
|
+
s(:array_pattern,
|
8463
|
+
s(:match_var, :x),
|
8464
|
+
s(:match_rest, s(:match_var, :y)),
|
8465
|
+
s(:match_var, :z)),
|
8466
|
+
nil,
|
8467
|
+
s(:nil)),
|
8468
|
+
%q{in x, *y, z then nil},
|
8469
|
+
%q{ ~~~~~~~~ expression (in_pattern.array_pattern)}
|
8470
|
+
)
|
8471
|
+
|
8472
|
+
assert_parses_pattern_match(
|
8473
|
+
s(:in_pattern,
|
8474
|
+
s(:array_pattern,
|
8475
|
+
s(:match_rest, s(:match_var, :x)),
|
8476
|
+
s(:match_var, :y),
|
8477
|
+
s(:match_var, :z)),
|
8478
|
+
nil,
|
8479
|
+
s(:nil)),
|
8480
|
+
%q{in *x, y, z then nil},
|
8481
|
+
%q{ ~~~~~~~~ expression (in_pattern.array_pattern)}
|
8482
|
+
)
|
8483
|
+
|
8484
|
+
assert_parses_pattern_match(
|
8485
|
+
s(:in_pattern,
|
8486
|
+
s(:array_pattern,
|
8487
|
+
s(:int, 1),
|
8488
|
+
s(:str, 'a'),
|
8489
|
+
s(:array_pattern),
|
8490
|
+
s(:hash_pattern)),
|
8491
|
+
nil,
|
8492
|
+
s(:nil)),
|
8493
|
+
%q{in 1, "a", [], {} then nil},
|
8494
|
+
%q{ ~~~~~~~~~~~~~~ expression (in_pattern.array_pattern)}
|
8495
|
+
)
|
8496
|
+
end
|
8497
|
+
|
8498
|
+
def test_pattern_matching_explicit_array_match
|
8499
|
+
assert_parses_pattern_match(
|
8500
|
+
s(:in_pattern,
|
8501
|
+
s(:array_pattern,
|
8502
|
+
s(:match_var, :x)),
|
8503
|
+
nil,
|
8504
|
+
s(:nil)),
|
8505
|
+
%q{in [x] then nil},
|
8506
|
+
%q{ ~~~ expression (in_pattern.array_pattern)
|
8507
|
+
| ~ begin (in_pattern.array_pattern)
|
8508
|
+
| ~ end (in_pattern.array_pattern)}
|
8509
|
+
)
|
8510
|
+
|
8511
|
+
assert_parses_pattern_match(
|
8512
|
+
s(:in_pattern,
|
8513
|
+
s(:array_pattern_with_tail,
|
8514
|
+
s(:match_var, :x)),
|
8515
|
+
nil,
|
8516
|
+
s(:nil)),
|
8517
|
+
%q{in [x,] then nil},
|
8518
|
+
%q{ ~~~~ expression (in_pattern.array_pattern_with_tail)
|
8519
|
+
| ~ begin (in_pattern.array_pattern_with_tail)
|
8520
|
+
| ~ end (in_pattern.array_pattern_with_tail)}
|
8521
|
+
)
|
8522
|
+
|
8523
|
+
assert_parses_pattern_match(
|
8524
|
+
s(:in_pattern,
|
8525
|
+
s(:array_pattern,
|
8526
|
+
s(:match_var, :x),
|
8527
|
+
s(:match_var, :y)),
|
8528
|
+
nil,
|
8529
|
+
s(:true)),
|
8530
|
+
%q{in [x, y] then true},
|
8531
|
+
%q{ ~~~~~~ expression (in_pattern.array_pattern)
|
8532
|
+
| ~ begin (in_pattern.array_pattern)
|
8533
|
+
| ~ end (in_pattern.array_pattern)}
|
8534
|
+
)
|
8535
|
+
|
8536
|
+
assert_parses_pattern_match(
|
8537
|
+
s(:in_pattern,
|
8538
|
+
s(:array_pattern_with_tail,
|
8539
|
+
s(:match_var, :x),
|
8540
|
+
s(:match_var, :y)),
|
8541
|
+
nil,
|
8542
|
+
s(:true)),
|
8543
|
+
%q{in [x, y,] then true},
|
8544
|
+
%q{ ~~~~~~~ expression (in_pattern.array_pattern_with_tail)
|
8545
|
+
| ~ begin (in_pattern.array_pattern_with_tail)
|
8546
|
+
| ~ end (in_pattern.array_pattern_with_tail)}
|
8547
|
+
)
|
8548
|
+
|
8549
|
+
assert_parses_pattern_match(
|
8550
|
+
s(:in_pattern,
|
8551
|
+
s(:array_pattern,
|
8552
|
+
s(:match_var, :x),
|
8553
|
+
s(:match_var, :y),
|
8554
|
+
s(:match_rest)),
|
8555
|
+
nil,
|
8556
|
+
s(:true)),
|
8557
|
+
%q{in [x, y, *] then true},
|
8558
|
+
%q{ ~~~~~~~~~ expression (in_pattern.array_pattern)
|
8559
|
+
| ~ begin (in_pattern.array_pattern)
|
8560
|
+
| ~ end (in_pattern.array_pattern)}
|
8561
|
+
)
|
8562
|
+
|
8563
|
+
assert_parses_pattern_match(
|
8564
|
+
s(:in_pattern,
|
8565
|
+
s(:array_pattern,
|
8566
|
+
s(:match_var, :x),
|
8567
|
+
s(:match_var, :y),
|
8568
|
+
s(:match_rest, s(:match_var, :z))),
|
8569
|
+
nil,
|
8570
|
+
s(:true)),
|
8571
|
+
%q{in [x, y, *z] then true},
|
8572
|
+
%q{ ~~~~~~~~~~ expression (in_pattern.array_pattern)
|
8573
|
+
| ~ begin (in_pattern.array_pattern)
|
8574
|
+
| ~ end (in_pattern.array_pattern)}
|
8575
|
+
)
|
8576
|
+
|
8577
|
+
assert_parses_pattern_match(
|
8578
|
+
s(:in_pattern,
|
8579
|
+
s(:array_pattern,
|
8580
|
+
s(:match_var, :x),
|
8581
|
+
s(:match_rest, s(:match_var, :y)),
|
8582
|
+
s(:match_var, :z)),
|
8583
|
+
nil,
|
8584
|
+
s(:true)),
|
8585
|
+
%q{in [x, *y, z] then true},
|
8586
|
+
%q{ ~~~~~~~~~~ expression (in_pattern.array_pattern)
|
8587
|
+
| ~ begin (in_pattern.array_pattern)
|
8588
|
+
| ~ end (in_pattern.array_pattern)}
|
8589
|
+
)
|
8590
|
+
|
8591
|
+
assert_parses_pattern_match(
|
8592
|
+
s(:in_pattern,
|
8593
|
+
s(:array_pattern,
|
8594
|
+
s(:match_var, :x),
|
8595
|
+
s(:match_rest),
|
8596
|
+
s(:match_var, :y)),
|
8597
|
+
nil,
|
8598
|
+
s(:true)),
|
8599
|
+
%q{in [x, *, y] then true},
|
8600
|
+
%q{ ~~~~~~~~~ expression (in_pattern.array_pattern)
|
8601
|
+
| ~ begin (in_pattern.array_pattern)
|
8602
|
+
| ~ end (in_pattern.array_pattern)}
|
8603
|
+
)
|
8604
|
+
|
8605
|
+
assert_parses_pattern_match(
|
8606
|
+
s(:in_pattern,
|
8607
|
+
s(:array_pattern,
|
8608
|
+
s(:match_rest, s(:match_var, :x)),
|
8609
|
+
s(:match_var, :y)),
|
8610
|
+
nil,
|
8611
|
+
s(:true)),
|
8612
|
+
%q{in [*x, y] then true},
|
8613
|
+
%q{ ~~~~~~~ expression (in_pattern.array_pattern)
|
8614
|
+
| ~ begin (in_pattern.array_pattern)
|
8615
|
+
| ~ end (in_pattern.array_pattern)}
|
8616
|
+
)
|
8617
|
+
|
8618
|
+
assert_parses_pattern_match(
|
8619
|
+
s(:in_pattern,
|
8620
|
+
s(:array_pattern,
|
8621
|
+
s(:match_rest),
|
8622
|
+
s(:match_var, :x)),
|
8623
|
+
nil,
|
8624
|
+
s(:true)),
|
8625
|
+
%q{in [*, x] then true},
|
8626
|
+
%q{ ~~~~~~ expression (in_pattern.array_pattern)
|
8627
|
+
| ~ begin (in_pattern.array_pattern)
|
8628
|
+
| ~ end (in_pattern.array_pattern)}
|
8629
|
+
)
|
8630
|
+
end
|
8631
|
+
|
8632
|
+
def test_pattern_matching_hash
|
8633
|
+
assert_parses_pattern_match(
|
8634
|
+
s(:in_pattern,
|
8635
|
+
s(:hash_pattern),
|
8636
|
+
nil,
|
8637
|
+
s(:true)),
|
8638
|
+
%q{in {} then true},
|
8639
|
+
%q{ ~~ expression (in_pattern.hash_pattern)}
|
8640
|
+
)
|
8641
|
+
|
8642
|
+
assert_parses_pattern_match(
|
8643
|
+
s(:in_pattern,
|
8644
|
+
s(:hash_pattern,
|
8645
|
+
s(:pair, s(:sym, :a), s(:int, 1))),
|
8646
|
+
nil,
|
8647
|
+
s(:true)),
|
8648
|
+
%q{in a: 1 then true},
|
8649
|
+
%q{ ~~~~ expression (in_pattern.hash_pattern)}
|
8650
|
+
)
|
8651
|
+
|
8652
|
+
assert_parses_pattern_match(
|
8653
|
+
s(:in_pattern,
|
8654
|
+
s(:hash_pattern,
|
8655
|
+
s(:pair, s(:sym, :a), s(:int, 1))),
|
8656
|
+
nil,
|
8657
|
+
s(:true)),
|
8658
|
+
%q{in { a: 1 } then true},
|
8659
|
+
%q{ ~~~~~~~~ expression (in_pattern.hash_pattern)
|
8660
|
+
| ~ begin (in_pattern.hash_pattern)
|
8661
|
+
| ~ end (in_pattern.hash_pattern)}
|
8662
|
+
)
|
8663
|
+
|
8664
|
+
assert_parses_pattern_match(
|
8665
|
+
s(:in_pattern,
|
8666
|
+
s(:hash_pattern,
|
8667
|
+
s(:match_var, :a)),
|
8668
|
+
nil,
|
8669
|
+
s(:true)),
|
8670
|
+
%q{in a: then true},
|
8671
|
+
%q{ ~~ expression (in_pattern.hash_pattern)
|
8672
|
+
| ~ name (in_pattern.hash_pattern.match_var)
|
8673
|
+
| ~~ expression (in_pattern.hash_pattern.match_var)}
|
8674
|
+
)
|
8675
|
+
|
8676
|
+
assert_parses_pattern_match(
|
8677
|
+
s(:in_pattern,
|
8678
|
+
s(:hash_pattern,
|
8679
|
+
s(:match_rest, s(:match_var, :a))),
|
8680
|
+
nil,
|
8681
|
+
s(:true)),
|
8682
|
+
%q{in **a then true},
|
8683
|
+
%q{ ~~~ expression (in_pattern.hash_pattern)
|
8684
|
+
| ~~~ expression (in_pattern.hash_pattern.match_rest)
|
8685
|
+
| ~~ operator (in_pattern.hash_pattern.match_rest)
|
8686
|
+
| ~ expression (in_pattern.hash_pattern.match_rest.match_var)
|
8687
|
+
| ~ name (in_pattern.hash_pattern.match_rest.match_var)}
|
8688
|
+
)
|
8689
|
+
|
8690
|
+
assert_parses_pattern_match(
|
8691
|
+
s(:in_pattern,
|
8692
|
+
s(:hash_pattern,
|
8693
|
+
s(:match_rest)),
|
8694
|
+
nil,
|
8695
|
+
s(:true)),
|
8696
|
+
%q{in ** then true},
|
8697
|
+
%q{ ~~ expression (in_pattern.hash_pattern)
|
8698
|
+
| ~~ expression (in_pattern.hash_pattern.match_rest)
|
8699
|
+
| ~~ operator (in_pattern.hash_pattern.match_rest)}
|
8700
|
+
)
|
8701
|
+
|
8702
|
+
assert_parses_pattern_match(
|
8703
|
+
s(:in_pattern,
|
8704
|
+
s(:hash_pattern,
|
8705
|
+
s(:pair, s(:sym, :a), s(:int, 1)),
|
8706
|
+
s(:pair, s(:sym, :b), s(:int, 2))),
|
8707
|
+
nil,
|
8708
|
+
s(:true)),
|
8709
|
+
%q{in a: 1, b: 2 then true},
|
8710
|
+
%q{ ~~~~~~~~~~ expression (in_pattern.hash_pattern)}
|
8711
|
+
)
|
8712
|
+
|
8713
|
+
assert_parses_pattern_match(
|
8714
|
+
s(:in_pattern,
|
8715
|
+
s(:hash_pattern,
|
8716
|
+
s(:match_var, :a),
|
8717
|
+
s(:match_var, :b)),
|
8718
|
+
nil,
|
8719
|
+
s(:true)),
|
8720
|
+
%q{in a:, b: then true},
|
8721
|
+
%q{ ~~~~~~ expression (in_pattern.hash_pattern)}
|
8722
|
+
)
|
8723
|
+
|
8724
|
+
assert_parses_pattern_match(
|
8725
|
+
s(:in_pattern,
|
8726
|
+
s(:hash_pattern,
|
8727
|
+
s(:pair, s(:sym, :a), s(:int, 1)),
|
8728
|
+
s(:match_var, :_a),
|
8729
|
+
s(:match_rest)),
|
8730
|
+
nil,
|
8731
|
+
s(:true)),
|
8732
|
+
%q{in a: 1, _a:, ** then true},
|
8733
|
+
%q{ ~~~~~~~~~~~~~ expression (in_pattern.hash_pattern)}
|
8734
|
+
)
|
8735
|
+
end
|
8736
|
+
|
8737
|
+
def test_pattern_matching_hash_with_string_keys
|
8738
|
+
# Match + assign
|
8739
|
+
|
8740
|
+
assert_parses_pattern_match(
|
8741
|
+
s(:in_pattern,
|
8742
|
+
s(:hash_pattern,
|
8743
|
+
s(:match_var, :a)),
|
8744
|
+
nil,
|
8745
|
+
s(:true)),
|
8746
|
+
%q{in "a": then true},
|
8747
|
+
%q{ ~~~~ expression (in_pattern.hash_pattern.match_var)
|
8748
|
+
| ~ name (in_pattern.hash_pattern.match_var)}
|
8749
|
+
)
|
8750
|
+
|
8751
|
+
assert_parses_pattern_match(
|
8752
|
+
s(:in_pattern,
|
8753
|
+
s(:hash_pattern,
|
8754
|
+
s(:match_var, :a)),
|
8755
|
+
nil,
|
8756
|
+
s(:true)),
|
8757
|
+
%q{in "#{ 'a' }": then true},
|
8758
|
+
%q{ ~~~~~~~~~~~ expression (in_pattern.hash_pattern.match_var)
|
8759
|
+
| ~ name (in_pattern.hash_pattern.match_var)}
|
8760
|
+
)
|
8761
|
+
|
8762
|
+
assert_parses_pattern_match(
|
8763
|
+
s(:in_pattern,
|
8764
|
+
s(:hash_pattern,
|
8765
|
+
s(:match_var, :a)),
|
8766
|
+
nil,
|
8767
|
+
s(:true)),
|
8768
|
+
%q{in "#{ %q{a} }": then true},
|
8769
|
+
%q{ ~~~~~~~~~~~~~ expression (in_pattern.hash_pattern.match_var)
|
8770
|
+
| ~ name (in_pattern.hash_pattern.match_var)}
|
8771
|
+
)
|
8772
|
+
|
8773
|
+
assert_parses_pattern_match(
|
8774
|
+
s(:in_pattern,
|
8775
|
+
s(:hash_pattern,
|
8776
|
+
s(:match_var, :a)),
|
8777
|
+
nil,
|
8778
|
+
s(:true)),
|
8779
|
+
%q{in "#{ %Q{a} }": then true},
|
8780
|
+
%q{ ~~~~~~~~~~~~~ expression (in_pattern.hash_pattern.match_var)
|
8781
|
+
| ~ name (in_pattern.hash_pattern.match_var)}
|
8782
|
+
)
|
8783
|
+
|
8784
|
+
# Only match
|
8785
|
+
|
8786
|
+
assert_parses_pattern_match(
|
8787
|
+
s(:in_pattern,
|
8788
|
+
s(:hash_pattern,
|
8789
|
+
s(:pair, s(:sym, :a), s(:int, 1))),
|
8790
|
+
nil,
|
8791
|
+
s(:true)),
|
8792
|
+
%q{in "a": 1 then true},
|
8793
|
+
)
|
8794
|
+
|
8795
|
+
assert_parses_pattern_match(
|
8796
|
+
s(:in_pattern,
|
8797
|
+
s(:hash_pattern,
|
8798
|
+
s(:pair,
|
8799
|
+
s(:dsym, s(:begin, s(:str, "a"))),
|
8800
|
+
s(:int, 1))),
|
8801
|
+
nil,
|
8802
|
+
s(:true)),
|
8803
|
+
%q{in "#{ 'a' }": 1 then true},
|
8804
|
+
)
|
8805
|
+
|
8806
|
+
assert_parses_pattern_match(
|
8807
|
+
s(:in_pattern,
|
8808
|
+
s(:hash_pattern,
|
8809
|
+
s(:pair,
|
8810
|
+
s(:dsym, s(:begin, s(:str, "a"))),
|
8811
|
+
s(:int, 1))),
|
8812
|
+
nil,
|
8813
|
+
s(:true)),
|
8814
|
+
%q{in "#{ %q{a} }": 1 then true},
|
8815
|
+
)
|
8816
|
+
|
8817
|
+
assert_parses_pattern_match(
|
8818
|
+
s(:in_pattern,
|
8819
|
+
s(:hash_pattern,
|
8820
|
+
s(:pair,
|
8821
|
+
s(:dsym, s(:begin, s(:str, "a"))),
|
8822
|
+
s(:int, 1))),
|
8823
|
+
nil,
|
8824
|
+
s(:true)),
|
8825
|
+
%q{in "#{ %Q{a} }": 1 then true},
|
8826
|
+
)
|
8827
|
+
end
|
8828
|
+
|
8829
|
+
def test_pattern_matching_hash_with_heredoc_keys
|
8830
|
+
# Ruby <3, the following case is acceptable by the MRI's grammar,
|
8831
|
+
# so it has to be reducable by parser.
|
8832
|
+
# We have a code for that in the builder.rb that reject it via
|
8833
|
+
# diagnostic error because of the wrong lvar name
|
8834
|
+
assert_diagnoses(
|
8835
|
+
[:error, :lvar_name, { name: "a\n" }],
|
8836
|
+
%Q{case nil; in "\#{ <<-HERE }":;\na\nHERE\nelse\nend},
|
8837
|
+
%q{ ~~~~~~~ location},
|
8838
|
+
SINCE_2_7
|
8839
|
+
)
|
8840
|
+
end
|
8841
|
+
|
8842
|
+
def test_pattern_matching_keyword_variable
|
8843
|
+
assert_parses_pattern_match(
|
8844
|
+
s(:in_pattern,
|
8845
|
+
s(:self),
|
8846
|
+
nil,
|
8847
|
+
s(:true)),
|
8848
|
+
%q{in self then true}
|
8849
|
+
)
|
8850
|
+
end
|
8851
|
+
|
8852
|
+
def test_pattern_matching_lambda
|
8853
|
+
assert_parses_pattern_match(
|
8854
|
+
s(:in_pattern,
|
8855
|
+
s(:block,
|
8856
|
+
s(:lambda),
|
8857
|
+
s(:args),
|
8858
|
+
s(:int, 42)),
|
8859
|
+
nil,
|
8860
|
+
s(:true)),
|
8861
|
+
%q{in ->{ 42 } then true}
|
8862
|
+
)
|
8863
|
+
end
|
8864
|
+
|
8865
|
+
def test_pattern_matching_ranges
|
8866
|
+
assert_parses_pattern_match(
|
8867
|
+
s(:in_pattern,
|
8868
|
+
s(:irange, s(:int, 1), s(:int, 2)),
|
8869
|
+
nil,
|
8870
|
+
s(:true)),
|
8871
|
+
%q{in 1..2 then true}
|
8872
|
+
)
|
8873
|
+
|
8874
|
+
assert_parses_pattern_match(
|
8875
|
+
s(:in_pattern,
|
8876
|
+
s(:irange, s(:int, 1), nil),
|
8877
|
+
nil,
|
8878
|
+
s(:true)),
|
8879
|
+
%q{in 1.. then true}
|
8880
|
+
)
|
8881
|
+
|
8882
|
+
assert_parses_pattern_match(
|
8883
|
+
s(:in_pattern,
|
8884
|
+
s(:irange, nil, s(:int, 2)),
|
8885
|
+
nil,
|
8886
|
+
s(:true)),
|
8887
|
+
%q{in ..2 then true}
|
8888
|
+
)
|
8889
|
+
|
8890
|
+
assert_parses_pattern_match(
|
8891
|
+
s(:in_pattern,
|
8892
|
+
s(:erange, s(:int, 1), s(:int, 2)),
|
8893
|
+
nil,
|
8894
|
+
s(:true)),
|
8895
|
+
%q{in 1...2 then true}
|
8896
|
+
)
|
8897
|
+
|
8898
|
+
assert_parses_pattern_match(
|
8899
|
+
s(:in_pattern,
|
8900
|
+
s(:erange, s(:int, 1), nil),
|
8901
|
+
nil,
|
8902
|
+
s(:true)),
|
8903
|
+
%q{in 1... then true}
|
8904
|
+
)
|
8905
|
+
|
8906
|
+
assert_parses_pattern_match(
|
8907
|
+
s(:in_pattern,
|
8908
|
+
s(:erange, nil, s(:int, 2)),
|
8909
|
+
nil,
|
8910
|
+
s(:true)),
|
8911
|
+
%q{in ...2 then true}
|
8912
|
+
)
|
8913
|
+
end
|
8914
|
+
|
8915
|
+
def test_pattern_matching_expr_in_paren
|
8916
|
+
assert_parses_pattern_match(
|
8917
|
+
s(:in_pattern,
|
8918
|
+
s(:begin, s(:int, 1)),
|
8919
|
+
nil,
|
8920
|
+
s(:true)),
|
8921
|
+
%q{in (1) then true},
|
8922
|
+
%q{ ~~~ expression (in_pattern.begin)
|
8923
|
+
| ~ begin (in_pattern.begin)
|
8924
|
+
| ~ end (in_pattern.begin)}
|
8925
|
+
)
|
8926
|
+
end
|
8927
|
+
|
8928
|
+
def test_pattern_matching_constants
|
8929
|
+
assert_parses_pattern_match(
|
8930
|
+
s(:in_pattern,
|
8931
|
+
s(:const, nil, :A),
|
8932
|
+
nil,
|
8933
|
+
s(:true)),
|
8934
|
+
%q{in A then true},
|
8935
|
+
%q{ ~ expression (in_pattern.const)
|
8936
|
+
| ~ name (in_pattern.const)}
|
8937
|
+
)
|
8938
|
+
|
8939
|
+
assert_parses_pattern_match(
|
8940
|
+
s(:in_pattern,
|
8941
|
+
s(:const, s(:const, nil, :A), :B),
|
8942
|
+
nil,
|
8943
|
+
s(:true)),
|
8944
|
+
%q{in A::B then true},
|
8945
|
+
%q{ ~~~~ expression (in_pattern.const)
|
8946
|
+
| ~~ double_colon (in_pattern.const)
|
8947
|
+
| ~ name (in_pattern.const)}
|
8948
|
+
)
|
8949
|
+
|
8950
|
+
assert_parses_pattern_match(
|
8951
|
+
s(:in_pattern,
|
8952
|
+
s(:const, s(:cbase), :A),
|
8953
|
+
nil,
|
8954
|
+
s(:true)),
|
8955
|
+
%q{in ::A then true},
|
8956
|
+
%q{ ~~~ expression (in_pattern.const)
|
8957
|
+
| ~~ double_colon (in_pattern.const)
|
8958
|
+
| ~ name (in_pattern.const)}
|
8959
|
+
)
|
8960
|
+
end
|
8961
|
+
|
8962
|
+
def test_pattern_matching_const_pattern
|
8963
|
+
assert_parses_pattern_match(
|
8964
|
+
s(:in_pattern,
|
8965
|
+
s(:const_pattern,
|
8966
|
+
s(:const, nil, :A),
|
8967
|
+
s(:array_pattern,
|
8968
|
+
s(:int, 1),
|
8969
|
+
s(:int, 2))),
|
8970
|
+
nil,
|
8971
|
+
s(:true)),
|
8972
|
+
%q{in A(1, 2) then true},
|
8973
|
+
%q{ ~~~~~~ expression (in_pattern.const_pattern)
|
8974
|
+
| ~ begin (in_pattern.const_pattern)
|
8975
|
+
| ~ end (in_pattern.const_pattern)
|
8976
|
+
| ~ expression (in_pattern.const_pattern.const)
|
8977
|
+
| ~~~~ expression (in_pattern.const_pattern.array_pattern)}
|
8978
|
+
)
|
8979
|
+
|
8980
|
+
assert_parses_pattern_match(
|
8981
|
+
s(:in_pattern,
|
8982
|
+
s(:const_pattern,
|
8983
|
+
s(:const, nil, :A),
|
8984
|
+
s(:hash_pattern,
|
8985
|
+
s(:match_var, :x))),
|
8986
|
+
nil,
|
8987
|
+
s(:true)),
|
8988
|
+
%q{in A(x:) then true},
|
8989
|
+
%q{ ~~~~ expression (in_pattern.const_pattern)
|
8990
|
+
| ~ begin (in_pattern.const_pattern)
|
8991
|
+
| ~ end (in_pattern.const_pattern)
|
8992
|
+
| ~ expression (in_pattern.const_pattern.const)
|
8993
|
+
| ~~ expression (in_pattern.const_pattern.hash_pattern)}
|
8994
|
+
)
|
8995
|
+
|
8996
|
+
assert_parses_pattern_match(
|
8997
|
+
s(:in_pattern,
|
8998
|
+
s(:const_pattern,
|
8999
|
+
s(:const, nil, :A),
|
9000
|
+
nil),
|
9001
|
+
nil,
|
9002
|
+
s(:true)),
|
9003
|
+
%q{in A() then true},
|
9004
|
+
%q{ ~~ expression (in_pattern.const_pattern)
|
9005
|
+
| ~ begin (in_pattern.const_pattern)
|
9006
|
+
| ~ end (in_pattern.const_pattern)}
|
9007
|
+
)
|
9008
|
+
|
9009
|
+
assert_parses_pattern_match(
|
9010
|
+
s(:in_pattern,
|
9011
|
+
s(:const_pattern,
|
9012
|
+
s(:const, nil, :A),
|
9013
|
+
s(:array_pattern,
|
9014
|
+
s(:int, 1),
|
9015
|
+
s(:int, 2))),
|
9016
|
+
nil,
|
9017
|
+
s(:true)),
|
9018
|
+
%q{in A[1, 2] then true},
|
9019
|
+
%q{ ~~~~~~ expression (in_pattern.const_pattern)
|
9020
|
+
| ~ begin (in_pattern.const_pattern)
|
9021
|
+
| ~ end (in_pattern.const_pattern)
|
9022
|
+
| ~ expression (in_pattern.const_pattern.const)
|
9023
|
+
| ~~~~ expression (in_pattern.const_pattern.array_pattern)}
|
9024
|
+
)
|
9025
|
+
|
9026
|
+
assert_parses_pattern_match(
|
9027
|
+
s(:in_pattern,
|
9028
|
+
s(:const_pattern,
|
9029
|
+
s(:const, nil, :A),
|
9030
|
+
s(:hash_pattern,
|
9031
|
+
s(:match_var, :x))),
|
9032
|
+
nil,
|
9033
|
+
s(:true)),
|
9034
|
+
%q{in A[x:] then true},
|
9035
|
+
%q{ ~~~~ expression (in_pattern.const_pattern)
|
9036
|
+
| ~ begin (in_pattern.const_pattern)
|
9037
|
+
| ~ end (in_pattern.const_pattern)
|
9038
|
+
| ~ expression (in_pattern.const_pattern.const)
|
9039
|
+
| ~~ expression (in_pattern.const_pattern.hash_pattern)}
|
9040
|
+
)
|
9041
|
+
|
9042
|
+
assert_parses_pattern_match(
|
9043
|
+
s(:in_pattern,
|
9044
|
+
s(:const_pattern,
|
9045
|
+
s(:const, nil, :A),
|
9046
|
+
nil),
|
9047
|
+
nil,
|
9048
|
+
s(:true)),
|
9049
|
+
%q{in A[] then true},
|
9050
|
+
%q{ ~~ expression (in_pattern.const_pattern)
|
9051
|
+
| ~ begin (in_pattern.const_pattern)
|
9052
|
+
| ~ end (in_pattern.const_pattern)}
|
9053
|
+
)
|
9054
|
+
end
|
9055
|
+
|
9056
|
+
def test_pattern_matching_match_alt
|
9057
|
+
assert_parses_pattern_match(
|
9058
|
+
s(:in_pattern,
|
9059
|
+
s(:match_alt, s(:int, 1), s(:int, 2)),
|
9060
|
+
nil,
|
9061
|
+
s(:true)),
|
9062
|
+
%q{in 1 | 2 then true},
|
9063
|
+
%q{ ~~~~~ expression (in_pattern.match_alt)
|
9064
|
+
| ~ operator (in_pattern.match_alt)}
|
9065
|
+
)
|
9066
|
+
end
|
9067
|
+
|
9068
|
+
def test_pattern_matching_match_as
|
9069
|
+
assert_parses_pattern_match(
|
9070
|
+
s(:in_pattern,
|
9071
|
+
s(:match_as,
|
9072
|
+
s(:int, 1),
|
9073
|
+
s(:match_var, :a)),
|
9074
|
+
nil,
|
9075
|
+
s(:true)),
|
9076
|
+
%q{in 1 => a then true},
|
9077
|
+
%q{ ~~~~~~ expression (in_pattern.match_as)
|
9078
|
+
| ~~ operator (in_pattern.match_as)}
|
9079
|
+
)
|
9080
|
+
end
|
9081
|
+
|
9082
|
+
def test_pattern_matching_else
|
9083
|
+
assert_parses(
|
9084
|
+
s(:case_match,
|
9085
|
+
s(:int, 1),
|
9086
|
+
s(:in_pattern,
|
9087
|
+
s(:int, 2), nil,
|
9088
|
+
s(:int, 3)),
|
9089
|
+
s(:int, 4)),
|
9090
|
+
%q{case 1; in 2; 3; else; 4; end},
|
9091
|
+
%q{ ~~~~ else},
|
9092
|
+
SINCE_2_7
|
9093
|
+
)
|
9094
|
+
end
|
9095
|
+
|
9096
|
+
def assert_pattern_matching_defines_local_variables(match_code, lvar_names, versions = SINCE_2_7)
|
9097
|
+
code = "case 1; #{match_code}; then [#{lvar_names.join(', ')}]; end"
|
9098
|
+
|
9099
|
+
with_versions(versions) do |version, parser|
|
9100
|
+
source_file = Parser::Source::Buffer.new('(assert_context)')
|
9101
|
+
source_file.source = code
|
9102
|
+
|
9103
|
+
lvar_names.each do |lvar_name|
|
9104
|
+
refute parser.static_env.declared?(lvar_name),
|
9105
|
+
"(#{version}) local variable #{lvar_name.to_s.inspect} has to be undefined before asserting"
|
9106
|
+
end
|
9107
|
+
|
9108
|
+
before = parser.static_env.instance_variable_get(:@variables).to_a
|
9109
|
+
|
9110
|
+
begin
|
9111
|
+
parsed_ast = parser.parse(source_file)
|
9112
|
+
rescue Parser::SyntaxError => exc
|
9113
|
+
backtrace = exc.backtrace
|
9114
|
+
Exception.instance_method(:initialize).bind(exc).
|
9115
|
+
call("(#{version}) #{exc.message}")
|
9116
|
+
exc.set_backtrace(backtrace)
|
9117
|
+
raise
|
9118
|
+
end
|
9119
|
+
|
9120
|
+
lvar_names.each do |lvar_name|
|
9121
|
+
assert parser.static_env.declared?(lvar_name),
|
9122
|
+
"(#{version}) expected local variable #{lvar_name.to_s.inspect} to be defined after parsing"
|
9123
|
+
end
|
9124
|
+
|
9125
|
+
after = parser.static_env.instance_variable_get(:@variables).to_a
|
9126
|
+
extra = after - before - lvar_names
|
9127
|
+
|
9128
|
+
assert extra.empty?,
|
9129
|
+
"(#{version}) expected only #{lvar_names.inspect} " \
|
9130
|
+
"to be defined during parsing, but also got #{extra.inspect}"
|
9131
|
+
end
|
9132
|
+
end
|
9133
|
+
|
9134
|
+
def test_pattern_matching_creates_locals
|
9135
|
+
assert_pattern_matching_defines_local_variables(
|
9136
|
+
%q{in a, *b, c},
|
9137
|
+
[:a, :b, :c]
|
9138
|
+
)
|
9139
|
+
|
9140
|
+
assert_pattern_matching_defines_local_variables(
|
9141
|
+
%q{in d | e | f},
|
9142
|
+
[:d, :e, :f]
|
9143
|
+
)
|
9144
|
+
|
9145
|
+
assert_pattern_matching_defines_local_variables(
|
9146
|
+
%q{in { g:, **h }},
|
9147
|
+
[:g, :h]
|
9148
|
+
)
|
9149
|
+
|
9150
|
+
assert_pattern_matching_defines_local_variables(
|
9151
|
+
%q{in A(i, *j, k)},
|
9152
|
+
[:i, :j, :k]
|
9153
|
+
)
|
9154
|
+
|
9155
|
+
assert_pattern_matching_defines_local_variables(
|
9156
|
+
%q{in 1 => l},
|
9157
|
+
[:l]
|
9158
|
+
)
|
9159
|
+
|
9160
|
+
assert_pattern_matching_defines_local_variables(
|
9161
|
+
%q{in "m":},
|
9162
|
+
[:m]
|
9163
|
+
)
|
9164
|
+
end
|
9165
|
+
|
9166
|
+
def test_pattern_matching__FILE__LINE_literals
|
9167
|
+
assert_parses(
|
9168
|
+
s(:case_match,
|
9169
|
+
s(:array,
|
9170
|
+
s(:str, "(assert_parses)"),
|
9171
|
+
s(:send,
|
9172
|
+
s(:int, 1), :+,
|
9173
|
+
s(:int, 1)),
|
9174
|
+
s(:__ENCODING__)),
|
9175
|
+
s(:in_pattern,
|
9176
|
+
s(:array_pattern,
|
9177
|
+
s(:str, "(assert_parses)"),
|
9178
|
+
s(:int, 2),
|
9179
|
+
s(:__ENCODING__)), nil, nil), nil),
|
9180
|
+
<<-RUBY,
|
9181
|
+
case [__FILE__, __LINE__ + 1, __ENCODING__]
|
9182
|
+
in [__FILE__, __LINE__, __ENCODING__]
|
9183
|
+
end
|
9184
|
+
RUBY
|
9185
|
+
%q{},
|
9186
|
+
SINCE_2_7)
|
9187
|
+
end
|
9188
|
+
|
9189
|
+
def test_pattern_matching_nil_pattern
|
9190
|
+
assert_parses_pattern_match(
|
9191
|
+
s(:in_pattern,
|
9192
|
+
s(:hash_pattern,
|
9193
|
+
s(:match_nil_pattern)),
|
9194
|
+
nil,
|
9195
|
+
s(:true)),
|
9196
|
+
%q{in **nil then true},
|
9197
|
+
%q{ ~~~~~ expression (in_pattern.hash_pattern.match_nil_pattern)
|
9198
|
+
| ~~~ name (in_pattern.hash_pattern.match_nil_pattern)}
|
9199
|
+
)
|
9200
|
+
end
|
9201
|
+
|
9202
|
+
def test_pattern_matching_single_line
|
9203
|
+
assert_parses(
|
9204
|
+
s(:begin,
|
9205
|
+
s(:in_match,
|
9206
|
+
s(:int, 1),
|
9207
|
+
s(:array_pattern,
|
9208
|
+
s(:match_var, :a))),
|
9209
|
+
s(:lvar, :a)),
|
9210
|
+
%q{1 in [a]; a},
|
9211
|
+
%q{~~~~~~~~ expression (in_match)
|
9212
|
+
| ~~ operator (in_match)},
|
9213
|
+
SINCE_2_7)
|
9214
|
+
end
|
9215
|
+
|
9216
|
+
def test_ruby_bug_pattern_matching_restore_in_kwarg_flag
|
9217
|
+
refute_diagnoses(
|
9218
|
+
"p(({} in {a:}), a:\n 1)",
|
9219
|
+
SINCE_2_7)
|
9220
|
+
end
|
9221
|
+
|
9222
|
+
def test_pattern_matching_duplicate_variable_name
|
9223
|
+
assert_diagnoses(
|
9224
|
+
[:error, :duplicate_variable_name, { :name => 'a' }],
|
9225
|
+
%q{case 0; in a, a; end},
|
9226
|
+
%q{ ^ location},
|
9227
|
+
SINCE_2_7)
|
9228
|
+
|
9229
|
+
refute_diagnoses(
|
9230
|
+
%q{case [0, 1, 2, 3]; in _, _, _a, _a; end},
|
9231
|
+
SINCE_2_7)
|
9232
|
+
|
9233
|
+
assert_diagnoses(
|
9234
|
+
[:error, :duplicate_variable_name, { :name => 'a' }],
|
9235
|
+
%q{case 0; in a, {a:}; end},
|
9236
|
+
%q{ ^ location},
|
9237
|
+
SINCE_2_7)
|
9238
|
+
|
9239
|
+
assert_diagnoses(
|
9240
|
+
[:error, :duplicate_variable_name, { :name => 'a' }],
|
9241
|
+
%q{case 0; in a, {"a":}; end},
|
9242
|
+
%q{ ^ location},
|
9243
|
+
SINCE_2_7)
|
9244
|
+
|
9245
|
+
assert_diagnoses(
|
9246
|
+
[:error, :duplicate_variable_name, { :name => 'a' }],
|
9247
|
+
%q{0 in [a, a]},
|
9248
|
+
%q{ ^ location},
|
9249
|
+
SINCE_2_7)
|
9250
|
+
end
|
9251
|
+
|
9252
|
+
def test_pattern_matching_duplicate_hash_keys
|
9253
|
+
assert_diagnoses(
|
9254
|
+
[:error, :duplicate_pattern_key, { :name => 'a' }],
|
9255
|
+
%q{ case 0; in a: 1, a: 2; end },
|
9256
|
+
%q{ ^^ location},
|
9257
|
+
SINCE_2_7)
|
9258
|
+
|
9259
|
+
assert_diagnoses(
|
9260
|
+
[:error, :duplicate_pattern_key, { :name => 'a' }],
|
9261
|
+
%q{ case 0; in a: 1, "a": 2; end },
|
9262
|
+
%q{ ^^^^ location},
|
9263
|
+
SINCE_2_7)
|
9264
|
+
|
9265
|
+
assert_diagnoses(
|
9266
|
+
[:error, :duplicate_pattern_key, { :name => 'a' }],
|
9267
|
+
%q{ case 0; in "a": 1, "a": 2; end },
|
9268
|
+
%q{ ^^^^ location},
|
9269
|
+
SINCE_2_7)
|
9270
|
+
|
9271
|
+
assert_diagnoses(
|
9272
|
+
[:error, :duplicate_pattern_key, { :name => "a\0" }],
|
9273
|
+
%q{ case 0; in "a\x0":a1, "a\0":a2; end },
|
9274
|
+
%q{ ^^^^^^ location},
|
9275
|
+
SINCE_2_7)
|
9276
|
+
|
9277
|
+
assert_diagnoses(
|
9278
|
+
[:error, :duplicate_pattern_key, { :name => "abc" }],
|
9279
|
+
%q{ case 0; in "abc":a1, "a#{"b"}c":a2; end },
|
9280
|
+
%q{ ^^^^^^^^^^^ location},
|
9281
|
+
SINCE_2_7)
|
9282
|
+
end
|
9283
|
+
|
9284
|
+
def test_pattern_matching_required_parentheses_for_in_match
|
9285
|
+
assert_diagnoses(
|
9286
|
+
[:error, :unexpected_token, { :token => 'tCOMMA' }],
|
9287
|
+
%{1 in a, b},
|
9288
|
+
%{ ^ location},
|
9289
|
+
SINCE_2_7)
|
9290
|
+
|
9291
|
+
assert_diagnoses(
|
9292
|
+
[:error, :unexpected_token, { :token => 'tLABEL' }],
|
9293
|
+
%{1 in a:},
|
9294
|
+
%{ ^^ location},
|
9295
|
+
SINCE_2_7)
|
9296
|
+
end
|
7644
9297
|
end
|