ruby_parser 3.15.0 → 3.19.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/History.rdoc +151 -0
  4. data/Manifest.txt +7 -0
  5. data/README.rdoc +9 -6
  6. data/Rakefile +141 -31
  7. data/bin/ruby_parse_extract_error +1 -1
  8. data/compare/normalize.rb +8 -3
  9. data/debugging.md +133 -0
  10. data/gauntlet.md +107 -0
  11. data/lib/rp_extensions.rb +15 -36
  12. data/lib/rp_stringscanner.rb +20 -51
  13. data/lib/ruby20_parser.rb +7544 -3633
  14. data/lib/ruby20_parser.y +335 -257
  15. data/lib/ruby21_parser.rb +7518 -3678
  16. data/lib/ruby21_parser.y +330 -254
  17. data/lib/ruby22_parser.rb +7652 -3689
  18. data/lib/ruby22_parser.y +334 -256
  19. data/lib/ruby23_parser.rb +7659 -3702
  20. data/lib/ruby23_parser.y +334 -256
  21. data/lib/ruby24_parser.rb +7748 -3721
  22. data/lib/ruby24_parser.y +334 -256
  23. data/lib/ruby25_parser.rb +7748 -3721
  24. data/lib/ruby25_parser.y +334 -256
  25. data/lib/ruby26_parser.rb +7755 -3726
  26. data/lib/ruby26_parser.y +334 -255
  27. data/lib/ruby27_parser.rb +10290 -4518
  28. data/lib/ruby27_parser.y +933 -254
  29. data/lib/ruby30_parser.rb +13258 -0
  30. data/lib/ruby30_parser.y +3459 -0
  31. data/lib/ruby31_parser.rb +13638 -0
  32. data/lib/ruby31_parser.y +3493 -0
  33. data/lib/ruby3_parser.yy +3548 -0
  34. data/lib/ruby_lexer.rb +277 -599
  35. data/lib/ruby_lexer.rex +28 -21
  36. data/lib/ruby_lexer.rex.rb +60 -24
  37. data/lib/ruby_lexer_strings.rb +638 -0
  38. data/lib/ruby_parser.rb +4 -0
  39. data/lib/ruby_parser.yy +974 -261
  40. data/lib/ruby_parser_extras.rb +355 -114
  41. data/test/test_ruby_lexer.rb +226 -129
  42. data/test/test_ruby_parser.rb +1653 -267
  43. data/tools/munge.rb +36 -8
  44. data/tools/ripper.rb +15 -10
  45. data.tar.gz.sig +0 -0
  46. metadata +55 -37
  47. metadata.gz.sig +0 -0
@@ -1,5 +1,6 @@
1
1
  # encoding: ASCII-8BIT
2
- # TODO: remove
2
+ # frozen_string_literal: true
3
+ # TODO: remove encoding comment
3
4
 
4
5
  require "sexp"
5
6
  require "ruby_lexer"
@@ -29,7 +30,7 @@ class Sexp
29
30
  end
30
31
 
31
32
  module RubyParserStuff
32
- VERSION = "3.15.0"
33
+ VERSION = "3.19.2"
33
34
 
34
35
  attr_accessor :lexer, :in_def, :in_single, :file
35
36
  attr_accessor :in_kwarg
@@ -115,7 +116,7 @@ module RubyParserStuff
115
116
  def initialize(options = {})
116
117
  super()
117
118
 
118
- v = self.class.name[/2\d/]
119
+ v = self.class.name[/[23]\d/]
119
120
  raise "Bad Class name #{self.class}" unless v
120
121
 
121
122
  self.lexer = RubyLexer.new v && v.to_i
@@ -155,11 +156,31 @@ module RubyParserStuff
155
156
  end
156
157
 
157
158
  args.each do |arg|
159
+ if arg.instance_of? Array and arg.size == 2 and arg.last.is_a? Numeric then
160
+ arg = arg.first
161
+ end
162
+
158
163
  case arg
159
164
  when Sexp then
160
165
  case arg.sexp_type
161
166
  when :args, :block, :array, :call_args then # HACK call_args mismatch
162
- result.concat arg.sexp_body
167
+ rest = arg.sexp_body
168
+
169
+ rest.map! { |x|
170
+ if x.instance_of? Array and x.size == 2 and Numeric === x.last then
171
+ x.first
172
+ else
173
+ x
174
+ end
175
+ }
176
+
177
+ result.concat rest
178
+ when :forward_args then
179
+ self.env[:*] = :lvar # TODO: arg_var(p, idFWD_REST) ?
180
+ self.env[:**] = :lvar
181
+ self.env[:&] = :lvar
182
+
183
+ result << arg
163
184
  when :block_arg then
164
185
  result << :"&#{arg.last}"
165
186
  when :shadow then
@@ -179,6 +200,8 @@ module RubyParserStuff
179
200
  name = arg.to_s.delete("&*")
180
201
  self.env[name.to_sym] = :lvar unless name.empty?
181
202
  result << arg
203
+ when true, false then
204
+ self.in_kwarg = arg
182
205
  when ",", "|", ";", "(", ")", nil then
183
206
  # ignore
184
207
  else
@@ -189,6 +212,27 @@ module RubyParserStuff
189
212
  result
190
213
  end
191
214
 
215
+ def end_args args
216
+ lexer.lex_state = RubyLexer::State::Values::EXPR_BEG
217
+ lexer.command_start = true
218
+ self.args args
219
+ end
220
+
221
+ def attrset_id? id
222
+ id =~ /^\[\]=$|^\w+=$/
223
+ end
224
+
225
+ def endless_method_name defn_or_defs
226
+ name = defn_or_defs[1]
227
+ name = defn_or_defs[2] unless Symbol === name
228
+
229
+ if attrset_id? name then
230
+ yyerror "setter method cannot be defined in an endless method definition"
231
+ end
232
+
233
+ # TODO? token_info_drop(p, "def", loc->beg_pos);
234
+ end
235
+
192
236
  def array_to_hash array
193
237
  case array.sexp_type
194
238
  when :kwsplat then
@@ -208,17 +252,10 @@ module RubyParserStuff
208
252
  end
209
253
 
210
254
  def assignable(lhs, value = nil)
211
- id = lhs.to_sym unless Sexp === lhs
212
-
213
- raise "WTF" if Sexp === id
214
- id = id.to_sym if Sexp === id
215
-
216
- raise "write a test 1" if id.to_s =~ /^(?:self|nil|true|false|__LINE__|__FILE__)$/
255
+ id, line = lhs
256
+ id = id.to_sym
217
257
 
218
- raise SyntaxError, "Can't change the value of #{id}" if
219
- id.to_s =~ /^(?:self|nil|true|false|__LINE__|__FILE__)$/
220
-
221
- result = case id.to_s
258
+ result = case id
222
259
  when /^@@/ then
223
260
  asgn = in_def || in_single > 0
224
261
  s((asgn ? :cvasgn : :cvdecl), id)
@@ -239,17 +276,9 @@ module RubyParserStuff
239
276
 
240
277
  self.env[id] ||= :lvar if result.sexp_type == :lasgn
241
278
 
242
- line = case lhs
243
- when Sexp then
244
- lhs.line
245
- else
246
- value && value.line || lexer.lineno
247
- end
248
-
249
279
  result << value if value
250
- result.line = line
251
-
252
- return result
280
+ result.line line
281
+ result
253
282
  end
254
283
 
255
284
  def backref_assign_error ref
@@ -273,9 +302,9 @@ module RubyParserStuff
273
302
  line = [head.line, tail.line].compact.min
274
303
 
275
304
  head = remove_begin(head)
276
- head = s(:block, head) unless head.node_type == :block
305
+ head = s(:block, head).line(line) unless head.sexp_type == :block
277
306
 
278
- head.line = line
307
+ # head.line = line
279
308
  head << tail
280
309
  end
281
310
 
@@ -301,6 +330,10 @@ module RubyParserStuff
301
330
  end
302
331
 
303
332
  args.each do |arg|
333
+ if arg.instance_of? Array and arg.size == 2 and arg.last.is_a? Numeric then
334
+ arg = arg.first
335
+ end
336
+
304
337
  case arg
305
338
  when Sexp then
306
339
  case arg.sexp_type
@@ -311,7 +344,10 @@ module RubyParserStuff
311
344
  end
312
345
  when Symbol then
313
346
  result << arg
314
- when ",", nil then
347
+ when Array then
348
+ id, _line = arg
349
+ result << id
350
+ when ",", nil, "(" then
315
351
  # ignore
316
352
  else
317
353
  raise "unhandled: #{arg.inspect} in #{args.inspect}"
@@ -435,7 +471,7 @@ module RubyParserStuff
435
471
  end
436
472
  else
437
473
  warn "unprocessed: %p" % [s]
438
- end.map { |l| whitespace_width l[/^[ \t]*/] }
474
+ end.map { |l| whitespace_width l }
439
475
  }.compact.min
440
476
  end
441
477
 
@@ -459,7 +495,6 @@ module RubyParserStuff
459
495
  end
460
496
 
461
497
  def gettable(id)
462
- lineno = id.lineno if id.respond_to? :lineno
463
498
  id = id.to_sym if String === id
464
499
 
465
500
  result = case id.to_s
@@ -480,8 +515,6 @@ module RubyParserStuff
480
515
  end
481
516
  end
482
517
 
483
- result.line lineno if lineno
484
-
485
518
  raise "identifier #{id.inspect} is not valid" unless result
486
519
 
487
520
  result
@@ -540,7 +573,7 @@ module RubyParserStuff
540
573
  header.map! { |s| s.force_encoding "ASCII-8BIT" } if has_enc
541
574
 
542
575
  first = header.first || ""
543
- encoding, str = "utf-8", str.b[3..-1] if first =~ /\A\xEF\xBB\xBF/
576
+ encoding, str = +"utf-8", str.b[3..-1] if first =~ /\A\xEF\xBB\xBF/
544
577
 
545
578
  encoding = $1.strip if header.find { |s|
546
579
  s[/^#.*?-\*-.*?coding:\s*([^ ;]+).*?-\*-/, 1] ||
@@ -624,7 +657,7 @@ module RubyParserStuff
624
657
  when :evstr then
625
658
  if htype == :str then
626
659
  f, l = head.file, head.line
627
- head = s(:dstr, *head.sexp_body).line head.line
660
+ head = s(:dstr, *head.sexp_body)
628
661
  head.file = f
629
662
  head.line = l
630
663
  end
@@ -643,6 +676,13 @@ module RubyParserStuff
643
676
  return head
644
677
  end
645
678
 
679
+ def local_pop in_def
680
+ lexer.cond.pop # group = local_pop
681
+ lexer.cmdarg.pop
682
+ self.env.unextend
683
+ self.in_def = in_def
684
+ end
685
+
646
686
  def logical_op type, left, right
647
687
  left = value_expr left
648
688
 
@@ -672,6 +712,80 @@ module RubyParserStuff
672
712
  new_call val[0], :"[]", val[2]
673
713
  end
674
714
 
715
+ def new_arg val
716
+ arg, = val
717
+
718
+ case arg
719
+ when Symbol then
720
+ result = s(:args, arg).line line
721
+ when Sexp then
722
+ result = arg
723
+ when Array then
724
+ (arg, line), = val
725
+ result = s(:args, arg).line line
726
+ else
727
+ debug20 32
728
+ raise "Unknown f_arg type: #{val.inspect}"
729
+ end
730
+
731
+ result
732
+ end
733
+
734
+ def ary_to_pat ary
735
+ pat = ary.dup
736
+ pat.sexp_type = :array_TAIL
737
+
738
+ new_array_pattern nil, nil, pat, ary.line
739
+ end
740
+
741
+ def new_array_pattern const, pre_arg, arypat, loc
742
+ result = s(:array_pat, const).line loc
743
+ result << pre_arg if pre_arg
744
+
745
+ if arypat && arypat.sexp_type == :array_TAIL then
746
+ result.concat arypat.sexp_body
747
+ else
748
+ raise "NO?: %p" % [arypat]
749
+ end
750
+
751
+ result
752
+ end
753
+
754
+ def array_pat_concat lhs, rhs
755
+ case lhs.sexp_type
756
+ when :PATTERN then
757
+ lhs.sexp_type = :array_pat
758
+ end
759
+
760
+ if rhs then
761
+ case rhs.sexp_type
762
+ when :array_pat, :array_TAIL, :PATTERN then
763
+ lhs.concat rhs.sexp_body
764
+ else
765
+ lhs << rhs
766
+ end
767
+ end
768
+ end
769
+
770
+ def new_array_pattern_tail pre_args, has_rest, rest_arg, post_args
771
+ # TODO: remove has_rest once all tests pass !!!
772
+ rest_arg = if has_rest then
773
+ :"*#{rest_arg}"
774
+ else
775
+ nil
776
+ end
777
+
778
+ result = s(:array_TAIL).line 666
779
+
780
+ array_pat_concat result, pre_args
781
+
782
+ result << rest_arg if rest_arg
783
+
784
+ array_pat_concat result, post_args
785
+
786
+ result
787
+ end
788
+
675
789
  def new_assign lhs, rhs
676
790
  return nil unless lhs
677
791
 
@@ -691,6 +805,8 @@ module RubyParserStuff
691
805
  end
692
806
 
693
807
  def new_attrasgn recv, meth, call_op = :"."
808
+ call_op = call_op.first if Array === call_op
809
+
694
810
  meth = :"#{meth}="
695
811
 
696
812
  result = case call_op.to_sym
@@ -755,6 +871,8 @@ module RubyParserStuff
755
871
  end
756
872
 
757
873
  def new_call recv, meth, args = nil, call_op = :"."
874
+ call_op = call_op.first if Array === call_op
875
+
758
876
  result = case call_op.to_sym
759
877
  when :"."
760
878
  s(:call, recv, meth)
@@ -782,10 +900,14 @@ module RubyParserStuff
782
900
  result
783
901
  end
784
902
 
903
+ def new_in pat, body, cases, line
904
+ s(:in, pat, body, cases).line line
905
+ end
906
+
785
907
  def new_case expr, body, line
786
908
  result = s(:case, expr)
787
909
 
788
- while body and body.node_type == :when
910
+ while body and [:when, :in].include? body.sexp_type
789
911
  result << body
790
912
  body = body.delete_at 3
791
913
  end
@@ -804,8 +926,11 @@ module RubyParserStuff
804
926
  end
805
927
 
806
928
  def new_class val
929
+ # TODO: get line from class keyword
807
930
  line, path, superclass, body = val[1], val[2], val[3], val[5]
808
931
 
932
+ path = path.first if path.instance_of? Array
933
+
809
934
  result = s(:class, path, superclass)
810
935
 
811
936
  if body then
@@ -828,7 +953,8 @@ module RubyParserStuff
828
953
  end
829
954
 
830
955
  def new_const_op_asgn val
831
- lhs, asgn_op, rhs = val[0], val[1].to_sym, val[2]
956
+ lhs, (asgn_op, _), rhs = val
957
+ asgn_op = asgn_op.to_sym
832
958
 
833
959
  result = case asgn_op
834
960
  when :"||" then
@@ -844,20 +970,62 @@ module RubyParserStuff
844
970
  end
845
971
 
846
972
  def new_defn val
847
- (_, line), name, _, args, body, nil_body_line, * = val
848
- body ||= s(:nil).line nil_body_line
973
+ _, (name, line), in_def, args, body, _ = val
974
+
975
+ body ||= s(:nil).line line
849
976
 
850
977
  args.line line
851
978
 
852
979
  result = s(:defn, name.to_sym, args).line line
853
980
 
854
- if body then
855
- if body.sexp_type == :block then
856
- result.push(*body.sexp_body)
981
+ if body.sexp_type == :block then
982
+ result.push(*body.sexp_body)
983
+ else
984
+ result.push body
985
+ end
986
+
987
+ result.comments = self.comments.pop
988
+
989
+ [result, in_def]
990
+ end
991
+
992
+ def new_endless_defn val
993
+ (name, line, in_def), args, _, body, _, resbody = val
994
+
995
+ result =
996
+ if resbody then
997
+ s(:defn, name, args,
998
+ new_rescue(body,
999
+ new_resbody(s(:array).line(line),
1000
+ resbody))).line line
857
1001
  else
858
- result.push body
1002
+ s(:defn, name, args, body).line line
859
1003
  end
860
- end
1004
+
1005
+ local_pop in_def
1006
+ endless_method_name result
1007
+
1008
+ result.comments = self.comments.pop
1009
+
1010
+ result
1011
+ end
1012
+
1013
+ def new_endless_defs val
1014
+ (recv, (name, line, in_def)), args, _, body, _, resbody = val
1015
+
1016
+ result =
1017
+ if resbody then
1018
+ s(:defs, recv, name, args,
1019
+ new_rescue(body,
1020
+ new_resbody(s(:array).line(line),
1021
+ resbody))).line line
1022
+ else
1023
+ s(:defs, recv, name, args, body).line(line)
1024
+ end
1025
+
1026
+ self.in_single -= 1
1027
+ local_pop in_def
1028
+ endless_method_name result
861
1029
 
862
1030
  result.comments = self.comments.pop
863
1031
 
@@ -865,34 +1033,51 @@ module RubyParserStuff
865
1033
  end
866
1034
 
867
1035
  def new_defs val
868
- _, recv, _, _, name, (_in_def, line), args, body, _ = val
1036
+ _, recv, (name, line), in_def, args, body, _ = val
869
1037
 
870
1038
  body ||= s(:nil).line line
871
1039
 
872
1040
  args.line line
873
1041
 
874
- result = s(:defs, recv, name.to_sym, args)
1042
+ result = s(:defs, recv, name.to_sym, args).line line
875
1043
 
876
1044
  # TODO: remove_begin
877
1045
  # TODO: reduce_nodes
878
1046
 
879
- if body then
880
- if body.sexp_type == :block then
881
- result.push(*body.sexp_body)
882
- else
883
- result.push body
884
- end
1047
+ if body.sexp_type == :block then
1048
+ result.push(*body.sexp_body)
1049
+ else
1050
+ result.push body
885
1051
  end
886
1052
 
887
- result.line = recv.line
888
1053
  result.comments = self.comments.pop
889
- result
1054
+
1055
+ [result, in_def]
890
1056
  end
891
1057
 
892
1058
  def new_do_body args, body, lineno
893
1059
  new_iter(nil, args, body).line(lineno)
894
1060
  end
895
1061
 
1062
+ def new_find_pattern const, pat
1063
+ pat.sexp_type = :find_pat
1064
+ pat.insert 1, const
1065
+ end
1066
+
1067
+ def new_find_pattern_tail lhs, mid, rhs
1068
+ lhs_id, line = lhs
1069
+ rhs_id, _line = rhs
1070
+
1071
+ # TODO: fpinfo->pre_rest_arg = pre_rest_arg ? assignable(p, pre_rest_arg, 0, loc) : NODE_SPECIAL_NO_NAME_REST;
1072
+
1073
+ lhs_id = "*#{lhs_id}".to_sym
1074
+ rhs_id = "*#{rhs_id}".to_sym
1075
+
1076
+ raise "BAD?" unless mid.sexp_type == :array_TAIL
1077
+
1078
+ s(:find_pat_TAIL, lhs_id, *mid.sexp_body, rhs_id).line line
1079
+ end
1080
+
896
1081
  def new_for expr, var, body
897
1082
  result = s(:for, expr, var).line(var.line)
898
1083
  result << body if body
@@ -902,7 +1087,47 @@ module RubyParserStuff
902
1087
  def new_hash val
903
1088
  _, line, assocs = val
904
1089
 
905
- s(:hash).line(line).concat assocs.values
1090
+ s(:hash).line(line).concat assocs.sexp_body
1091
+ end
1092
+
1093
+ def new_hash_pattern const, hash_pat, loc
1094
+ _, pat, kw_args, kw_rest_arg = hash_pat
1095
+
1096
+ line = (const||hash_pat).line
1097
+
1098
+ result = s(:hash_pat, const).line line
1099
+ result.concat pat.sexp_body if pat
1100
+ result << kw_args if kw_args
1101
+ result << kw_rest_arg if kw_rest_arg
1102
+ result
1103
+ end
1104
+
1105
+ def new_hash_pattern_tail kw_args, kw_rest_arg, line # TODO: remove line arg
1106
+ # kw_rest_arg = assignable(kw_rest_arg, nil).line line if kw_rest_arg
1107
+
1108
+ result = s(:hash_pat).line line
1109
+ result << kw_args
1110
+
1111
+ if kw_rest_arg then
1112
+ name = kw_rest_arg.value
1113
+ # TODO: I _hate_ this:
1114
+ assignable [name, kw_rest_arg.line] if name != :**
1115
+ result << kw_rest_arg
1116
+ end
1117
+
1118
+ result
1119
+ end
1120
+
1121
+ def push_pktbl
1122
+ end
1123
+
1124
+ def pop_pktbl
1125
+ end
1126
+
1127
+ def push_pvtbl
1128
+ end
1129
+
1130
+ def pop_pvtbl
906
1131
  end
907
1132
 
908
1133
  def new_if c, t, f
@@ -979,9 +1204,12 @@ module RubyParserStuff
979
1204
  end
980
1205
 
981
1206
  def new_module val
1207
+ # TODO: get line from module keyword
982
1208
  line, path, body = val[1], val[2], val[4]
983
1209
 
984
- result = s(:module, path)
1210
+ path = path.first if path.instance_of? Array
1211
+
1212
+ result = s(:module, path).line line
985
1213
 
986
1214
  if body then # REFACTOR?
987
1215
  if body.sexp_type == :block then
@@ -991,32 +1219,33 @@ module RubyParserStuff
991
1219
  end
992
1220
  end
993
1221
 
994
- result.line = line
995
1222
  result.comments = self.comments.pop
996
1223
  result
997
1224
  end
998
1225
 
999
1226
  def new_op_asgn val
1000
- lhs, asgn_op, arg = val[0], val[1].to_sym, val[2]
1001
- name = gettable(lhs.value).line lhs.line
1002
- arg = remove_begin(arg)
1003
- result = case asgn_op # REFACTOR
1227
+ lhs, (op, _line), rhs = val
1228
+ op = op.to_sym
1229
+
1230
+ name = gettable(lhs.last).line lhs.line
1231
+ arg = remove_begin rhs
1232
+ result = case op # REFACTOR
1004
1233
  when :"||" then
1005
1234
  lhs << arg
1006
- s(:op_asgn_or, name, lhs)
1235
+ s(:op_asgn_or, name, lhs).line lhs.line
1007
1236
  when :"&&" then
1008
1237
  lhs << arg
1009
- s(:op_asgn_and, name, lhs)
1238
+ s(:op_asgn_and, name, lhs).line lhs.line
1010
1239
  else
1011
- lhs << new_call(name, asgn_op, argl(arg))
1240
+ lhs << new_call(name, op, argl(arg))
1012
1241
  lhs
1013
1242
  end
1014
- result.line = lhs.line
1243
+
1015
1244
  result
1016
1245
  end
1017
1246
 
1018
1247
  def new_op_asgn1 val
1019
- lhs, _, args, _, op, rhs = val
1248
+ lhs, _, args, _, (op, _), rhs = val
1020
1249
 
1021
1250
  args.sexp_type = :arglist if args
1022
1251
 
@@ -1026,7 +1255,7 @@ module RubyParserStuff
1026
1255
  end
1027
1256
 
1028
1257
  def new_op_asgn2 val
1029
- recv, call_op, meth, op, arg = val
1258
+ recv, (call_op, _), (meth, _), (op, _), arg = val
1030
1259
  meth = :"#{meth}="
1031
1260
 
1032
1261
  result = case call_op.to_sym
@@ -1043,36 +1272,28 @@ module RubyParserStuff
1043
1272
  end
1044
1273
 
1045
1274
  def new_qsym_list
1046
- result = s(:array).line lexer.lineno
1047
- self.lexer.fixup_lineno
1048
- result
1275
+ s(:array).line lexer.lineno
1049
1276
  end
1050
1277
 
1051
1278
  def new_qsym_list_entry val
1052
- _, str, _ = val
1053
- result = s(:lit, str.to_sym).line lexer.lineno
1054
- self.lexer.fixup_lineno
1055
- result
1279
+ _, (str, line), _ = val
1280
+ s(:lit, str.to_sym).line line
1056
1281
  end
1057
1282
 
1058
1283
  def new_qword_list
1059
- result = s(:array).line lexer.lineno
1060
- self.lexer.fixup_lineno
1061
- result
1284
+ s(:array).line lexer.lineno
1062
1285
  end
1063
1286
 
1064
1287
  def new_qword_list_entry val
1065
- _, str, _ = val
1288
+ _, (str, line), _ = val
1066
1289
  str.force_encoding("ASCII-8BIT") unless str.valid_encoding?
1067
- result = s(:str, str).line lexer.lineno # TODO: problematic? grab from parser
1068
- self.lexer.fixup_lineno
1069
- result
1290
+ s(:str, str).line line
1070
1291
  end
1071
1292
 
1072
1293
  def new_regexp val
1073
- _, node, options = val
1294
+ (_, line), node, (options, _) = val
1074
1295
 
1075
- node ||= s(:str, "").line lexer.lineno
1296
+ node ||= s(:str, "").line line
1076
1297
 
1077
1298
  o, k = 0, nil
1078
1299
  options.split(//).uniq.each do |c| # FIX: this has a better home
@@ -1099,12 +1320,12 @@ module RubyParserStuff
1099
1320
  begin
1100
1321
  Regexp.new(node[1], o)
1101
1322
  rescue RegexpError => e
1102
- warn "WA\RNING: #{e.message} for #{node[1].inspect} #{options.inspect}"
1323
+ warn "WARNING: #{e.message} for #{node[1].inspect} #{options.inspect}"
1103
1324
  begin
1104
- warn "WA\RNING: trying to recover with ENC_UTF8"
1325
+ warn "WARNING: trying to recover with ENC_UTF8"
1105
1326
  Regexp.new(node[1], Regexp::ENC_UTF8)
1106
1327
  rescue RegexpError => e
1107
- warn "WA\RNING: trying to recover with ENC_NONE"
1328
+ warn "WARNING: trying to recover with ENC_NONE"
1108
1329
  Regexp.new(node[1], Regexp::ENC_NONE)
1109
1330
  end
1110
1331
  end
@@ -1117,7 +1338,7 @@ module RubyParserStuff
1117
1338
  end
1118
1339
  node << o if o and o != 0
1119
1340
  else
1120
- node = s(:dregx, "", node).line node.line
1341
+ node = s(:dregx, "", node).line line
1121
1342
  node.sexp_type = :dregx_once if options =~ /o/
1122
1343
  node << o if o and o != 0
1123
1344
  end
@@ -1159,17 +1380,16 @@ module RubyParserStuff
1159
1380
  end
1160
1381
 
1161
1382
  def new_string val
1162
- str, = val
1383
+ (str, line), = val
1384
+
1163
1385
  str.force_encoding("UTF-8")
1164
1386
  # TODO: remove:
1165
1387
  str.force_encoding("ASCII-8BIT") unless str.valid_encoding?
1166
- result = s(:str, str).line lexer.lineno
1167
- self.lexer.fixup_lineno str.count("\n")
1168
- result
1388
+ s(:str, str).line line
1169
1389
  end
1170
1390
 
1171
1391
  def new_super args
1172
- if args && args.node_type == :block_pass then
1392
+ if args && args.sexp_type == :block_pass then
1173
1393
  s(:super, args).line args.line
1174
1394
  else
1175
1395
  args ||= s(:arglist).line lexer.lineno
@@ -1177,32 +1397,30 @@ module RubyParserStuff
1177
1397
  end
1178
1398
  end
1179
1399
 
1400
+ def new_symbol val
1401
+ name = val.last
1402
+ s(:lit, name.to_sym).line lexer.lineno
1403
+ end
1404
+
1180
1405
  def new_symbol_list
1181
- result = s(:array).line lexer.lineno
1182
- self.lexer.fixup_lineno
1183
- result
1406
+ # TODO: hunt down and try to remove ALL lexer.lineno usage!
1407
+ s(:array).line lexer.lineno
1184
1408
  end
1185
1409
 
1186
1410
  def new_symbol_list_entry val
1187
1411
  _, sym, _ = val
1188
1412
 
1189
- sym ||= s(:str, "")
1190
-
1191
- line = lexer.lineno
1413
+ sym ||= s(:str, "").line lexer.lineno
1192
1414
 
1193
1415
  case sym.sexp_type
1194
1416
  when :dstr then
1195
1417
  sym.sexp_type = :dsym
1196
1418
  when :str then
1197
- sym = s(:lit, sym.last.to_sym)
1419
+ sym = s(:lit, sym.last.to_sym).line sym.line
1198
1420
  else
1199
- sym = s(:dsym, "", sym || s(:str, "").line(line))
1421
+ sym = s(:dsym, "", sym).line sym.line
1200
1422
  end
1201
1423
 
1202
- sym.line line
1203
-
1204
- self.lexer.fixup_lineno
1205
-
1206
1424
  sym
1207
1425
  end
1208
1426
 
@@ -1244,16 +1462,12 @@ module RubyParserStuff
1244
1462
  end
1245
1463
 
1246
1464
  def new_word_list
1247
- result = s(:array).line lexer.lineno
1248
- self.lexer.fixup_lineno
1249
- result
1465
+ s(:array).line lexer.lineno
1250
1466
  end
1251
1467
 
1252
1468
  def new_word_list_entry val
1253
1469
  _, word, _ = val
1254
- result = word.sexp_type == :evstr ? s(:dstr, "", word).line(word.line) : word
1255
- self.lexer.fixup_lineno
1256
- result
1470
+ word.sexp_type == :evstr ? s(:dstr, "", word).line(word.line) : word
1257
1471
  end
1258
1472
 
1259
1473
  def new_xstring val
@@ -1277,9 +1491,9 @@ module RubyParserStuff
1277
1491
 
1278
1492
  def new_yield args = nil
1279
1493
  # TODO: raise args.inspect unless [:arglist].include? args.first # HACK
1280
- raise "write a test 4" if args && args.node_type == :block_pass
1494
+ raise "write a test 4" if args && args.sexp_type == :block_pass
1281
1495
  raise SyntaxError, "Block argument should not be given." if
1282
- args && args.node_type == :block_pass
1496
+ args && args.sexp_type == :block_pass
1283
1497
 
1284
1498
  args ||= s(:arglist).line lexer.lineno
1285
1499
 
@@ -1289,18 +1503,30 @@ module RubyParserStuff
1289
1503
  s(:yield, *args.sexp_body).line args.line
1290
1504
  end
1291
1505
 
1506
+ def prev_value_to_lineno v
1507
+ s, n = v
1508
+ if String === s then
1509
+ n
1510
+ else
1511
+ lexer.lineno
1512
+ end
1513
+ end
1514
+
1292
1515
  def next_token
1293
1516
  token = self.lexer.next_token
1294
1517
 
1295
1518
  if token and token.first != RubyLexer::EOF then
1296
1519
  self.last_token_type = token
1297
1520
  return token
1521
+ elsif !token
1522
+ return self.lexer.next_token
1298
1523
  else
1299
1524
  return [false, false]
1300
1525
  end
1301
1526
  end
1302
1527
 
1303
1528
  def on_error(et, ev, values)
1529
+ ev = ev.first if ev.instance_of?(Array) && ev.size == 2 && ev.last.is_a?(Integer)
1304
1530
  super
1305
1531
  rescue Racc::ParseError => e
1306
1532
  # I don't like how the exception obscures the error message
@@ -1314,18 +1540,17 @@ module RubyParserStuff
1314
1540
  # Timeout::Error if it runs for more than +time+ seconds.
1315
1541
 
1316
1542
  def process(str, file = "(string)", time = 10)
1543
+ str.freeze
1544
+
1317
1545
  Timeout.timeout time do
1318
1546
  raise "bad val: #{str.inspect}" unless String === str
1319
1547
 
1320
- str = handle_encoding str
1548
+ self.lexer.string = handle_encoding str
1321
1549
 
1322
1550
  self.file = file.dup
1323
1551
 
1324
1552
  @yydebug = ENV.has_key? "DEBUG"
1325
1553
 
1326
- # HACK -- need to get tests passing more than have graceful code
1327
- self.lexer.ss = RPStringScanner.new str
1328
-
1329
1554
  do_parse
1330
1555
  end
1331
1556
  end
@@ -1381,6 +1606,14 @@ module RubyParserStuff
1381
1606
  result
1382
1607
  end
1383
1608
 
1609
+ def debug n
1610
+ if ENV["PRY"] then
1611
+ require "pry"; binding.pry
1612
+ end
1613
+
1614
+ raise RubyParser::SyntaxError, "debug #{n}"
1615
+ end
1616
+
1384
1617
  def syntax_error msg
1385
1618
  raise RubyParser::SyntaxError, msg
1386
1619
  end
@@ -1425,6 +1658,8 @@ module RubyParserStuff
1425
1658
 
1426
1659
  if remove_width then
1427
1660
  line[idx..-1]
1661
+ elsif line[idx] == "\n"
1662
+ nil
1428
1663
  else
1429
1664
  col
1430
1665
  end
@@ -1432,6 +1667,12 @@ module RubyParserStuff
1432
1667
 
1433
1668
  alias remove_whitespace_width whitespace_width
1434
1669
 
1670
+ def wrap type, node
1671
+ value, line = node
1672
+ value = value.to_sym if value.respond_to? :to_sym
1673
+ s(type, value).line line
1674
+ end
1675
+
1435
1676
  class Keyword
1436
1677
  include RubyLexer::State::Values
1437
1678