parser 2.7.0.5 → 2.7.1.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.travis.yml +21 -32
- data/CHANGELOG.md +59 -1
- data/README.md +2 -2
- data/Rakefile +2 -1
- data/doc/AST_FORMAT.md +106 -3
- data/lib/parser.rb +1 -0
- data/lib/parser/all.rb +1 -0
- data/lib/parser/ast/processor.rb +9 -0
- data/lib/parser/builders/default.rb +103 -12
- data/lib/parser/context.rb +1 -0
- data/lib/parser/current.rb +13 -4
- data/lib/parser/diagnostic.rb +1 -1
- data/lib/parser/diagnostic/engine.rb +1 -2
- data/lib/parser/lexer.rl +15 -1
- data/lib/parser/macruby.y +14 -4
- data/lib/parser/messages.rb +15 -0
- data/lib/parser/meta.rb +4 -4
- data/lib/parser/ruby18.y +2 -0
- data/lib/parser/ruby19.y +14 -4
- data/lib/parser/ruby20.y +14 -4
- data/lib/parser/ruby21.y +9 -2
- data/lib/parser/ruby22.y +9 -2
- data/lib/parser/ruby23.y +9 -2
- data/lib/parser/ruby24.y +9 -2
- data/lib/parser/ruby25.y +9 -2
- data/lib/parser/ruby26.y +9 -2
- data/lib/parser/ruby27.y +28 -8
- data/lib/parser/ruby28.y +3043 -0
- data/lib/parser/rubymotion.y +14 -4
- data/lib/parser/runner.rb +26 -2
- data/lib/parser/runner/ruby_rewrite.rb +2 -2
- data/lib/parser/source/buffer.rb +3 -1
- data/lib/parser/source/comment/associator.rb +14 -4
- data/lib/parser/source/map/endless_definition.rb +23 -0
- data/lib/parser/source/range.rb +17 -1
- data/lib/parser/source/tree_rewriter.rb +115 -12
- data/lib/parser/source/tree_rewriter/action.rb +135 -26
- data/lib/parser/tree_rewriter.rb +1 -2
- data/lib/parser/version.rb +1 -1
- data/parser.gemspec +3 -2
- data/test/helper.rb +49 -6
- data/test/parse_helper.rb +27 -23
- data/test/test_ast_processor.rb +32 -0
- data/test/test_base.rb +1 -1
- data/test/test_current.rb +2 -0
- data/test/test_diagnostic.rb +6 -7
- data/test/test_diagnostic_engine.rb +5 -8
- data/test/test_lexer.rb +17 -8
- data/test/test_meta.rb +12 -0
- data/test/test_parser.rb +477 -54
- data/test/test_runner_parse.rb +22 -1
- data/test/test_runner_rewrite.rb +1 -1
- data/test/test_source_buffer.rb +4 -1
- data/test/test_source_comment.rb +2 -2
- data/test/test_source_comment_associator.rb +47 -15
- data/test/test_source_map.rb +1 -2
- data/test/test_source_range.rb +29 -9
- data/test/test_source_rewriter.rb +4 -4
- data/test/test_source_rewriter_action.rb +2 -2
- data/test/test_source_tree_rewriter.rb +201 -13
- metadata +19 -12
data/test/test_meta.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'helper'
|
4
|
+
|
5
|
+
class TestMeta < Minitest::Test
|
6
|
+
def test_NODE_TYPES
|
7
|
+
for_each_node do |node|
|
8
|
+
assert Parser::Meta::NODE_TYPES.include?(node.type),
|
9
|
+
"Type #{node.type} missing from Parser::Meta::NODE_TYPES"
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
data/test/test_parser.rb
CHANGED
@@ -29,6 +29,7 @@ class TestParser < Minitest::Test
|
|
29
29
|
SINCE_2_5 = SINCE_2_4 - %w(2.4)
|
30
30
|
SINCE_2_6 = SINCE_2_5 - %w(2.5)
|
31
31
|
SINCE_2_7 = SINCE_2_6 - %w(2.6)
|
32
|
+
SINCE_2_8 = SINCE_2_7 - %w(2.7)
|
32
33
|
|
33
34
|
# Guidelines for test naming:
|
34
35
|
# * Test structure follows structure of AST_FORMAT.md.
|
@@ -5359,8 +5360,7 @@ class TestParser < Minitest::Test
|
|
5359
5360
|
|
5360
5361
|
def test_crlf_line_endings
|
5361
5362
|
with_versions(ALL_VERSIONS) do |_ver, parser|
|
5362
|
-
source_file = Parser::Source::Buffer.new('(comments)')
|
5363
|
-
source_file.source = "\r\nfoo"
|
5363
|
+
source_file = Parser::Source::Buffer.new('(comments)', source: "\r\nfoo")
|
5364
5364
|
|
5365
5365
|
range = lambda do |from, to|
|
5366
5366
|
Parser::Source::Range.new(source_file, from, to)
|
@@ -5433,8 +5433,7 @@ class TestParser < Minitest::Test
|
|
5433
5433
|
with_versions(ALL_VERSIONS) do |_ver, parser|
|
5434
5434
|
parser.builder.emit_file_line_as_literals = false
|
5435
5435
|
|
5436
|
-
source_file = Parser::Source::Buffer.new('(comments)')
|
5437
|
-
source_file.source = "[__FILE__, __LINE__]"
|
5436
|
+
source_file = Parser::Source::Buffer.new('(comments)', source: "[__FILE__, __LINE__]")
|
5438
5437
|
|
5439
5438
|
ast = parser.parse(source_file)
|
5440
5439
|
|
@@ -5518,8 +5517,7 @@ class TestParser < Minitest::Test
|
|
5518
5517
|
|
5519
5518
|
def assert_parses_with_comments(ast_pattern, source, comments_pattern)
|
5520
5519
|
with_versions(ALL_VERSIONS) do |_ver, parser|
|
5521
|
-
source_file = Parser::Source::Buffer.new('(comments)')
|
5522
|
-
source_file.source = source
|
5520
|
+
source_file = Parser::Source::Buffer.new('(comments)', source: source)
|
5523
5521
|
|
5524
5522
|
comments_pattern_here = comments_pattern.map do |(from, to)|
|
5525
5523
|
range = Parser::Source::Range.new(source_file, from, to)
|
@@ -5550,8 +5548,8 @@ class TestParser < Minitest::Test
|
|
5550
5548
|
|
5551
5549
|
def test_tokenize
|
5552
5550
|
with_versions(ALL_VERSIONS) do |_ver, parser|
|
5553
|
-
source_file = Parser::Source::Buffer.new('(tokenize)'
|
5554
|
-
|
5551
|
+
source_file = Parser::Source::Buffer.new('(tokenize)',
|
5552
|
+
source: "1 + # foo\n 2")
|
5555
5553
|
|
5556
5554
|
range = lambda do |from, to|
|
5557
5555
|
Parser::Source::Range.new(source_file, from, to)
|
@@ -5577,8 +5575,8 @@ class TestParser < Minitest::Test
|
|
5577
5575
|
|
5578
5576
|
def test_tokenize_recover
|
5579
5577
|
with_versions(ALL_VERSIONS) do |_ver, parser|
|
5580
|
-
source_file = Parser::Source::Buffer.new('(tokenize)'
|
5581
|
-
|
5578
|
+
source_file = Parser::Source::Buffer.new('(tokenize)',
|
5579
|
+
source: "1 + # foo\n ")
|
5582
5580
|
|
5583
5581
|
range = lambda do |from, to|
|
5584
5582
|
Parser::Source::Range.new(source_file, from, to)
|
@@ -6553,39 +6551,64 @@ class TestParser < Minitest::Test
|
|
6553
6551
|
|
6554
6552
|
def test_context_class
|
6555
6553
|
[
|
6556
|
-
%q{class A;},
|
6557
|
-
%q{class A < B;}
|
6554
|
+
%q{class A; get_context; end},
|
6555
|
+
%q{class A < B; get_context; end}
|
6558
6556
|
].each do |code|
|
6559
6557
|
assert_context([:class], code, ALL_VERSIONS)
|
6560
6558
|
end
|
6561
6559
|
end
|
6562
6560
|
|
6561
|
+
def test_context_module
|
6562
|
+
assert_context(
|
6563
|
+
[:module],
|
6564
|
+
%q{module M; get_context; end},
|
6565
|
+
ALL_VERSIONS)
|
6566
|
+
end
|
6567
|
+
|
6563
6568
|
def test_context_sclass
|
6564
6569
|
assert_context(
|
6565
6570
|
[:sclass],
|
6566
|
-
%q{class << foo;},
|
6571
|
+
%q{class << foo; get_context; end},
|
6567
6572
|
ALL_VERSIONS)
|
6568
6573
|
end
|
6569
6574
|
|
6570
6575
|
def test_context_def
|
6571
|
-
|
6572
|
-
|
6573
|
-
%q{def m;}
|
6574
|
-
|
6576
|
+
[
|
6577
|
+
%q{def m; get_context; end},
|
6578
|
+
%q{def m(a = get_context); end}
|
6579
|
+
].each do |code|
|
6580
|
+
assert_context([:def], code, ALL_VERSIONS)
|
6581
|
+
end
|
6582
|
+
|
6583
|
+
[
|
6584
|
+
%q{def m() = get_context},
|
6585
|
+
%q{def m(a = get_context) = 42}
|
6586
|
+
].each do |code|
|
6587
|
+
assert_context([:def], code, SINCE_2_8)
|
6588
|
+
end
|
6575
6589
|
end
|
6576
6590
|
|
6577
6591
|
def test_context_defs
|
6578
|
-
|
6579
|
-
|
6580
|
-
%q{def foo.m;}
|
6581
|
-
|
6592
|
+
[
|
6593
|
+
%q{def foo.m; get_context; end},
|
6594
|
+
%q{def foo.m(a = get_context); end}
|
6595
|
+
].each do |code|
|
6596
|
+
assert_context([:defs], code, ALL_VERSIONS)
|
6597
|
+
end
|
6598
|
+
|
6599
|
+
[
|
6600
|
+
%q{def foo.m() = get_context},
|
6601
|
+
%q{def foo.m(a = get_context) = 42}
|
6602
|
+
].each do |code|
|
6603
|
+
assert_context([:defs], code, SINCE_2_8)
|
6604
|
+
end
|
6582
6605
|
end
|
6583
6606
|
|
6584
6607
|
def test_context_cmd_brace_block
|
6585
6608
|
[
|
6586
|
-
'tap foo {',
|
6587
|
-
'foo.tap foo {',
|
6588
|
-
'foo::tap foo {'
|
6609
|
+
'tap foo { get_context }',
|
6610
|
+
'foo.tap foo { get_context }',
|
6611
|
+
'foo::tap foo { get_context }'
|
6589
6612
|
].each do |code|
|
6590
6613
|
assert_context([:block], code, ALL_VERSIONS)
|
6591
6614
|
end
|
@@ -6593,12 +6616,12 @@ class TestParser < Minitest::Test
|
|
6593
6616
|
|
6594
6617
|
def test_context_brace_block
|
6595
6618
|
[
|
6596
|
-
'tap {',
|
6597
|
-
'foo.tap {',
|
6598
|
-
'foo::tap {',
|
6599
|
-
'tap do',
|
6600
|
-
'foo.tap do',
|
6601
|
-
'foo::tap do'
|
6619
|
+
'tap { get_context }',
|
6620
|
+
'foo.tap { get_context }',
|
6621
|
+
'foo::tap { get_context }',
|
6622
|
+
'tap do get_context end',
|
6623
|
+
'foo.tap do get_context end',
|
6624
|
+
'foo::tap do get_context end'
|
6602
6625
|
].each do |code|
|
6603
6626
|
assert_context([:block], code, ALL_VERSIONS)
|
6604
6627
|
end
|
@@ -6606,9 +6629,9 @@ class TestParser < Minitest::Test
|
|
6606
6629
|
|
6607
6630
|
def test_context_do_block
|
6608
6631
|
[
|
6609
|
-
%q{tap 1 do},
|
6610
|
-
%q{foo.tap do},
|
6611
|
-
%q{foo::tap do}
|
6632
|
+
%q{tap 1 do get_context end},
|
6633
|
+
%q{foo.tap do get_context end},
|
6634
|
+
%q{foo::tap do get_context end}
|
6612
6635
|
].each do |code|
|
6613
6636
|
assert_context([:block], code, ALL_VERSIONS)
|
6614
6637
|
end
|
@@ -6616,8 +6639,12 @@ class TestParser < Minitest::Test
|
|
6616
6639
|
|
6617
6640
|
def test_context_lambda
|
6618
6641
|
[
|
6619
|
-
'->() {',
|
6620
|
-
'->() do'
|
6642
|
+
'->() { get_context }',
|
6643
|
+
'->() do get_context end',
|
6644
|
+
'-> { get_context }',
|
6645
|
+
'-> do get_context end',
|
6646
|
+
'->(a = get_context) {}',
|
6647
|
+
'->(a = get_context) do end'
|
6621
6648
|
].each do |code|
|
6622
6649
|
assert_context([:lambda], code, SINCE_1_9)
|
6623
6650
|
end
|
@@ -6625,28 +6652,61 @@ class TestParser < Minitest::Test
|
|
6625
6652
|
|
6626
6653
|
def test_context_nested
|
6627
6654
|
assert_context(
|
6628
|
-
[:class, :sclass, :defs, :def, :block],
|
6629
|
-
%q{
|
6655
|
+
[:class, :module, :sclass, :defs, :def, :block],
|
6656
|
+
%q{
|
6657
|
+
class A
|
6658
|
+
module M
|
6659
|
+
class << foo
|
6660
|
+
def bar.m
|
6661
|
+
def m
|
6662
|
+
tap do
|
6663
|
+
get_context
|
6664
|
+
end
|
6665
|
+
end
|
6666
|
+
end
|
6667
|
+
end
|
6668
|
+
end
|
6669
|
+
end
|
6670
|
+
},
|
6630
6671
|
ALL_VERSIONS)
|
6631
6672
|
|
6632
6673
|
assert_context(
|
6633
|
-
[:class, :sclass, :defs, :def, :lambda, :block],
|
6634
|
-
%q{
|
6674
|
+
[:class, :module, :sclass, :defs, :def, :lambda, :block],
|
6675
|
+
%q{
|
6676
|
+
class A
|
6677
|
+
module M
|
6678
|
+
class << foo
|
6679
|
+
def bar.m
|
6680
|
+
def m
|
6681
|
+
-> do
|
6682
|
+
tap do
|
6683
|
+
get_context
|
6684
|
+
end
|
6685
|
+
end
|
6686
|
+
end
|
6687
|
+
end
|
6688
|
+
end
|
6689
|
+
end
|
6690
|
+
end
|
6691
|
+
},
|
6635
6692
|
SINCE_1_9)
|
6636
6693
|
|
6637
6694
|
assert_context(
|
6638
6695
|
[],
|
6639
6696
|
%q{
|
6640
6697
|
class A
|
6641
|
-
|
6642
|
-
|
6643
|
-
def m
|
6644
|
-
|
6698
|
+
module M
|
6699
|
+
class << foo
|
6700
|
+
def bar.m
|
6701
|
+
def m
|
6702
|
+
tap do
|
6703
|
+
end
|
6645
6704
|
end
|
6646
6705
|
end
|
6647
6706
|
end
|
6648
6707
|
end
|
6649
6708
|
end
|
6709
|
+
get_context
|
6650
6710
|
},
|
6651
6711
|
ALL_VERSIONS)
|
6652
6712
|
|
@@ -6654,17 +6714,20 @@ class TestParser < Minitest::Test
|
|
6654
6714
|
[],
|
6655
6715
|
%q{
|
6656
6716
|
class A
|
6657
|
-
|
6658
|
-
|
6659
|
-
def m
|
6660
|
-
|
6661
|
-
|
6717
|
+
module M
|
6718
|
+
class << foo
|
6719
|
+
def bar.m
|
6720
|
+
def m
|
6721
|
+
-> do
|
6722
|
+
tap do
|
6723
|
+
end
|
6662
6724
|
end
|
6663
6725
|
end
|
6664
6726
|
end
|
6665
6727
|
end
|
6666
6728
|
end
|
6667
6729
|
end
|
6730
|
+
get_context
|
6668
6731
|
},
|
6669
6732
|
SINCE_1_9)
|
6670
6733
|
end
|
@@ -7748,7 +7811,8 @@ class TestParser < Minitest::Test
|
|
7748
7811
|
end
|
7749
7812
|
end
|
7750
7813
|
|
7751
|
-
def
|
7814
|
+
def test_forward_args_legacy
|
7815
|
+
Parser::Builders::Default.emit_forward_arg = false
|
7752
7816
|
assert_parses(
|
7753
7817
|
s(:def, :foo,
|
7754
7818
|
s(:forward_args),
|
@@ -7780,7 +7844,27 @@ class TestParser < Minitest::Test
|
|
7780
7844
|
%q{def foo(...); end},
|
7781
7845
|
%q{},
|
7782
7846
|
SINCE_2_7)
|
7847
|
+
ensure
|
7848
|
+
Parser::Builders::Default.emit_forward_arg = true
|
7849
|
+
end
|
7850
|
+
|
7851
|
+
def test_forward_arg
|
7852
|
+
assert_parses(
|
7853
|
+
s(:def, :foo,
|
7854
|
+
s(:args,
|
7855
|
+
s(:forward_arg)),
|
7856
|
+
s(:send, nil, :bar,
|
7857
|
+
s(:forwarded_args))),
|
7858
|
+
%q{def foo(...); bar(...); end},
|
7859
|
+
%q{ ~ begin (args)
|
7860
|
+
| ~~~~~ expression (args)
|
7861
|
+
| ~ end (args)
|
7862
|
+
| ~~~ expression (args.forward_arg)
|
7863
|
+
| ~~~ expression (send.forwarded_args)},
|
7864
|
+
SINCE_2_7)
|
7865
|
+
end
|
7783
7866
|
|
7867
|
+
def test_forward_args_invalid
|
7784
7868
|
assert_diagnoses(
|
7785
7869
|
[:error, :block_and_blockarg],
|
7786
7870
|
%q{def foo(...) bar(...) { }; end},
|
@@ -7806,6 +7890,12 @@ class TestParser < Minitest::Test
|
|
7806
7890
|
%q{ ^^^ location},
|
7807
7891
|
SINCE_2_7)
|
7808
7892
|
|
7893
|
+
assert_diagnoses(
|
7894
|
+
[:error, :unexpected_token, { :token => 'tBDOT3' }],
|
7895
|
+
%q{def foo(x,y,z); bar(x, y, z, ...); end},
|
7896
|
+
%q{ ^^^ location},
|
7897
|
+
SINCE_2_8)
|
7898
|
+
|
7809
7899
|
assert_diagnoses(
|
7810
7900
|
[:error, :unexpected_token, { :token => 'tBDOT3' }],
|
7811
7901
|
%q{def foo(x,y,z); super(...); end},
|
@@ -7822,7 +7912,13 @@ class TestParser < Minitest::Test
|
|
7822
7912
|
[:error, :unexpected_token, { :token => 'tBDOT3' }],
|
7823
7913
|
%q{->(...) {}},
|
7824
7914
|
%q{ ^^^ location},
|
7825
|
-
|
7915
|
+
['2.7'])
|
7916
|
+
|
7917
|
+
assert_diagnoses(
|
7918
|
+
[:error, :unexpected_token, { :token => 'tDOT3' }],
|
7919
|
+
%q{->(...) {}},
|
7920
|
+
%q{ ^^^ location},
|
7921
|
+
SINCE_2_8)
|
7826
7922
|
|
7827
7923
|
# Here and below the parser asssumes that
|
7828
7924
|
# it can be a beginningless range, so the error comes after reducing right paren
|
@@ -7875,6 +7971,26 @@ class TestParser < Minitest::Test
|
|
7875
7971
|
SINCE_2_7)
|
7876
7972
|
end
|
7877
7973
|
|
7974
|
+
def test_trailing_forward_arg
|
7975
|
+
assert_parses(
|
7976
|
+
s(:def, :foo,
|
7977
|
+
s(:args,
|
7978
|
+
s(:arg, :a),
|
7979
|
+
s(:arg, :b),
|
7980
|
+
s(:forward_arg)),
|
7981
|
+
s(:send, nil, :bar,
|
7982
|
+
s(:lvar, :a),
|
7983
|
+
s(:int, 42),
|
7984
|
+
s(:forwarded_args))),
|
7985
|
+
%q{def foo(a, b, ...); bar(a, 42, ...); end},
|
7986
|
+
%q{ ~ begin (args)
|
7987
|
+
| ~~~~~~~~~~~ expression (args)
|
7988
|
+
| ~ end (args)
|
7989
|
+
| ~~~ expression (args.forward_arg)},
|
7990
|
+
SINCE_2_8)
|
7991
|
+
end
|
7992
|
+
|
7993
|
+
|
7878
7994
|
def test_erange_without_parentheses_at_eol
|
7879
7995
|
assert_diagnoses(
|
7880
7996
|
[:warning, :triple_dot_at_eol],
|
@@ -8344,7 +8460,7 @@ class TestParser < Minitest::Test
|
|
8344
8460
|
nil),
|
8345
8461
|
"#{case_pre}#{code}; end",
|
8346
8462
|
source_maps,
|
8347
|
-
|
8463
|
+
versions
|
8348
8464
|
)
|
8349
8465
|
end
|
8350
8466
|
|
@@ -8675,6 +8791,18 @@ class TestParser < Minitest::Test
|
|
8675
8791
|
| ~ end (in_pattern.hash_pattern)}
|
8676
8792
|
)
|
8677
8793
|
|
8794
|
+
assert_parses_pattern_match(
|
8795
|
+
s(:in_pattern,
|
8796
|
+
s(:hash_pattern,
|
8797
|
+
s(:pair, s(:sym, :a), s(:int, 1))),
|
8798
|
+
nil,
|
8799
|
+
s(:true)),
|
8800
|
+
%q{in { a: 1, } then true},
|
8801
|
+
%q{ ~~~~~~~~~ expression (in_pattern.hash_pattern)
|
8802
|
+
| ~ begin (in_pattern.hash_pattern)
|
8803
|
+
| ~ end (in_pattern.hash_pattern)}
|
8804
|
+
)
|
8805
|
+
|
8678
8806
|
assert_parses_pattern_match(
|
8679
8807
|
s(:in_pattern,
|
8680
8808
|
s(:hash_pattern,
|
@@ -8746,6 +8874,67 @@ class TestParser < Minitest::Test
|
|
8746
8874
|
%q{in a: 1, _a:, ** then true},
|
8747
8875
|
%q{ ~~~~~~~~~~~~~ expression (in_pattern.hash_pattern)}
|
8748
8876
|
)
|
8877
|
+
|
8878
|
+
assert_parses_pattern_match(
|
8879
|
+
s(:in_pattern,
|
8880
|
+
s(:hash_pattern,
|
8881
|
+
s(:pair,
|
8882
|
+
s(:sym, :a),
|
8883
|
+
s(:int, 1))), nil,
|
8884
|
+
s(:false)),
|
8885
|
+
%q{
|
8886
|
+
in {a: 1
|
8887
|
+
}
|
8888
|
+
false
|
8889
|
+
},
|
8890
|
+
%q{}
|
8891
|
+
)
|
8892
|
+
|
8893
|
+
|
8894
|
+
assert_parses_pattern_match(
|
8895
|
+
s(:in_pattern,
|
8896
|
+
s(:hash_pattern,
|
8897
|
+
s(:pair,
|
8898
|
+
s(:sym, :a),
|
8899
|
+
s(:int, 2))), nil,
|
8900
|
+
s(:false)),
|
8901
|
+
%q{
|
8902
|
+
in {a:
|
8903
|
+
2}
|
8904
|
+
false
|
8905
|
+
},
|
8906
|
+
%q{}
|
8907
|
+
)
|
8908
|
+
|
8909
|
+
assert_parses_pattern_match(
|
8910
|
+
s(:in_pattern,
|
8911
|
+
s(:hash_pattern,
|
8912
|
+
s(:pair,
|
8913
|
+
s(:sym, :a),
|
8914
|
+
s(:hash_pattern,
|
8915
|
+
s(:match_var, :b))),
|
8916
|
+
s(:match_var, :c)), nil,
|
8917
|
+
s(:send, nil, :p,
|
8918
|
+
s(:lvar, :c))),
|
8919
|
+
%q{
|
8920
|
+
in a: {b:}, c:
|
8921
|
+
p c
|
8922
|
+
},
|
8923
|
+
%q{}
|
8924
|
+
)
|
8925
|
+
|
8926
|
+
assert_parses_pattern_match(
|
8927
|
+
s(:in_pattern,
|
8928
|
+
s(:hash_pattern,
|
8929
|
+
s(:match_var, :a)), nil,
|
8930
|
+
s(:true)),
|
8931
|
+
%q{
|
8932
|
+
in {a:
|
8933
|
+
}
|
8934
|
+
true
|
8935
|
+
},
|
8936
|
+
%q{}
|
8937
|
+
)
|
8749
8938
|
end
|
8750
8939
|
|
8751
8940
|
def test_pattern_matching_hash_with_string_keys
|
@@ -8860,6 +9049,22 @@ class TestParser < Minitest::Test
|
|
8860
9049
|
%q{ ~~~~~~~ location},
|
8861
9050
|
SINCE_2_7
|
8862
9051
|
)
|
9052
|
+
|
9053
|
+
assert_diagnoses(
|
9054
|
+
[:error, :pm_interp_in_var_name],
|
9055
|
+
%q{case a; in "#{a}": 1; end},
|
9056
|
+
%q{ ~~~~~~~ location},
|
9057
|
+
SINCE_2_7
|
9058
|
+
)
|
9059
|
+
end
|
9060
|
+
|
9061
|
+
def test_pattern_matching_invalid_lvar_name
|
9062
|
+
assert_diagnoses(
|
9063
|
+
[:error, :lvar_name, { name: :a? }],
|
9064
|
+
%q{case a; in a?:; end},
|
9065
|
+
%q{ ~~ location},
|
9066
|
+
SINCE_2_7
|
9067
|
+
)
|
8863
9068
|
end
|
8864
9069
|
|
8865
9070
|
def test_pattern_matching_keyword_variable
|
@@ -9137,8 +9342,7 @@ class TestParser < Minitest::Test
|
|
9137
9342
|
code = "case 1; #{match_code}; then [#{lvar_names.join(', ')}]; end"
|
9138
9343
|
|
9139
9344
|
with_versions(versions) do |version, parser|
|
9140
|
-
source_file = Parser::Source::Buffer.new('(assert_context)')
|
9141
|
-
source_file.source = code
|
9345
|
+
source_file = Parser::Source::Buffer.new('(assert_context)', source: code)
|
9142
9346
|
|
9143
9347
|
lvar_names.each do |lvar_name|
|
9144
9348
|
refute parser.static_env.declared?(lvar_name),
|
@@ -9148,7 +9352,7 @@ class TestParser < Minitest::Test
|
|
9148
9352
|
before = parser.static_env.instance_variable_get(:@variables).to_a
|
9149
9353
|
|
9150
9354
|
begin
|
9151
|
-
|
9355
|
+
_parsed_ast = parser.parse(source_file)
|
9152
9356
|
rescue Parser::SyntaxError => exc
|
9153
9357
|
backtrace = exc.backtrace
|
9154
9358
|
Exception.instance_method(:initialize).bind(exc).
|
@@ -9354,4 +9558,223 @@ class TestParser < Minitest::Test
|
|
9354
9558
|
%{},
|
9355
9559
|
SINCE_1_9)
|
9356
9560
|
end
|
9561
|
+
|
9562
|
+
def test_endless_method
|
9563
|
+
assert_parses(
|
9564
|
+
s(:def_e, :foo,
|
9565
|
+
s(:args),
|
9566
|
+
s(:int, 42)),
|
9567
|
+
%q{def foo() = 42},
|
9568
|
+
%q{~~~ keyword
|
9569
|
+
| ~~~ name
|
9570
|
+
| ^ assignment
|
9571
|
+
|~~~~~~~~~~~~~~ expression},
|
9572
|
+
SINCE_2_8)
|
9573
|
+
|
9574
|
+
assert_parses(
|
9575
|
+
s(:def_e, :inc,
|
9576
|
+
s(:args, s(:arg, :x)),
|
9577
|
+
s(:send,
|
9578
|
+
s(:lvar, :x), :+,
|
9579
|
+
s(:int, 1))),
|
9580
|
+
%q{def inc(x) = x + 1},
|
9581
|
+
%q{~~~ keyword
|
9582
|
+
| ~~~ name
|
9583
|
+
| ^ assignment
|
9584
|
+
|~~~~~~~~~~~~~~~~~~ expression},
|
9585
|
+
SINCE_2_8)
|
9586
|
+
|
9587
|
+
assert_parses(
|
9588
|
+
s(:defs_e, s(:send, nil, :obj), :foo,
|
9589
|
+
s(:args),
|
9590
|
+
s(:int, 42)),
|
9591
|
+
%q{def obj.foo() = 42},
|
9592
|
+
%q{~~~ keyword
|
9593
|
+
| ^ operator
|
9594
|
+
| ~~~ name
|
9595
|
+
| ^ assignment
|
9596
|
+
|~~~~~~~~~~~~~~~~~~ expression},
|
9597
|
+
SINCE_2_8)
|
9598
|
+
|
9599
|
+
assert_parses(
|
9600
|
+
s(:defs_e, s(:send, nil, :obj), :inc,
|
9601
|
+
s(:args, s(:arg, :x)),
|
9602
|
+
s(:send,
|
9603
|
+
s(:lvar, :x), :+,
|
9604
|
+
s(:int, 1))),
|
9605
|
+
%q{def obj.inc(x) = x + 1},
|
9606
|
+
%q{~~~ keyword
|
9607
|
+
| ~~~ name
|
9608
|
+
| ^ operator
|
9609
|
+
| ^ assignment
|
9610
|
+
|~~~~~~~~~~~~~~~~~~~~~~ expression},
|
9611
|
+
SINCE_2_8)
|
9612
|
+
end
|
9613
|
+
|
9614
|
+
def test_endless_method_forwarded_args_legacy
|
9615
|
+
Parser::Builders::Default.emit_forward_arg = false
|
9616
|
+
assert_parses(
|
9617
|
+
s(:def_e, :foo,
|
9618
|
+
s(:forward_args),
|
9619
|
+
s(:send, nil, :bar,
|
9620
|
+
s(:forwarded_args))),
|
9621
|
+
%q{def foo(...) = bar(...)},
|
9622
|
+
%q{~~~ keyword
|
9623
|
+
| ~~~ name
|
9624
|
+
| ^ assignment
|
9625
|
+
|~~~~~~~~~~~~~~~~~~~~~~~ expression},
|
9626
|
+
SINCE_2_8)
|
9627
|
+
Parser::Builders::Default.emit_forward_arg = true
|
9628
|
+
end
|
9629
|
+
|
9630
|
+
def test_endless_method_without_brackets
|
9631
|
+
assert_diagnoses(
|
9632
|
+
[:error, :unexpected_token, { :token => 'tEQL' }],
|
9633
|
+
%Q{def foo = 42},
|
9634
|
+
%q{ ^ location},
|
9635
|
+
SINCE_2_8)
|
9636
|
+
|
9637
|
+
assert_diagnoses(
|
9638
|
+
[:error, :unexpected_token, { :token => 'tEQL' }],
|
9639
|
+
%Q{def obj.foo = 42},
|
9640
|
+
%q{ ^ location},
|
9641
|
+
SINCE_2_8
|
9642
|
+
)
|
9643
|
+
end
|
9644
|
+
|
9645
|
+
def test_endless_method_with_rescue_mod
|
9646
|
+
assert_parses(
|
9647
|
+
s(:def_e, :m,
|
9648
|
+
s(:args),
|
9649
|
+
s(:rescue,
|
9650
|
+
s(:int, 1),
|
9651
|
+
s(:resbody, nil, nil,
|
9652
|
+
s(:int, 2)), nil)),
|
9653
|
+
%q{def m() = 1 rescue 2},
|
9654
|
+
%q{},
|
9655
|
+
SINCE_2_8)
|
9656
|
+
|
9657
|
+
assert_parses(
|
9658
|
+
s(:defs_e,
|
9659
|
+
s(:self), :m,
|
9660
|
+
s(:args),
|
9661
|
+
s(:rescue,
|
9662
|
+
s(:int, 1),
|
9663
|
+
s(:resbody, nil, nil,
|
9664
|
+
s(:int, 2)), nil)),
|
9665
|
+
%q{def self.m() = 1 rescue 2},
|
9666
|
+
%q{},
|
9667
|
+
SINCE_2_8)
|
9668
|
+
end
|
9669
|
+
|
9670
|
+
def test_rasgn
|
9671
|
+
assert_parses(
|
9672
|
+
s(:rasgn,
|
9673
|
+
s(:int, 1), s(:lvasgn, :a)),
|
9674
|
+
%q{1 => a},
|
9675
|
+
%q{~~~~~~ expression
|
9676
|
+
| ^^ operator},
|
9677
|
+
SINCE_2_8)
|
9678
|
+
|
9679
|
+
assert_parses(
|
9680
|
+
s(:rasgn,
|
9681
|
+
s(:send, s(:int, 1), :+, s(:int, 2)),
|
9682
|
+
s(:gvasgn, :$a)),
|
9683
|
+
%q{1 + 2 => $a},
|
9684
|
+
%q{~~~~~~~~~~~ expression
|
9685
|
+
| ^^ operator},
|
9686
|
+
SINCE_2_8)
|
9687
|
+
end
|
9688
|
+
|
9689
|
+
def test_mrasgn
|
9690
|
+
assert_parses(
|
9691
|
+
s(:mrasgn,
|
9692
|
+
s(:send, s(:int, 13), :divmod, s(:int, 5)),
|
9693
|
+
s(:mlhs, s(:lvasgn, :a), s(:lvasgn, :b))),
|
9694
|
+
%q{13.divmod(5) => a,b},
|
9695
|
+
%q{~~~~~~~~~~~~~~~~~~~ expression
|
9696
|
+
| ^^ operator},
|
9697
|
+
SINCE_2_8)
|
9698
|
+
|
9699
|
+
assert_parses(
|
9700
|
+
s(:mrasgn,
|
9701
|
+
s(:mrasgn,
|
9702
|
+
s(:send, s(:int, 13), :divmod, s(:int, 5)),
|
9703
|
+
s(:mlhs, s(:lvasgn, :a), s(:lvasgn, :b))),
|
9704
|
+
s(:mlhs, s(:lvasgn, :c), s(:lvasgn, :d))),
|
9705
|
+
%q{13.divmod(5) => a,b => c, d},
|
9706
|
+
%q{~~~~~~~~~~~~~~~~~~~ expression (mrasgn)
|
9707
|
+
|~~~~~~~~~~~~~~~~~~~~~~~~~~~ expression},
|
9708
|
+
SINCE_2_8)
|
9709
|
+
end
|
9710
|
+
|
9711
|
+
def test_rasgn_line_continuation
|
9712
|
+
assert_diagnoses(
|
9713
|
+
[:error, :unexpected_token, { :token => 'tASSOC' }],
|
9714
|
+
%Q{13.divmod(5)\n=> a,b; [a, b]},
|
9715
|
+
%{ ^^ location},
|
9716
|
+
SINCE_2_8)
|
9717
|
+
end
|
9718
|
+
|
9719
|
+
def test_find_pattern
|
9720
|
+
assert_parses_pattern_match(
|
9721
|
+
s(:in_pattern,
|
9722
|
+
s(:find_pattern,
|
9723
|
+
s(:match_rest,
|
9724
|
+
s(:match_var, :x)),
|
9725
|
+
s(:match_as,
|
9726
|
+
s(:int, 1),
|
9727
|
+
s(:match_var, :a)),
|
9728
|
+
s(:match_rest,
|
9729
|
+
s(:match_var, :y))),
|
9730
|
+
nil,
|
9731
|
+
s(:true)),
|
9732
|
+
%q{in [*x, 1 => a, *y] then true},
|
9733
|
+
%q{ ~~~~~~~~~~~~~~~~ expression (in_pattern.find_pattern)
|
9734
|
+
| ~ begin (in_pattern.find_pattern)
|
9735
|
+
| ~ end (in_pattern.find_pattern)
|
9736
|
+
| ~~ expression (in_pattern.find_pattern.match_rest/1)
|
9737
|
+
| ~~ expression (in_pattern.find_pattern.match_rest/2)},
|
9738
|
+
SINCE_2_8)
|
9739
|
+
|
9740
|
+
assert_parses_pattern_match(
|
9741
|
+
s(:in_pattern,
|
9742
|
+
s(:const_pattern,
|
9743
|
+
s(:const, nil, :String),
|
9744
|
+
s(:find_pattern,
|
9745
|
+
s(:match_rest),
|
9746
|
+
s(:int, 1),
|
9747
|
+
s(:match_rest))),
|
9748
|
+
nil,
|
9749
|
+
s(:true)),
|
9750
|
+
%q{in String(*, 1, *) then true},
|
9751
|
+
%q{ ~~~~~~~ expression (in_pattern.const_pattern.find_pattern)},
|
9752
|
+
SINCE_2_8)
|
9753
|
+
|
9754
|
+
assert_parses_pattern_match(
|
9755
|
+
s(:in_pattern,
|
9756
|
+
s(:const_pattern,
|
9757
|
+
s(:const, nil, :Array),
|
9758
|
+
s(:find_pattern,
|
9759
|
+
s(:match_rest),
|
9760
|
+
s(:int, 1),
|
9761
|
+
s(:match_rest))),
|
9762
|
+
nil,
|
9763
|
+
s(:true)),
|
9764
|
+
%q{in Array[*, 1, *] then true},
|
9765
|
+
%q{ ~~~~~~~ expression (in_pattern.const_pattern.find_pattern)},
|
9766
|
+
SINCE_2_8)
|
9767
|
+
|
9768
|
+
assert_parses_pattern_match(
|
9769
|
+
s(:in_pattern,
|
9770
|
+
s(:find_pattern,
|
9771
|
+
s(:match_rest),
|
9772
|
+
s(:int, 42),
|
9773
|
+
s(:match_rest)),
|
9774
|
+
nil,
|
9775
|
+
s(:true)),
|
9776
|
+
%q{in *, 42, * then true},
|
9777
|
+
%q{ ~~~~~~~~ expression (in_pattern.find_pattern)},
|
9778
|
+
SINCE_2_8)
|
9779
|
+
end
|
9357
9780
|
end
|