brakeman 5.2.1 → 5.2.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (60) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGES.md +8 -0
  3. data/bundle/load.rb +2 -2
  4. data/bundle/ruby/2.7.0/gems/{parallel-1.21.0 → parallel-1.22.1}/MIT-LICENSE.txt +0 -0
  5. data/bundle/ruby/2.7.0/gems/{parallel-1.21.0 → parallel-1.22.1}/lib/parallel/processor_count.rb +2 -3
  6. data/bundle/ruby/2.7.0/gems/parallel-1.22.1/lib/parallel/version.rb +4 -0
  7. data/bundle/ruby/2.7.0/gems/{parallel-1.21.0 → parallel-1.22.1}/lib/parallel.rb +84 -4
  8. data/bundle/ruby/2.7.0/gems/{ruby_parser-3.18.1 → ruby_parser-3.19.1}/History.rdoc +28 -0
  9. data/bundle/ruby/2.7.0/gems/{ruby_parser-3.18.1 → ruby_parser-3.19.1}/Manifest.txt +2 -0
  10. data/bundle/ruby/2.7.0/gems/{ruby_parser-3.18.1 → ruby_parser-3.19.1}/README.rdoc +8 -6
  11. data/bundle/ruby/2.7.0/gems/{ruby_parser-3.18.1 → ruby_parser-3.19.1}/compare/normalize.rb +0 -0
  12. data/bundle/ruby/2.7.0/gems/{ruby_parser-3.18.1 → ruby_parser-3.19.1}/debugging.md +0 -0
  13. data/bundle/ruby/2.7.0/gems/{ruby_parser-3.18.1 → ruby_parser-3.19.1}/gauntlet.md +19 -18
  14. data/bundle/ruby/2.7.0/gems/{ruby_parser-3.18.1 → ruby_parser-3.19.1}/lib/rp_extensions.rb +0 -0
  15. data/bundle/ruby/2.7.0/gems/{ruby_parser-3.18.1 → ruby_parser-3.19.1}/lib/rp_stringscanner.rb +0 -0
  16. data/bundle/ruby/2.7.0/gems/ruby_parser-3.19.1/lib/ruby20_parser.rb +10973 -0
  17. data/bundle/ruby/2.7.0/gems/{ruby_parser-3.18.1 → ruby_parser-3.19.1}/lib/ruby20_parser.y +14 -27
  18. data/bundle/ruby/2.7.0/gems/ruby_parser-3.19.1/lib/ruby21_parser.rb +10980 -0
  19. data/bundle/ruby/2.7.0/gems/{ruby_parser-3.18.1 → ruby_parser-3.19.1}/lib/ruby21_parser.y +14 -27
  20. data/bundle/ruby/2.7.0/gems/ruby_parser-3.19.1/lib/ruby22_parser.rb +11123 -0
  21. data/bundle/ruby/2.7.0/gems/{ruby_parser-3.18.1 → ruby_parser-3.19.1}/lib/ruby22_parser.y +14 -27
  22. data/bundle/ruby/2.7.0/gems/ruby_parser-3.19.1/lib/ruby23_parser.rb +11132 -0
  23. data/bundle/ruby/2.7.0/gems/{ruby_parser-3.18.1 → ruby_parser-3.19.1}/lib/ruby23_parser.y +14 -27
  24. data/bundle/ruby/2.7.0/gems/ruby_parser-3.19.1/lib/ruby24_parser.rb +11231 -0
  25. data/bundle/ruby/2.7.0/gems/{ruby_parser-3.18.1 → ruby_parser-3.19.1}/lib/ruby24_parser.y +14 -27
  26. data/bundle/ruby/2.7.0/gems/ruby_parser-3.19.1/lib/ruby25_parser.rb +11231 -0
  27. data/bundle/ruby/2.7.0/gems/{ruby_parser-3.18.1 → ruby_parser-3.19.1}/lib/ruby25_parser.y +14 -27
  28. data/bundle/ruby/2.7.0/gems/ruby_parser-3.19.1/lib/ruby26_parser.rb +11253 -0
  29. data/bundle/ruby/2.7.0/gems/{ruby_parser-3.18.1 → ruby_parser-3.19.1}/lib/ruby26_parser.y +14 -27
  30. data/bundle/ruby/2.7.0/gems/ruby_parser-3.19.1/lib/ruby27_parser.rb +12980 -0
  31. data/bundle/ruby/2.7.0/gems/{ruby_parser-3.18.1 → ruby_parser-3.19.1}/lib/ruby27_parser.y +19 -41
  32. data/bundle/ruby/2.7.0/gems/ruby_parser-3.19.1/lib/ruby30_parser.rb +13242 -0
  33. data/bundle/ruby/2.7.0/gems/{ruby_parser-3.18.1 → ruby_parser-3.19.1}/lib/ruby30_parser.y +65 -90
  34. data/bundle/ruby/2.7.0/gems/ruby_parser-3.19.1/lib/ruby31_parser.rb +13622 -0
  35. data/bundle/ruby/2.7.0/gems/{ruby_parser-3.18.1/lib/ruby3_parser.yy → ruby_parser-3.19.1/lib/ruby31_parser.y} +110 -105
  36. data/bundle/ruby/2.7.0/gems/ruby_parser-3.19.1/lib/ruby3_parser.yy +3536 -0
  37. data/bundle/ruby/2.7.0/gems/{ruby_parser-3.18.1 → ruby_parser-3.19.1}/lib/ruby_lexer.rb +0 -0
  38. data/bundle/ruby/2.7.0/gems/{ruby_parser-3.18.1 → ruby_parser-3.19.1}/lib/ruby_lexer.rex +0 -0
  39. data/bundle/ruby/2.7.0/gems/{ruby_parser-3.18.1 → ruby_parser-3.19.1}/lib/ruby_lexer.rex.rb +0 -0
  40. data/bundle/ruby/2.7.0/gems/{ruby_parser-3.18.1 → ruby_parser-3.19.1}/lib/ruby_lexer_strings.rb +0 -0
  41. data/bundle/ruby/2.7.0/gems/{ruby_parser-3.18.1 → ruby_parser-3.19.1}/lib/ruby_parser.rb +2 -0
  42. data/bundle/ruby/2.7.0/gems/{ruby_parser-3.18.1 → ruby_parser-3.19.1}/lib/ruby_parser.yy +19 -41
  43. data/bundle/ruby/2.7.0/gems/{ruby_parser-3.18.1 → ruby_parser-3.19.1}/lib/ruby_parser_extras.rb +55 -2
  44. data/bundle/ruby/2.7.0/gems/{ruby_parser-3.18.1 → ruby_parser-3.19.1}/tools/munge.rb +0 -0
  45. data/bundle/ruby/2.7.0/gems/{ruby_parser-3.18.1 → ruby_parser-3.19.1}/tools/ripper.rb +0 -0
  46. data/lib/brakeman/checks/check_sql.rb +3 -2
  47. data/lib/brakeman/checks/check_unsafe_reflection.rb +7 -2
  48. data/lib/brakeman/processors/alias_processor.rb +17 -1
  49. data/lib/brakeman/version.rb +1 -1
  50. metadata +44 -42
  51. data/bundle/ruby/2.7.0/gems/parallel-1.21.0/lib/parallel/version.rb +0 -4
  52. data/bundle/ruby/2.7.0/gems/ruby_parser-3.18.1/lib/ruby20_parser.rb +0 -7128
  53. data/bundle/ruby/2.7.0/gems/ruby_parser-3.18.1/lib/ruby21_parser.rb +0 -7182
  54. data/bundle/ruby/2.7.0/gems/ruby_parser-3.18.1/lib/ruby22_parser.rb +0 -7228
  55. data/bundle/ruby/2.7.0/gems/ruby_parser-3.18.1/lib/ruby23_parser.rb +0 -7237
  56. data/bundle/ruby/2.7.0/gems/ruby_parser-3.18.1/lib/ruby24_parser.rb +0 -7268
  57. data/bundle/ruby/2.7.0/gems/ruby_parser-3.18.1/lib/ruby25_parser.rb +0 -7268
  58. data/bundle/ruby/2.7.0/gems/ruby_parser-3.18.1/lib/ruby26_parser.rb +0 -7287
  59. data/bundle/ruby/2.7.0/gems/ruby_parser-3.18.1/lib/ruby27_parser.rb +0 -8517
  60. data/bundle/ruby/2.7.0/gems/ruby_parser-3.18.1/lib/ruby30_parser.rb +0 -8751
@@ -1,10 +1,6 @@
1
1
  # -*- racc -*-
2
2
 
3
- #if V == 30
4
- class Ruby30Parser
5
- #else
6
- fail "version not specified or supported on code generation"
7
- #endif
3
+ class Ruby31Parser
8
4
 
9
5
  token kCLASS kMODULE kDEF kUNDEF kBEGIN kRESCUE kENSURE kEND kIF kUNLESS
10
6
  kTHEN kELSIF kELSE kCASE kWHEN kWHILE kUNTIL kFOR kBREAK kNEXT
@@ -84,7 +80,7 @@ rule
84
80
  | klBEGIN
85
81
  {
86
82
  if (self.in_def || self.in_single > 0) then
87
- debug 11
83
+ debug 1
88
84
  yyerror "BEGIN in method"
89
85
  end
90
86
  self.env.extend
@@ -139,7 +135,7 @@ rule
139
135
  | error stmt
140
136
  {
141
137
  result = val[1]
142
- debug 12
138
+ debug 2
143
139
  }
144
140
 
145
141
  stmt_or_begin: stmt
@@ -211,7 +207,7 @@ rule
211
207
  (_, line), _, stmt, _ = val
212
208
 
213
209
  if (self.in_def || self.in_single > 0) then
214
- debug 13
210
+ debug 3
215
211
  yyerror "END in method; use at_exit"
216
212
  end
217
213
 
@@ -286,6 +282,22 @@ rule
286
282
 
287
283
  result = s(:op_asgn, lhs1, rhs, lhs2.to_sym, id.to_sym).line line
288
284
  }
285
+ | defn_head f_opt_paren_args tEQL command
286
+ {
287
+ result = new_endless_defn val
288
+ }
289
+ | defn_head f_opt_paren_args tEQL command kRESCUE_MOD arg
290
+ {
291
+ result = new_endless_defn val
292
+ }
293
+ | defs_head f_opt_paren_args tEQL command
294
+ {
295
+ result = new_endless_defs val
296
+ }
297
+ | defs_head f_opt_paren_args tEQL command kRESCUE_MOD arg
298
+ {
299
+ result = new_endless_defs val
300
+ }
289
301
  | backref tOP_ASGN command_rhs
290
302
  {
291
303
  self.backref_assign_error val[0]
@@ -339,7 +351,7 @@ rule
339
351
  self.in_kwarg = true
340
352
  self.env.extend
341
353
  }
342
- p_expr
354
+ p_top_expr_body
343
355
  {
344
356
  lhs, _, in_kwarg, rhs = val
345
357
 
@@ -359,7 +371,7 @@ rule
359
371
  self.in_kwarg = true
360
372
  self.env.extend
361
373
  }
362
- p_expr
374
+ p_top_expr_body
363
375
  {
364
376
  self.env.unextend
365
377
 
@@ -679,7 +691,7 @@ rule
679
691
  | primary_value tCOLON2 tCONSTANT
680
692
  {
681
693
  if (self.in_def || self.in_single > 0) then
682
- debug 14
694
+ debug 4
683
695
  yyerror "dynamic constant assignment"
684
696
  end
685
697
 
@@ -691,7 +703,7 @@ rule
691
703
  | tCOLON3 tCONSTANT
692
704
  {
693
705
  if (self.in_def || self.in_single > 0) then
694
- debug 15
706
+ debug 5
695
707
  yyerror "dynamic constant assignment"
696
708
  end
697
709
 
@@ -718,7 +730,7 @@ rule
718
730
 
719
731
  result = self.assignable var
720
732
 
721
- debug 16
733
+ debug 6
722
734
  }
723
735
  | primary_value tLBRACK2 opt_call_args rbracket
724
736
  {
@@ -749,7 +761,7 @@ rule
749
761
  expr, _, (id, _line) = val
750
762
 
751
763
  if (self.in_def || self.in_single > 0) then
752
- debug 17
764
+ debug 7
753
765
  yyerror "dynamic constant assignment"
754
766
  end
755
767
 
@@ -761,7 +773,7 @@ rule
761
773
  _, (id, l) = val
762
774
 
763
775
  if (self.in_def || self.in_single > 0) then
764
- debug 18
776
+ debug 8
765
777
  yyerror "dynamic constant assignment"
766
778
  end
767
779
 
@@ -780,8 +792,7 @@ rule
780
792
 
781
793
  cpath: tCOLON3 cname
782
794
  {
783
- _, (name, line) = val
784
- result = s(:colon3, name.to_sym).line line
795
+ result = wrap :colon3, val[1]
785
796
  }
786
797
  | cname
787
798
  {
@@ -806,9 +817,7 @@ rule
806
817
 
807
818
  fitem: fname
808
819
  {
809
- (id, line), = val
810
-
811
- result = s(:lit, id.to_sym).line line
820
+ result = wrap :lit, val[0]
812
821
  }
813
822
  | symbol
814
823
 
@@ -877,9 +886,9 @@ rule
877
886
  }
878
887
  | tCOLON3 tCONSTANT tOP_ASGN arg_rhs
879
888
  {
880
- _, (lhs, line), op, rhs = val
889
+ _, lhs, op, rhs = val
881
890
 
882
- lhs = s(:colon3, lhs.to_sym).line line
891
+ lhs = wrap :colon3, lhs
883
892
  result = new_const_op_asgn [lhs, op, rhs]
884
893
  }
885
894
  | backref tOP_ASGN arg_rhs
@@ -962,8 +971,8 @@ rule
962
971
  }
963
972
  | tUMINUS_NUM simple_numeric tPOW arg
964
973
  {
965
- _, (num, line), _, arg = val
966
- lit = s(:lit, num).line line
974
+ _, num, _, arg = val
975
+ lit = wrap :lit, num
967
976
  result = new_call(new_call(lit, :"**", argl(arg)), :"-@")
968
977
 
969
978
  }
@@ -1056,46 +1065,19 @@ rule
1056
1065
  }
1057
1066
  | defn_head f_opt_paren_args tEQL arg
1058
1067
  {
1059
- (name, line, in_def), args, _, body = val
1060
-
1061
- result = s(:defn, name, args, body).line line
1062
-
1063
- local_pop in_def
1064
- endless_method_name result
1068
+ result = new_endless_defn val
1065
1069
  }
1066
1070
  | defn_head f_opt_paren_args tEQL arg kRESCUE_MOD arg
1067
1071
  {
1068
- (name, line, in_def), args, _, body, _, resbody = val
1069
-
1070
- result = s(:defn, name, args,
1071
- new_rescue(body,
1072
- new_resbody(s(:array).line(line),
1073
- resbody))).line line
1074
-
1075
- local_pop in_def
1076
- endless_method_name result
1072
+ result = new_endless_defn val
1077
1073
  }
1078
1074
  | defs_head f_opt_paren_args tEQL arg
1079
1075
  {
1080
- (recv, (name, line, in_def)), args, _, body = val
1081
-
1082
- result = s(:defs, recv, name, args, body).line(line)
1083
-
1084
- self.in_single -= 1
1085
- local_pop in_def
1086
- endless_method_name result
1076
+ result = new_endless_defs val
1087
1077
  }
1088
1078
  | defs_head f_opt_paren_args tEQL arg kRESCUE_MOD arg
1089
1079
  {
1090
- (recv, (name, line, in_def)), args, _, body, _, resbody = val
1091
-
1092
- result = s(:defs, recv, name, args,
1093
- new_rescue(body,
1094
- new_resbody(s(:array).line(line),
1095
- resbody))).line line
1096
-
1097
- local_pop in_def
1098
- endless_method_name result
1080
+ result = new_endless_defs val
1099
1081
  }
1100
1082
  | primary
1101
1083
 
@@ -1251,6 +1233,11 @@ rule
1251
1233
  _, arg = val
1252
1234
  result = s(:block_pass, arg).line arg.line
1253
1235
  }
1236
+ | tAMPER
1237
+ {
1238
+ (_, line), = val
1239
+ result = s(:block_pass).line line
1240
+ }
1254
1241
 
1255
1242
  opt_block_arg: tCOMMA block_arg
1256
1243
  {
@@ -1370,9 +1357,7 @@ rule
1370
1357
  }
1371
1358
  | tCOLON3 tCONSTANT
1372
1359
  {
1373
- _, (id, line) = val
1374
-
1375
- result = s(:colon3, id.to_sym).line line
1360
+ result = wrap :colon3, val[1]
1376
1361
  }
1377
1362
  | tLBRACK { result = lexer.lineno } aref_args tRBRACK
1378
1363
  {
@@ -1425,7 +1410,7 @@ rule
1425
1410
  }
1426
1411
  | kNOT tLPAREN2 rparen
1427
1412
  {
1428
- debug 19
1413
+ debug 9
1429
1414
  }
1430
1415
  | fcall brace_block
1431
1416
  {
@@ -1735,6 +1720,8 @@ rule
1735
1720
  f_any_kwrest: f_kwrest
1736
1721
  | f_no_kwarg
1737
1722
 
1723
+ f_eq: tEQL # TODO: self.in_argdef = false
1724
+
1738
1725
  block_args_tail: f_block_kwarg tCOMMA f_kwrest opt_f_block_arg
1739
1726
  {
1740
1727
  result = call_args val
@@ -1865,8 +1852,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1865
1852
 
1866
1853
  bvar: tIDENTIFIER
1867
1854
  {
1868
- (id, line), = val
1869
- result = s(:shadow, id.to_sym).line line
1855
+ result = wrap :shadow, val[0]
1870
1856
  }
1871
1857
  | f_bad_arg
1872
1858
 
@@ -2205,6 +2191,7 @@ opt_block_args_tail: tCOMMA block_args_tail
2205
2191
  p_lbracket: tLBRACK2 { push_pktbl }
2206
2192
 
2207
2193
  p_expr_basic: p_value
2194
+ | p_variable
2208
2195
  | p_const p_lparen p_args tRPAREN
2209
2196
  {
2210
2197
  lhs, _, args, _ = val
@@ -2480,7 +2467,7 @@ opt_block_args_tail: tCOMMA block_args_tail
2480
2467
  assignable [lhs.value, lhs.line]
2481
2468
  else
2482
2469
  # TODO or done?
2483
- debug 666
2470
+ debug 10
2484
2471
  end
2485
2472
 
2486
2473
  # TODO PAIR -> LIST ?
@@ -2489,9 +2476,12 @@ opt_block_args_tail: tCOMMA block_args_tail
2489
2476
 
2490
2477
  p_kw_label: tLABEL
2491
2478
  {
2492
- (id, line), = val
2493
-
2494
- result = s(:lit, id.to_sym).line line
2479
+ result = wrap :lit, val[0]
2480
+ }
2481
+ | tSTRING_BEG string_contents tLABEL_END
2482
+ {
2483
+ # you can't actually get here the way I lex labels
2484
+ debug 11
2495
2485
  }
2496
2486
 
2497
2487
  p_kwrest: kwrest_mark tIDENTIFIER
@@ -2551,8 +2541,8 @@ opt_block_args_tail: tCOMMA block_args_tail
2551
2541
 
2552
2542
  result = s(:dot3, v1, nil).line v1.line
2553
2543
  }
2554
- | p_variable
2555
2544
  | p_var_ref
2545
+ | p_expr_ref
2556
2546
  | p_const
2557
2547
  | tBDOT2 p_primitive
2558
2548
  {
@@ -2586,26 +2576,31 @@ opt_block_args_tail: tCOMMA block_args_tail
2586
2576
 
2587
2577
  p_variable: tIDENTIFIER
2588
2578
  {
2589
- (id, line), = val
2590
-
2591
2579
  # TODO: error_duplicate_pattern_variable(p, $1, &@1);
2592
2580
  # TODO: assignable(p, $1, 0, &@$);
2593
- result = s(:lvar, id.to_sym).line line
2581
+ result = wrap :lvar, val[0]
2594
2582
  }
2595
2583
 
2596
2584
  p_var_ref: tCARET tIDENTIFIER
2597
2585
  {
2598
- _, (id, line) = val
2599
-
2600
2586
  # TODO: check id against env for lvar or dvar
2587
+ result = wrap :lvar, val[1]
2588
+ }
2589
+ | tCARET nonlocal_var
2590
+ {
2591
+ _, var = val
2592
+ result = var
2593
+ }
2601
2594
 
2602
- result = s(:lvar, id.to_sym).line line
2595
+ p_expr_ref: tCARET tLPAREN expr_value rparen
2596
+ {
2597
+ _, _, expr, _ = val
2598
+ result = expr # TODO? s(:begin, expr).line expr.line
2603
2599
  }
2604
2600
 
2605
2601
  p_const: tCOLON3 cname
2606
2602
  {
2607
- _, (id, line) = val
2608
- result = s(:colon3, id.to_sym).line line
2603
+ result = wrap :colon3, val[1]
2609
2604
  }
2610
2605
  | p_const tCOLON2 cname
2611
2606
  {
@@ -2617,8 +2612,7 @@ opt_block_args_tail: tCOMMA block_args_tail
2617
2612
  | tCONSTANT
2618
2613
  {
2619
2614
  # TODO $$ = gettable(p, $1, &@$);
2620
- (id, line), = val
2621
- result = s(:const, id.to_sym).line line
2615
+ result = wrap :const, val[0]
2622
2616
  }
2623
2617
  ######################################################################
2624
2618
 
@@ -2676,7 +2670,7 @@ opt_block_args_tail: tCOMMA block_args_tail
2676
2670
 
2677
2671
  string: tCHAR
2678
2672
  {
2679
- debug 36
2673
+ debug 12
2680
2674
  }
2681
2675
  | string1
2682
2676
  | string string1
@@ -2897,25 +2891,22 @@ regexp_contents: none
2897
2891
  when nil then
2898
2892
  result = s(:evstr).line line
2899
2893
  else
2900
- debug 37
2894
+ debug 13
2901
2895
  raise "unknown string body: #{stmt.inspect}"
2902
2896
  end
2903
2897
  }
2904
2898
 
2905
2899
  string_dvar: tGVAR
2906
2900
  {
2907
- (id, line), = val
2908
- result = s(:gvar, id.to_sym).line line
2901
+ result = wrap :gvar, val[0]
2909
2902
  }
2910
2903
  | tIVAR
2911
2904
  {
2912
- (id, line), = val
2913
- result = s(:ivar, id.to_sym).line line
2905
+ result = wrap :ivar, val[0]
2914
2906
  }
2915
2907
  | tCVAR
2916
2908
  {
2917
- (id, line), = val
2918
- result = s(:cvar, id.to_sym).line line
2909
+ result = wrap :cvar, val[0]
2919
2910
  }
2920
2911
  | backref
2921
2912
 
@@ -2924,17 +2915,13 @@ regexp_contents: none
2924
2915
 
2925
2916
  ssym: tSYMBEG sym
2926
2917
  {
2927
- _, (id, line) = val
2928
-
2929
2918
  lexer.lex_state = EXPR_END
2930
- result = s(:lit, id.to_sym).line line
2919
+ result = wrap :lit, val[1]
2931
2920
  }
2932
2921
  | tSYMBOL
2933
2922
  {
2934
- (id, line), = val
2935
-
2936
2923
  lexer.lex_state = EXPR_END
2937
- result = s(:lit, id.to_sym).line line
2924
+ result = wrap :lit, val[0]
2938
2925
  }
2939
2926
 
2940
2927
  sym: fname | tIVAR | tGVAR | tCVAR
@@ -2955,7 +2942,7 @@ regexp_contents: none
2955
2942
  when :evstr then
2956
2943
  result = s(:dsym, "", result).line result.line
2957
2944
  else
2958
- debug 38
2945
+ debug 14
2959
2946
  end
2960
2947
  }
2961
2948
 
@@ -2971,6 +2958,10 @@ regexp_contents: none
2971
2958
  | tRATIONAL
2972
2959
  | tIMAGINARY
2973
2960
 
2961
+ nonlocal_var: tIVAR { result = wrap :ivar, val[0] }
2962
+ | tGVAR { result = wrap :gvar, val[0] }
2963
+ | tCVAR { result = wrap :cvar, val[0] }
2964
+
2974
2965
  user_variable: tIDENTIFIER
2975
2966
  | tIVAR
2976
2967
  | tGVAR
@@ -3015,7 +3006,7 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
3015
3006
  | keyword_variable
3016
3007
  {
3017
3008
  result = self.assignable val[0]
3018
- debug 39
3009
+ debug 15
3019
3010
  }
3020
3011
 
3021
3012
  backref: tNTH_REF
@@ -3053,14 +3044,6 @@ f_opt_paren_args: f_paren_args
3053
3044
  {
3054
3045
  result = end_args val
3055
3046
  }
3056
- | tLPAREN2 f_arg tCOMMA args_forward rparen
3057
- {
3058
- result = end_args val
3059
- }
3060
- | tLPAREN2 args_forward rparen
3061
- {
3062
- result = end_args val
3063
- }
3064
3047
 
3065
3048
  f_arglist: f_paren_args
3066
3049
  | {
@@ -3086,6 +3069,7 @@ f_opt_paren_args: f_paren_args
3086
3069
  result = args val
3087
3070
  }
3088
3071
  | f_block_arg
3072
+ | args_forward
3089
3073
 
3090
3074
  opt_args_tail: tCOMMA args_tail
3091
3075
  {
@@ -3296,17 +3280,25 @@ f_opt_paren_args: f_paren_args
3296
3280
  result = [id, lexer.lineno] # TODO: tPOW/tDSTAR include lineno
3297
3281
  }
3298
3282
 
3299
- f_opt: f_arg_asgn tEQL arg_value
3283
+ f_opt: f_arg_asgn
3284
+ f_eq
3285
+ arg_value
3300
3286
  {
3301
3287
  lhs, _, rhs = val
3302
3288
  result = self.assignable lhs, rhs
3303
3289
  # TODO: detect duplicate names
3290
+ # TODO? p->cur_arg = 0;
3291
+ # TODO? p->ctxt.in_argdef = 1;
3304
3292
  }
3305
3293
 
3306
- f_block_opt: f_arg_asgn tEQL primary_value
3294
+ f_block_opt: f_arg_asgn
3295
+ f_eq
3296
+ primary_value
3307
3297
  {
3308
3298
  lhs, _, rhs = val
3309
3299
  result = self.assignable lhs, rhs
3300
+ # TODO? p->cur_arg = 0;
3301
+ # TODO? p->ctxt.in_argdef = 1;
3310
3302
  }
3311
3303
 
3312
3304
  f_block_optarg: f_block_opt
@@ -3358,6 +3350,12 @@ f_opt_paren_args: f_paren_args
3358
3350
  self.env[identifier] = :lvar
3359
3351
  result = ["&#{identifier}".to_sym, line]
3360
3352
  }
3353
+ | blkarg_mark
3354
+ {
3355
+ (_, line), = val
3356
+
3357
+ result = [:&, line]
3358
+ }
3361
3359
 
3362
3360
  opt_f_block_arg: tCOMMA f_block_arg
3363
3361
  {
@@ -3404,10 +3402,17 @@ f_opt_paren_args: f_paren_args
3404
3402
  }
3405
3403
  | tLABEL arg_value
3406
3404
  {
3407
- (label, line), arg = val
3405
+ label, arg = val
3406
+
3407
+ lit = wrap :lit, label
3408
+ result = s(:array, lit, arg).line lit.line
3409
+ }
3410
+ | tLABEL
3411
+ {
3412
+ lit = wrap :lit, val[0]
3413
+ arg = nil
3408
3414
 
3409
- lit = s(:lit, label.to_sym).line line
3410
- result = s(:array, lit, arg).line line
3415
+ result = s(:array, lit, arg).line lit.line
3411
3416
  }
3412
3417
  | tSTRING_BEG string_contents tLABEL_END arg_value
3413
3418
  {