parser 2.7.1.4 → 2.7.1.5

Sign up to get free protection for your applications and to get access to all the features.
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