parser 2.7.0.5 → 2.7.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|