ruby_parser 3.17.0 → 3.19.0

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 (46) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/History.rdoc +109 -0
  4. data/Manifest.txt +5 -0
  5. data/README.rdoc +9 -6
  6. data/Rakefile +85 -24
  7. data/bin/ruby_parse_extract_error +1 -1
  8. data/compare/normalize.rb +6 -1
  9. data/gauntlet.md +108 -0
  10. data/lib/rp_extensions.rb +15 -36
  11. data/lib/rp_stringscanner.rb +20 -51
  12. data/lib/ruby20_parser.rb +7430 -3528
  13. data/lib/ruby20_parser.y +328 -257
  14. data/lib/ruby21_parser.rb +7408 -3572
  15. data/lib/ruby21_parser.y +323 -254
  16. data/lib/ruby22_parser.rb +7543 -3601
  17. data/lib/ruby22_parser.y +327 -256
  18. data/lib/ruby23_parser.rb +7549 -3612
  19. data/lib/ruby23_parser.y +327 -256
  20. data/lib/ruby24_parser.rb +7640 -3624
  21. data/lib/ruby24_parser.y +327 -256
  22. data/lib/ruby25_parser.rb +7640 -3623
  23. data/lib/ruby25_parser.y +327 -256
  24. data/lib/ruby26_parser.rb +7649 -3632
  25. data/lib/ruby26_parser.y +326 -255
  26. data/lib/ruby27_parser.rb +10132 -4545
  27. data/lib/ruby27_parser.y +871 -262
  28. data/lib/ruby30_parser.rb +10504 -4655
  29. data/lib/ruby30_parser.y +1065 -333
  30. data/lib/ruby31_parser.rb +13622 -0
  31. data/lib/ruby31_parser.y +3481 -0
  32. data/lib/ruby3_parser.yy +3536 -0
  33. data/lib/ruby_lexer.rb +261 -609
  34. data/lib/ruby_lexer.rex +27 -20
  35. data/lib/ruby_lexer.rex.rb +59 -23
  36. data/lib/ruby_lexer_strings.rb +638 -0
  37. data/lib/ruby_parser.rb +2 -0
  38. data/lib/ruby_parser.yy +903 -272
  39. data/lib/ruby_parser_extras.rb +333 -113
  40. data/test/test_ruby_lexer.rb +181 -129
  41. data/test/test_ruby_parser.rb +1529 -288
  42. data/tools/munge.rb +34 -6
  43. data/tools/ripper.rb +15 -10
  44. data.tar.gz.sig +0 -0
  45. metadata +27 -23
  46. 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.16.0"
33
+ VERSION = "3.19.0"
33
34
 
34
35
  attr_accessor :lexer, :in_def, :in_single, :file
35
36
  attr_accessor :in_kwarg
@@ -155,11 +156,25 @@ 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
163
178
  when :forward_args then
164
179
  self.env[:*] = :lvar # TODO: arg_var(p, idFWD_REST) ?
165
180
  self.env[:**] = :lvar
@@ -185,6 +200,8 @@ module RubyParserStuff
185
200
  name = arg.to_s.delete("&*")
186
201
  self.env[name.to_sym] = :lvar unless name.empty?
187
202
  result << arg
203
+ when true, false then
204
+ self.in_kwarg = arg
188
205
  when ",", "|", ";", "(", ")", nil then
189
206
  # ignore
190
207
  else
@@ -195,6 +212,23 @@ module RubyParserStuff
195
212
  result
196
213
  end
197
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 endless_method_name defn_or_defs
222
+ name = defn_or_defs[1]
223
+ name = defn_or_defs[2] unless Symbol === name
224
+
225
+ if name.end_with? "=" then
226
+ yyerror "setter method cannot be defined in an endless method definition"
227
+ end
228
+
229
+ # TODO? token_info_drop(p, "def", loc->beg_pos);
230
+ end
231
+
198
232
  def array_to_hash array
199
233
  case array.sexp_type
200
234
  when :kwsplat then
@@ -214,17 +248,10 @@ module RubyParserStuff
214
248
  end
215
249
 
216
250
  def assignable(lhs, value = nil)
217
- id = lhs.to_sym unless Sexp === lhs
218
-
219
- raise "WTF" if Sexp === id
220
- id = id.to_sym if Sexp === id
221
-
222
- raise "write a test 1" if id.to_s =~ /^(?:self|nil|true|false|__LINE__|__FILE__)$/
223
-
224
- raise SyntaxError, "Can't change the value of #{id}" if
225
- id.to_s =~ /^(?:self|nil|true|false|__LINE__|__FILE__)$/
251
+ id, line = lhs
252
+ id = id.to_sym
226
253
 
227
- result = case id.to_s
254
+ result = case id
228
255
  when /^@@/ then
229
256
  asgn = in_def || in_single > 0
230
257
  s((asgn ? :cvasgn : :cvdecl), id)
@@ -245,17 +272,9 @@ module RubyParserStuff
245
272
 
246
273
  self.env[id] ||= :lvar if result.sexp_type == :lasgn
247
274
 
248
- line = case lhs
249
- when Sexp then
250
- lhs.line
251
- else
252
- value && value.line || lexer.lineno
253
- end
254
-
255
275
  result << value if value
256
- result.line = line
257
-
258
- return result
276
+ result.line line
277
+ result
259
278
  end
260
279
 
261
280
  def backref_assign_error ref
@@ -279,9 +298,9 @@ module RubyParserStuff
279
298
  line = [head.line, tail.line].compact.min
280
299
 
281
300
  head = remove_begin(head)
282
- head = s(:block, head) unless head.node_type == :block
301
+ head = s(:block, head).line(line) unless head.sexp_type == :block
283
302
 
284
- head.line = line
303
+ # head.line = line
285
304
  head << tail
286
305
  end
287
306
 
@@ -307,6 +326,10 @@ module RubyParserStuff
307
326
  end
308
327
 
309
328
  args.each do |arg|
329
+ if arg.instance_of? Array and arg.size == 2 and arg.last.is_a? Numeric then
330
+ arg = arg.first
331
+ end
332
+
310
333
  case arg
311
334
  when Sexp then
312
335
  case arg.sexp_type
@@ -317,6 +340,9 @@ module RubyParserStuff
317
340
  end
318
341
  when Symbol then
319
342
  result << arg
343
+ when Array then
344
+ id, _line = arg
345
+ result << id
320
346
  when ",", nil, "(" then
321
347
  # ignore
322
348
  else
@@ -441,7 +467,7 @@ module RubyParserStuff
441
467
  end
442
468
  else
443
469
  warn "unprocessed: %p" % [s]
444
- end.map { |l| whitespace_width l[/^[ \t]*/] }
470
+ end.map { |l| whitespace_width l.chomp }
445
471
  }.compact.min
446
472
  end
447
473
 
@@ -465,7 +491,6 @@ module RubyParserStuff
465
491
  end
466
492
 
467
493
  def gettable(id)
468
- lineno = id.lineno if id.respond_to? :lineno
469
494
  id = id.to_sym if String === id
470
495
 
471
496
  result = case id.to_s
@@ -486,8 +511,6 @@ module RubyParserStuff
486
511
  end
487
512
  end
488
513
 
489
- result.line lineno if lineno
490
-
491
514
  raise "identifier #{id.inspect} is not valid" unless result
492
515
 
493
516
  result
@@ -546,7 +569,7 @@ module RubyParserStuff
546
569
  header.map! { |s| s.force_encoding "ASCII-8BIT" } if has_enc
547
570
 
548
571
  first = header.first || ""
549
- encoding, str = "utf-8", str.b[3..-1] if first =~ /\A\xEF\xBB\xBF/
572
+ encoding, str = +"utf-8", str.b[3..-1] if first =~ /\A\xEF\xBB\xBF/
550
573
 
551
574
  encoding = $1.strip if header.find { |s|
552
575
  s[/^#.*?-\*-.*?coding:\s*([^ ;]+).*?-\*-/, 1] ||
@@ -630,7 +653,7 @@ module RubyParserStuff
630
653
  when :evstr then
631
654
  if htype == :str then
632
655
  f, l = head.file, head.line
633
- head = s(:dstr, *head.sexp_body).line head.line
656
+ head = s(:dstr, *head.sexp_body)
634
657
  head.file = f
635
658
  head.line = l
636
659
  end
@@ -649,6 +672,13 @@ module RubyParserStuff
649
672
  return head
650
673
  end
651
674
 
675
+ def local_pop in_def
676
+ lexer.cond.pop # group = local_pop
677
+ lexer.cmdarg.pop
678
+ self.env.unextend
679
+ self.in_def = in_def
680
+ end
681
+
652
682
  def logical_op type, left, right
653
683
  left = value_expr left
654
684
 
@@ -678,6 +708,73 @@ module RubyParserStuff
678
708
  new_call val[0], :"[]", val[2]
679
709
  end
680
710
 
711
+ def new_arg val
712
+ arg, = val
713
+
714
+ case arg
715
+ when Symbol then
716
+ result = s(:args, arg).line line
717
+ when Sexp then
718
+ result = arg
719
+ when Array then
720
+ (arg, line), = val
721
+ result = s(:args, arg).line line
722
+ else
723
+ debug20 32
724
+ raise "Unknown f_arg type: #{val.inspect}"
725
+ end
726
+
727
+ result
728
+ end
729
+
730
+ def new_array_pattern const, pre_arg, arypat, loc
731
+ result = s(:array_pat, const).line loc
732
+ result << pre_arg if pre_arg
733
+
734
+ if arypat && arypat.sexp_type == :array_TAIL then
735
+ result.concat arypat.sexp_body
736
+ else
737
+ raise "NO?: %p" % [arypat]
738
+ end
739
+
740
+ result
741
+ end
742
+
743
+ def array_pat_concat lhs, rhs
744
+ case lhs.sexp_type
745
+ when :PATTERN then
746
+ lhs.sexp_type = :array_pat
747
+ end
748
+
749
+ if rhs then
750
+ case rhs.sexp_type
751
+ when :array_pat, :array_TAIL, :PATTERN then
752
+ lhs.concat rhs.sexp_body
753
+ else
754
+ lhs << rhs
755
+ end
756
+ end
757
+ end
758
+
759
+ def new_array_pattern_tail pre_args, has_rest, rest_arg, post_args
760
+ # TODO: remove has_rest once all tests pass !!!
761
+ rest_arg = if has_rest then
762
+ :"*#{rest_arg}"
763
+ else
764
+ nil
765
+ end
766
+
767
+ result = s(:array_TAIL).line 666
768
+
769
+ array_pat_concat result, pre_args
770
+
771
+ result << rest_arg if rest_arg
772
+
773
+ array_pat_concat result, post_args
774
+
775
+ result
776
+ end
777
+
681
778
  def new_assign lhs, rhs
682
779
  return nil unless lhs
683
780
 
@@ -697,6 +794,8 @@ module RubyParserStuff
697
794
  end
698
795
 
699
796
  def new_attrasgn recv, meth, call_op = :"."
797
+ call_op = call_op.first if Array === call_op
798
+
700
799
  meth = :"#{meth}="
701
800
 
702
801
  result = case call_op.to_sym
@@ -761,6 +860,8 @@ module RubyParserStuff
761
860
  end
762
861
 
763
862
  def new_call recv, meth, args = nil, call_op = :"."
863
+ call_op = call_op.first if Array === call_op
864
+
764
865
  result = case call_op.to_sym
765
866
  when :"."
766
867
  s(:call, recv, meth)
@@ -788,10 +889,14 @@ module RubyParserStuff
788
889
  result
789
890
  end
790
891
 
892
+ def new_in pat, body, cases, line
893
+ s(:in, pat, body, cases).line line
894
+ end
895
+
791
896
  def new_case expr, body, line
792
897
  result = s(:case, expr)
793
898
 
794
- while body and body.node_type == :when
899
+ while body and [:when, :in].include? body.sexp_type
795
900
  result << body
796
901
  body = body.delete_at 3
797
902
  end
@@ -810,8 +915,11 @@ module RubyParserStuff
810
915
  end
811
916
 
812
917
  def new_class val
918
+ # TODO: get line from class keyword
813
919
  line, path, superclass, body = val[1], val[2], val[3], val[5]
814
920
 
921
+ path = path.first if path.instance_of? Array
922
+
815
923
  result = s(:class, path, superclass)
816
924
 
817
925
  if body then
@@ -834,7 +942,8 @@ module RubyParserStuff
834
942
  end
835
943
 
836
944
  def new_const_op_asgn val
837
- lhs, asgn_op, rhs = val[0], val[1].to_sym, val[2]
945
+ lhs, (asgn_op, _), rhs = val
946
+ asgn_op = asgn_op.to_sym
838
947
 
839
948
  result = case asgn_op
840
949
  when :"||" then
@@ -850,55 +959,110 @@ module RubyParserStuff
850
959
  end
851
960
 
852
961
  def new_defn val
853
- (_, line), name, _, args, body, nil_body_line, * = val
854
- body ||= s(:nil).line nil_body_line
962
+ _, (name, line), in_def, args, body, _ = val
963
+
964
+ body ||= s(:nil).line line
855
965
 
856
966
  args.line line
857
967
 
858
968
  result = s(:defn, name.to_sym, args).line line
859
969
 
860
- if body then
861
- if body.sexp_type == :block then
862
- result.push(*body.sexp_body)
863
- else
864
- result.push body
865
- end
970
+ if body.sexp_type == :block then
971
+ result.push(*body.sexp_body)
972
+ else
973
+ result.push body
866
974
  end
867
975
 
868
976
  result.comments = self.comments.pop
869
977
 
978
+ [result, in_def]
979
+ end
980
+
981
+ def new_endless_defn val
982
+ (name, line, in_def), args, _, body, _, resbody = val
983
+
984
+ result =
985
+ if resbody then
986
+ s(:defn, name, args,
987
+ new_rescue(body,
988
+ new_resbody(s(:array).line(line),
989
+ resbody))).line line
990
+ else
991
+ s(:defn, name, args, body).line line
992
+ end
993
+
994
+ local_pop in_def
995
+ endless_method_name result
996
+
997
+ result
998
+ end
999
+
1000
+ def new_endless_defs val
1001
+ (recv, (name, line, in_def)), args, _, body, _, resbody = val
1002
+
1003
+ result =
1004
+ if resbody then
1005
+ s(:defs, recv, name, args,
1006
+ new_rescue(body,
1007
+ new_resbody(s(:array).line(line),
1008
+ resbody))).line line
1009
+ else
1010
+ s(:defs, recv, name, args, body).line(line)
1011
+ end
1012
+
1013
+ self.in_single -= 1
1014
+ local_pop in_def
1015
+ endless_method_name result
1016
+
870
1017
  result
871
1018
  end
872
1019
 
873
1020
  def new_defs val
874
- _, recv, _, _, name, (_in_def, line), args, body, _ = val
1021
+ _, recv, (name, line), in_def, args, body, _ = val
875
1022
 
876
1023
  body ||= s(:nil).line line
877
1024
 
878
1025
  args.line line
879
1026
 
880
- result = s(:defs, recv, name.to_sym, args)
1027
+ result = s(:defs, recv, name.to_sym, args).line line
881
1028
 
882
1029
  # TODO: remove_begin
883
1030
  # TODO: reduce_nodes
884
1031
 
885
- if body then
886
- if body.sexp_type == :block then
887
- result.push(*body.sexp_body)
888
- else
889
- result.push body
890
- end
1032
+ if body.sexp_type == :block then
1033
+ result.push(*body.sexp_body)
1034
+ else
1035
+ result.push body
891
1036
  end
892
1037
 
893
- result.line = recv.line
894
1038
  result.comments = self.comments.pop
895
- result
1039
+
1040
+ [result, in_def]
896
1041
  end
897
1042
 
898
1043
  def new_do_body args, body, lineno
899
1044
  new_iter(nil, args, body).line(lineno)
900
1045
  end
901
1046
 
1047
+ def new_find_pattern const, pat
1048
+ pat.sexp_type = :find_pat
1049
+ pat.insert 1, const
1050
+ end
1051
+
1052
+ def new_find_pattern_tail lhs, mid, rhs
1053
+ lhs_id, line = lhs
1054
+ rhs_id, _line = rhs
1055
+
1056
+ # TODO: fpinfo->pre_rest_arg = pre_rest_arg ? assignable(p, pre_rest_arg, 0, loc) : NODE_SPECIAL_NO_NAME_REST;
1057
+
1058
+ lhs_id = "*#{lhs_id}".to_sym
1059
+ rhs_id = "*#{rhs_id}".to_sym
1060
+
1061
+ mid.sexp_type = :array_pat # HACK?
1062
+
1063
+ s(:find_pat_TAIL, lhs_id, mid, rhs_id).line line
1064
+ end
1065
+
902
1066
  def new_for expr, var, body
903
1067
  result = s(:for, expr, var).line(var.line)
904
1068
  result << body if body
@@ -908,7 +1072,47 @@ module RubyParserStuff
908
1072
  def new_hash val
909
1073
  _, line, assocs = val
910
1074
 
911
- s(:hash).line(line).concat assocs.values
1075
+ s(:hash).line(line).concat assocs.sexp_body
1076
+ end
1077
+
1078
+ def new_hash_pattern const, hash_pat, loc
1079
+ _, pat, kw_args, kw_rest_arg = hash_pat
1080
+
1081
+ line = (const||hash_pat).line
1082
+
1083
+ result = s(:hash_pat, const).line line
1084
+ result.concat pat.sexp_body if pat
1085
+ result << kw_args if kw_args
1086
+ result << kw_rest_arg if kw_rest_arg
1087
+ result
1088
+ end
1089
+
1090
+ def new_hash_pattern_tail kw_args, kw_rest_arg, line # TODO: remove line arg
1091
+ # kw_rest_arg = assignable(kw_rest_arg, nil).line line if kw_rest_arg
1092
+
1093
+ result = s(:hash_pat).line line
1094
+ result << kw_args
1095
+
1096
+ if kw_rest_arg then
1097
+ name = kw_rest_arg.value
1098
+ # TODO: I _hate_ this:
1099
+ assignable [name, kw_rest_arg.line] if name != :**
1100
+ result << kw_rest_arg
1101
+ end
1102
+
1103
+ result
1104
+ end
1105
+
1106
+ def push_pktbl
1107
+ end
1108
+
1109
+ def pop_pktbl
1110
+ end
1111
+
1112
+ def push_pvtbl
1113
+ end
1114
+
1115
+ def pop_pvtbl
912
1116
  end
913
1117
 
914
1118
  def new_if c, t, f
@@ -985,9 +1189,12 @@ module RubyParserStuff
985
1189
  end
986
1190
 
987
1191
  def new_module val
1192
+ # TODO: get line from module keyword
988
1193
  line, path, body = val[1], val[2], val[4]
989
1194
 
990
- result = s(:module, path)
1195
+ path = path.first if path.instance_of? Array
1196
+
1197
+ result = s(:module, path).line line
991
1198
 
992
1199
  if body then # REFACTOR?
993
1200
  if body.sexp_type == :block then
@@ -997,32 +1204,33 @@ module RubyParserStuff
997
1204
  end
998
1205
  end
999
1206
 
1000
- result.line = line
1001
1207
  result.comments = self.comments.pop
1002
1208
  result
1003
1209
  end
1004
1210
 
1005
1211
  def new_op_asgn val
1006
- lhs, asgn_op, arg = val[0], val[1].to_sym, val[2]
1007
- name = gettable(lhs.value).line lhs.line
1008
- arg = remove_begin(arg)
1009
- result = case asgn_op # REFACTOR
1212
+ lhs, (op, _line), rhs = val
1213
+ op = op.to_sym
1214
+
1215
+ name = gettable(lhs.last).line lhs.line
1216
+ arg = remove_begin rhs
1217
+ result = case op # REFACTOR
1010
1218
  when :"||" then
1011
1219
  lhs << arg
1012
- s(:op_asgn_or, name, lhs)
1220
+ s(:op_asgn_or, name, lhs).line lhs.line
1013
1221
  when :"&&" then
1014
1222
  lhs << arg
1015
- s(:op_asgn_and, name, lhs)
1223
+ s(:op_asgn_and, name, lhs).line lhs.line
1016
1224
  else
1017
- lhs << new_call(name, asgn_op, argl(arg))
1225
+ lhs << new_call(name, op, argl(arg))
1018
1226
  lhs
1019
1227
  end
1020
- result.line = lhs.line
1228
+
1021
1229
  result
1022
1230
  end
1023
1231
 
1024
1232
  def new_op_asgn1 val
1025
- lhs, _, args, _, op, rhs = val
1233
+ lhs, _, args, _, (op, _), rhs = val
1026
1234
 
1027
1235
  args.sexp_type = :arglist if args
1028
1236
 
@@ -1032,7 +1240,7 @@ module RubyParserStuff
1032
1240
  end
1033
1241
 
1034
1242
  def new_op_asgn2 val
1035
- recv, call_op, meth, op, arg = val
1243
+ recv, (call_op, _), (meth, _), (op, _), arg = val
1036
1244
  meth = :"#{meth}="
1037
1245
 
1038
1246
  result = case call_op.to_sym
@@ -1049,36 +1257,28 @@ module RubyParserStuff
1049
1257
  end
1050
1258
 
1051
1259
  def new_qsym_list
1052
- result = s(:array).line lexer.lineno
1053
- self.lexer.fixup_lineno
1054
- result
1260
+ s(:array).line lexer.lineno
1055
1261
  end
1056
1262
 
1057
1263
  def new_qsym_list_entry val
1058
- _, str, _ = val
1059
- result = s(:lit, str.to_sym).line lexer.lineno
1060
- self.lexer.fixup_lineno
1061
- result
1264
+ _, (str, line), _ = val
1265
+ s(:lit, str.to_sym).line line
1062
1266
  end
1063
1267
 
1064
1268
  def new_qword_list
1065
- result = s(:array).line lexer.lineno
1066
- self.lexer.fixup_lineno
1067
- result
1269
+ s(:array).line lexer.lineno
1068
1270
  end
1069
1271
 
1070
1272
  def new_qword_list_entry val
1071
- _, str, _ = val
1273
+ _, (str, line), _ = val
1072
1274
  str.force_encoding("ASCII-8BIT") unless str.valid_encoding?
1073
- result = s(:str, str).line lexer.lineno # TODO: problematic? grab from parser
1074
- self.lexer.fixup_lineno
1075
- result
1275
+ s(:str, str).line line
1076
1276
  end
1077
1277
 
1078
1278
  def new_regexp val
1079
- _, node, options = val
1279
+ (_, line), node, (options, _) = val
1080
1280
 
1081
- node ||= s(:str, "").line lexer.lineno
1281
+ node ||= s(:str, "").line line
1082
1282
 
1083
1283
  o, k = 0, nil
1084
1284
  options.split(//).uniq.each do |c| # FIX: this has a better home
@@ -1105,12 +1305,12 @@ module RubyParserStuff
1105
1305
  begin
1106
1306
  Regexp.new(node[1], o)
1107
1307
  rescue RegexpError => e
1108
- warn "WA\RNING: #{e.message} for #{node[1].inspect} #{options.inspect}"
1308
+ warn "WARNING: #{e.message} for #{node[1].inspect} #{options.inspect}"
1109
1309
  begin
1110
- warn "WA\RNING: trying to recover with ENC_UTF8"
1310
+ warn "WARNING: trying to recover with ENC_UTF8"
1111
1311
  Regexp.new(node[1], Regexp::ENC_UTF8)
1112
1312
  rescue RegexpError => e
1113
- warn "WA\RNING: trying to recover with ENC_NONE"
1313
+ warn "WARNING: trying to recover with ENC_NONE"
1114
1314
  Regexp.new(node[1], Regexp::ENC_NONE)
1115
1315
  end
1116
1316
  end
@@ -1123,7 +1323,7 @@ module RubyParserStuff
1123
1323
  end
1124
1324
  node << o if o and o != 0
1125
1325
  else
1126
- node = s(:dregx, "", node).line node.line
1326
+ node = s(:dregx, "", node).line line
1127
1327
  node.sexp_type = :dregx_once if options =~ /o/
1128
1328
  node << o if o and o != 0
1129
1329
  end
@@ -1165,17 +1365,16 @@ module RubyParserStuff
1165
1365
  end
1166
1366
 
1167
1367
  def new_string val
1168
- str, = val
1368
+ (str, line), = val
1369
+
1169
1370
  str.force_encoding("UTF-8")
1170
1371
  # TODO: remove:
1171
1372
  str.force_encoding("ASCII-8BIT") unless str.valid_encoding?
1172
- result = s(:str, str).line lexer.lineno
1173
- self.lexer.fixup_lineno str.count("\n")
1174
- result
1373
+ s(:str, str).line line
1175
1374
  end
1176
1375
 
1177
1376
  def new_super args
1178
- if args && args.node_type == :block_pass then
1377
+ if args && args.sexp_type == :block_pass then
1179
1378
  s(:super, args).line args.line
1180
1379
  else
1181
1380
  args ||= s(:arglist).line lexer.lineno
@@ -1183,32 +1382,30 @@ module RubyParserStuff
1183
1382
  end
1184
1383
  end
1185
1384
 
1385
+ def new_symbol val
1386
+ name = val.last
1387
+ s(:lit, name.to_sym).line lexer.lineno
1388
+ end
1389
+
1186
1390
  def new_symbol_list
1187
- result = s(:array).line lexer.lineno
1188
- self.lexer.fixup_lineno
1189
- result
1391
+ # TODO: hunt down and try to remove ALL lexer.lineno usage!
1392
+ s(:array).line lexer.lineno
1190
1393
  end
1191
1394
 
1192
1395
  def new_symbol_list_entry val
1193
1396
  _, sym, _ = val
1194
1397
 
1195
- sym ||= s(:str, "")
1196
-
1197
- line = lexer.lineno
1398
+ sym ||= s(:str, "").line lexer.lineno
1198
1399
 
1199
1400
  case sym.sexp_type
1200
1401
  when :dstr then
1201
1402
  sym.sexp_type = :dsym
1202
1403
  when :str then
1203
- sym = s(:lit, sym.last.to_sym)
1404
+ sym = s(:lit, sym.last.to_sym).line sym.line
1204
1405
  else
1205
- sym = s(:dsym, "", sym || s(:str, "").line(line))
1406
+ sym = s(:dsym, "", sym).line sym.line
1206
1407
  end
1207
1408
 
1208
- sym.line line
1209
-
1210
- self.lexer.fixup_lineno
1211
-
1212
1409
  sym
1213
1410
  end
1214
1411
 
@@ -1250,16 +1447,12 @@ module RubyParserStuff
1250
1447
  end
1251
1448
 
1252
1449
  def new_word_list
1253
- result = s(:array).line lexer.lineno
1254
- self.lexer.fixup_lineno
1255
- result
1450
+ s(:array).line lexer.lineno
1256
1451
  end
1257
1452
 
1258
1453
  def new_word_list_entry val
1259
1454
  _, word, _ = val
1260
- result = word.sexp_type == :evstr ? s(:dstr, "", word).line(word.line) : word
1261
- self.lexer.fixup_lineno
1262
- result
1455
+ word.sexp_type == :evstr ? s(:dstr, "", word).line(word.line) : word
1263
1456
  end
1264
1457
 
1265
1458
  def new_xstring val
@@ -1283,9 +1476,9 @@ module RubyParserStuff
1283
1476
 
1284
1477
  def new_yield args = nil
1285
1478
  # TODO: raise args.inspect unless [:arglist].include? args.first # HACK
1286
- raise "write a test 4" if args && args.node_type == :block_pass
1479
+ raise "write a test 4" if args && args.sexp_type == :block_pass
1287
1480
  raise SyntaxError, "Block argument should not be given." if
1288
- args && args.node_type == :block_pass
1481
+ args && args.sexp_type == :block_pass
1289
1482
 
1290
1483
  args ||= s(:arglist).line lexer.lineno
1291
1484
 
@@ -1295,18 +1488,30 @@ module RubyParserStuff
1295
1488
  s(:yield, *args.sexp_body).line args.line
1296
1489
  end
1297
1490
 
1491
+ def prev_value_to_lineno v
1492
+ s, n = v
1493
+ if String === s then
1494
+ n
1495
+ else
1496
+ lexer.lineno
1497
+ end
1498
+ end
1499
+
1298
1500
  def next_token
1299
1501
  token = self.lexer.next_token
1300
1502
 
1301
1503
  if token and token.first != RubyLexer::EOF then
1302
1504
  self.last_token_type = token
1303
1505
  return token
1506
+ elsif !token
1507
+ return self.lexer.next_token
1304
1508
  else
1305
1509
  return [false, false]
1306
1510
  end
1307
1511
  end
1308
1512
 
1309
1513
  def on_error(et, ev, values)
1514
+ ev = ev.first if ev.instance_of?(Array) && ev.size == 2 && ev.last.is_a?(Integer)
1310
1515
  super
1311
1516
  rescue Racc::ParseError => e
1312
1517
  # I don't like how the exception obscures the error message
@@ -1320,18 +1525,17 @@ module RubyParserStuff
1320
1525
  # Timeout::Error if it runs for more than +time+ seconds.
1321
1526
 
1322
1527
  def process(str, file = "(string)", time = 10)
1528
+ str.freeze
1529
+
1323
1530
  Timeout.timeout time do
1324
1531
  raise "bad val: #{str.inspect}" unless String === str
1325
1532
 
1326
- str = handle_encoding str
1533
+ self.lexer.string = handle_encoding str
1327
1534
 
1328
1535
  self.file = file.dup
1329
1536
 
1330
1537
  @yydebug = ENV.has_key? "DEBUG"
1331
1538
 
1332
- # HACK -- need to get tests passing more than have graceful code
1333
- self.lexer.ss = RPStringScanner.new str
1334
-
1335
1539
  do_parse
1336
1540
  end
1337
1541
  end
@@ -1387,6 +1591,14 @@ module RubyParserStuff
1387
1591
  result
1388
1592
  end
1389
1593
 
1594
+ def debug n
1595
+ if ENV["PRY"] then
1596
+ require "pry"; binding.pry
1597
+ end
1598
+
1599
+ raise RubyParser::SyntaxError, "debug #{n}"
1600
+ end
1601
+
1390
1602
  def syntax_error msg
1391
1603
  raise RubyParser::SyntaxError, msg
1392
1604
  end
@@ -1431,6 +1643,8 @@ module RubyParserStuff
1431
1643
 
1432
1644
  if remove_width then
1433
1645
  line[idx..-1]
1646
+ elsif line[idx].nil?
1647
+ nil
1434
1648
  else
1435
1649
  col
1436
1650
  end
@@ -1438,6 +1652,12 @@ module RubyParserStuff
1438
1652
 
1439
1653
  alias remove_whitespace_width whitespace_width
1440
1654
 
1655
+ def wrap type, node
1656
+ value, line = node
1657
+ value = value.to_sym if value.respond_to? :to_sym
1658
+ s(type, value).line line
1659
+ end
1660
+
1441
1661
  class Keyword
1442
1662
  include RubyLexer::State::Values
1443
1663