ruby_parser 3.3.0 → 3.4.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -59,28 +59,8 @@ class RPStringScanner < StringScanner
59
59
  end
60
60
  end
61
61
 
62
- def current_line # HAHA fuck you (HACK)
63
- string_to_pos[/\A.*__LINE__/m].split(/\n/).size
64
- end
65
-
66
- def extra_lines_added
67
- @extra_lines_added ||= 0
68
- end
69
-
70
- def extra_lines_added= val
71
- @extra_lines_added = val
72
- end
73
-
74
- def lineno
75
- string[0...charpos].count("\n") + 1 - extra_lines_added
76
- end
77
-
78
- # TODO: once we get rid of these, we can make things like
79
- # TODO: current_line and lineno much more accurate and easy to do
80
-
81
62
  def unread_many str # TODO: remove this entirely - we should not need it
82
63
  warn({:unread_many => caller[0]}.inspect) if ENV['TALLY']
83
- self.extra_lines_added += str.count("\n") - 1
84
64
  begin
85
65
  string[charpos, 0] = str
86
66
  rescue IndexError
@@ -111,7 +91,7 @@ class RPStringScanner < StringScanner
111
91
  end
112
92
 
113
93
  module RubyParserStuff
114
- VERSION = "3.3.0" unless constants.include? "VERSION" # SIGH
94
+ VERSION = "3.4.0" unless constants.include? "VERSION" # SIGH
115
95
 
116
96
  attr_accessor :lexer, :in_def, :in_single, :file
117
97
  attr_reader :env, :comments
@@ -148,15 +128,6 @@ module RubyParserStuff
148
128
  raise RubyParser::SyntaxError, msg
149
129
  end
150
130
 
151
- def arg_add(node1, node2) # TODO: nuke
152
- return s(:arglist, node2) unless node1
153
-
154
- node1[0] = :arglist if node1[0] == :array
155
- return node1 << node2 if node1[0] == :arglist
156
-
157
- return s(:arglist, node1, node2)
158
- end
159
-
160
131
  def arg_blk_pass node1, node2 # TODO: nuke
161
132
  node1 = s(:arglist, node1) unless [:arglist, :call_args, :array, :args].include? node1.first
162
133
  node1 << node2 if node2
@@ -391,6 +362,7 @@ module RubyParserStuff
391
362
  end
392
363
 
393
364
  def gettable(id)
365
+ lineno = id.lineno if id.respond_to? :lineno
394
366
  id = id.to_sym if String === id
395
367
 
396
368
  result = case id.to_s
@@ -411,7 +383,7 @@ module RubyParserStuff
411
383
  end
412
384
  end
413
385
 
414
- result.line(result.line - 1) if result.line and lexer.src.bol?
386
+ result.line lineno if lineno
415
387
 
416
388
  raise "identifier #{id.inspect} is not valid" unless result
417
389
 
@@ -457,7 +429,7 @@ module RubyParserStuff
457
429
  list
458
430
  end
459
431
 
460
- def literal_concat head, tail
432
+ def literal_concat head, tail # TODO: ugh. rewrite
461
433
  return tail unless head
462
434
  return head unless tail
463
435
 
@@ -476,8 +448,10 @@ module RubyParserStuff
476
448
  end
477
449
  when :dstr then
478
450
  if htype == :str then
451
+ lineno = head.line
479
452
  tail[1] = head[-1] + tail[1]
480
453
  head = tail
454
+ head.line = lineno
481
455
  else
482
456
  tail[0] = :array
483
457
  tail[1] = s(:str, tail[1])
@@ -563,7 +537,7 @@ module RubyParserStuff
563
537
  end
564
538
 
565
539
  def argl x
566
- x = s(:arglist, x) if x and x[0] != :arglist
540
+ x = s(:arglist, x) if x and x[0] == :array
567
541
  x
568
542
  end
569
543
 
@@ -587,12 +561,13 @@ module RubyParserStuff
587
561
  # TODO: need a test with f(&b) to produce block_pass
588
562
  # TODO: need a test with f(&b) { } to produce warning
589
563
 
590
- args ||= s(:arglist)
591
- args[0] = :arglist if [:args, :array, :call_args].include? args.first
592
- args = s(:arglist, args) unless args.first == :arglist
593
-
594
- # HACK quick hack to make this work quickly... easy to clean up above
595
- result.concat args[1..-1]
564
+ if args
565
+ if [:arglist, :args, :array, :call_args].include? args.first
566
+ result.concat args.sexp_body
567
+ else
568
+ result << args
569
+ end
570
+ end
596
571
 
597
572
  line = result.grep(Sexp).map(&:line).compact.min
598
573
  result.line = line if line
@@ -600,9 +575,8 @@ module RubyParserStuff
600
575
  result
601
576
  end
602
577
 
603
- def new_case expr, body
578
+ def new_case expr, body, line
604
579
  result = s(:case, expr)
605
- line = (expr || body).line
606
580
 
607
581
  while body and body.node_type == :when
608
582
  result << body
@@ -794,8 +768,14 @@ module RubyParserStuff
794
768
  begin
795
769
  Regexp.new(node[1], o)
796
770
  rescue RegexpError => e
797
- warn "Ignoring: #{e.message}"
798
- Regexp.new(node[1], Regexp::ENC_NONE)
771
+ warn "WA\RNING: #{e.message} for #{node[1].inspect} #{options.inspect}"
772
+ begin
773
+ warn "WA\RNING: trying to recover with ENC_UTF8"
774
+ Regexp.new(node[1], Regexp::ENC_UTF8)
775
+ rescue RegexpError => e
776
+ warn "WA\RNING: trying to recover with ENC_NONE"
777
+ Regexp.new(node[1], Regexp::ENC_NONE)
778
+ end
799
779
  end
800
780
  end
801
781
  when :dstr then
@@ -919,8 +899,10 @@ module RubyParserStuff
919
899
  end
920
900
 
921
901
  def next_token
922
- if self.lexer.advance then
923
- return self.lexer.token, self.lexer.yacc_value
902
+ token = self.lexer.next_token
903
+
904
+ if token and token.first != RubyLexer::EOF then
905
+ return token
924
906
  else
925
907
  return [false, '$end']
926
908
  end
@@ -932,18 +914,13 @@ module RubyParserStuff
932
914
  rhs = value_expr rhs
933
915
 
934
916
  case lhs[0]
935
- when :gasgn, :iasgn, :lasgn, :masgn, :cdecl, :cvdecl, :cvasgn then
936
- lhs << rhs
937
- when :attrasgn then
917
+ when :lasgn, :iasgn, :cdecl, :cvdecl, :gasgn, :cvasgn, :attrasgn then
938
918
  lhs << rhs
939
- when :call then
940
- args = lhs.pop unless Symbol === lhs.last
941
- lhs.concat arg_add(args, rhs)[1..-1]
942
919
  when :const then
943
920
  lhs[0] = :cdecl
944
921
  lhs << rhs
945
922
  else
946
- raise "unknown lhs #{lhs.inspect}"
923
+ raise "unknown lhs #{lhs.inspect} w/ #{rhs.inspect}"
947
924
  end
948
925
 
949
926
  lhs
@@ -1033,10 +1010,12 @@ module RubyParserStuff
1033
1010
  str = handle_encoding str
1034
1011
 
1035
1012
  self.file = file.dup
1036
- self.lexer.src = str
1037
1013
 
1038
1014
  @yydebug = ENV.has_key? 'DEBUG'
1039
1015
 
1016
+ # HACK -- need to get tests passing more than have graceful code
1017
+ self.lexer.ss = RPStringScanner.new str
1018
+
1040
1019
  do_parse
1041
1020
  end
1042
1021
  end
@@ -1086,7 +1065,7 @@ module RubyParserStuff
1086
1065
 
1087
1066
  def s(*args)
1088
1067
  result = Sexp.new(*args)
1089
- result.line ||= lexer.lineno if lexer.src # otherwise...
1068
+ result.line ||= lexer.lineno if lexer.ss # otherwise...
1090
1069
  result.file = self.file
1091
1070
  result
1092
1071
  end
@@ -1369,6 +1348,16 @@ unless "".respond_to?(:grep) then
1369
1348
  end
1370
1349
  end
1371
1350
 
1351
+ class String
1352
+ ##
1353
+ # This is a hack used by the lexer to sneak in line numbers at the
1354
+ # identifier level. This should be MUCH smaller than making
1355
+ # process_token return [value, lineno] and modifying EVERYTHING that
1356
+ # reduces tIDENTIFIER.
1357
+
1358
+ attr_accessor :lineno
1359
+ end
1360
+
1372
1361
  class Sexp
1373
1362
  attr_writer :paren
1374
1363
 
@@ -1386,12 +1375,10 @@ class Sexp
1386
1375
  self.value.to_sym
1387
1376
  end
1388
1377
 
1389
- def add x
1390
- concat x
1391
- end
1378
+ alias :add :<<
1392
1379
 
1393
1380
  def add_all x
1394
- raise "no: #{self.inspect}.add_all #{x.inspect}" # TODO: need a test to trigger this
1381
+ self.concat x.sexp_body
1395
1382
  end
1396
1383
 
1397
1384
  def block_pass?
@@ -20,7 +20,7 @@ class TestRubyLexer < Minitest::Test
20
20
 
21
21
  def setup_lexer input, exp_sexp = nil
22
22
  setup_new_parser
23
- lex.src = input
23
+ lex.ss = RPStringScanner.new(input)
24
24
  lex.lex_state = self.lex_state
25
25
  end
26
26
 
@@ -71,11 +71,11 @@ class TestRubyLexer < Minitest::Test
71
71
  end
72
72
 
73
73
  def assert_next_lexeme token=nil, value=nil, state=nil, paren=nil, brace=nil
74
- adv = @lex.advance
74
+ adv = @lex.next_token
75
75
 
76
76
  assert adv, "no more tokens"
77
77
 
78
- act_token, act_value = @lex.token, @lex.yacc_value
78
+ act_token, act_value = adv
79
79
 
80
80
  msg = message {
81
81
  act = [act_token, act_value, @lex.lex_state,
@@ -98,20 +98,20 @@ class TestRubyLexer < Minitest::Test
98
98
  end
99
99
 
100
100
  def assert_read_escape expected, input
101
- @lex.src = input
101
+ @lex.ss.string = input
102
102
  assert_equal expected, @lex.read_escape, input
103
103
  end
104
104
 
105
105
  def assert_read_escape_bad input # TODO: rename refute_read_escape
106
- @lex.src = input
106
+ @lex.ss.string = input
107
107
  assert_raises RubyParser::SyntaxError do
108
108
  @lex.read_escape
109
109
  end
110
110
  end
111
111
 
112
112
  def refute_lexeme
113
- x = @lex.advance
114
- y = [@lex.token, @lex.yacc_value]
113
+ x = y = @lex.next_token
114
+
115
115
  refute x, "not empty: #{y.inspect}"
116
116
  end
117
117
 
@@ -146,10 +146,10 @@ class TestRubyLexer < Minitest::Test
146
146
 
147
147
  ## Tests:
148
148
 
149
- def test_advance
150
- assert @lex.advance # blah
151
- assert @lex.advance # blah
152
- refute @lex.advance # nada
149
+ def test_next_token
150
+ assert_equal [:tIDENTIFIER, "blah"], @lex.next_token
151
+ assert_equal [:tIDENTIFIER, "blah"], @lex.next_token
152
+ assert_nil @lex.next_token
153
153
  end
154
154
 
155
155
  def test_unicode_ident
@@ -834,6 +834,14 @@ class TestRubyLexer < Minitest::Test
834
834
  :kEND, "end", :expr_end)
835
835
  end
836
836
 
837
+ def test_yylex_is_your_spacebar_broken?
838
+ assert_lex3(":a!=:b",
839
+ nil,
840
+ :tSYMBOL, "a", :expr_end,
841
+ :tNEQ, "!=", :expr_beg,
842
+ :tSYMBOL, "b", :expr_end)
843
+ end
844
+
837
845
  def test_yylex_do_cond
838
846
  assert_lex3("x do 42 end",
839
847
  nil,
@@ -2538,8 +2546,9 @@ class TestRubyLexer < Minitest::Test
2538
2546
  end
2539
2547
 
2540
2548
  def test_yylex_underscore_end
2541
- @lex.src = "__END__\n"
2542
- refute_lexeme
2549
+ assert_lex3("__END__\n",
2550
+ nil,
2551
+ RubyLexer::EOF, RubyLexer::EOF, nil)
2543
2552
  end
2544
2553
 
2545
2554
  def test_yylex_uplus
@@ -603,14 +603,8 @@ module TestRubyParserShared
603
603
  assert_parse rb, pt
604
604
  end
605
605
 
606
- STARTING_LINE = {
607
- "case_no_expr" => 2, # TODO this should be 1
608
- "structure_unused_literal_wwtt" => 3, # yes, 3... odd test
609
- }
610
-
611
606
  def after_process_hook klass, node, data, input_name, output_name
612
- expected = STARTING_LINE[node] || 1
613
- assert_equal expected, @result.line, "should have proper line number"
607
+ assert_equal 1, @result.line, "should have proper line number"
614
608
  end
615
609
 
616
610
  def test_parse_line_block
@@ -639,13 +633,10 @@ module TestRubyParserShared
639
633
  s(:call, nil, :b).line(2),
640
634
  s(:call, nil, :c).line(3))
641
635
 
642
- # see skipped test: test_parse_line_block_inline_comment2
643
636
  assert_parse rb, pt
644
637
  end
645
638
 
646
- def test_parse_line_block_inline_comment2
647
- skip "I can't fix this yet. Very involved. (process_token to return lineno)"
648
-
639
+ def test_parse_line_block_inline_multiline_comment
649
640
  rb = "a\nb # comment\n# another comment\nc"
650
641
  pt = s(:block,
651
642
  s(:call, nil, :a).line(1),
@@ -655,14 +646,12 @@ module TestRubyParserShared
655
646
  assert_parse rb, pt
656
647
  end
657
648
 
658
- def test_parse_line_block_inline_comment3
659
- skip "not yet"
660
-
649
+ def test_parse_line_block_inline_comment_leading_newlines
661
650
  rb = "\n\n\na\nb # comment\n# another comment\nc"
662
651
  pt = s(:block,
663
652
  s(:call, nil, :a).line(4),
664
- s(:call, nil, :b).line(6),
665
- s(:call, nil, :c).line(8)).line(1)
653
+ s(:call, nil, :b).line(5),
654
+ s(:call, nil, :c).line(7)).line(4)
666
655
 
667
656
  assert_parse rb, pt
668
657
  end
@@ -681,6 +670,20 @@ module TestRubyParserShared
681
670
  assert_equal 2, result[3].line, "call should have line number"
682
671
  end
683
672
 
673
+ def test_parse_line_call_ivar_line_break_paren
674
+ rb = "a(@b\n)"
675
+ pt = s(:call, nil, :a, s(:ivar, :@b).line(1)).line(1)
676
+
677
+ assert_parse rb, pt
678
+ end
679
+
680
+ def test_parse_line_call_ivar_arg_no_parens_line_break
681
+ rb = "a @b\n"
682
+ pt = s(:call, nil, :a, s(:ivar, :@b).line(1)).line(1)
683
+
684
+ assert_parse rb, pt
685
+ end
686
+
684
687
  def test_parse_line_defn_no_parens
685
688
  pt = s(:defn, :f, s(:args), s(:nil))
686
689
 
@@ -708,6 +711,15 @@ module TestRubyParserShared
708
711
  assert_equal 4, body.return.line, "return should have line number"
709
712
  end
710
713
 
714
+ def test_parse_line_evstr_after_break
715
+ rb = "\"a\"\\\n\"\#{b}\""
716
+ pt = s(:dstr, "a",
717
+ s(:evstr,
718
+ s(:call, nil, :b).line(2)).line(2)).line(1)
719
+
720
+ assert_parse rb, pt
721
+ end
722
+
711
723
  def test_parse_line_iter_call_parens
712
724
  rb = "f(a) do |x, y|\n x + y\nend"
713
725
 
@@ -727,15 +739,12 @@ module TestRubyParserShared
727
739
  rb = "f a do |x, y|\n x + y\nend"
728
740
 
729
741
  pt = s(:iter,
730
- s(:call, nil, :f, s(:call, nil, :a)),
731
- s(:args, :x, :y),
732
- s(:call, s(:lvar, :x), :+, s(:lvar, :y)))
742
+ s(:call, nil, :f, s(:call, nil, :a).line(1)).line(1),
743
+ s(:args, :x, :y).line(1),
744
+ s(:call, s(:lvar, :x).line(2), :+,
745
+ s(:lvar, :y).line(2)).line(2)).line(1)
733
746
 
734
- assert_parse_line rb, pt, 1
735
-
736
- assert_equal 1, result[1].line, "call should have line number"
737
- assert_equal 1, result[2].line, "masgn should have line number"
738
- assert_equal 2, result[3].line, "call should have line number"
747
+ assert_parse rb, pt
739
748
  end
740
749
 
741
750
  def test_parse_line_heredoc
@@ -797,6 +806,15 @@ module TestRubyParserShared
797
806
  assert_equal 3, result.if.return.lit.line
798
807
  end
799
808
 
809
+ def test_parse_line_trailing_newlines
810
+ rb = "a \nb"
811
+ pt = s(:block,
812
+ s(:call, nil, :a).line(1),
813
+ s(:call, nil, :b).line(2)).line(1)
814
+
815
+ assert_parse rb, pt
816
+ end
817
+
800
818
  def test_bug_and
801
819
  rb = "true and []"
802
820
  pt = s(:and, s(:true), s(:array))
@@ -1044,7 +1062,7 @@ module TestRubyParserShared
1044
1062
  s(:call, nil, :p, s(:str, "a").line(2)).line(2),
1045
1063
  s(:lasgn, :b, s(:lit, 1).line(3)).line(3),
1046
1064
  s(:call, nil, :p, s(:lvar, :b).line(4)).line(4),
1047
- s(:lasgn, :c, s(:lit, 1).line(5)).line(5)).line(2), # TODO line 2?
1065
+ s(:lasgn, :c, s(:lit, 1).line(5)).line(5)).line(2),
1048
1066
  nil).line(1),
1049
1067
  s(:call, nil, :a).line(7)).line(1)
1050
1068
 
@@ -2051,6 +2069,16 @@ class TestRuby18Parser < RubyParserTestCase
2051
2069
  self.processor = Ruby18Parser.new
2052
2070
  end
2053
2071
 
2072
+ def test_call_space_before_paren_args
2073
+ rb = "a (:b, :c, :d => :e)"
2074
+ pt = s(:call, nil, :a,
2075
+ s(:lit, :b),
2076
+ s(:lit, :c),
2077
+ s(:hash, s(:lit, :d), s(:lit, :e)))
2078
+
2079
+ assert_parse rb, pt
2080
+ end
2081
+
2054
2082
  def test_flip2_env_lvar
2055
2083
  rb = "if a..b then end"
2056
2084
  pt = s(:if, s(:flip2, s(:call, nil, :a), s(:call, nil, :b)), nil, nil)
@@ -2848,6 +2876,38 @@ class TestRuby20Parser < RubyParserTestCase
2848
2876
  self.processor = Ruby20Parser.new
2849
2877
  end
2850
2878
 
2879
+ def test_block_call_dot_op2_brace_block
2880
+ rb = "a.b c() do d end.e do |f| g end"
2881
+ pt = s(:iter,
2882
+ s(:call,
2883
+ s(:iter,
2884
+ s(:call, s(:call, nil, :a), :b, s(:call, nil, :c)),
2885
+ s(:args),
2886
+ s(:call, nil, :d)),
2887
+ :e),
2888
+ s(:args, :f),
2889
+ s(:call, nil, :g))
2890
+
2891
+
2892
+ assert_parse rb, pt
2893
+ end
2894
+
2895
+ def test_block_call_dot_op2_cmd_args_do_block
2896
+ rb = "a.b c() do d end.e f do |g| h end"
2897
+ pt = s(:iter,
2898
+ s(:call,
2899
+ s(:iter,
2900
+ s(:call, s(:call, nil, :a), :b, s(:call, nil, :c)),
2901
+ s(:args),
2902
+ s(:call, nil, :d)),
2903
+ :e,
2904
+ s(:call, nil, :f)),
2905
+ s(:args, :g),
2906
+ s(:call, nil, :h))
2907
+
2908
+ assert_parse rb, pt
2909
+ end
2910
+
2851
2911
  def test_defn_kwarg_val
2852
2912
  rb = "def f(a, b:1) end"
2853
2913
  pt = s(:defn, :f, s(:args, :a, s(:kwarg, :b, s(:lit, 1))), s(:nil))