brakeman 5.0.4 → 5.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (159) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGES.md +49 -1
  3. data/README.md +1 -1
  4. data/bundle/load.rb +5 -4
  5. data/bundle/ruby/2.7.0/gems/{haml-5.2.1 → haml-5.2.2}/CHANGELOG.md +8 -0
  6. data/bundle/ruby/2.7.0/gems/{haml-5.2.1 → haml-5.2.2}/FAQ.md +0 -0
  7. data/bundle/ruby/2.7.0/gems/{haml-5.2.1 → haml-5.2.2}/Gemfile +0 -0
  8. data/bundle/ruby/2.7.0/gems/{haml-5.2.1 → haml-5.2.2}/MIT-LICENSE +0 -0
  9. data/bundle/ruby/2.7.0/gems/{haml-5.2.1 → haml-5.2.2}/README.md +19 -13
  10. data/bundle/ruby/2.7.0/gems/{haml-5.2.1 → haml-5.2.2}/REFERENCE.md +10 -3
  11. data/bundle/ruby/2.7.0/gems/{haml-5.2.1 → haml-5.2.2}/TODO +0 -0
  12. data/bundle/ruby/2.7.0/gems/{haml-5.2.1 → haml-5.2.2}/haml.gemspec +0 -0
  13. data/bundle/ruby/2.7.0/gems/{haml-5.2.1 → haml-5.2.2}/lib/haml/attribute_builder.rb +55 -0
  14. data/bundle/ruby/2.7.0/gems/{haml-5.2.1 → haml-5.2.2}/lib/haml/attribute_compiler.rb +4 -2
  15. data/bundle/ruby/2.7.0/gems/{haml-5.2.1 → haml-5.2.2}/lib/haml/attribute_parser.rb +0 -0
  16. data/bundle/ruby/2.7.0/gems/{haml-5.2.1 → haml-5.2.2}/lib/haml/buffer.rb +0 -56
  17. data/bundle/ruby/2.7.0/gems/{haml-5.2.1 → haml-5.2.2}/lib/haml/compiler.rb +0 -0
  18. data/bundle/ruby/2.7.0/gems/{haml-5.2.1 → haml-5.2.2}/lib/haml/engine.rb +0 -0
  19. data/bundle/ruby/2.7.0/gems/{haml-5.2.1 → haml-5.2.2}/lib/haml/error.rb +0 -0
  20. data/bundle/ruby/2.7.0/gems/{haml-5.2.1 → haml-5.2.2}/lib/haml/escapable.rb +0 -0
  21. data/bundle/ruby/2.7.0/gems/{haml-5.2.1 → haml-5.2.2}/lib/haml/exec.rb +0 -0
  22. data/bundle/ruby/2.7.0/gems/{haml-5.2.1 → haml-5.2.2}/lib/haml/filters.rb +0 -0
  23. data/bundle/ruby/2.7.0/gems/{haml-5.2.1 → haml-5.2.2}/lib/haml/generator.rb +0 -0
  24. data/bundle/ruby/2.7.0/gems/{haml-5.2.1 → haml-5.2.2}/lib/haml/helpers/action_view_extensions.rb +0 -0
  25. data/bundle/ruby/2.7.0/gems/{haml-5.2.1 → haml-5.2.2}/lib/haml/helpers/action_view_mods.rb +0 -0
  26. data/bundle/ruby/2.7.0/gems/{haml-5.2.1 → haml-5.2.2}/lib/haml/helpers/action_view_xss_mods.rb +0 -0
  27. data/bundle/ruby/2.7.0/gems/{haml-5.2.1 → haml-5.2.2}/lib/haml/helpers/safe_erubi_template.rb +0 -0
  28. data/bundle/ruby/2.7.0/gems/{haml-5.2.1 → haml-5.2.2}/lib/haml/helpers/safe_erubis_template.rb +0 -0
  29. data/bundle/ruby/2.7.0/gems/{haml-5.2.1 → haml-5.2.2}/lib/haml/helpers/xss_mods.rb +0 -0
  30. data/bundle/ruby/2.7.0/gems/{haml-5.2.1 → haml-5.2.2}/lib/haml/helpers.rb +0 -0
  31. data/bundle/ruby/2.7.0/gems/{haml-5.2.1 → haml-5.2.2}/lib/haml/options.rb +0 -0
  32. data/bundle/ruby/2.7.0/gems/{haml-5.2.1 → haml-5.2.2}/lib/haml/parser.rb +0 -0
  33. data/bundle/ruby/2.7.0/gems/{haml-5.2.1 → haml-5.2.2}/lib/haml/plugin.rb +18 -1
  34. data/bundle/ruby/2.7.0/gems/{haml-5.2.1 → haml-5.2.2}/lib/haml/railtie.rb +5 -0
  35. data/bundle/ruby/2.7.0/gems/{haml-5.2.1 → haml-5.2.2}/lib/haml/sass_rails_filter.rb +0 -0
  36. data/bundle/ruby/2.7.0/gems/{haml-5.2.1 → haml-5.2.2}/lib/haml/template/options.rb +0 -0
  37. data/bundle/ruby/2.7.0/gems/{haml-5.2.1 → haml-5.2.2}/lib/haml/template.rb +0 -0
  38. data/bundle/ruby/2.7.0/gems/{haml-5.2.1 → haml-5.2.2}/lib/haml/temple_engine.rb +2 -1
  39. data/bundle/ruby/2.7.0/gems/{haml-5.2.1 → haml-5.2.2}/lib/haml/temple_line_counter.rb +0 -0
  40. data/bundle/ruby/2.7.0/gems/{haml-5.2.1 → haml-5.2.2}/lib/haml/util.rb +0 -0
  41. data/bundle/ruby/2.7.0/gems/{haml-5.2.1 → haml-5.2.2}/lib/haml/version.rb +1 -1
  42. data/bundle/ruby/2.7.0/gems/{haml-5.2.1 → haml-5.2.2}/lib/haml.rb +0 -0
  43. data/bundle/ruby/2.7.0/gems/{haml-5.2.1 → haml-5.2.2}/yard/default/fulldoc/html/css/common.sass +0 -0
  44. data/bundle/ruby/2.7.0/gems/{haml-5.2.1 → haml-5.2.2}/yard/default/layout/html/footer.erb +0 -0
  45. data/bundle/ruby/2.7.0/gems/parallel-1.21.0/MIT-LICENSE.txt +20 -0
  46. data/bundle/ruby/2.7.0/gems/parallel-1.21.0/lib/parallel/processor_count.rb +45 -0
  47. data/bundle/ruby/2.7.0/gems/parallel-1.21.0/lib/parallel/version.rb +4 -0
  48. data/bundle/ruby/2.7.0/gems/parallel-1.21.0/lib/parallel.rb +532 -0
  49. data/bundle/ruby/2.7.0/gems/{ruby_parser-3.16.0 → ruby_parser-3.18.1}/History.rdoc +88 -0
  50. data/bundle/ruby/2.7.0/gems/{ruby_parser-3.16.0 → ruby_parser-3.18.1}/Manifest.txt +3 -0
  51. data/bundle/ruby/2.7.0/gems/{ruby_parser-3.16.0 → ruby_parser-3.18.1}/README.rdoc +1 -0
  52. data/bundle/ruby/2.7.0/gems/{ruby_parser-3.16.0 → ruby_parser-3.18.1}/compare/normalize.rb +6 -1
  53. data/bundle/ruby/2.7.0/gems/{ruby_parser-3.16.0 → ruby_parser-3.18.1}/debugging.md +0 -0
  54. data/bundle/ruby/2.7.0/gems/ruby_parser-3.18.1/gauntlet.md +106 -0
  55. data/bundle/ruby/2.7.0/gems/{ruby_parser-3.16.0 → ruby_parser-3.18.1}/lib/rp_extensions.rb +15 -36
  56. data/bundle/ruby/2.7.0/gems/ruby_parser-3.18.1/lib/rp_stringscanner.rb +33 -0
  57. data/bundle/ruby/2.7.0/gems/ruby_parser-3.18.1/lib/ruby20_parser.rb +7128 -0
  58. data/bundle/ruby/2.7.0/gems/{ruby_parser-3.16.0 → ruby_parser-3.18.1}/lib/ruby20_parser.y +335 -252
  59. data/bundle/ruby/2.7.0/gems/ruby_parser-3.18.1/lib/ruby21_parser.rb +7182 -0
  60. data/bundle/ruby/2.7.0/gems/{ruby_parser-3.16.0 → ruby_parser-3.18.1}/lib/ruby21_parser.y +330 -249
  61. data/bundle/ruby/2.7.0/gems/ruby_parser-3.18.1/lib/ruby22_parser.rb +7228 -0
  62. data/bundle/ruby/2.7.0/gems/{ruby_parser-3.16.0 → ruby_parser-3.18.1}/lib/ruby22_parser.y +334 -251
  63. data/bundle/ruby/2.7.0/gems/ruby_parser-3.18.1/lib/ruby23_parser.rb +7237 -0
  64. data/bundle/ruby/2.7.0/gems/{ruby_parser-3.16.0/lib/ruby26_parser.y → ruby_parser-3.18.1/lib/ruby23_parser.y} +336 -276
  65. data/bundle/ruby/2.7.0/gems/ruby_parser-3.18.1/lib/ruby24_parser.rb +7268 -0
  66. data/bundle/ruby/2.7.0/gems/{ruby_parser-3.16.0 → ruby_parser-3.18.1}/lib/ruby24_parser.y +334 -251
  67. data/bundle/ruby/2.7.0/gems/ruby_parser-3.18.1/lib/ruby25_parser.rb +7268 -0
  68. data/bundle/ruby/2.7.0/gems/{ruby_parser-3.16.0/lib/ruby30_parser.y → ruby_parser-3.18.1/lib/ruby25_parser.y} +335 -304
  69. data/bundle/ruby/2.7.0/gems/ruby_parser-3.18.1/lib/ruby26_parser.rb +7287 -0
  70. data/bundle/ruby/2.7.0/gems/{ruby_parser-3.16.0/lib/ruby27_parser.y → ruby_parser-3.18.1/lib/ruby26_parser.y} +334 -288
  71. data/bundle/ruby/2.7.0/gems/ruby_parser-3.18.1/lib/ruby27_parser.rb +8517 -0
  72. data/bundle/ruby/2.7.0/gems/{ruby_parser-3.16.0/lib/ruby_parser.yy → ruby_parser-3.18.1/lib/ruby27_parser.y} +906 -380
  73. data/bundle/ruby/2.7.0/gems/ruby_parser-3.18.1/lib/ruby30_parser.rb +8751 -0
  74. data/bundle/ruby/2.7.0/gems/ruby_parser-3.18.1/lib/ruby30_parser.y +3472 -0
  75. data/bundle/ruby/2.7.0/gems/ruby_parser-3.18.1/lib/ruby3_parser.yy +3476 -0
  76. data/bundle/ruby/2.7.0/gems/{ruby_parser-3.16.0 → ruby_parser-3.18.1}/lib/ruby_lexer.rb +261 -609
  77. data/bundle/ruby/2.7.0/gems/{ruby_parser-3.16.0 → ruby_parser-3.18.1}/lib/ruby_lexer.rex +27 -20
  78. data/bundle/ruby/2.7.0/gems/{ruby_parser-3.16.0 → ruby_parser-3.18.1}/lib/ruby_lexer.rex.rb +59 -23
  79. data/bundle/ruby/2.7.0/gems/ruby_parser-3.18.1/lib/ruby_lexer_strings.rb +638 -0
  80. data/bundle/ruby/2.7.0/gems/{ruby_parser-3.16.0 → ruby_parser-3.18.1}/lib/ruby_parser.rb +0 -0
  81. data/bundle/ruby/2.7.0/gems/ruby_parser-3.18.1/lib/ruby_parser.yy +3487 -0
  82. data/bundle/ruby/2.7.0/gems/{ruby_parser-3.16.0 → ruby_parser-3.18.1}/lib/ruby_parser_extras.rb +296 -115
  83. data/bundle/ruby/2.7.0/gems/{ruby_parser-3.16.0 → ruby_parser-3.18.1}/tools/munge.rb +34 -6
  84. data/bundle/ruby/2.7.0/gems/ruby_parser-3.18.1/tools/ripper.rb +44 -0
  85. data/bundle/ruby/2.7.0/gems/{sexp_processor-4.15.3 → sexp_processor-4.16.0}/History.rdoc +15 -0
  86. data/bundle/ruby/2.7.0/gems/{sexp_processor-4.15.3 → sexp_processor-4.16.0}/Manifest.txt +0 -0
  87. data/bundle/ruby/2.7.0/gems/{sexp_processor-4.15.3 → sexp_processor-4.16.0}/README.rdoc +0 -0
  88. data/bundle/ruby/2.7.0/gems/{sexp_processor-4.15.3 → sexp_processor-4.16.0}/lib/composite_sexp_processor.rb +0 -0
  89. data/bundle/ruby/2.7.0/gems/{sexp_processor-4.15.3 → sexp_processor-4.16.0}/lib/pt_testcase.rb +7 -2
  90. data/bundle/ruby/2.7.0/gems/{sexp_processor-4.15.3 → sexp_processor-4.16.0}/lib/sexp.rb +19 -9
  91. data/bundle/ruby/2.7.0/gems/{sexp_processor-4.15.3 → sexp_processor-4.16.0}/lib/sexp_matcher.rb +0 -0
  92. data/bundle/ruby/2.7.0/gems/{sexp_processor-4.15.3 → sexp_processor-4.16.0}/lib/sexp_processor.rb +1 -1
  93. data/bundle/ruby/2.7.0/gems/{sexp_processor-4.15.3 → sexp_processor-4.16.0}/lib/strict_sexp.rb +25 -3
  94. data/bundle/ruby/2.7.0/gems/{sexp_processor-4.15.3 → sexp_processor-4.16.0}/lib/unique.rb +0 -0
  95. data/bundle/ruby/2.7.0/gems/{unicode-display_width-1.7.0 → unicode-display_width-1.8.0}/CHANGELOG.md +4 -0
  96. data/bundle/ruby/2.7.0/gems/{unicode-display_width-1.7.0 → unicode-display_width-1.8.0}/MIT-LICENSE.txt +0 -0
  97. data/bundle/ruby/2.7.0/gems/{unicode-display_width-1.7.0 → unicode-display_width-1.8.0}/README.md +1 -1
  98. data/bundle/ruby/2.7.0/gems/unicode-display_width-1.8.0/data/display_width.marshal.gz +0 -0
  99. data/bundle/ruby/2.7.0/gems/{unicode-display_width-1.7.0 → unicode-display_width-1.8.0}/lib/unicode/display_width/constants.rb +2 -2
  100. data/bundle/ruby/2.7.0/gems/{unicode-display_width-1.7.0 → unicode-display_width-1.8.0}/lib/unicode/display_width/index.rb +0 -0
  101. data/bundle/ruby/2.7.0/gems/{unicode-display_width-1.7.0 → unicode-display_width-1.8.0}/lib/unicode/display_width/no_string_ext.rb +0 -0
  102. data/bundle/ruby/2.7.0/gems/{unicode-display_width-1.7.0 → unicode-display_width-1.8.0}/lib/unicode/display_width/string_ext.rb +0 -0
  103. data/bundle/ruby/2.7.0/gems/{unicode-display_width-1.7.0 → unicode-display_width-1.8.0}/lib/unicode/display_width.rb +0 -0
  104. data/lib/brakeman/app_tree.rb +1 -1
  105. data/lib/brakeman/checks/base_check.rb +10 -0
  106. data/lib/brakeman/checks/check_detailed_exceptions.rb +1 -1
  107. data/lib/brakeman/checks/check_eol_rails.rb +23 -0
  108. data/lib/brakeman/checks/check_eol_ruby.rb +26 -0
  109. data/lib/brakeman/checks/check_evaluation.rb +1 -1
  110. data/lib/brakeman/checks/check_execute.rb +10 -0
  111. data/lib/brakeman/checks/check_json_parsing.rb +1 -1
  112. data/lib/brakeman/checks/check_render.rb +15 -1
  113. data/lib/brakeman/checks/check_sql.rb +58 -7
  114. data/lib/brakeman/checks/check_symbol_dos.rb +1 -1
  115. data/lib/brakeman/checks/check_verb_confusion.rb +1 -1
  116. data/lib/brakeman/checks/eol_check.rb +47 -0
  117. data/lib/brakeman/file_parser.rb +45 -15
  118. data/lib/brakeman/options.rb +15 -2
  119. data/lib/brakeman/processors/alias_processor.rb +91 -9
  120. data/lib/brakeman/processors/controller_alias_processor.rb +6 -43
  121. data/lib/brakeman/processors/gem_processor.rb +3 -0
  122. data/lib/brakeman/processors/haml_template_processor.rb +9 -0
  123. data/lib/brakeman/processors/lib/call_conversion_helper.rb +12 -6
  124. data/lib/brakeman/processors/lib/rails3_route_processor.rb +2 -0
  125. data/lib/brakeman/processors/library_processor.rb +9 -0
  126. data/lib/brakeman/processors/model_processor.rb +32 -0
  127. data/lib/brakeman/report/ignore/config.rb +1 -1
  128. data/lib/brakeman/report/ignore/interactive.rb +1 -1
  129. data/lib/brakeman/report/report_csv.rb +1 -1
  130. data/lib/brakeman/report/report_github.rb +31 -0
  131. data/lib/brakeman/report/report_sarif.rb +22 -3
  132. data/lib/brakeman/report/report_text.rb +1 -1
  133. data/lib/brakeman/report.rb +4 -1
  134. data/lib/brakeman/rescanner.rb +1 -1
  135. data/lib/brakeman/scanner.rb +19 -14
  136. data/lib/brakeman/tracker/collection.rb +57 -7
  137. data/lib/brakeman/tracker/config.rb +8 -1
  138. data/lib/brakeman/tracker/method_info.rb +70 -0
  139. data/lib/brakeman/tracker.rb +33 -4
  140. data/lib/brakeman/util.rb +34 -18
  141. data/lib/brakeman/version.rb +1 -1
  142. data/lib/brakeman/warning_codes.rb +2 -0
  143. data/lib/brakeman.rb +8 -2
  144. data/lib/ruby_parser/bm_sexp.rb +24 -0
  145. metadata +107 -95
  146. data/bundle/ruby/2.7.0/gems/ruby_parser-3.16.0/lib/rp_stringscanner.rb +0 -64
  147. data/bundle/ruby/2.7.0/gems/ruby_parser-3.16.0/lib/ruby20_parser.rb +0 -7075
  148. data/bundle/ruby/2.7.0/gems/ruby_parser-3.16.0/lib/ruby21_parser.rb +0 -7148
  149. data/bundle/ruby/2.7.0/gems/ruby_parser-3.16.0/lib/ruby22_parser.rb +0 -7185
  150. data/bundle/ruby/2.7.0/gems/ruby_parser-3.16.0/lib/ruby23_parser.rb +0 -7199
  151. data/bundle/ruby/2.7.0/gems/ruby_parser-3.16.0/lib/ruby23_parser.y +0 -2643
  152. data/bundle/ruby/2.7.0/gems/ruby_parser-3.16.0/lib/ruby24_parser.rb +0 -7219
  153. data/bundle/ruby/2.7.0/gems/ruby_parser-3.16.0/lib/ruby25_parser.rb +0 -7218
  154. data/bundle/ruby/2.7.0/gems/ruby_parser-3.16.0/lib/ruby25_parser.y +0 -2651
  155. data/bundle/ruby/2.7.0/gems/ruby_parser-3.16.0/lib/ruby26_parser.rb +0 -7240
  156. data/bundle/ruby/2.7.0/gems/ruby_parser-3.16.0/lib/ruby27_parser.rb +0 -7358
  157. data/bundle/ruby/2.7.0/gems/ruby_parser-3.16.0/lib/ruby30_parser.rb +0 -7358
  158. data/bundle/ruby/2.7.0/gems/ruby_parser-3.16.0/tools/ripper.rb +0 -39
  159. data/bundle/ruby/2.7.0/gems/unicode-display_width-1.7.0/data/display_width.marshal.gz +0 -0
@@ -18,7 +18,7 @@ token kCLASS kMODULE kDEF kUNDEF kBEGIN kRESCUE kENSURE kEND kIF kUNLESS
18
18
  tBACK_REF2 tSYMBEG tSTRING_BEG tXSTRING_BEG tREGEXP_BEG
19
19
  tWORDS_BEG tQWORDS_BEG tSTRING_DBEG tSTRING_DVAR tSTRING_END
20
20
  tSTRING tSYMBOL tNL tEH tCOLON tCOMMA tSPACE tSEMI tLAMBDA
21
- tLAMBEG tDSTAR tCHAR tSYMBOLS_BEG tQSYMBOLS_BEG tSTRING_DEND tUBANG
21
+ tLAMBEG tDSTAR tCHAR tSYMBOLS_BEG tQSYMBOLS_BEG tSTRING_DEND
22
22
  tRATIONAL tIMAGINARY
23
23
  tLABEL_END
24
24
 
@@ -78,7 +78,7 @@ rule
78
78
  | klBEGIN
79
79
  {
80
80
  if (self.in_def || self.in_single > 0) then
81
- debug20 1
81
+ debug 11
82
82
  yyerror "BEGIN in method"
83
83
  end
84
84
  self.env.extend
@@ -103,7 +103,9 @@ rule
103
103
  bodystmt: compstmt opt_rescue k_else
104
104
  {
105
105
  res = _values[-2]
106
- yyerror "else without rescue is useless" unless res
106
+ # TODO: move down to main match so I can just use val
107
+
108
+ warn "else without rescue is useless" unless res
107
109
  }
108
110
  compstmt
109
111
  opt_ensure
@@ -133,7 +135,7 @@ rule
133
135
  | error stmt
134
136
  {
135
137
  result = val[1]
136
- debug20 2, val, result
138
+ debug 12
137
139
  }
138
140
 
139
141
  stmt_or_begin: stmt
@@ -141,6 +143,10 @@ rule
141
143
  {
142
144
  yyerror "BEGIN is permitted only at toplevel"
143
145
  }
146
+ begin_block
147
+ {
148
+ result = val[2] # wtf?
149
+ }
144
150
 
145
151
  stmt: kALIAS fitem
146
152
  {
@@ -153,12 +159,12 @@ rule
153
159
  }
154
160
  | kALIAS tGVAR tGVAR
155
161
  {
156
- (_, line), lhs, rhs = val
162
+ (_, line), (lhs, _), (rhs, _) = val
157
163
  result = s(:valias, lhs.to_sym, rhs.to_sym).line line
158
164
  }
159
165
  | kALIAS tGVAR tBACK_REF
160
166
  {
161
- (_, line), lhs, rhs = val
167
+ (_, line), (lhs, _), (rhs, _) = val
162
168
  result = s(:valias, lhs.to_sym, :"$#{rhs}").line line
163
169
  }
164
170
  | kALIAS tGVAR tNTH_REF
@@ -201,7 +207,7 @@ rule
201
207
  (_, line), _, stmt, _ = val
202
208
 
203
209
  if (self.in_def || self.in_single > 0) then
204
- debug20 3
210
+ debug 13
205
211
  yyerror "END in method; use at_exit"
206
212
  end
207
213
 
@@ -241,32 +247,31 @@ rule
241
247
  }
242
248
  | primary_value call_op tIDENTIFIER tOP_ASGN command_rhs
243
249
  {
244
- prim, _, id, opasgn, rhs = val
245
- result = s(:op_asgn, prim, rhs, id.to_sym, opasgn.to_sym)
246
- if val[1] == '&.'
247
- result.sexp_type = :safe_op_asgn
248
- end
249
- result.line = val[0].line
250
+ prim, (call_op, _), (id, _), (op_asgn, _), rhs = val
251
+
252
+ result = s(:op_asgn, prim, rhs, id.to_sym, op_asgn.to_sym)
253
+ result.sexp_type = :safe_op_asgn if call_op == '&.'
254
+ result.line prim.line
250
255
  }
251
256
  | primary_value call_op tCONSTANT tOP_ASGN command_rhs
252
257
  {
253
- result = s(:op_asgn, val[0], val[4], val[2].to_sym, val[3].to_sym)
254
- if val[1] == '&.'
255
- result.sexp_type = :safe_op_asgn
256
- end
257
- result.line = val[0].line
258
+ prim, (call_op, _), (id, _), (op_asgn, _), rhs = val
259
+
260
+ result = s(:op_asgn, prim, rhs, id.to_sym, op_asgn.to_sym)
261
+ result.sexp_type = :safe_op_asgn if call_op == '&.'
262
+ result.line prim.line
258
263
  }
259
264
  | primary_value tCOLON2 tCONSTANT tOP_ASGN command_rhs
260
265
  {
261
- lhs1, _, lhs2, op, rhs = val
266
+ lhs1, _, (lhs2, line), (id, _), rhs = val
262
267
 
263
- result = s(:op_asgn, lhs1, rhs, lhs2.to_sym, op.to_sym)
268
+ result = s(:op_asgn, lhs1, rhs, lhs2.to_sym, id.to_sym).line line
264
269
  }
265
270
  | primary_value tCOLON2 tIDENTIFIER tOP_ASGN command_rhs
266
271
  {
267
- lhs1, _, lhs2, op, rhs = val
272
+ lhs1, _, (lhs2, line), (id, _), rhs = val
268
273
 
269
- result = s(:op_asgn, lhs1, rhs, lhs2.to_sym, op.to_sym)
274
+ result = s(:op_asgn, lhs1, rhs, lhs2.to_sym, id.to_sym).line line
270
275
  }
271
276
  | backref tOP_ASGN command_rhs
272
277
  {
@@ -304,7 +309,7 @@ rule
304
309
  # TODO: fix line number to tBANG... but causes BAD shift/reduce conflict
305
310
  # REFACTOR: call_uni_op -- see parse26.y
306
311
  }
307
- | arg
312
+ | arg =tLBRACE_ARG
308
313
 
309
314
  expr_value: expr
310
315
  {
@@ -329,7 +334,7 @@ rule
329
334
  block_command: block_call
330
335
  | block_call call_op2 operation2 command_args
331
336
  {
332
- blk, _, msg, args = val
337
+ blk, _, (msg, _line), args = val
333
338
  result = new_call(blk, msg.to_sym, args).line blk.line
334
339
  }
335
340
 
@@ -343,15 +348,15 @@ rule
343
348
  _, line, body, _ = val
344
349
 
345
350
  result = body
346
- result.line = line
351
+ result.line line
347
352
 
348
353
  # self.env.unextend
349
354
  }
350
355
 
351
356
  fcall: operation
352
357
  {
353
- msg, = val
354
- result = new_call(nil, msg.to_sym).line lexer.lineno
358
+ (msg, line), = val
359
+ result = new_call(nil, msg.to_sym).line line
355
360
  }
356
361
 
357
362
  command: fcall command_args =tLOWEST
@@ -374,12 +379,14 @@ rule
374
379
  }
375
380
  | primary_value call_op operation2 command_args =tLOWEST
376
381
  {
377
- lhs, callop, op, args = val
382
+ lhs, callop, (op, _), args = val
383
+
378
384
  result = new_call lhs, op.to_sym, args, callop
385
+ result.line lhs.line
379
386
  }
380
387
  | primary_value call_op operation2 command_args cmd_brace_block
381
388
  {
382
- recv, _, msg, args, block = val
389
+ recv, _, (msg, _line), args, block = val
383
390
  call = new_call recv, msg.to_sym, args, val[1]
384
391
 
385
392
  block_dup_check call, block
@@ -389,11 +396,14 @@ rule
389
396
  }
390
397
  | primary_value tCOLON2 operation2 command_args =tLOWEST
391
398
  {
392
- result = new_call val[0], val[2].to_sym, val[3]
399
+ lhs, _, (id, line), args = val
400
+
401
+ result = new_call lhs, id.to_sym, args
402
+ result.line line
393
403
  }
394
404
  | primary_value tCOLON2 operation2 command_args cmd_brace_block
395
405
  {
396
- recv, _, msg, args, block = val
406
+ recv, _, (msg, _line), args, block = val
397
407
  call = new_call recv, msg.to_sym, args
398
408
 
399
409
  block_dup_check call, block
@@ -551,25 +561,29 @@ rule
551
561
  }
552
562
  | primary_value call_op tIDENTIFIER
553
563
  {
554
- result = new_attrasgn val[0], val[2], val[1]
564
+ lhs, call_op, (id, _line) = val
565
+
566
+ result = new_attrasgn lhs, id, call_op
555
567
  }
556
568
  | primary_value tCOLON2 tIDENTIFIER
557
569
  {
558
- recv, _, id = val
570
+ recv, _, (id, _line) = val
559
571
  result = new_attrasgn recv, id
560
572
  }
561
573
  | primary_value call_op tCONSTANT
562
574
  {
563
- result = new_attrasgn val[0], val[2], val[1]
575
+ lhs, call_op, (id, _line) = val
576
+
577
+ result = new_attrasgn lhs, id, call_op
564
578
  }
565
579
  | primary_value tCOLON2 tCONSTANT
566
580
  {
567
581
  if (self.in_def || self.in_single > 0) then
568
- debug20 7
582
+ debug 14
569
583
  yyerror "dynamic constant assignment"
570
584
  end
571
585
 
572
- expr, _, id = val
586
+ expr, _, (id, _line) = val
573
587
  l = expr.line
574
588
 
575
589
  result = s(:const, s(:colon2, expr, id.to_sym).line(l), nil).line l
@@ -577,58 +591,65 @@ rule
577
591
  | tCOLON3 tCONSTANT
578
592
  {
579
593
  if (self.in_def || self.in_single > 0) then
580
- debug20 8
594
+ debug 15
581
595
  yyerror "dynamic constant assignment"
582
596
  end
583
597
 
584
- _, id = val
585
- l = lexer.lineno
598
+ _, (id, l) = val
586
599
 
587
600
  result = s(:const, nil, s(:colon3, id.to_sym).line(l)).line l
588
601
  }
589
602
  | backref
590
603
  {
591
- self.backref_assign_error val[0]
604
+ ref, = val
605
+
606
+ self.backref_assign_error ref
592
607
  }
593
608
 
594
609
  lhs: user_variable
595
610
  {
596
- line = lexer.lineno
597
- result = self.assignable val[0]
598
- result.line = line
611
+ var, = val
612
+
613
+ result = self.assignable var
599
614
  }
600
615
  | keyword_variable
601
616
  {
602
- line = lexer.lineno
603
- result = self.assignable val[0]
604
- result.line = line
605
- debug20 9, val, result
617
+ var, = val
618
+
619
+ result = self.assignable var
620
+
621
+ debug 16
606
622
  }
607
623
  | primary_value tLBRACK2 opt_call_args rbracket
608
624
  {
609
625
  lhs, _, args, _ = val
626
+
610
627
  result = self.aryset lhs, args
611
628
  }
612
629
  | primary_value call_op tIDENTIFIER # REFACTOR
613
630
  {
614
- lhs, op, id = val
631
+ lhs, op, (id, _line) = val
632
+
615
633
  result = new_attrasgn lhs, id, op
616
634
  }
617
635
  | primary_value tCOLON2 tIDENTIFIER
618
636
  {
619
- lhs, _, id = val
637
+ lhs, _, (id, _line) = val
638
+
620
639
  result = new_attrasgn lhs, id
621
640
  }
622
641
  | primary_value call_op tCONSTANT # REFACTOR?
623
642
  {
624
- result = new_attrasgn val[0], val[2], val[1]
643
+ lhs, call_op, (id, _line) = val
644
+
645
+ result = new_attrasgn lhs, id, call_op
625
646
  }
626
647
  | primary_value tCOLON2 tCONSTANT
627
648
  {
628
- expr, _, id = val
649
+ expr, _, (id, _line) = val
629
650
 
630
651
  if (self.in_def || self.in_single > 0) then
631
- debug20 10
652
+ debug 17
632
653
  yyerror "dynamic constant assignment"
633
654
  end
634
655
 
@@ -637,14 +658,13 @@ rule
637
658
  }
638
659
  | tCOLON3 tCONSTANT
639
660
  {
640
- _, id = val
661
+ _, (id, l) = val
641
662
 
642
663
  if (self.in_def || self.in_single > 0) then
643
- debug20 11
664
+ debug 18
644
665
  yyerror "dynamic constant assignment"
645
666
  end
646
667
 
647
- l = lexer.lineno
648
668
  result = s(:const, s(:colon3, id.to_sym).line(l)).line l
649
669
  }
650
670
  | backref
@@ -660,16 +680,17 @@ rule
660
680
 
661
681
  cpath: tCOLON3 cname
662
682
  {
663
- _, name = val
664
- result = s(:colon3, name.to_sym).line lexer.lineno
683
+ _, (name, line) = val
684
+ result = s(:colon3, name.to_sym).line line
665
685
  }
666
686
  | cname
667
687
  {
668
- result = val[0].to_sym
688
+ (id, line), = val
689
+ result = [id.to_sym, line] # TODO: sexp?
669
690
  }
670
691
  | primary_value tCOLON2 cname
671
692
  {
672
- pval, _, name = val
693
+ pval, _, (name, _line) = val
673
694
 
674
695
  result = s(:colon2, pval, name.to_sym)
675
696
  result.line pval.line
@@ -679,24 +700,17 @@ rule
679
700
  | op
680
701
  {
681
702
  lexer.lex_state = EXPR_END
682
- result = val[0]
683
703
  }
684
704
 
685
705
  | reswords
686
- {
687
- (sym, _line), = val
688
- lexer.lex_state = EXPR_END
689
- result = sym
690
- }
691
-
692
- fsym: fname | symbol
693
706
 
694
- fitem: fsym
707
+ fitem: fname
695
708
  {
696
- id, = val
697
- result = s(:lit, id.to_sym).line lexer.lineno
709
+ (id, line), = val
710
+
711
+ result = s(:lit, id.to_sym).line line
698
712
  }
699
- | dsym
713
+ | symbol
700
714
 
701
715
  undef_list: fitem
702
716
  {
@@ -717,8 +731,6 @@ rule
717
731
  | tNEQ | tLSHFT | tRSHFT | tPLUS | tMINUS | tSTAR2
718
732
  | tSTAR | tDIVIDE | tPERCENT | tPOW | tDSTAR | tBANG | tTILDE
719
733
  | tUPLUS | tUMINUS | tAREF | tASET | tBACK_REF2
720
- # TODO: tUBANG dead?
721
- | tUBANG
722
734
 
723
735
  reswords: k__LINE__ | k__FILE__ | k__ENCODING__ | klBEGIN | klEND
724
736
  | kALIAS | kAND | kBEGIN | kBREAK | kCASE
@@ -752,24 +764,20 @@ rule
752
764
  }
753
765
  | primary_value tCOLON2 tIDENTIFIER tOP_ASGN arg_rhs
754
766
  {
755
- lhs, _, id, op, rhs = val
767
+ lhs, _, (id, _line), (op, _), rhs = val
756
768
 
757
769
  result = s(:op_asgn, lhs, rhs, id.to_sym, op.to_sym).line lhs.line
758
770
  }
759
771
  | primary_value tCOLON2 tCONSTANT tOP_ASGN arg_rhs
760
772
  {
761
- lhs1, _, lhs2, op, rhs = val
773
+ lhs1, _, (lhs2, _line), op, rhs = val
762
774
 
763
775
  lhs = s(:colon2, lhs1, lhs2.to_sym).line lhs1.line
764
776
  result = new_const_op_asgn [lhs, op, rhs]
765
777
  }
766
- | tCOLON3 tCONSTANT
778
+ | tCOLON3 tCONSTANT tOP_ASGN arg_rhs
767
779
  {
768
- result = self.lexer.lineno
769
- }
770
- tOP_ASGN arg_rhs
771
- {
772
- _, lhs, line, op, rhs = val
780
+ _, (lhs, line), op, rhs = val
773
781
 
774
782
  lhs = s(:colon3, lhs.to_sym).line line
775
783
  result = new_const_op_asgn [lhs, op, rhs]
@@ -783,7 +791,7 @@ rule
783
791
  | arg tDOT2 arg
784
792
  {
785
793
  v1, v2 = val[0], val[2]
786
- if v1.node_type == :lit and v2.node_type == :lit and Integer === v1.last and Integer === v2.last then
794
+ if v1.sexp_type == :lit and v2.sexp_type == :lit and Integer === v1.last and Integer === v2.last then
787
795
  result = s(:lit, (v1.last)..(v2.last)).line v1.line
788
796
  else
789
797
  result = s(:dot2, v1, v2).line v1.line
@@ -792,7 +800,7 @@ rule
792
800
  | arg tDOT3 arg
793
801
  {
794
802
  v1, v2 = val[0], val[2]
795
- if v1.node_type == :lit and v2.node_type == :lit and Integer === v1.last and Integer === v2.last then
803
+ if v1.sexp_type == :lit and v2.sexp_type == :lit and Integer === v1.last and Integer === v2.last then
796
804
  result = s(:lit, (v1.last)...(v2.last)).line v1.line
797
805
  else
798
806
  result = s(:dot3, v1, v2).line v1.line
@@ -826,8 +834,9 @@ rule
826
834
  }
827
835
  | tUMINUS_NUM simple_numeric tPOW arg
828
836
  {
829
- lit = s(:lit, val[1]).line lexer.lineno
830
- result = new_call(new_call(lit, :"**", argl(val[3])), :"-@")
837
+ _, (num, line), _, arg = val
838
+ lit = s(:lit, num).line line
839
+ result = new_call(new_call(lit, :"**", argl(arg)), :"-@")
831
840
 
832
841
  }
833
842
  | tUPLUS arg
@@ -926,12 +935,12 @@ rule
926
935
 
927
936
  rel_expr: arg relop arg =tGT
928
937
  {
929
- lhs, op, rhs = val
938
+ lhs, (op, _), rhs = val
930
939
  result = new_call lhs, op.to_sym, argl(rhs)
931
940
  }
932
941
  | rel_expr relop arg =tGT
933
942
  {
934
- lhs, op, rhs = val
943
+ lhs, (op, _), rhs = val
935
944
  warn "comparison '%s' after comparison", op
936
945
  result = new_call lhs, op.to_sym, argl(rhs)
937
946
  }
@@ -1122,8 +1131,9 @@ rule
1122
1131
  | backref
1123
1132
  | tFID
1124
1133
  {
1125
- msg, = val
1134
+ (msg, line), = val
1126
1135
  result = new_call nil, msg.to_sym
1136
+ result.line line
1127
1137
  }
1128
1138
  | k_begin
1129
1139
  {
@@ -1165,15 +1175,15 @@ rule
1165
1175
  }
1166
1176
  | primary_value tCOLON2 tCONSTANT
1167
1177
  {
1168
- expr, _, id = val
1178
+ expr, _, (id, _line) = val
1169
1179
 
1170
1180
  result = s(:colon2, expr, id.to_sym).line expr.line
1171
1181
  }
1172
1182
  | tCOLON3 tCONSTANT
1173
1183
  {
1174
- _, id = val
1184
+ _, (id, line) = val
1175
1185
 
1176
- result = s(:colon3, id.to_sym).line lexer.lineno
1186
+ result = s(:colon3, id.to_sym).line line
1177
1187
  }
1178
1188
  | tLBRACK { result = lexer.lineno } aref_args tRBRACK
1179
1189
  {
@@ -1197,15 +1207,21 @@ rule
1197
1207
  }
1198
1208
  | kYIELD tLPAREN2 call_args rparen
1199
1209
  {
1200
- result = new_yield val[2]
1210
+ (_, line), _, args, _ = val
1211
+
1212
+ result = new_yield(args).line line
1201
1213
  }
1202
1214
  | kYIELD tLPAREN2 rparen
1203
1215
  {
1204
- result = new_yield
1216
+ (_, line), _, _ = val
1217
+
1218
+ result = new_yield.line line
1205
1219
  }
1206
1220
  | kYIELD
1207
1221
  {
1208
- result = new_yield
1222
+ (_, line), = val
1223
+
1224
+ result = new_yield.line line
1209
1225
  }
1210
1226
  | kDEFINED opt_nl tLPAREN2 expr rparen
1211
1227
  {
@@ -1220,7 +1236,7 @@ rule
1220
1236
  }
1221
1237
  | kNOT tLPAREN2 rparen
1222
1238
  {
1223
- debug20 14, val, result
1239
+ debug 20
1224
1240
  }
1225
1241
  | fcall brace_block
1226
1242
  {
@@ -1238,9 +1254,10 @@ rule
1238
1254
  iter.insert 1, call # FIX
1239
1255
  result = iter
1240
1256
  }
1241
- | tLAMBDA lambda
1257
+ | lambda
1242
1258
  {
1243
- result = val[1] # TODO: fix lineno
1259
+ expr, = val
1260
+ result = expr
1244
1261
  }
1245
1262
  | k_if expr_value then compstmt if_tail k_end
1246
1263
  {
@@ -1283,7 +1300,6 @@ rule
1283
1300
  }
1284
1301
  cpath superclass
1285
1302
  {
1286
- self.comments.push self.lexer.comments
1287
1303
  if (self.in_def || self.in_single > 0) then
1288
1304
  yyerror "class definition in method body"
1289
1305
  end
@@ -1293,7 +1309,7 @@ rule
1293
1309
  {
1294
1310
  result = new_class val
1295
1311
  self.env.unextend
1296
- self.lexer.comments # we don't care about comments in the body
1312
+ self.lexer.ignore_body_comments
1297
1313
  }
1298
1314
  | k_class tLSHFT
1299
1315
  {
@@ -1314,7 +1330,7 @@ rule
1314
1330
  {
1315
1331
  result = new_sclass val
1316
1332
  self.env.unextend
1317
- self.lexer.comments # we don't care about comments in the body
1333
+ self.lexer.ignore_body_comments
1318
1334
  }
1319
1335
  | k_module
1320
1336
  {
@@ -1322,7 +1338,6 @@ rule
1322
1338
  }
1323
1339
  cpath
1324
1340
  {
1325
- self.comments.push self.lexer.comments
1326
1341
  yyerror "module definition in method body" if
1327
1342
  self.in_def or self.in_single > 0
1328
1343
 
@@ -1332,7 +1347,7 @@ rule
1332
1347
  {
1333
1348
  result = new_module val
1334
1349
  self.env.unextend
1335
- self.lexer.comments # we don't care about comments in the body
1350
+ self.lexer.ignore_body_comments
1336
1351
  }
1337
1352
  | k_def fname
1338
1353
  {
@@ -1342,21 +1357,17 @@ rule
1342
1357
  self.env.extend
1343
1358
  lexer.cmdarg.push false
1344
1359
  lexer.cond.push false
1345
-
1346
- self.comments.push self.lexer.comments
1347
1360
  }
1348
- f_arglist bodystmt { result = lexer.lineno } k_end
1361
+ f_arglist bodystmt k_end
1349
1362
  {
1350
- in_def = val[2]
1351
-
1352
- result = new_defn val
1363
+ result, in_def = new_defn val
1353
1364
 
1354
1365
  lexer.cond.pop # group = local_pop
1355
1366
  lexer.cmdarg.pop
1356
1367
  self.env.unextend
1357
1368
  self.in_def = in_def
1358
1369
 
1359
- self.lexer.comments # we don't care about comments in the body
1370
+ self.lexer.ignore_body_comments
1360
1371
  }
1361
1372
  | k_def singleton dot_or_colon
1362
1373
  {
@@ -1364,7 +1375,7 @@ rule
1364
1375
  }
1365
1376
  fname
1366
1377
  {
1367
- result = [self.in_def, lexer.lineno]
1378
+ result = self.in_def
1368
1379
 
1369
1380
  self.in_single += 1 # TODO: remove?
1370
1381
 
@@ -1374,13 +1385,18 @@ rule
1374
1385
  lexer.cond.push false
1375
1386
 
1376
1387
  lexer.lex_state = EXPR_ENDFN|EXPR_LABEL
1377
- self.comments.push self.lexer.comments
1378
1388
  }
1379
1389
  f_arglist bodystmt k_end
1380
1390
  {
1381
- _, _recv, _, _, _name, (in_def, _lineno), _args, _body, _ = val
1382
1391
 
1383
- result = new_defs val
1392
+ # [kdef, recv, _, _, (name, line), in_def, args, body, kend]
1393
+ # =>
1394
+ # [kdef, recv, (name, line), in_def, args, body, kend]
1395
+
1396
+ val.delete_at 3
1397
+ val.delete_at 2
1398
+
1399
+ result, in_def = new_defs val
1384
1400
 
1385
1401
  lexer.cond.pop # group = local_pop
1386
1402
  lexer.cmdarg.pop
@@ -1391,7 +1407,7 @@ rule
1391
1407
 
1392
1408
  # TODO: restore cur_arg ? what's cur_arg?
1393
1409
 
1394
- self.lexer.comments # we don't care about comments in the body
1410
+ self.lexer.ignore_body_comments
1395
1411
  }
1396
1412
  | kBREAK
1397
1413
  {
@@ -1428,8 +1444,17 @@ rule
1428
1444
  k_case: kCASE
1429
1445
  k_for: kFOR
1430
1446
  k_class: kCLASS
1447
+ {
1448
+ self.comments.push self.lexer.comments
1449
+ }
1431
1450
  k_module: kMODULE
1451
+ {
1452
+ self.comments.push self.lexer.comments
1453
+ }
1432
1454
  k_def: kDEF
1455
+ {
1456
+ self.comments.push self.lexer.comments
1457
+ }
1433
1458
  k_do: kDO
1434
1459
  k_do_block: kDO_BLOCK
1435
1460
  k_rescue: kRESCUE
@@ -1490,51 +1515,42 @@ rule
1490
1515
 
1491
1516
  result = block_var args
1492
1517
  }
1493
- | f_marg_list tCOMMA tSTAR f_norm_arg
1518
+ | f_marg_list tCOMMA f_rest_marg
1494
1519
  {
1495
- args, _, _, splat = val
1520
+ args, _, rest = val
1496
1521
 
1497
- result = block_var args, "*#{splat}".to_sym
1522
+ result = block_var args, rest
1498
1523
  }
1499
- | f_marg_list tCOMMA tSTAR f_norm_arg tCOMMA f_marg_list
1524
+ | f_marg_list tCOMMA f_rest_marg tCOMMA f_marg_list
1500
1525
  {
1501
- args, _, _, splat, _, args2 = val
1526
+ lhs, _, splat, _, rhs = val
1502
1527
 
1503
- result = block_var args, "*#{splat}".to_sym, args2
1528
+ result = block_var lhs, splat, rhs
1504
1529
  }
1505
- | f_marg_list tCOMMA tSTAR
1530
+ | f_rest_marg
1506
1531
  {
1507
- args, _, _ = val
1532
+ rest, = val
1508
1533
 
1509
- result = block_var args, :*
1534
+ result = block_var rest
1510
1535
  }
1511
- | f_marg_list tCOMMA tSTAR tCOMMA f_marg_list
1536
+ | f_rest_marg tCOMMA f_marg_list
1512
1537
  {
1513
- args, _, _, _, args2 = val
1538
+ splat, _, rest = val
1514
1539
 
1515
- result = block_var args, :*, args2
1540
+ result = block_var splat, rest
1516
1541
  }
1517
- | tSTAR f_norm_arg
1518
- {
1519
- _, splat = val
1520
1542
 
1521
- result = block_var :"*#{splat}"
1522
- }
1523
- | tSTAR f_norm_arg tCOMMA f_marg_list
1543
+ f_rest_marg: tSTAR f_norm_arg
1524
1544
  {
1525
- _, splat, _, args = val
1545
+ _, (id, line) = val
1526
1546
 
1527
- result = block_var :"*#{splat}", args
1547
+ result = args ["*#{id}".to_sym]
1548
+ result.line line
1528
1549
  }
1529
1550
  | tSTAR
1530
1551
  {
1531
- result = block_var :*
1532
- }
1533
- | tSTAR tCOMMA f_marg_list
1534
- {
1535
- _, _, args = val
1536
-
1537
- result = block_var :*, args
1552
+ result = args [:*]
1553
+ result.line lexer.lineno # FIX: tSTAR -> line
1538
1554
  }
1539
1555
 
1540
1556
  block_args_tail: f_block_kwarg tCOMMA f_kwrest opt_f_block_arg
@@ -1551,8 +1567,8 @@ rule
1551
1567
  }
1552
1568
  | f_block_arg
1553
1569
  {
1554
- line = lexer.lineno
1555
- result = call_args val # TODO: push line down
1570
+ (id, line), = val
1571
+ result = call_args [id]
1556
1572
  result.line line
1557
1573
  }
1558
1574
 
@@ -1661,13 +1677,13 @@ opt_block_args_tail: tCOMMA block_args_tail
1661
1677
 
1662
1678
  bvar: tIDENTIFIER
1663
1679
  {
1664
- id, = val
1665
- line = lexer.lineno
1680
+ (id, line), = val
1666
1681
  result = s(:shadow, id.to_sym).line line
1667
1682
  }
1668
1683
  | f_bad_arg
1669
1684
 
1670
- lambda: {
1685
+ lambda: tLAMBDA
1686
+ {
1671
1687
  self.env.extend :dynamic
1672
1688
  result = [lexer.lineno, lexer.lpar_beg]
1673
1689
  lexer.paren_nest += 1
@@ -1679,14 +1695,14 @@ opt_block_args_tail: tCOMMA block_args_tail
1679
1695
  }
1680
1696
  lambda_body
1681
1697
  {
1682
- (line, lpar), args, _cmdarg, body = val
1698
+ _, (line, lpar), args, _cmdarg, body = val
1683
1699
  lexer.lpar_beg = lpar
1684
1700
 
1685
1701
  lexer.cmdarg.pop
1686
1702
 
1687
1703
  call = s(:lambda).line line
1688
1704
  result = new_iter call, args, body
1689
- result.line = line
1705
+ result.line line
1690
1706
  self.env.unextend # TODO: dynapush & dynapop
1691
1707
  }
1692
1708
 
@@ -1721,23 +1737,28 @@ opt_block_args_tail: tCOMMA block_args_tail
1721
1737
  ## if (nd_type($1) == NODE_YIELD) {
1722
1738
  ## compile_error(PARSER_ARG "block given to yield");
1723
1739
 
1724
- syntax_error "Both block arg and actual block given." if
1725
- val[0].block_pass?
1740
+ cmd, blk = val
1726
1741
 
1727
- val = invert_block_call val if inverted? val
1742
+ syntax_error "Both block arg and actual block given." if
1743
+ cmd.block_pass?
1728
1744
 
1729
- cmd, blk = val
1745
+ if inverted? val then
1746
+ val = invert_block_call val
1747
+ cmd, blk = val
1748
+ end
1730
1749
 
1731
1750
  result = blk
1732
1751
  result.insert 1, cmd
1733
1752
  }
1734
1753
  | block_call call_op2 operation2 opt_paren_args
1735
1754
  {
1736
- result = new_call val[0], val[2].to_sym, val[3]
1755
+ lhs, _, (id, _line), args = val
1756
+
1757
+ result = new_call lhs, id.to_sym, args
1737
1758
  }
1738
1759
  | block_call call_op2 operation2 opt_paren_args brace_block
1739
1760
  {
1740
- iter1, _, name, args, iter2 = val
1761
+ iter1, _, (name, _line), args, iter2 = val
1741
1762
 
1742
1763
  call = new_call iter1, name.to_sym, args
1743
1764
  iter2.insert 1, call
@@ -1746,7 +1767,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1746
1767
  }
1747
1768
  | block_call call_op2 operation2 command_args do_block
1748
1769
  {
1749
- iter1, _, name, args, iter2 = val
1770
+ iter1, _, (name, _line), args, iter2 = val
1750
1771
 
1751
1772
  call = new_call iter1, name.to_sym, args
1752
1773
  iter2.insert 1, call
@@ -1754,28 +1775,29 @@ opt_block_args_tail: tCOMMA block_args_tail
1754
1775
  result = iter2
1755
1776
  }
1756
1777
 
1757
- method_call: fcall
1778
+ method_call: fcall paren_args
1758
1779
  {
1759
- result = self.lexer.lineno
1760
- }
1761
- paren_args
1762
- {
1763
- call, lineno, args = val
1780
+ call, args = val
1764
1781
 
1765
1782
  result = call.concat args.sexp_body if args
1766
- result.line lineno
1767
1783
  }
1768
1784
  | primary_value call_op operation2 opt_paren_args
1769
1785
  {
1770
- result = new_call val[0], val[2].to_sym, val[3], val[1]
1786
+ recv, call_op, (op, _line), args = val
1787
+
1788
+ result = new_call recv, op.to_sym, args, call_op
1771
1789
  }
1772
1790
  | primary_value tCOLON2 operation2 paren_args
1773
1791
  {
1774
- result = new_call val[0], val[2].to_sym, val[3]
1792
+ recv, _, (op, _line), args = val
1793
+
1794
+ result = new_call recv, op.to_sym, args
1775
1795
  }
1776
1796
  | primary_value tCOLON2 operation3
1777
1797
  {
1778
- result = new_call val[0], val[2].to_sym
1798
+ lhs, _, (id, _line) = val
1799
+
1800
+ result = new_call lhs, id.to_sym
1779
1801
  }
1780
1802
  | primary_value call_op paren_args
1781
1803
  {
@@ -1808,7 +1830,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1808
1830
  _, line, body, _ = val
1809
1831
 
1810
1832
  result = body
1811
- result.line = line
1833
+ result.line line
1812
1834
 
1813
1835
  self.env.unextend
1814
1836
  }
@@ -1822,7 +1844,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1822
1844
  _, line, body, _ = val
1823
1845
 
1824
1846
  result = body
1825
- result.line = line
1847
+ result.line line
1826
1848
 
1827
1849
  self.env.unextend
1828
1850
  }
@@ -1851,14 +1873,39 @@ opt_block_args_tail: tCOMMA block_args_tail
1851
1873
  self.env.unextend
1852
1874
  }
1853
1875
 
1876
+ case_args: arg_value
1877
+ {
1878
+ arg, = val
1879
+
1880
+ result = s(:array, arg).line arg.line
1881
+ }
1882
+ | tSTAR arg_value
1883
+ {
1884
+ _, arg = val
1885
+
1886
+ result = s(:array, s(:splat, arg).line(arg.line)).line arg.line
1887
+ }
1888
+ | case_args tCOMMA arg_value
1889
+ {
1890
+ args, _, id = val
1891
+
1892
+ result = self.list_append args, id
1893
+ }
1894
+ | case_args tCOMMA tSTAR arg_value
1895
+ {
1896
+ args, _, _, id = val
1897
+
1898
+ result = self.list_append args, s(:splat, id).line(id.line)
1899
+ }
1900
+
1854
1901
  case_body: k_when
1855
1902
  {
1856
1903
  result = self.lexer.lineno
1857
1904
  }
1858
- args then compstmt cases
1905
+ case_args then compstmt cases
1859
1906
  {
1860
1907
  result = new_when(val[2], val[4])
1861
- result.line = val[1]
1908
+ result.line val[1]
1862
1909
  result << val[5] if val[5]
1863
1910
  }
1864
1911
 
@@ -1904,17 +1951,10 @@ opt_block_args_tail: tCOMMA block_args_tail
1904
1951
 
1905
1952
  literal: numeric
1906
1953
  {
1907
- line = lexer.lineno
1908
- result = s(:lit, val[0])
1909
- result.line = line
1954
+ (lit, line), = val
1955
+ result = s(:lit, lit).line line
1910
1956
  }
1911
1957
  | symbol
1912
- {
1913
- line = lexer.lineno
1914
- result = s(:lit, val[0])
1915
- result.line = line
1916
- }
1917
- | dsym
1918
1958
 
1919
1959
  strings: string
1920
1960
  {
@@ -1925,7 +1965,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1925
1965
 
1926
1966
  string: tCHAR
1927
1967
  {
1928
- debug20 23, val, result
1968
+ debug 37
1929
1969
  }
1930
1970
  | string1
1931
1971
  | string string1
@@ -1935,11 +1975,11 @@ opt_block_args_tail: tCOMMA block_args_tail
1935
1975
 
1936
1976
  string1: tSTRING_BEG string_contents tSTRING_END
1937
1977
  {
1938
- _, str, (_, func) = val
1978
+ (_, line), str, (_, func) = val
1939
1979
 
1940
- str = dedent str if func =~ RubyLexer::STR_FUNC_ICNTNT
1980
+ str = dedent str if func =~ RubyLexer::STR_FUNC_DEDENT
1941
1981
 
1942
- result = str
1982
+ result = str.line line
1943
1983
  }
1944
1984
  | tSTRING
1945
1985
  {
@@ -1959,11 +1999,15 @@ opt_block_args_tail: tCOMMA block_args_tail
1959
1999
 
1960
2000
  words: tWORDS_BEG tSPACE tSTRING_END
1961
2001
  {
1962
- result = s(:array).line lexer.lineno
2002
+ (_, line), _, _ = val
2003
+
2004
+ result = s(:array).line line
1963
2005
  }
1964
2006
  | tWORDS_BEG word_list tSTRING_END
1965
2007
  {
1966
- result = val[1]
2008
+ (_, line), list, _ = val
2009
+
2010
+ result = list.line line
1967
2011
  }
1968
2012
 
1969
2013
  word_list: none
@@ -1983,18 +2027,20 @@ opt_block_args_tail: tCOMMA block_args_tail
1983
2027
 
1984
2028
  symbols: tSYMBOLS_BEG tSPACE tSTRING_END
1985
2029
  {
1986
- result = s(:array).line lexer.lineno
2030
+ (_, line), _, _ = val
2031
+
2032
+ result = s(:array).line line
1987
2033
  }
1988
- | tSYMBOLS_BEG { result = lexer.lineno } symbol_list tSTRING_END
2034
+ | tSYMBOLS_BEG symbol_list tSTRING_END
1989
2035
  {
1990
- _, line, list, _, = val
1991
- list.line = line
2036
+ (_, line), list, _, = val
2037
+ list.line line
1992
2038
  result = list
1993
2039
  }
1994
2040
 
1995
2041
  symbol_list: none
1996
2042
  {
1997
- result = new_symbol_list.line lexer.lineno
2043
+ result = new_symbol_list
1998
2044
  }
1999
2045
  | symbol_list word tSPACE
2000
2046
  {
@@ -2004,20 +2050,28 @@ opt_block_args_tail: tCOMMA block_args_tail
2004
2050
 
2005
2051
  qwords: tQWORDS_BEG tSPACE tSTRING_END
2006
2052
  {
2007
- result = s(:array).line lexer.lineno
2053
+ (_, line), _, _ = val
2054
+
2055
+ result = s(:array).line line
2008
2056
  }
2009
2057
  | tQWORDS_BEG qword_list tSTRING_END
2010
2058
  {
2011
- result = val[1]
2059
+ (_, line), list, _ = val
2060
+
2061
+ result = list.line line
2012
2062
  }
2013
2063
 
2014
2064
  qsymbols: tQSYMBOLS_BEG tSPACE tSTRING_END
2015
2065
  {
2016
- result = s(:array).line lexer.lineno # FIX
2066
+ (_, line), _, _ = val
2067
+
2068
+ result = s(:array).line line
2017
2069
  }
2018
2070
  | tQSYMBOLS_BEG qsym_list tSTRING_END
2019
2071
  {
2020
- result = val[1]
2072
+ (_, line), list, _ = val
2073
+
2074
+ result = list.line line
2021
2075
  }
2022
2076
 
2023
2077
  qword_list: none
@@ -2040,7 +2094,8 @@ opt_block_args_tail: tCOMMA block_args_tail
2040
2094
 
2041
2095
  string_contents: none
2042
2096
  {
2043
- result = s(:str, "").line lexer.lineno
2097
+ line = prev_value_to_lineno _values.last
2098
+ result = s(:str, +"").line line
2044
2099
  }
2045
2100
  | string_contents string_content
2046
2101
  {
@@ -2115,8 +2170,8 @@ regexp_contents: none
2115
2170
  lexer.brace_nest = brace_nest
2116
2171
  lexer.string_nest = string_nest
2117
2172
 
2118
- lexer.cmdarg.pop
2119
2173
  lexer.cond.pop
2174
+ lexer.cmdarg.pop
2120
2175
 
2121
2176
  lexer.lex_state = oldlex_state
2122
2177
 
@@ -2131,29 +2186,49 @@ regexp_contents: none
2131
2186
  when nil then
2132
2187
  result = s(:evstr).line line
2133
2188
  else
2134
- debug20 25
2189
+ debug 38
2135
2190
  raise "unknown string body: #{stmt.inspect}"
2136
2191
  end
2137
2192
  }
2138
2193
 
2139
- string_dvar: tGVAR { result = s(:gvar, val[0].to_sym).line lexer.lineno }
2140
- | tIVAR { result = s(:ivar, val[0].to_sym).line lexer.lineno }
2141
- | tCVAR { result = s(:cvar, val[0].to_sym).line lexer.lineno }
2194
+ string_dvar: tGVAR
2195
+ {
2196
+ (id, line), = val
2197
+ result = s(:gvar, id.to_sym).line line
2198
+ }
2199
+ | tIVAR
2200
+ {
2201
+ (id, line), = val
2202
+ result = s(:ivar, id.to_sym).line line
2203
+ }
2204
+ | tCVAR
2205
+ {
2206
+ (id, line), = val
2207
+ result = s(:cvar, id.to_sym).line line
2208
+ }
2142
2209
  | backref
2143
2210
 
2144
- symbol: tSYMBEG sym
2211
+ symbol: ssym
2212
+ | dsym
2213
+
2214
+ ssym: tSYMBEG sym
2145
2215
  {
2216
+ _, (id, line) = val
2217
+
2146
2218
  lexer.lex_state = EXPR_END
2147
- result = val[1].to_sym
2219
+ result = s(:lit, id.to_sym).line line
2148
2220
  }
2149
2221
  | tSYMBOL
2150
2222
  {
2151
- result = val[0].to_sym
2223
+ (id, line), = val
2224
+
2225
+ lexer.lex_state = EXPR_END
2226
+ result = s(:lit, id.to_sym).line line
2152
2227
  }
2153
2228
 
2154
2229
  sym: fname | tIVAR | tGVAR | tCVAR
2155
2230
 
2156
- dsym: tSYMBEG xstring_contents tSTRING_END
2231
+ dsym: tSYMBEG string_contents tSTRING_END
2157
2232
  {
2158
2233
  _, result, _ = val
2159
2234
 
@@ -2169,14 +2244,15 @@ regexp_contents: none
2169
2244
  when :evstr then
2170
2245
  result = s(:dsym, "", result).line result.line
2171
2246
  else
2172
- debug20 26, val, result
2247
+ debug 39
2173
2248
  end
2174
2249
  }
2175
2250
 
2176
2251
  numeric: simple_numeric
2177
- | tUMINUS_NUM simple_numeric
2252
+ | tUMINUS_NUM simple_numeric =tLOWEST
2178
2253
  {
2179
- result = -val[1] # TODO: pt_testcase
2254
+ _, (num, line) = val
2255
+ result = [-num, line]
2180
2256
  }
2181
2257
 
2182
2258
  simple_numeric: tINTEGER
@@ -2209,8 +2285,10 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2209
2285
 
2210
2286
  var_ref: user_variable
2211
2287
  {
2212
- var = val[0]
2288
+ raise "NO: #{val.inspect}" if Sexp === val.first
2289
+ (var, line), = val
2213
2290
  result = Sexp === var ? var : self.gettable(var)
2291
+ result.line line
2214
2292
  }
2215
2293
  | keyword_variable
2216
2294
  {
@@ -2225,11 +2303,19 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2225
2303
  | keyword_variable
2226
2304
  {
2227
2305
  result = self.assignable val[0]
2228
- debug20 29, val, result
2306
+ debug 40
2229
2307
  }
2230
2308
 
2231
- backref: tNTH_REF { result = s(:nth_ref, val[0]).line lexer.lineno }
2232
- | tBACK_REF { result = s(:back_ref, val[0]).line lexer.lineno }
2309
+ backref: tNTH_REF
2310
+ {
2311
+ (ref, line), = val
2312
+ result = s(:nth_ref, ref).line line
2313
+ }
2314
+ | tBACK_REF
2315
+ {
2316
+ (ref, line), = val
2317
+ result = s(:back_ref, ref).line line
2318
+ }
2233
2319
 
2234
2320
  superclass: tLT
2235
2321
  {
@@ -2247,9 +2333,7 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2247
2333
 
2248
2334
  f_arglist: tLPAREN2 f_args rparen
2249
2335
  {
2250
- result = val[1]
2251
- self.lexer.lex_state = EXPR_BEG
2252
- self.lexer.command_start = true
2336
+ result = end_args val
2253
2337
  }
2254
2338
  | {
2255
2339
  result = self.in_kwarg
@@ -2258,12 +2342,7 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2258
2342
  }
2259
2343
  f_args term
2260
2344
  {
2261
- kwarg, args, _ = val
2262
-
2263
- self.in_kwarg = kwarg
2264
- result = args
2265
- lexer.lex_state = EXPR_BEG
2266
- lexer.command_start = true
2345
+ result = end_args val
2267
2346
  }
2268
2347
 
2269
2348
  args_tail: f_kwarg tCOMMA f_kwrest opt_f_block_arg
@@ -2348,9 +2427,9 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2348
2427
  |
2349
2428
  {
2350
2429
  result = args val
2430
+ # result.line lexer.lineno
2351
2431
  }
2352
2432
 
2353
- args_forward: tBDOT3
2354
2433
 
2355
2434
  f_bad_arg: tCONSTANT
2356
2435
  {
@@ -2372,10 +2451,11 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2372
2451
  f_norm_arg: f_bad_arg
2373
2452
  | tIDENTIFIER
2374
2453
  {
2375
- identifier = val[0].to_sym
2454
+ (id, line), = val
2455
+ identifier = id.to_sym
2376
2456
  self.env[identifier] = :lvar
2377
2457
 
2378
- result = identifier
2458
+ result = [identifier, line]
2379
2459
  }
2380
2460
 
2381
2461
  f_arg_asgn: f_norm_arg
@@ -2383,22 +2463,14 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2383
2463
  f_arg_item: f_arg_asgn
2384
2464
  | tLPAREN f_margs rparen
2385
2465
  {
2386
- result = val[1]
2466
+ _, margs, _ = val
2467
+
2468
+ result = margs
2387
2469
  }
2388
2470
 
2389
2471
  f_arg: f_arg_item
2390
2472
  {
2391
- arg, = val
2392
-
2393
- case arg
2394
- when Symbol then
2395
- result = s(:args, arg).line lexer.lineno
2396
- when Sexp then
2397
- result = arg
2398
- else
2399
- debug20 32
2400
- raise "Unknown f_arg type: #{val.inspect}"
2401
- end
2473
+ result = new_arg val
2402
2474
  }
2403
2475
  | f_arg tCOMMA f_arg_item
2404
2476
  {
@@ -2410,7 +2482,7 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2410
2482
  result = s(:args, list).line list.line
2411
2483
  end
2412
2484
 
2413
- result << item
2485
+ result << (Sexp === item ? item : item.first)
2414
2486
  }
2415
2487
 
2416
2488
  f_label: tLABEL
@@ -2471,27 +2543,33 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2471
2543
  kwrest_mark: tPOW
2472
2544
  | tDSTAR
2473
2545
 
2546
+
2474
2547
  f_kwrest: kwrest_mark tIDENTIFIER
2475
2548
  {
2476
- name = val[1].to_sym
2477
- self.assignable name
2478
- result = :"**#{name}"
2549
+ _, (id, line) = val
2550
+
2551
+ name = id.to_sym
2552
+ self.assignable [name, line]
2553
+ result = [:"**#{name}", line]
2479
2554
  }
2480
2555
  | kwrest_mark
2481
2556
  {
2482
- result = :"**"
2483
- self.env[result] = :lvar
2557
+ id = :"**"
2558
+ self.env[id] = :lvar # TODO: needed?!?
2559
+ result = [id, lexer.lineno] # TODO: tPOW/tDSTAR include lineno
2484
2560
  }
2485
2561
 
2486
2562
  f_opt: f_arg_asgn tEQL arg_value
2487
2563
  {
2488
- result = self.assignable val[0], val[2]
2564
+ lhs, _, rhs = val
2565
+ result = self.assignable lhs, rhs
2489
2566
  # TODO: detect duplicate names
2490
2567
  }
2491
2568
 
2492
2569
  f_block_opt: f_arg_asgn tEQL primary_value
2493
2570
  {
2494
- result = self.assignable val[0], val[2]
2571
+ lhs, _, rhs = val
2572
+ result = self.assignable lhs, rhs
2495
2573
  }
2496
2574
 
2497
2575
  f_block_optarg: f_block_opt
@@ -2521,30 +2599,33 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2521
2599
  f_rest_arg: restarg_mark tIDENTIFIER
2522
2600
  {
2523
2601
  # TODO: differs from parse.y - needs tests
2524
- name = val[1].to_sym
2525
- self.assignable name
2526
- result = :"*#{name}"
2602
+ _, (id, line) = val
2603
+ name = id.to_sym
2604
+ self.assignable [name, line]
2605
+ result = [:"*#{name}", line]
2527
2606
  }
2528
2607
  | restarg_mark
2529
2608
  {
2530
2609
  name = :"*"
2531
2610
  self.env[name] = :lvar
2532
- result = name
2611
+ result = [name, lexer.lineno] # FIX: tSTAR to include lineno
2533
2612
  }
2534
2613
 
2535
2614
  blkarg_mark: tAMPER2 | tAMPER
2536
2615
 
2537
2616
  f_block_arg: blkarg_mark tIDENTIFIER
2538
2617
  {
2539
- identifier = val[1].to_sym
2618
+ _, (id, line) = val
2619
+ identifier = id.to_sym
2540
2620
 
2541
2621
  self.env[identifier] = :lvar
2542
- result = "&#{identifier}".to_sym
2622
+ result = ["&#{identifier}".to_sym, line]
2543
2623
  }
2544
2624
 
2545
2625
  opt_f_block_arg: tCOMMA f_block_arg
2546
2626
  {
2547
- result = val[1]
2627
+ _, arg = val
2628
+ result = arg
2548
2629
  }
2549
2630
  |
2550
2631
  {
@@ -2593,9 +2674,11 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2593
2674
  }
2594
2675
  | tSTRING_BEG string_contents tLABEL_END arg_value
2595
2676
  {
2596
- _, sym, _, value = val
2677
+ (_, line), sym, _, value = val
2678
+
2597
2679
  sym.sexp_type = :dsym
2598
- result = s(:array, sym, value).line sym.line
2680
+
2681
+ result = s(:array, sym, value).line line
2599
2682
  }
2600
2683
  | tDSTAR arg_value
2601
2684
  {