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.
Files changed (63) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.travis.yml +21 -32
  4. data/CHANGELOG.md +59 -1
  5. data/README.md +2 -2
  6. data/Rakefile +2 -1
  7. data/doc/AST_FORMAT.md +106 -3
  8. data/lib/parser.rb +1 -0
  9. data/lib/parser/all.rb +1 -0
  10. data/lib/parser/ast/processor.rb +9 -0
  11. data/lib/parser/builders/default.rb +103 -12
  12. data/lib/parser/context.rb +1 -0
  13. data/lib/parser/current.rb +13 -4
  14. data/lib/parser/diagnostic.rb +1 -1
  15. data/lib/parser/diagnostic/engine.rb +1 -2
  16. data/lib/parser/lexer.rl +15 -1
  17. data/lib/parser/macruby.y +14 -4
  18. data/lib/parser/messages.rb +15 -0
  19. data/lib/parser/meta.rb +4 -4
  20. data/lib/parser/ruby18.y +2 -0
  21. data/lib/parser/ruby19.y +14 -4
  22. data/lib/parser/ruby20.y +14 -4
  23. data/lib/parser/ruby21.y +9 -2
  24. data/lib/parser/ruby22.y +9 -2
  25. data/lib/parser/ruby23.y +9 -2
  26. data/lib/parser/ruby24.y +9 -2
  27. data/lib/parser/ruby25.y +9 -2
  28. data/lib/parser/ruby26.y +9 -2
  29. data/lib/parser/ruby27.y +28 -8
  30. data/lib/parser/ruby28.y +3043 -0
  31. data/lib/parser/rubymotion.y +14 -4
  32. data/lib/parser/runner.rb +26 -2
  33. data/lib/parser/runner/ruby_rewrite.rb +2 -2
  34. data/lib/parser/source/buffer.rb +3 -1
  35. data/lib/parser/source/comment/associator.rb +14 -4
  36. data/lib/parser/source/map/endless_definition.rb +23 -0
  37. data/lib/parser/source/range.rb +17 -1
  38. data/lib/parser/source/tree_rewriter.rb +115 -12
  39. data/lib/parser/source/tree_rewriter/action.rb +135 -26
  40. data/lib/parser/tree_rewriter.rb +1 -2
  41. data/lib/parser/version.rb +1 -1
  42. data/parser.gemspec +3 -2
  43. data/test/helper.rb +49 -6
  44. data/test/parse_helper.rb +27 -23
  45. data/test/test_ast_processor.rb +32 -0
  46. data/test/test_base.rb +1 -1
  47. data/test/test_current.rb +2 -0
  48. data/test/test_diagnostic.rb +6 -7
  49. data/test/test_diagnostic_engine.rb +5 -8
  50. data/test/test_lexer.rb +17 -8
  51. data/test/test_meta.rb +12 -0
  52. data/test/test_parser.rb +477 -54
  53. data/test/test_runner_parse.rb +22 -1
  54. data/test/test_runner_rewrite.rb +1 -1
  55. data/test/test_source_buffer.rb +4 -1
  56. data/test/test_source_comment.rb +2 -2
  57. data/test/test_source_comment_associator.rb +47 -15
  58. data/test/test_source_map.rb +1 -2
  59. data/test/test_source_range.rb +29 -9
  60. data/test/test_source_rewriter.rb +4 -4
  61. data/test/test_source_rewriter_action.rb +2 -2
  62. data/test/test_source_tree_rewriter.rb +201 -13
  63. metadata +19 -12
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 00a9bc5b2d70892e4743417168e53dc469c80328c3983e71b41f312becd116b0
4
- data.tar.gz: 1abbc88751dc8d3b7c28d2df69b71a773533ed2d3726de50df8cfaaa79887aaa
3
+ metadata.gz: c4dbd5dfd3a249d65b4d2b20c54b668749b3d5360e7feef7772924c135b78d86
4
+ data.tar.gz: ca30aca7f92a24fb96ef74c1a21149d9d43fb541d86bdae0b113f5ea5e267137
5
5
  SHA512:
6
- metadata.gz: 32455424b4003ba1510d53b162aa8691bdaea5708b4d88d392d6c89cfa3b6479f1d47c9f42fedd40e663366192434aaf851dbe65cbd1a629c54b7681cfb37879
7
- data.tar.gz: 0c464e9acd5cf95161e18552e4680230417a05e7ad14e805b8661e4bb2ee7a99f4ad2f4e0212c48b35bc9f3ed8549b6723925f0b194e0a57873a2eb472450dbb
6
+ metadata.gz: deb6edb6b828f309ebc6eb58e19613fe13c490e780895dfad01aceeeb0111781bc9e90b81bf6be35069afed44bd5f683c8120f134abd3d6aa7546a15fb370c19
7
+ data.tar.gz: 0c5a25dade42d9c74bc115aa8ecfd8dbfbcdeadc0fee6e994f44532ed994ac0c47aeccccc5405ddc9b5bd3804e4c47874163e6d468e47cb14ddd647ffb2c118c
data/.gitignore CHANGED
@@ -29,5 +29,6 @@ lib/parser/ruby24.rb
29
29
  lib/parser/ruby25.rb
30
30
  lib/parser/ruby26.rb
31
31
  lib/parser/ruby27.rb
32
+ lib/parser/ruby28.rb
32
33
  lib/parser/macruby.rb
33
34
  lib/parser/rubymotion.rb
@@ -1,51 +1,40 @@
1
1
  dist: trusty
2
2
  language: ruby
3
- matrix:
3
+ jobs:
4
4
  include:
5
- - name: 2.0.0 / Parser tests
6
- rvm: 2.0.0
7
- script: bundle exec rake test_cov
8
- - name: 2.2.10 / Parser tests
9
- rvm: 2.2.10
10
- script: bundle exec rake test_cov
11
- - name: 2.3.8 / Parser tests
12
- rvm: 2.3.8
13
- script: bundle exec rake test_cov
14
- - name: 2.4.9 / Parser tests
15
- rvm: 2.4.9
5
+ - name: jruby-9.1.15.0 / Parser tests
6
+ rvm: jruby-9.1.15.0
7
+ script: bundle exec rake test
8
+ - name: truffleruby / Parser tests
9
+ rvm: truffleruby
10
+ script: TRUFFLERUBYOPT=--engine.Mode=latency bundle exec rake test
11
+ - name: 2.4.10 / Parser tests
12
+ rvm: 2.4.10
16
13
  script: bundle exec rake test_cov
17
- - name: 2.5.7 / Parser tests
18
- rvm: 2.5.7
14
+ - name: 2.5.8 / Parser tests
15
+ rvm: 2.5.8
19
16
  script: bundle exec rake test_cov
20
- - name: 2.6.5 / Parser tests
21
- rvm: 2.6.5
17
+ - name: 2.6.6 / Parser tests
18
+ rvm: 2.6.6
22
19
  script: bundle exec rake test_cov
23
- - name: 2.7.0 / Parser tests
24
- rvm: 2.7.0
20
+ - name: 2.7.1 / Parser tests
21
+ rvm: 2.7.1
25
22
  script: bundle exec rake test_cov
26
23
  - name: ruby-head / Parser tests
27
24
  rvm: ruby-head
28
25
  script: bundle exec rake test_cov
29
- - name: jruby-9.1.15.0 / Parser tests
30
- rvm: jruby-9.1.15.0
31
- script: bundle exec rake test_cov
32
- - name: rbx-2 / Parser tests
33
- rvm: rbx-2
34
- script: bundle exec rake test_cov
35
- - name: 2.5.7 / Rubocop tests
36
- rvm: 2.5.7
26
+ - name: 2.5.8 / Rubocop tests
27
+ rvm: 2.5.8
37
28
  script: ./ci/run_rubocop_specs
38
- - name: 2.6.5 / Rubocop tests
39
- rvm: 2.6.5
29
+ - name: 2.6.6 / Rubocop tests
30
+ rvm: 2.6.6
40
31
  script: ./ci/run_rubocop_specs
41
- - name: 2.7.0 / Rubocop tests
42
- rvm: 2.7.0
32
+ - name: 2.7.1 / Rubocop tests
33
+ rvm: 2.7.1
43
34
  script: ./ci/run_rubocop_specs
44
35
  allow_failures:
45
36
  - rvm: ruby-head
46
- - rvm: rbx-2
47
37
  - script: ./ci/run_rubocop_specs
48
38
  before_install:
49
- - gem install bundler -v '< 2'
50
39
  - bundle --version
51
40
  - gem --version
@@ -1,9 +1,67 @@
1
1
  Changelog
2
2
  =========
3
3
 
4
- Not released (2020-03-20)
4
+ Not released (2020-06-19)
5
5
  -------------------------
6
6
 
7
+ Features implemented:
8
+ * ruby28.y: add find pattern. (#714) (Ilya Bylich)
9
+ * lexer.rl: reject `->...` and `->(...)` with the same error. (#713) (Ilya Bylich)
10
+ * ruby28.y: accept leading args before forward arg. (#712) (Ilya Bylich)
11
+ * Added `emit_forward_arg` compatibility flag. (#710) (Ilya Bylich)
12
+ * ruby28.y: include entire lambda expr in lambda rule. (#708) (Ilya Bylich)
13
+ * ruby28.y: extracted excessed_comma rule. (#706) (Ilya Bylich)
14
+ * Source::TreeRewriter: Improved merging and representations (#703) (Marc-André Lafortune)
15
+
16
+ Bugs fixed:
17
+ * ruby*.y: fixed context inside lambda args and module. (#709) (Ilya Bylich)
18
+
19
+ v2.7.1.3 (2020-05-26)
20
+ ---------------------
21
+
22
+ API modifications:
23
+ * fixed all warnings. tests are running in verbose mode now. (#685) (Ilya Bylich)
24
+
25
+ Features implemented:
26
+ * ruby-[parse, rewrite]: add legacy switches (#699) (Marc-André Lafortune)
27
+ * Added Parser::Source::Range#to_range. (#697) (Ilya Bylich)
28
+ * ruby28.y: support rescue modifier in endless method definition. (#696) (Ilya Bylich)
29
+ * ruby28.y: unify kwrest and no-kwrest rules. (#694) (Ilya Bylich)
30
+ * ruby28.y: add right hand assignment (#682) (Vladimir Dementyev)
31
+
32
+ Bugs fixed:
33
+ * fix Comment.associate for postfix conditions/loops (#688) (Marc-André Lafortune)
34
+
35
+ v2.7.1.2 (2020-04-30)
36
+ ---------------------
37
+
38
+ Features implemented:
39
+ * ruby28.y: endless method definition (#676) (Vladimir Dementyev)
40
+ * ruby28.y: branch parser (#677) (Vladimir Dementyev)
41
+
42
+ Bugs fixed:
43
+ * ruby27.y: reject invalid lvar in pattern matching (#680) (Vladimir Dementyev)
44
+
45
+ v2.7.1.1 (2020-04-15)
46
+ ---------------------
47
+
48
+ Features implemented:
49
+ * Add Source::Range#eql? and hash (#675) (Marc-André Lafortune)
50
+ * Source::TreeRewriter: Add #merge, #merge! and #empty? (#674) (Marc-André Lafortune)
51
+
52
+ v2.7.1.0 (2020-04-03)
53
+ ---------------------
54
+
55
+ API modifications:
56
+ * Bump ruby versions to 2.4.10, 2.5.8, 2.6.6, 2.7.1. (#665) (Ilya Bylich)
57
+
58
+ Features implemented:
59
+ * ruby27.y: allow newlines inside braced pattern. (#664) (Ilya Bylich)
60
+ * ruby27.y: Allow trailing comma in hash pattern (#661) (Koichi ITO)
61
+
62
+ v2.7.0.5 (2020-03-20)
63
+ ---------------------
64
+
7
65
  Features implemented:
8
66
  * ruby27.y: fix array pattern with tail source map (#659) (Vladimir Dementyev)
9
67
 
data/README.md CHANGED
@@ -29,6 +29,7 @@ below for explanation of `emit_*` calls):
29
29
  Parser::Builders::Default.emit_encoding = true
30
30
  Parser::Builders::Default.emit_index = true
31
31
  Parser::Builders::Default.emit_arg_inside_procarg0 = true
32
+ Parser::Builders::Default.emit_forward_arg = true
32
33
 
33
34
  Parse a chunk of code:
34
35
 
@@ -59,8 +60,7 @@ Parse a chunk of code and display all diagnostics:
59
60
  puts diag.render
60
61
  end
61
62
 
62
- buffer = Parser::Source::Buffer.new('(string)')
63
- buffer.source = "foo *bar"
63
+ buffer = Parser::Source::Buffer.new('(string)', source: "foo *bar")
64
64
 
65
65
  p parser.parse(buffer)
66
66
  # (string):1:5: warning: `*' interpreted as argument prefix
data/Rakefile CHANGED
@@ -11,7 +11,7 @@ task :default => [:test]
11
11
  Rake::TestTask.new do |t|
12
12
  t.libs = %w(test/ lib/)
13
13
  t.test_files = FileList["test/**/test_*.rb"]
14
- t.warning = false
14
+ t.warning = true
15
15
  end
16
16
 
17
17
  task :test_cov do
@@ -32,6 +32,7 @@ GENERATED_FILES = %w(lib/parser/lexer.rb
32
32
  lib/parser/ruby25.rb
33
33
  lib/parser/ruby26.rb
34
34
  lib/parser/ruby27.rb
35
+ lib/parser/ruby28.rb
35
36
  lib/parser/macruby.rb
36
37
  lib/parser/rubymotion.rb)
37
38
 
@@ -637,7 +637,7 @@ Format:
637
637
  (masgn (mlhs (ivasgn :@a) (cvasgn :@@b)) (array (splat (lvar :c))))
638
638
  "@a, @@b = *c"
639
639
 
640
- (masgn (mlhs (mlhs (lvasgn :a) (lvasgn :b)) (lvasgn :c)) (lvar :d))
640
+ (masgn (mlhs (lvasgn :a) (mlhs (lvasgn :b)) (lvasgn :c)) (lvar :d))
641
641
  "a, (b, c) = d"
642
642
 
643
643
  (masgn (mlhs (send (self) :a=) (send (self) :[]= (int 1))) (lvar :a))
@@ -730,6 +730,28 @@ Format:
730
730
 
731
731
  ~~~
732
732
 
733
+ ### Right-hand assignment
734
+
735
+ Format:
736
+
737
+ ~~~
738
+ (rasgn (int 1) (lvasgn :a))
739
+ "1 => a"
740
+ ~~~~~~ expression
741
+ ~~ operator
742
+ ~~~
743
+
744
+ #### Multiple right-hand assignment
745
+
746
+ Format:
747
+
748
+ ~~~
749
+ (mrasgn (send (int 13) :divmod (int 5)) (mlhs (lvasgn :a) (lvasgn :b)))
750
+ "13.divmod(5) => a,b"
751
+ ~~~~~~~~~~~~~~~~~~~ expression
752
+ ^^ operator
753
+ ~~~
754
+
733
755
  ## Class and module definition
734
756
 
735
757
  ### Module
@@ -802,6 +824,33 @@ Format:
802
824
  ~~~~~~~~~~~~~~~~~ expression
803
825
  ~~~
804
826
 
827
+ ### "Endless" method
828
+
829
+ Format:
830
+
831
+ ~~~
832
+ (def_e :foo (args) (int 42))
833
+ "def foo() = 42"
834
+ ~~~ keyword
835
+ ~~~ name
836
+ ^ assignment
837
+ ~~~~~~~~~~~~~~ expression
838
+ ~~~
839
+
840
+
841
+ ### "Endless" singleton method
842
+
843
+ Format:
844
+
845
+ ~~~
846
+ (defs_e (self) :foo (args) (int 42))
847
+ "def self.foo() = 42"
848
+ ~~~ keyword
849
+ ~~~ name
850
+ ^ assignment
851
+ ~~~~~~~~~~~~~~~~~~~ expression
852
+ ~~~
853
+
805
854
  ### Undefinition
806
855
 
807
856
  Format:
@@ -1115,13 +1164,13 @@ s(:numblock,
1115
1164
 
1116
1165
  ## Forward arguments
1117
1166
 
1118
- ### Method definition accepting forwarding arguments
1167
+ ### Method definition accepting only forwarding arguments
1119
1168
 
1120
1169
  Ruby 2.7 introduced a feature called "arguments forwarding".
1121
1170
  When a method takes any arguments for forwarding them in the future
1122
1171
  the whole `args` node gets replaced with `forward-args` node.
1123
1172
 
1124
- Format:
1173
+ Format if `emit_forward_arg` compatibility flag is disabled:
1125
1174
 
1126
1175
  ~~~
1127
1176
  (def :foo
@@ -1132,6 +1181,25 @@ Format:
1132
1181
  ~~~~~ expression
1133
1182
  ~~~
1134
1183
 
1184
+ However, Ruby 2.8 added support for leading arguments before `...`, and so
1185
+ it can't be used as a replacement of the `(args)` node anymore. To solve it
1186
+ `emit_forward_arg` should be enabled.
1187
+
1188
+ Format if `emit_forward_arg` compatibility flag is enabled:
1189
+
1190
+ ~~~
1191
+ (def :foo
1192
+ (args
1193
+ (forward-arg)) nil)
1194
+ "def foo(...); end"
1195
+ ~ begin (args)
1196
+ ~ end (args)
1197
+ ~~~~~ expression (args)
1198
+ ~~~ expression (forward_arg)
1199
+ ~~~
1200
+
1201
+ Note that the node is called `forward_arg` when emitted separately.
1202
+
1135
1203
  ### Method call taking arguments of the currently forwarding method
1136
1204
 
1137
1205
  Format:
@@ -2123,6 +2191,24 @@ Format:
2123
2191
  ~~~ name (match-nil-pattern)
2124
2192
  ~~~
2125
2193
 
2194
+ ### Matching using find pattern
2195
+
2196
+ Format:
2197
+
2198
+ ~~~
2199
+ (find-pattern
2200
+ (match-rest
2201
+ (match-var :a))
2202
+ (int 42)
2203
+ (match-rest))
2204
+ "in [*, 42, *]"
2205
+ ~ begin
2206
+ ~ end
2207
+ ~~~~~~~~~~ expression
2208
+ ~~~
2209
+
2210
+ Note that it can be used as a top-level pattern only when used in a `case` statement. In that case `begin` and `end` are empty.
2211
+
2126
2212
  ### Matching using const pattern
2127
2213
 
2128
2214
  #### With array pattern
@@ -2178,3 +2264,20 @@ Format:
2178
2264
  ~ expression (const-pattern.const)
2179
2265
  ~~ expression (const-pattern.array_pattern)
2180
2266
  ~~~
2267
+
2268
+ #### With find pattern
2269
+
2270
+ Format:
2271
+
2272
+ ~~~
2273
+ (const-pattern
2274
+ (const nil :X)
2275
+ (find-pattern
2276
+ (match-rest)
2277
+ (int 42)
2278
+ (match-rest)))
2279
+ "in X[*, 42, *]"
2280
+ ~ begin
2281
+ ~ end
2282
+ ~~~~~~~~~~~ expression
2283
+ ~~~
@@ -46,6 +46,7 @@ module Parser
46
46
  require 'parser/source/map/variable'
47
47
  require 'parser/source/map/keyword'
48
48
  require 'parser/source/map/definition'
49
+ require 'parser/source/map/endless_definition'
49
50
  require 'parser/source/map/send'
50
51
  require 'parser/source/map/index'
51
52
  require 'parser/source/map/condition'
@@ -10,3 +10,4 @@ require 'parser/ruby24'
10
10
  require 'parser/ruby25'
11
11
  require 'parser/ruby26'
12
12
  require 'parser/ruby27'
13
+ require 'parser/ruby28'
@@ -75,6 +75,9 @@ module Parser
75
75
  alias on_mlhs process_regular_node
76
76
  alias on_masgn process_regular_node
77
77
 
78
+ alias on_rasgn process_regular_node
79
+ alias on_mrasgn process_regular_node
80
+
78
81
  def on_const(node)
79
82
  scope_node, name = *node
80
83
 
@@ -124,6 +127,7 @@ module Parser
124
127
  alias on_kwarg process_argument_node
125
128
  alias on_kwoptarg process_argument_node
126
129
  alias on_kwrestarg process_argument_node
130
+ alias on_forward_arg process_argument_node
127
131
 
128
132
  def on_procarg0(node)
129
133
  if node.children[0].is_a?(Symbol)
@@ -159,6 +163,8 @@ module Parser
159
163
  ])
160
164
  end
161
165
 
166
+ alias on_def_e on_def
167
+
162
168
  def on_defs(node)
163
169
  definee_node, name, args_node, body_node = *node
164
170
 
@@ -168,6 +174,8 @@ module Parser
168
174
  ])
169
175
  end
170
176
 
177
+ alias on_defs_e on_defs
178
+
171
179
  alias on_undef process_regular_node
172
180
  alias on_alias process_regular_node
173
181
 
@@ -250,6 +258,7 @@ module Parser
250
258
  alias on_array_pattern_with_tail process_regular_node
251
259
  alias on_hash_pattern process_regular_node
252
260
  alias on_const_pattern process_regular_node
261
+ alias on_find_pattern process_regular_node
253
262
 
254
263
  # @private
255
264
  def process_variable_node(node)
@@ -80,6 +80,8 @@ module Parser
80
80
  attr_accessor :emit_index
81
81
  end
82
82
 
83
+ @emit_index = false
84
+
83
85
  class << self
84
86
  ##
85
87
  # AST compatibility attribute; causes a single non-mlhs
@@ -95,7 +97,36 @@ module Parser
95
97
  attr_accessor :emit_arg_inside_procarg0
96
98
  end
97
99
 
98
- @emit_index = false
100
+ @emit_arg_inside_procarg0 = false
101
+
102
+ class << self
103
+ ##
104
+ # AST compatibility attribute; arguments forwarding initially
105
+ # didn't have support for leading arguments
106
+ # (i.e. `def m(a, ...); end` was a syntax error). However, Ruby 2.8
107
+ # added support for any number of arguments in front of the `...`.
108
+ #
109
+ # If set to false (the default):
110
+ # 1. `def m(...) end` is emitted as
111
+ # s(:def, :m, s(:forward_args), nil)
112
+ # 2. `def m(a, b, ...) end` is emitted as
113
+ # s(:def, :m,
114
+ # s(:args, s(:arg, :a), s(:arg, :b), s(:forward_arg)))
115
+ #
116
+ # If set to true it uses a single format:
117
+ # 1. `def m(...) end` is emitted as
118
+ # s(:def, :m, s(:args, s(:forward_arg)))
119
+ # 2. `def m(a, b, ...) end` is emitted as
120
+ # s(:def, :m, s(:args, s(:arg, :a), s(:arg, :b), s(:forward_arg)))
121
+ #
122
+ # It does't matter that much on 2.7 (because there can't be any leading arguments),
123
+ # but on 2.8 it should be better enabled to use a single AST format.
124
+ #
125
+ # @return [Boolean]
126
+ attr_accessor :emit_forward_arg
127
+ end
128
+
129
+ @emit_forward_arg = false
99
130
 
100
131
  class << self
101
132
  ##
@@ -106,6 +137,7 @@ module Parser
106
137
  @emit_encoding = true
107
138
  @emit_index = true
108
139
  @emit_arg_inside_procarg0 = true
140
+ @emit_forward_arg = true
109
141
  end
110
142
  end
111
143
 
@@ -619,6 +651,15 @@ module Parser
619
651
  binary_op_map(lhs, eql_t, rhs))
620
652
  end
621
653
 
654
+ def rassign(lhs, assoc_t, rhs)
655
+ n(:rasgn, [lhs, rhs], binary_op_map(lhs, assoc_t, rhs))
656
+ end
657
+
658
+ def multi_rassign(lhs, assoc_t, rhs)
659
+ n(:mrasgn, [ lhs, rhs ],
660
+ binary_op_map(lhs, assoc_t, rhs))
661
+ end
662
+
622
663
  #
623
664
  # Class and module definition
624
665
  #
@@ -652,19 +693,28 @@ module Parser
652
693
  definition_map(def_t, nil, name_t, end_t))
653
694
  end
654
695
 
696
+ def def_endless_method(def_t, name_t, args,
697
+ assignment_t, body)
698
+ n(:def_e, [ value(name_t).to_sym, args, body ],
699
+ endless_definition_map(def_t, nil, name_t, assignment_t, body))
700
+ end
701
+
655
702
  def def_singleton(def_t, definee, dot_t,
656
703
  name_t, args,
657
704
  body, end_t)
658
- case definee.type
659
- when :int, :str, :dstr, :sym, :dsym,
660
- :regexp, :array, :hash
705
+ return unless validate_definee(definee)
661
706
 
662
- diagnostic :error, :singleton_literal, nil, definee.loc.expression
707
+ n(:defs, [ definee, value(name_t).to_sym, args, body ],
708
+ definition_map(def_t, dot_t, name_t, end_t))
709
+ end
663
710
 
664
- else
665
- n(:defs, [ definee, value(name_t).to_sym, args, body ],
666
- definition_map(def_t, dot_t, name_t, end_t))
667
- end
711
+ def def_endless_singleton(def_t, definee, dot_t,
712
+ name_t, args,
713
+ assignment_t, body)
714
+ return unless validate_definee(definee)
715
+
716
+ n(:defs_e, [ definee, value(name_t).to_sym, args, body ],
717
+ endless_definition_map(def_t, dot_t, name_t, assignment_t, body))
668
718
  end
669
719
 
670
720
  def undef_method(undef_t, names)
@@ -691,8 +741,18 @@ module Parser
691
741
  n(:numargs, [ max_numparam ], nil)
692
742
  end
693
743
 
694
- def forward_args(begin_t, dots_t, end_t)
695
- n(:forward_args, [], collection_map(begin_t, token_map(dots_t), end_t))
744
+ def forward_only_args(begin_t, dots_t, end_t)
745
+ if self.class.emit_forward_arg
746
+ arg = forward_arg(dots_t)
747
+ n(:args, [ arg ],
748
+ collection_map(begin_t, [ arg ], end_t))
749
+ else
750
+ n(:forward_args, [], collection_map(begin_t, token_map(dots_t), end_t))
751
+ end
752
+ end
753
+
754
+ def forward_arg(dots_t)
755
+ n(:forward_arg, [], token_map(dots_t))
696
756
  end
697
757
 
698
758
  def arg(name_t)
@@ -1239,8 +1299,10 @@ module Parser
1239
1299
 
1240
1300
  def match_var(name_t)
1241
1301
  name = value(name_t).to_sym
1302
+ name_l = loc(name_t)
1242
1303
 
1243
- check_duplicate_pattern_variable(name, loc(name_t))
1304
+ check_lvar_name(name, name_l)
1305
+ check_duplicate_pattern_variable(name, name_l)
1244
1306
  @parser.static_env.declare(name)
1245
1307
 
1246
1308
  n(:match_var, [ name ],
@@ -1253,6 +1315,7 @@ module Parser
1253
1315
  expr_l = loc(name_t)
1254
1316
  name_l = expr_l.adjust(end_pos: -1)
1255
1317
 
1318
+ check_lvar_name(name, name_l)
1256
1319
  check_duplicate_pattern_variable(name, name_l)
1257
1320
  @parser.static_env.declare(name)
1258
1321
 
@@ -1293,6 +1356,9 @@ module Parser
1293
1356
  Source::Map::Variable.new(name_l, expr_l))
1294
1357
  when :begin
1295
1358
  match_hash_var_from_str(begin_t, string.children, end_t)
1359
+ else
1360
+ # we only can get here if there is an interpolation, e.g., ``in "#{ a }":`
1361
+ diagnostic :error, :pm_interp_in_var_name, nil, loc(begin_t).join(loc(end_t))
1296
1362
  end
1297
1363
  end
1298
1364
 
@@ -1334,6 +1400,11 @@ module Parser
1334
1400
  collection_map(lbrack_t, elements, rbrack_t))
1335
1401
  end
1336
1402
 
1403
+ def find_pattern(lbrack_t, elements, rbrack_t)
1404
+ n(:find_pattern, elements,
1405
+ collection_map(lbrack_t, elements, rbrack_t))
1406
+ end
1407
+
1337
1408
  def match_with_trailing_comma(match, comma_t)
1338
1409
  n(:match_with_trailing_comma, [ match ], expr_map(match.loc.expression.join(loc(comma_t))))
1339
1410
  end
@@ -1737,6 +1808,14 @@ module Parser
1737
1808
  loc(end_t))
1738
1809
  end
1739
1810
 
1811
+ def endless_definition_map(keyword_t, operator_t, name_t, assignment_t, body_e)
1812
+ body_l = body_e.loc.expression
1813
+
1814
+ Source::Map::EndlessDefinition.new(loc(keyword_t),
1815
+ loc(operator_t), loc(name_t),
1816
+ loc(assignment_t), body_l)
1817
+ end
1818
+
1740
1819
  def send_map(receiver_e, dot_t, selector_t, begin_t=nil, args=[], end_t=nil)
1741
1820
  if receiver_e
1742
1821
  begin_l = receiver_e.loc.expression
@@ -1979,6 +2058,18 @@ module Parser
1979
2058
  @parser.send :yyerror
1980
2059
  end
1981
2060
  end
2061
+
2062
+ def validate_definee(definee)
2063
+ case definee.type
2064
+ when :int, :str, :dstr, :sym, :dsym,
2065
+ :regexp, :array, :hash
2066
+
2067
+ diagnostic :error, :singleton_literal, nil, definee.loc.expression
2068
+ false
2069
+ else
2070
+ true
2071
+ end
2072
+ end
1982
2073
  end
1983
2074
 
1984
2075
  end