parser 2.7.0.5 → 2.7.1.4

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