parser 2.7.1.4 → 2.7.1.5

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.
Files changed (57) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +1 -0
  3. data/CHANGELOG.md +22 -1
  4. data/Rakefile +1 -1
  5. data/doc/AST_FORMAT.md +6 -5
  6. data/lib/parser.rb +1 -1
  7. data/lib/parser/all.rb +1 -1
  8. data/lib/parser/ast/processor.rb +0 -7
  9. data/lib/parser/base.rb +6 -5
  10. data/lib/parser/builders/default.rb +55 -19
  11. data/lib/parser/current.rb +5 -5
  12. data/lib/parser/lexer.rb +23770 -0
  13. data/lib/parser/lexer.rl +1 -1
  14. data/lib/parser/macruby.rb +6149 -0
  15. data/lib/parser/macruby.y +1 -1
  16. data/lib/parser/max_numparam_stack.rb +1 -1
  17. data/lib/parser/messages.rb +2 -0
  18. data/lib/parser/meta.rb +3 -3
  19. data/lib/parser/ruby18.rb +5663 -0
  20. data/lib/parser/ruby18.y +1 -1
  21. data/lib/parser/ruby19.rb +6092 -0
  22. data/lib/parser/ruby19.y +1 -1
  23. data/lib/parser/ruby20.rb +6527 -0
  24. data/lib/parser/ruby20.y +1 -1
  25. data/lib/parser/ruby21.rb +6578 -0
  26. data/lib/parser/ruby21.y +1 -1
  27. data/lib/parser/ruby22.rb +6613 -0
  28. data/lib/parser/ruby22.y +1 -1
  29. data/lib/parser/ruby23.rb +6624 -0
  30. data/lib/parser/ruby23.y +1 -1
  31. data/lib/parser/ruby24.rb +6694 -0
  32. data/lib/parser/ruby24.y +1 -1
  33. data/lib/parser/ruby25.rb +6662 -0
  34. data/lib/parser/ruby25.y +1 -1
  35. data/lib/parser/ruby26.rb +6676 -0
  36. data/lib/parser/ruby26.y +1 -1
  37. data/lib/parser/ruby27.rb +7803 -0
  38. data/lib/parser/ruby27.y +1 -2
  39. data/lib/parser/ruby30.rb +8052 -0
  40. data/lib/parser/{ruby28.y → ruby30.y} +9 -4
  41. data/lib/parser/rubymotion.rb +6086 -0
  42. data/lib/parser/rubymotion.y +1 -1
  43. data/lib/parser/runner.rb +3 -3
  44. data/lib/parser/source/comment.rb +1 -1
  45. data/lib/parser/source/comment/associator.rb +1 -1
  46. data/lib/parser/source/map/{endless_definition.rb → method_definition.rb} +5 -3
  47. data/lib/parser/source/range.rb +2 -2
  48. data/lib/parser/version.rb +1 -1
  49. data/parser.gemspec +4 -1
  50. data/test/helper.rb +1 -1
  51. data/test/parse_helper.rb +26 -21
  52. data/test/test_current.rb +2 -2
  53. data/test/test_lexer.rb +1 -1
  54. data/test/test_parse_helper.rb +12 -9
  55. data/test/test_parser.rb +253 -47
  56. metadata +8 -9
  57. data/.gitignore +0 -34
@@ -512,7 +512,7 @@ rule
512
512
 
513
513
  fsym: fname
514
514
  {
515
- result = @builder.symbol(val[0])
515
+ result = @builder.symbol_internal(val[0])
516
516
  }
517
517
  | symbol
518
518
 
@@ -113,9 +113,9 @@ module Parser
113
113
  @parser_class = Parser::Ruby27
114
114
  end
115
115
 
116
- opts.on '--28', 'Parse as Ruby 2.8 would' do
117
- require 'parser/ruby28'
118
- @parser_class = Parser::Ruby28
116
+ opts.on '--30', 'Parse as Ruby 3.0 would' do
117
+ require 'parser/ruby30'
118
+ @parser_class = Parser::Ruby30
119
119
  end
120
120
 
121
121
  opts.on '--mac', 'Parse as MacRuby 0.12 would' do
@@ -10,7 +10,7 @@ module Parser
10
10
  # @return [String]
11
11
  #
12
12
  # @!attribute [r] location
13
- # @return [Parser::Source::Map]
13
+ # @return [Parser::Source::Range]
14
14
  #
15
15
  # @api public
16
16
  #
@@ -107,7 +107,7 @@ module Parser
107
107
 
108
108
  private
109
109
 
110
- POSTFIX_TYPES = Set[:if, :while, :while_post, :until, :until_post].freeze
110
+ POSTFIX_TYPES = Set[:if, :while, :while_post, :until, :until_post, :masgn].freeze
111
111
  def children_in_source_order(node)
112
112
  if POSTFIX_TYPES.include?(node.type)
113
113
  # All these types have either nodes with expressions, or `nil`
@@ -3,19 +3,21 @@
3
3
  module Parser
4
4
  module Source
5
5
 
6
- class Map::EndlessDefinition < Map
6
+ class Map::MethodDefinition < Map
7
7
  attr_reader :keyword
8
8
  attr_reader :operator
9
9
  attr_reader :name
10
+ attr_reader :end
10
11
  attr_reader :assignment
11
12
 
12
- def initialize(keyword_l, operator_l, name_l, assignment_l, body_l)
13
+ def initialize(keyword_l, operator_l, name_l, end_l, assignment_l, body_l)
13
14
  @keyword = keyword_l
14
15
  @operator = operator_l
15
16
  @name = name_l
17
+ @end = end_l
16
18
  @assignment = assignment_l
17
19
 
18
- super(@keyword.join(body_l))
20
+ super(@keyword.join(end_l || body_l))
19
21
  end
20
22
  end
21
23
 
@@ -112,11 +112,11 @@ module Parser
112
112
  # @raise RangeError
113
113
  #
114
114
  def column_range
115
- if self.begin.line != self.end.line
115
+ if line != last_line
116
116
  raise RangeError, "#{self.inspect} spans more than one line"
117
117
  end
118
118
 
119
- self.begin.column...self.end.column
119
+ column...last_column
120
120
  end
121
121
 
122
122
  ##
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Parser
4
- VERSION = '2.7.1.4'
4
+ VERSION = '2.7.1.5'
5
5
  end
@@ -32,10 +32,13 @@ Gem::Specification.new do |spec|
32
32
  lib/parser/ruby25.rb
33
33
  lib/parser/ruby26.rb
34
34
  lib/parser/ruby27.rb
35
- lib/parser/ruby28.rb
35
+ lib/parser/ruby30.rb
36
36
  lib/parser/macruby.rb
37
37
  lib/parser/rubymotion.rb
38
+ ) - %w(
39
+ .gitignore
38
40
  )
41
+
39
42
  spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
40
43
  spec.test_files = spec.files.grep(%r{^test/})
41
44
  spec.require_paths = ['lib']
@@ -18,7 +18,7 @@ if ENV.include?('COVERAGE') && SimpleCov.usable?
18
18
  ruby25.y
19
19
  ruby26.y
20
20
  ruby27.y
21
- ruby28.y
21
+ ruby30.y
22
22
  ),
23
23
  File.expand_path('../../lib/parser', __FILE__))
24
24
 
@@ -7,7 +7,7 @@ module ParseHelper
7
7
  require 'parser/macruby'
8
8
  require 'parser/rubymotion'
9
9
 
10
- ALL_VERSIONS = %w(1.8 1.9 2.0 2.1 2.2 2.3 2.4 2.5 2.6 2.7 2.8 mac ios)
10
+ ALL_VERSIONS = %w(1.8 1.9 2.0 2.1 2.2 2.3 2.4 2.5 2.6 2.7 3.0 mac ios)
11
11
 
12
12
  def setup
13
13
  @diagnostics = []
@@ -27,7 +27,7 @@ module ParseHelper
27
27
  when '2.5' then parser = Parser::Ruby25.new
28
28
  when '2.6' then parser = Parser::Ruby26.new
29
29
  when '2.7' then parser = Parser::Ruby27.new
30
- when '2.8' then parser = Parser::Ruby28.new
30
+ when '3.0' then parser = Parser::Ruby30.new
31
31
  when 'mac' then parser = Parser::MacRuby.new
32
32
  when 'ios' then parser = Parser::RubyMotion.new
33
33
  else raise "Unrecognized Ruby version #{version}"
@@ -49,15 +49,17 @@ module ParseHelper
49
49
  end
50
50
  end
51
51
 
52
- def assert_source_range(begin_pos, end_pos, range, version, what)
53
- assert range.is_a?(Parser::Source::Range),
54
- "(#{version}) #{range.inspect}.is_a?(Source::Range) for #{what}"
55
-
56
- assert_equal begin_pos, range.begin_pos,
57
- "(#{version}) begin of #{what}"
58
-
59
- assert_equal end_pos, range.end_pos,
60
- "(#{version}) end of #{what}"
52
+ def assert_source_range(expect_range, range, version, what)
53
+ if expect_range == nil
54
+ # Avoid "Use assert_nil if expecting nil from .... This will fail in Minitest 6.""
55
+ assert_nil range,
56
+ "(#{version}) range of #{what}"
57
+ else
58
+ assert range.is_a?(Parser::Source::Range),
59
+ "(#{version}) #{range.inspect}.is_a?(Source::Range) for #{what}"
60
+ assert_equal expect_range, range.to_range,
61
+ "(#{version}) range of #{what}"
62
+ end
61
63
  end
62
64
 
63
65
  # Use like this:
@@ -105,7 +107,7 @@ module ParseHelper
105
107
  assert_equal ast, parsed_ast,
106
108
  "(#{version}) AST equality"
107
109
 
108
- parse_source_map_descriptions(source_maps) do |begin_pos, end_pos, map_field, ast_path, line|
110
+ parse_source_map_descriptions(source_maps) do |range, map_field, ast_path, line|
109
111
 
110
112
  astlet = traverse_ast(parsed_ast, ast_path)
111
113
 
@@ -119,9 +121,9 @@ module ParseHelper
119
121
  assert astlet.location.respond_to?(map_field),
120
122
  "(#{version}) #{astlet.location.inspect}.respond_to?(#{map_field.inspect}) for:\n#{parsed_ast.inspect}"
121
123
 
122
- range = astlet.location.send(map_field)
124
+ found_range = astlet.location.send(map_field)
123
125
 
124
- assert_source_range(begin_pos, end_pos, range, version, line.inspect)
126
+ assert_source_range(range, found_range, version, line.inspect)
125
127
  end
126
128
 
127
129
  assert parser.instance_eval { @lexer }.cmdarg.empty?,
@@ -164,18 +166,18 @@ module ParseHelper
164
166
  assert_equal arguments, emitted_diagnostic.arguments
165
167
  assert_equal message, emitted_diagnostic.message
166
168
 
167
- parse_source_map_descriptions(source_maps) do |begin_pos, end_pos, map_field, ast_path, line|
169
+ parse_source_map_descriptions(source_maps) do |range, map_field, ast_path, line|
168
170
 
169
171
  case map_field
170
172
  when 'location'
171
- assert_source_range begin_pos, end_pos,
173
+ assert_source_range range,
172
174
  emitted_diagnostic.location,
173
175
  version, 'location'
174
176
 
175
177
  when 'highlights'
176
178
  index = ast_path.first.to_i
177
179
 
178
- assert_source_range begin_pos, end_pos,
180
+ assert_source_range range,
179
181
  emitted_diagnostic.highlights[index],
180
182
  version, "#{index}th highlight"
181
183
 
@@ -254,7 +256,7 @@ module ParseHelper
254
256
  SOURCE_MAP_DESCRIPTION_RE =
255
257
  /(?x)
256
258
  ^(?# $1 skip) ^(\s*)
257
- (?# $2 highlight) ([~\^]+)
259
+ (?# $2 highlight) ([~\^]+|\!)
258
260
  \s+
259
261
  (?# $3 source_map_field) ([a-z_]+)
260
262
  (?# $5 ast_path) (\s+\(([a-z_.\/0-9]+)\))?
@@ -272,8 +274,11 @@ module ParseHelper
272
274
  next if line.empty?
273
275
 
274
276
  if (match = SOURCE_MAP_DESCRIPTION_RE.match(line))
275
- begin_pos = match[1].length
276
- end_pos = begin_pos + match[2].length
277
+ if match[2] != '!'
278
+ begin_pos = match[1].length
279
+ end_pos = begin_pos + match[2].length
280
+ range = begin_pos...end_pos
281
+ end
277
282
  source_map_field = match[3]
278
283
 
279
284
  if match[5]
@@ -282,7 +287,7 @@ module ParseHelper
282
287
  ast_path = []
283
288
  end
284
289
 
285
- yield begin_pos, end_pos, source_map_field, ast_path, line
290
+ yield range, source_map_field, ast_path, line
286
291
  else
287
292
  raise "Cannot parse source map description line: #{line.inspect}."
288
293
  end
@@ -22,8 +22,8 @@ class TestCurrent < Minitest::Test
22
22
  assert_equal Parser::Ruby26, Parser::CurrentRuby
23
23
  when /^2\.7\.\d+/
24
24
  assert_equal Parser::Ruby27, Parser::CurrentRuby
25
- when /^2\.8\.\d+/
26
- assert_equal Parser::Ruby28, Parser::CurrentRuby
25
+ when /^3\.0\.\d+/
26
+ assert_equal Parser::Ruby30, Parser::CurrentRuby
27
27
  else
28
28
  flunk "Update test_current for #{RUBY_VERSION}"
29
29
  end
@@ -3568,7 +3568,7 @@ class TestLexer < Minitest::Test
3568
3568
  end
3569
3569
 
3570
3570
  def test_endless_method
3571
- setup_lexer(28)
3571
+ setup_lexer(30)
3572
3572
 
3573
3573
  assert_scanned('def foo() = 42',
3574
3574
  :kDEF, "def", [0, 3],
@@ -25,33 +25,36 @@ class TestParseHelper < Minitest::Test
25
25
  end
26
26
 
27
27
  def test_parse_mapsation_description
28
- assert_equal [[0, 4, 'expr', [], '~~~~ expr']],
28
+ assert_equal [[0...4, 'expr', [], '~~~~ expr']],
29
29
  parse_maps('~~~~ expr')
30
30
 
31
- assert_equal [[0, 4, 'expr', [], '^~~~ expr']],
31
+ assert_equal [[0...4, 'expr', [], '^~~~ expr']],
32
32
  parse_maps('^~~~ expr')
33
33
 
34
- assert_equal [[0, 4, 'expr', [], '^^^^ expr']],
34
+ assert_equal [[0...4, 'expr', [], '^^^^ expr']],
35
35
  parse_maps('^^^^ expr')
36
36
 
37
- assert_equal [[2, 3, 'op', [], ' ^ op']],
37
+ assert_equal [[2...3, 'op', [], ' ^ op']],
38
38
  parse_maps(' ^ op')
39
39
 
40
- assert_equal [[2, 3, 'op', ['foo'], ' ~ op (foo)']],
40
+ assert_equal [[2...3, 'op', ['foo'], ' ~ op (foo)']],
41
41
  parse_maps(' ~ op (foo)')
42
42
 
43
- assert_equal [[2, 4, 'op', ['foo', 'bar'], ' ~~ op (foo.bar)']],
43
+ assert_equal [[2...4, 'op', ['foo', 'bar'], ' ~~ op (foo.bar)']],
44
44
  parse_maps(' ~~ op (foo.bar)')
45
45
 
46
- assert_equal [[2, 4, 'op', ['foo/2', 'bar'], ' ~~ op (foo/2.bar)']],
46
+ assert_equal [[2...4, 'op', ['foo/2', 'bar'], ' ~~ op (foo/2.bar)']],
47
47
  parse_maps(' ~~ op (foo/2.bar)')
48
48
 
49
- assert_equal [[0, 4, 'expr', [], '~~~~ expr'],
50
- [5, 7, 'op', ['str', 'e_h'], ' ~~ op (str.e_h)']],
49
+ assert_equal [[0...4, 'expr', [], '~~~~ expr'],
50
+ [5...7, 'op', ['str', 'e_h'], ' ~~ op (str.e_h)']],
51
51
  parse_maps(%{
52
52
  |~~~~ expr
53
53
  | ~~ op (str.e_h)
54
54
  })
55
+
56
+ assert_equal [[nil, 'expr', [], '! expr']],
57
+ parse_maps('! expr')
55
58
  end
56
59
 
57
60
  def test_traverse_ast
@@ -29,7 +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
+ SINCE_3_0 = SINCE_2_7 - %w(2.7)
33
33
 
34
34
  # Guidelines for test naming:
35
35
  # * Test structure follows structure of AST_FORMAT.md.
@@ -1856,6 +1856,7 @@ class TestParser < Minitest::Test
1856
1856
  %q{def foo; end},
1857
1857
  %q{~~~ keyword
1858
1858
  | ~~~ name
1859
+ |! assignment
1859
1860
  | ~~~ end})
1860
1861
 
1861
1862
  assert_parses(
@@ -1976,7 +1977,9 @@ class TestParser < Minitest::Test
1976
1977
  %q{alias :foo bar},
1977
1978
  %q{~~~~~ keyword
1978
1979
  | ~~~~ expression (sym/1)
1980
+ | ^ begin (sym/1)
1979
1981
  | ~~~ expression (sym/2)
1982
+ | ! begin (sym/2)
1980
1983
  |~~~~~~~~~~~~~~ expression})
1981
1984
  end
1982
1985
 
@@ -6584,7 +6587,7 @@ class TestParser < Minitest::Test
6584
6587
  %q{def m() = get_context},
6585
6588
  %q{def m(a = get_context) = 42}
6586
6589
  ].each do |code|
6587
- assert_context([:def], code, SINCE_2_8)
6590
+ assert_context([:def], code, SINCE_3_0)
6588
6591
  end
6589
6592
  end
6590
6593
 
@@ -6600,7 +6603,7 @@ class TestParser < Minitest::Test
6600
6603
  %q{def foo.m() = get_context},
6601
6604
  %q{def foo.m(a = get_context) = 42}
6602
6605
  ].each do |code|
6603
- assert_context([:defs], code, SINCE_2_8)
6606
+ assert_context([:defs], code, SINCE_3_0)
6604
6607
  end
6605
6608
  end
6606
6609
 
@@ -7511,7 +7514,7 @@ class TestParser < Minitest::Test
7511
7514
  s(:nil))),
7512
7515
  %q{proc {_1 = nil}},
7513
7516
  %q{},
7514
- SINCE_2_7)
7517
+ %w(2.7))
7515
7518
 
7516
7519
  assert_diagnoses(
7517
7520
  [:error, :cant_assign_to_numparam, { :name => '_1' }],
@@ -7539,7 +7542,7 @@ class TestParser < Minitest::Test
7539
7542
 
7540
7543
  refute_diagnoses(
7541
7544
  %q{proc { _1 = nil; _1}},
7542
- SINCE_2_7)
7545
+ %w(2.7))
7543
7546
  end
7544
7547
 
7545
7548
  def test_numparams_in_nested_blocks
@@ -7894,7 +7897,7 @@ class TestParser < Minitest::Test
7894
7897
  [:error, :unexpected_token, { :token => 'tBDOT3' }],
7895
7898
  %q{def foo(x,y,z); bar(x, y, z, ...); end},
7896
7899
  %q{ ^^^ location},
7897
- SINCE_2_8)
7900
+ SINCE_3_0)
7898
7901
 
7899
7902
  assert_diagnoses(
7900
7903
  [:error, :unexpected_token, { :token => 'tBDOT3' }],
@@ -7918,7 +7921,7 @@ class TestParser < Minitest::Test
7918
7921
  [:error, :unexpected_token, { :token => 'tDOT3' }],
7919
7922
  %q{->(...) {}},
7920
7923
  %q{ ^^^ location},
7921
- SINCE_2_8)
7924
+ SINCE_3_0)
7922
7925
 
7923
7926
  # Here and below the parser asssumes that
7924
7927
  # it can be a beginningless range, so the error comes after reducing right paren
@@ -7987,7 +7990,7 @@ class TestParser < Minitest::Test
7987
7990
  | ~~~~~~~~~~~ expression (args)
7988
7991
  | ~ end (args)
7989
7992
  | ~~~ expression (args.forward_arg)},
7990
- SINCE_2_8)
7993
+ SINCE_3_0)
7991
7994
  end
7992
7995
 
7993
7996
 
@@ -8906,6 +8909,21 @@ class TestParser < Minitest::Test
8906
8909
  %q{}
8907
8910
  )
8908
8911
 
8912
+ assert_parses_pattern_match(
8913
+ s(:in_pattern,
8914
+ s(:hash_pattern,
8915
+ s(:pair,
8916
+ s(:sym, :Foo),
8917
+ s(:int, 42))), nil,
8918
+ s(:false)),
8919
+ %q{
8920
+ in {Foo: 42
8921
+ }
8922
+ false
8923
+ },
8924
+ %q{}
8925
+ )
8926
+
8909
8927
  assert_parses_pattern_match(
8910
8928
  s(:in_pattern,
8911
8929
  s(:hash_pattern,
@@ -9561,18 +9579,19 @@ class TestParser < Minitest::Test
9561
9579
 
9562
9580
  def test_endless_method
9563
9581
  assert_parses(
9564
- s(:def_e, :foo,
9582
+ s(:def, :foo,
9565
9583
  s(:args),
9566
9584
  s(:int, 42)),
9567
9585
  %q{def foo() = 42},
9568
9586
  %q{~~~ keyword
9569
9587
  | ~~~ name
9570
9588
  | ^ assignment
9589
+ |! end
9571
9590
  |~~~~~~~~~~~~~~ expression},
9572
- SINCE_2_8)
9591
+ SINCE_3_0)
9573
9592
 
9574
9593
  assert_parses(
9575
- s(:def_e, :inc,
9594
+ s(:def, :inc,
9576
9595
  s(:args, s(:arg, :x)),
9577
9596
  s(:send,
9578
9597
  s(:lvar, :x), :+,
@@ -9582,10 +9601,10 @@ class TestParser < Minitest::Test
9582
9601
  | ~~~ name
9583
9602
  | ^ assignment
9584
9603
  |~~~~~~~~~~~~~~~~~~ expression},
9585
- SINCE_2_8)
9604
+ SINCE_3_0)
9586
9605
 
9587
9606
  assert_parses(
9588
- s(:defs_e, s(:send, nil, :obj), :foo,
9607
+ s(:defs, s(:send, nil, :obj), :foo,
9589
9608
  s(:args),
9590
9609
  s(:int, 42)),
9591
9610
  %q{def obj.foo() = 42},
@@ -9594,10 +9613,10 @@ class TestParser < Minitest::Test
9594
9613
  | ~~~ name
9595
9614
  | ^ assignment
9596
9615
  |~~~~~~~~~~~~~~~~~~ expression},
9597
- SINCE_2_8)
9616
+ SINCE_3_0)
9598
9617
 
9599
9618
  assert_parses(
9600
- s(:defs_e, s(:send, nil, :obj), :inc,
9619
+ s(:defs, s(:send, nil, :obj), :inc,
9601
9620
  s(:args, s(:arg, :x)),
9602
9621
  s(:send,
9603
9622
  s(:lvar, :x), :+,
@@ -9608,13 +9627,13 @@ class TestParser < Minitest::Test
9608
9627
  | ^ operator
9609
9628
  | ^ assignment
9610
9629
  |~~~~~~~~~~~~~~~~~~~~~~ expression},
9611
- SINCE_2_8)
9630
+ SINCE_3_0)
9612
9631
  end
9613
9632
 
9614
9633
  def test_endless_method_forwarded_args_legacy
9615
9634
  Parser::Builders::Default.emit_forward_arg = false
9616
9635
  assert_parses(
9617
- s(:def_e, :foo,
9636
+ s(:def, :foo,
9618
9637
  s(:forward_args),
9619
9638
  s(:send, nil, :bar,
9620
9639
  s(:forwarded_args))),
@@ -9623,7 +9642,7 @@ class TestParser < Minitest::Test
9623
9642
  | ~~~ name
9624
9643
  | ^ assignment
9625
9644
  |~~~~~~~~~~~~~~~~~~~~~~~ expression},
9626
- SINCE_2_8)
9645
+ SINCE_3_0)
9627
9646
  Parser::Builders::Default.emit_forward_arg = true
9628
9647
  end
9629
9648
 
@@ -9632,19 +9651,19 @@ class TestParser < Minitest::Test
9632
9651
  [:error, :unexpected_token, { :token => 'tEQL' }],
9633
9652
  %Q{def foo = 42},
9634
9653
  %q{ ^ location},
9635
- SINCE_2_8)
9654
+ SINCE_3_0)
9636
9655
 
9637
9656
  assert_diagnoses(
9638
9657
  [:error, :unexpected_token, { :token => 'tEQL' }],
9639
9658
  %Q{def obj.foo = 42},
9640
9659
  %q{ ^ location},
9641
- SINCE_2_8
9660
+ SINCE_3_0
9642
9661
  )
9643
9662
  end
9644
9663
 
9645
9664
  def test_endless_method_with_rescue_mod
9646
9665
  assert_parses(
9647
- s(:def_e, :m,
9666
+ s(:def, :m,
9648
9667
  s(:args),
9649
9668
  s(:rescue,
9650
9669
  s(:int, 1),
@@ -9652,10 +9671,10 @@ class TestParser < Minitest::Test
9652
9671
  s(:int, 2)), nil)),
9653
9672
  %q{def m() = 1 rescue 2},
9654
9673
  %q{},
9655
- SINCE_2_8)
9674
+ SINCE_3_0)
9656
9675
 
9657
9676
  assert_parses(
9658
- s(:defs_e,
9677
+ s(:defs,
9659
9678
  s(:self), :m,
9660
9679
  s(:args),
9661
9680
  s(:rescue,
@@ -9664,48 +9683,48 @@ class TestParser < Minitest::Test
9664
9683
  s(:int, 2)), nil)),
9665
9684
  %q{def self.m() = 1 rescue 2},
9666
9685
  %q{},
9667
- SINCE_2_8)
9686
+ SINCE_3_0)
9668
9687
  end
9669
9688
 
9670
9689
  def test_rasgn
9671
9690
  assert_parses(
9672
- s(:rasgn,
9673
- s(:int, 1), s(:lvasgn, :a)),
9691
+ s(:lvasgn, :a,
9692
+ s(:int, 1)),
9674
9693
  %q{1 => a},
9675
9694
  %q{~~~~~~ expression
9676
9695
  | ^^ operator},
9677
- SINCE_2_8)
9696
+ SINCE_3_0)
9678
9697
 
9679
9698
  assert_parses(
9680
- s(:rasgn,
9681
- s(:send, s(:int, 1), :+, s(:int, 2)),
9682
- s(:gvasgn, :$a)),
9699
+ s(:gvasgn, :$a,
9700
+ s(:send, s(:int, 1), :+, s(:int, 2))),
9683
9701
  %q{1 + 2 => $a},
9684
9702
  %q{~~~~~~~~~~~ expression
9685
9703
  | ^^ operator},
9686
- SINCE_2_8)
9704
+ SINCE_3_0)
9687
9705
  end
9688
9706
 
9689
9707
  def test_mrasgn
9690
9708
  assert_parses(
9691
- s(:mrasgn,
9692
- s(:send, s(:int, 13), :divmod, s(:int, 5)),
9693
- s(:mlhs, s(:lvasgn, :a), s(:lvasgn, :b))),
9709
+ s(:masgn,
9710
+ s(:mlhs, s(:lvasgn, :a), s(:lvasgn, :b)),
9711
+ s(:send, s(:int, 13), :divmod, s(:int, 5))),
9694
9712
  %q{13.divmod(5) => a,b},
9695
9713
  %q{~~~~~~~~~~~~~~~~~~~ expression
9696
9714
  | ^^ operator},
9697
- SINCE_2_8)
9715
+ SINCE_3_0)
9698
9716
 
9699
9717
  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))),
9718
+ s(:masgn,
9719
+ s(:mlhs, s(:lvasgn, :c), s(:lvasgn, :d)),
9720
+ s(:masgn,
9721
+ s(:mlhs, s(:lvasgn, :a), s(:lvasgn, :b)),
9722
+ s(:send, s(:int, 13), :divmod, s(:int, 5))),
9723
+ ),
9705
9724
  %q{13.divmod(5) => a,b => c, d},
9706
- %q{~~~~~~~~~~~~~~~~~~~ expression (mrasgn)
9725
+ %q{~~~~~~~~~~~~~~~~~~~ expression (masgn)
9707
9726
  |~~~~~~~~~~~~~~~~~~~~~~~~~~~ expression},
9708
- SINCE_2_8)
9727
+ SINCE_3_0)
9709
9728
  end
9710
9729
 
9711
9730
  def test_rasgn_line_continuation
@@ -9713,7 +9732,7 @@ class TestParser < Minitest::Test
9713
9732
  [:error, :unexpected_token, { :token => 'tASSOC' }],
9714
9733
  %Q{13.divmod(5)\n=> a,b; [a, b]},
9715
9734
  %{ ^^ location},
9716
- SINCE_2_8)
9735
+ SINCE_3_0)
9717
9736
  end
9718
9737
 
9719
9738
  def test_find_pattern
@@ -9735,7 +9754,7 @@ class TestParser < Minitest::Test
9735
9754
  | ~ end (in_pattern.find_pattern)
9736
9755
  | ~~ expression (in_pattern.find_pattern.match_rest/1)
9737
9756
  | ~~ expression (in_pattern.find_pattern.match_rest/2)},
9738
- SINCE_2_8)
9757
+ SINCE_3_0)
9739
9758
 
9740
9759
  assert_parses_pattern_match(
9741
9760
  s(:in_pattern,
@@ -9749,7 +9768,7 @@ class TestParser < Minitest::Test
9749
9768
  s(:true)),
9750
9769
  %q{in String(*, 1, *) then true},
9751
9770
  %q{ ~~~~~~~ expression (in_pattern.const_pattern.find_pattern)},
9752
- SINCE_2_8)
9771
+ SINCE_3_0)
9753
9772
 
9754
9773
  assert_parses_pattern_match(
9755
9774
  s(:in_pattern,
@@ -9763,7 +9782,7 @@ class TestParser < Minitest::Test
9763
9782
  s(:true)),
9764
9783
  %q{in Array[*, 1, *] then true},
9765
9784
  %q{ ~~~~~~~ expression (in_pattern.const_pattern.find_pattern)},
9766
- SINCE_2_8)
9785
+ SINCE_3_0)
9767
9786
 
9768
9787
  assert_parses_pattern_match(
9769
9788
  s(:in_pattern,
@@ -9775,6 +9794,193 @@ class TestParser < Minitest::Test
9775
9794
  s(:true)),
9776
9795
  %q{in *, 42, * then true},
9777
9796
  %q{ ~~~~~~~~ expression (in_pattern.find_pattern)},
9778
- SINCE_2_8)
9797
+ SINCE_3_0)
9798
+ end
9799
+
9800
+ def test_invalid_source
9801
+ with_versions(ALL_VERSIONS) do |_ver, parser|
9802
+ source_file = Parser::Source::Buffer.new('(comments)', source: "def foo; en")
9803
+
9804
+ parser.diagnostics.all_errors_are_fatal = false
9805
+ ast = parser.parse(source_file)
9806
+ assert_nil(ast)
9807
+ end
9808
+ end
9809
+
9810
+ def test_reserved_for_numparam__before_30
9811
+ assert_parses(
9812
+ s(:block,
9813
+ s(:send, nil, :proc),
9814
+ s(:args),
9815
+ s(:lvasgn, :_1,
9816
+ s(:nil))),
9817
+ %q{proc {_1 = nil}},
9818
+ %q{},
9819
+ ALL_VERSIONS - SINCE_3_0)
9820
+
9821
+ assert_parses(
9822
+ s(:lvasgn, :_2,
9823
+ s(:int, 1)),
9824
+ %q{_2 = 1},
9825
+ %q{},
9826
+ ALL_VERSIONS - SINCE_3_0)
9827
+
9828
+ assert_parses(
9829
+ s(:block,
9830
+ s(:send, nil, :proc),
9831
+ s(:args,
9832
+ s(:procarg0,
9833
+ s(:arg, :_3))), nil),
9834
+ %q{proc {|_3|}},
9835
+ %q{},
9836
+ SINCE_1_9 - SINCE_3_0)
9837
+
9838
+ assert_parses(
9839
+ s(:def, :x,
9840
+ s(:args,
9841
+ s(:arg, :_4)), nil),
9842
+ %q{def x(_4) end},
9843
+ %q{},
9844
+ ALL_VERSIONS - SINCE_3_0)
9845
+
9846
+ assert_parses(
9847
+ s(:def, :_5,
9848
+ s(:args), nil),
9849
+ %q{def _5; end},
9850
+ %q{},
9851
+ ALL_VERSIONS - SINCE_3_0)
9852
+
9853
+ assert_parses(
9854
+ s(:defs,
9855
+ s(:self), :_6,
9856
+ s(:args), nil),
9857
+ %q{def self._6; end},
9858
+ %q{},
9859
+ ALL_VERSIONS - SINCE_3_0)
9860
+ end
9861
+
9862
+ def test_reserved_for_numparam__since_30
9863
+ # Regular assignments:
9864
+
9865
+ assert_diagnoses(
9866
+ [:error, :reserved_for_numparam, { :name => '_1' }],
9867
+ %q{proc {_1 = nil}},
9868
+ %q{ ^^ location},
9869
+ SINCE_3_0)
9870
+
9871
+ assert_diagnoses(
9872
+ [:error, :reserved_for_numparam, { :name => '_2' }],
9873
+ %q{_2 = 1},
9874
+ %q{^^ location},
9875
+ SINCE_3_0)
9876
+
9877
+ # Arguments:
9878
+
9879
+ [
9880
+ # req (procarg0)
9881
+ [
9882
+ %q{proc {|_3|}},
9883
+ %q{ ^^ location},
9884
+ ],
9885
+
9886
+ # req
9887
+ [
9888
+ %q{proc {|_3,|}},
9889
+ %q{ ^^ location},
9890
+ ],
9891
+
9892
+ # opt
9893
+ [
9894
+ %q{proc {|_3 = 42|}},
9895
+ %q{ ^^ location},
9896
+ ],
9897
+
9898
+ # mlhs
9899
+ [
9900
+ %q{proc {|(_3)|}},
9901
+ %q{ ^^ location},
9902
+ ],
9903
+
9904
+ # rest
9905
+ [
9906
+ %q{proc {|*_3|}},
9907
+ %q{ ^^ location},
9908
+ ],
9909
+
9910
+ # kwarg
9911
+ [
9912
+ %q{proc {|_3:|}},
9913
+ %q{ ^^^ location},
9914
+ ],
9915
+
9916
+ # kwoptarg
9917
+ [
9918
+ %q{proc {|_3: 42|}},
9919
+ %q{ ^^^ location},
9920
+ ],
9921
+
9922
+ # kwrestarg
9923
+ [
9924
+ %q{proc {|**_3|}},
9925
+ %q{ ^^ location},
9926
+ ],
9927
+
9928
+ # block
9929
+ [
9930
+ %q{proc {|&_3|}},
9931
+ %q{ ^^ location},
9932
+ ],
9933
+
9934
+ # shadowarg
9935
+ [
9936
+ %q{proc {|;_3|}},
9937
+ %q{ ^^ location},
9938
+ ],
9939
+ ].each do |(code, location)|
9940
+ assert_diagnoses(
9941
+ [:error, :reserved_for_numparam, { :name => '_3' }],
9942
+ code,
9943
+ location,
9944
+ SINCE_3_0)
9945
+ end
9946
+
9947
+ # Method definitions:
9948
+
9949
+ [
9950
+ # regular method
9951
+ [
9952
+ %q{def _5; end},
9953
+ %q{ ^^ location}
9954
+ ],
9955
+ # regular singleton method
9956
+ [
9957
+ %q{def self._5; end},
9958
+ %q{ ^^ location}
9959
+ ],
9960
+ # endless method
9961
+ [
9962
+ %q{def _5() = nil},
9963
+ %q{ ^^ location}
9964
+ ],
9965
+ # endless singleton method
9966
+ [
9967
+ %q{def self._5() = nil},
9968
+ %q{ ^^ location}
9969
+ ],
9970
+ ].each do |(code, location)|
9971
+ assert_diagnoses(
9972
+ [:error, :reserved_for_numparam, { :name => '_5' }],
9973
+ code,
9974
+ location,
9975
+ SINCE_3_0)
9976
+ end
9977
+ end
9978
+
9979
+ def test_endless_setter
9980
+ assert_diagnoses(
9981
+ [:error, :endless_setter],
9982
+ %q{def foo=() = 42},
9983
+ %q{ ^^^^ location},
9984
+ SINCE_3_0)
9779
9985
  end
9780
9986
  end