ruby_parser 3.0.0.a2 → 3.0.0.a3

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of ruby_parser might be problematic. Click here for more details.

@@ -35,6 +35,8 @@ class RubyLexer
35
35
  # What handles warnings
36
36
  attr_accessor :warnings
37
37
 
38
+ attr_accessor :space_seen
39
+
38
40
  EOF = :eof_haha!
39
41
 
40
42
  # ruby constants for strings (should this be moved somewhere else?)
@@ -221,9 +223,9 @@ class RubyLexer
221
223
 
222
224
  def initialize v = 18
223
225
  self.version = v
224
- self.cond = RubyParser::StackState.new(:cond)
225
- self.cmdarg = RubyParser::StackState.new(:cmdarg)
226
- self.tern = RubyParser::StackState.new(:tern)
226
+ self.cond = RubyParserStuff::StackState.new(:cond)
227
+ self.cmdarg = RubyParserStuff::StackState.new(:cmdarg)
228
+ self.tern = RubyParserStuff::StackState.new(:tern)
227
229
  self.nest = 0
228
230
  @comments = []
229
231
 
@@ -237,6 +239,7 @@ class RubyLexer
237
239
  end
238
240
 
239
241
  def lex_state= o
242
+ # warn "wtf lex_state = #{o.inspect}"
240
243
  raise "wtf\?" unless Symbol === o
241
244
  @lex_state = o
242
245
  end
@@ -640,7 +643,7 @@ class RubyLexer
640
643
 
641
644
  def yylex # 826 lines
642
645
  c = ''
643
- space_seen = false
646
+ self.space_seen = false
644
647
  command_state = false
645
648
  src = self.src
646
649
 
@@ -656,7 +659,7 @@ class RubyLexer
656
659
 
657
660
  loop do # START OF CASE
658
661
  if src.scan(/[\ \t\r\f\v]/) then # \s - \n + \v
659
- space_seen = true
662
+ self.space_seen = true
660
663
  next
661
664
  elsif src.check(/[^a-zA-Z]/) then
662
665
  if src.scan(/\n|#/) then
@@ -711,9 +714,9 @@ class RubyLexer
711
714
  end
712
715
  elsif src.scan(/\(/) then
713
716
  result = if ruby18 then
714
- yylex_paren18 space_seen
717
+ yylex_paren18
715
718
  else
716
- yylex_paren19 space_seen
719
+ yylex_paren19
717
720
  end
718
721
 
719
722
  self.expr_beg_push "("
@@ -755,10 +758,7 @@ class RubyLexer
755
758
 
756
759
  return process_token(command_state)
757
760
  elsif src.scan(/\:\:/) then
758
- if (lex_state == :expr_beg ||
759
- lex_state == :expr_mid ||
760
- lex_state == :expr_class ||
761
- (lex_state.is_argument && space_seen)) then
761
+ if is_beg? || lex_state == :expr_class || is_space_arg? then
762
762
  self.lex_state = :expr_beg
763
763
  self.yacc_value = "::"
764
764
  return :tCOLON3
@@ -1139,7 +1139,7 @@ class RubyLexer
1139
1139
  elsif src.scan(/\\/) then
1140
1140
  if src.scan(/\n/) then
1141
1141
  self.lineno = nil
1142
- space_seen = true
1142
+ self.space_seen = true
1143
1143
  next
1144
1144
  end
1145
1145
  rb_compile_error "bare backslash only allowed before newline"
@@ -1233,7 +1233,7 @@ class RubyLexer
1233
1233
  end
1234
1234
  end
1235
1235
 
1236
- def yylex_paren18 space_seen
1236
+ def yylex_paren18
1237
1237
  self.command_start = true
1238
1238
  result = :tLPAREN2
1239
1239
 
@@ -1253,17 +1253,39 @@ class RubyLexer
1253
1253
  result
1254
1254
  end
1255
1255
 
1256
- def yylex_paren19 space_seen
1257
- if (lex_state == :expr_beg || lex_state == :expr_mid ||
1258
- lex_state == :expr_value || lex_state == :expr_class) then
1256
+ def is_end?
1257
+ (lex_state == :expr_end ||
1258
+ lex_state == :expr_endarg ||
1259
+ lex_state == :expr_endfn)
1260
+ end
1261
+
1262
+ def is_arg?
1263
+ lex_state == :expr_arg || lex_state == :expr_cmdarg
1264
+ end
1265
+
1266
+ def is_beg?
1267
+ (lex_state == :expr_beg ||
1268
+ lex_state == :expr_mid ||
1269
+ lex_state == :expr_value ||
1270
+ lex_state == :expr_class)
1271
+ end
1272
+
1273
+ def is_space_arg? c = "x"
1274
+ is_arg? and space_seen and c !~ /\s/
1275
+ end
1276
+
1277
+ def yylex_paren19
1278
+ if is_beg? then
1259
1279
  result = :tLPAREN
1260
- elsif ((lex_state == :expr_arg || lex_state == :expr_cmdarg) and
1261
- space_seen) then
1280
+ elsif is_space_arg? then
1262
1281
  result = :tLPAREN_ARG
1263
1282
  else
1264
1283
  self.tern.push false
1265
1284
  result = :tLPAREN2
1266
1285
  end
1286
+
1287
+ # p :wtf_paren => [lex_state, space_seen, result]
1288
+
1267
1289
  # HACK paren_nest++;
1268
1290
 
1269
1291
  # HACK: this is a mess, but it makes the tests pass, so suck it
@@ -1334,7 +1356,11 @@ class RubyLexer
1334
1356
 
1335
1357
  unless lex_state == :expr_dot then
1336
1358
  # See if it is a reserved word.
1337
- keyword = RubyParser::Keyword.keyword token
1359
+ keyword = if ruby18 then # REFACTOR need 18/19 lexer subclasses
1360
+ RubyParserStuff::Keyword.keyword18 token
1361
+ else
1362
+ RubyParserStuff::Keyword.keyword19 token
1363
+ end
1338
1364
 
1339
1365
  if keyword then
1340
1366
  state = lex_state
@@ -2,6 +2,7 @@ require 'stringio'
2
2
  require 'racc/parser'
3
3
  require 'sexp'
4
4
  require 'strscan'
5
+ require 'ruby_lexer'
5
6
 
6
7
  def d o
7
8
  $stderr.puts o.inspect
@@ -115,7 +116,7 @@ class RPStringScanner < StringScanner
115
116
  end
116
117
 
117
118
  module RubyParserStuff
118
- VERSION = '3.0.0.a2' unless constants.include? "VERSION" # SIGH
119
+ VERSION = '3.0.0.a3' unless constants.include? "VERSION" # SIGH
119
120
 
120
121
  attr_accessor :lexer, :in_def, :in_single, :file
121
122
  attr_reader :env, :comments
@@ -223,6 +224,57 @@ module RubyParserStuff
223
224
  result
224
225
  end
225
226
 
227
+ def block_args19 val, id
228
+ # HACK OMG THIS CODE IS SOOO UGLY! CLEAN ME
229
+ untested = %w[1 2 3 4 7 9 10 11 12 14]
230
+ raise "no block_args19 #{id}" if untested.include? id
231
+
232
+ r = s(:array)
233
+
234
+ val.compact.each do |v|
235
+ next if %w[,].include? v
236
+ case v
237
+ when Sexp then
238
+ case v.first
239
+ when :args then
240
+ r.concat v[1..-1].map { |s| s(:lasgn, s) }
241
+ when :block_arg then
242
+ r << s(:lasgn, :"&#{v.last}")
243
+ else
244
+ raise "block_args19 #{id} unhandled sexp type:: #{v.inspect}"
245
+ end
246
+ when Symbol
247
+ case v.to_s
248
+ when /^\*(.+)/ then
249
+ r << s(:splat, s(:lasgn, $1.to_sym))
250
+ when /^\*/ then
251
+ r << s(:splat)
252
+ else
253
+ raise "block_args19 #{id} unhandled symbol type:: #{v.inspect}"
254
+ end
255
+ else
256
+ raise "block_args19 #{id} unhandled type:: #{v.inspect}"
257
+ end
258
+ end
259
+
260
+ if r.size > 2 then
261
+ r = s(:masgn, r)
262
+ elsif r.size == 2 then
263
+ case r.last.first
264
+ when :splat then
265
+ r = s(:masgn, r)
266
+ when :lasgn then
267
+ r = r.last
268
+ else
269
+ raise "oh noes!: #{r.inspect}"
270
+ end
271
+ else
272
+ raise "fuck no #{r.inspect}"
273
+ end
274
+
275
+ r
276
+ end
277
+
226
278
  def aryset receiver, index
227
279
  s(:attrasgn, receiver, :"[]=", *index[1..-1])
228
280
  end
@@ -389,7 +441,7 @@ module RubyParserStuff
389
441
  v = self.class.name[/1[89]/]
390
442
  self.lexer = RubyLexer.new v && v.to_i
391
443
  self.lexer.parser = self
392
- @env = Environment.new
444
+ @env = RubyParserStuff::Environment.new
393
445
  @comments = []
394
446
 
395
447
  @canonicalize_conditions = true
@@ -583,7 +635,7 @@ module RubyParserStuff
583
635
  end
584
636
 
585
637
  def new_compstmt val
586
- result = void_stmts(val[0])
638
+ result = void_stmts(val.grep(Sexp)[0])
587
639
  result = remove_begin(result) if result
588
640
  result
589
641
  end
@@ -1011,15 +1063,29 @@ module RubyParserStuff
1011
1063
  ["BEGIN", [:klBEGIN, :klBEGIN ], :expr_end ],
1012
1064
  ["while", [:kWHILE, :kWHILE_MOD ], :expr_beg ],
1013
1065
  ["alias", [:kALIAS, :kALIAS ], :expr_fname ],
1066
+ ["__ENCODING__", [:k__ENCODING__, :k__ENCODING__], :expr_end],
1014
1067
  ].map { |args| KWtable.new(*args) }
1015
1068
 
1016
1069
  # :startdoc:
1017
1070
 
1018
- WORDLIST = Hash[*wordlist.map { |o| [o.name, o] }.flatten] unless
1019
- defined? WORDLIST
1071
+ WORDLIST18 = Hash[*wordlist.map { |o| [o.name, o] }.flatten]
1072
+ WORDLIST19 = Hash[*wordlist.map { |o| [o.name, o] }.flatten]
1073
+
1074
+ %w[and case elsif for if in module or unless until when while].each do |k|
1075
+ WORDLIST19[k] = WORDLIST19[k].dup
1076
+ WORDLIST19[k].state = :expr_value
1077
+ end
1078
+ %w[not].each do |k|
1079
+ WORDLIST19[k] = WORDLIST19[k].dup
1080
+ WORDLIST19[k].state = :expr_arg
1081
+ end
1082
+
1083
+ def self.keyword18 str # REFACTOR
1084
+ WORDLIST18[str]
1085
+ end
1020
1086
 
1021
- def self.keyword str
1022
- WORDLIST[str]
1087
+ def self.keyword19 str
1088
+ WORDLIST19[str]
1023
1089
  end
1024
1090
  end
1025
1091
 
@@ -1138,11 +1204,21 @@ class Ruby18Parser < Racc::Parser
1138
1204
  include RubyParserStuff
1139
1205
  end
1140
1206
 
1141
- class RubyParser < Ruby18Parser
1207
+ ##
1208
+ # RubyParser is a compound parser that first attempts to parse using
1209
+ # the 1.9 syntax parser and falls back to the 1.8 syntax parser on a
1210
+ # parse error.
1211
+
1212
+ class RubyParser
1142
1213
  def initialize
1143
- super
1144
- warn "WA\RNING: Deprecated: RubyParser. Use Ruby18Parser or Ruby19Parser"
1145
- warn " from #{caller.first}"
1214
+ @p18 = Ruby18Parser.new
1215
+ @p19 = Ruby19Parser.new
1216
+ end
1217
+
1218
+ def parse s
1219
+ @p19.parse s
1220
+ rescue Racc::ParseError
1221
+ @p18.parse s
1146
1222
  end
1147
1223
  end
1148
1224
 
@@ -1172,11 +1248,11 @@ class Sexp
1172
1248
  end
1173
1249
 
1174
1250
  def add x
1175
- raise "no" # TODO: need a test to trigger this
1251
+ concat x
1176
1252
  end
1177
1253
 
1178
1254
  def add_all x
1179
- raise "no" # TODO: need a test to trigger this
1255
+ raise "no: #{self.inspect}.add_all #{x.inspect}" # TODO: need a test to trigger this
1180
1256
  end
1181
1257
 
1182
1258
  alias :node_type :sexp_type
@@ -1,28 +1,16 @@
1
1
  #!/usr/local/bin/ruby
2
2
 
3
- ENV['VERBOSE'] = "1"
3
+ # ENV['VERBOSE'] = "1"
4
4
 
5
5
  require 'rubygems'
6
6
  gem "minitest"
7
7
  require 'minitest/autorun'
8
8
  require 'ruby_parser'
9
9
 
10
- $: << File.expand_path('~/Work/p4/zss/src/ParseTree/dev/test')
10
+ $: << File.expand_path('~/Work/p4/zss/src/sexp_processor/dev/lib')
11
11
 
12
12
  require 'pt_testcase'
13
13
 
14
- class Ruby18Parser # FIX
15
- def process input
16
- parse input
17
- end
18
- end
19
-
20
- class Ruby19Parser
21
- def process input
22
- parse input
23
- end
24
- end
25
-
26
14
  class RubyParserTestCase < ParseTreeTestCase
27
15
  attr_accessor :result, :processor
28
16
 
@@ -44,13 +32,21 @@ class RubyParserTestCase < ParseTreeTestCase
44
32
  assert_equal pt, result
45
33
  end
46
34
 
35
+ def assert_parse_error rb, emsg
36
+ e = assert_raises Racc::ParseError do
37
+ processor.parse rb
38
+ end
39
+
40
+ assert_equal emsg, e.message.strip # TODO: why strip?
41
+ end
42
+
47
43
  def assert_parse_line rb, pt, line
48
44
  assert_parse rb, pt
49
45
  assert_equal line, result.line, "call should have line number"
50
46
  end
51
47
  end
52
48
 
53
- module TestRubyParser
49
+ module TestRubyParserShared
54
50
  def test_attrasgn_array_lhs
55
51
  rb = '[1, 2, 3, 4][from .. to] = ["a", "b", "c"]'
56
52
  pt = s(:attrasgn,
@@ -617,6 +613,103 @@ module TestRubyParser
617
613
  assert_equal 3, result.if.return.line
618
614
  assert_equal 3, result.if.return.lit.line
619
615
  end
616
+ end
617
+
618
+ class TestRubyParser < MiniTest::Unit::TestCase
619
+ def test_parse
620
+ processor = RubyParser.new
621
+
622
+ # 1.8 only syntax
623
+ rb = "while false : 42 end"
624
+ pt = s(:while, s(:false), s(:lit, 42), true)
625
+
626
+ assert_equal pt, processor.parse(rb)
627
+
628
+ # 1.9 only syntax
629
+ rb = "a.()"
630
+ pt = s(:call, s(:call, nil, :a), :call)
631
+
632
+ assert_equal pt, processor.parse(rb)
633
+
634
+ # bad syntax
635
+ e = assert_raises Racc::ParseError do
636
+ processor.parse "a.("
637
+ end
638
+
639
+ msg = "parse error on value \"(\" (tLPAREN2)"
640
+ assert_equal msg, e.message.strip
641
+ end
642
+ end
643
+
644
+ class TestRuby18Parser < RubyParserTestCase
645
+ include TestRubyParserShared
646
+
647
+ def setup
648
+ super
649
+
650
+ self.processor = Ruby18Parser.new
651
+ end
652
+
653
+ def test_flip2_env_lvar
654
+ rb = "if a..b then end"
655
+ pt = s(:if, s(:flip2, s(:call, nil, :a), s(:call, nil, :b)), nil, nil)
656
+
657
+ assert_parse rb, pt
658
+
659
+ top_env = processor.env.env.first
660
+
661
+ assert_kind_of Hash, top_env
662
+
663
+ flip = top_env.find { |k,v| k =~ /^flip/ }
664
+
665
+ assert flip
666
+ assert_equal :lvar, flip.last
667
+ end
668
+
669
+ def test_assoc_list_18
670
+ rb = "{1, 2, 3, 4}"
671
+ pt = s(:hash, s(:lit, 1), s(:lit, 2), s(:lit, 3), s(:lit, 4))
672
+
673
+ assert_parse rb, pt
674
+ end
675
+
676
+ def test_case_then_colon_18
677
+ rb = "case x; when Fixnum: 42; end"
678
+ pt = s(:case,
679
+ s(:call, nil, :x),
680
+ s(:when, s(:array, s(:const, :Fixnum)), s(:lit, 42)),
681
+ nil)
682
+
683
+ assert_parse rb, pt
684
+ end
685
+
686
+ def test_do_colon_18
687
+ rb = "while false : 42 end"
688
+ pt = s(:while, s(:false), s(:lit, 42), true)
689
+
690
+ assert_parse rb, pt
691
+ end
692
+
693
+ def test_parse_until_not_canonical
694
+ rb = "until not var.nil?\n 'foo'\nend"
695
+
696
+ pt = s(:while,
697
+ s(:call, s(:call, nil, :var), :nil?),
698
+ s(:str, "foo"), true)
699
+
700
+ assert_parse rb, pt
701
+ end
702
+
703
+ def test_parse_until_not_noncanonical
704
+ rb = "until not var.nil?\n 'foo'\nend"
705
+ pt = s(:until,
706
+ s(:not, s(:call, s(:call, nil, :var), :nil?)),
707
+ s(:str, "foo"), true)
708
+
709
+ processor.canonicalize_conditions = false
710
+
711
+ assert_parse rb, pt
712
+ end
620
713
 
621
714
  def test_parse_if_not_canonical
622
715
  rb = "if not var.nil? then 'foo' else 'bar'\nend"
@@ -631,8 +724,7 @@ module TestRubyParser
631
724
  def test_parse_if_not_noncanonical
632
725
  rb = "if not var.nil? then 'foo' else 'bar'\nend"
633
726
  pt = s(:if,
634
- s(:not,
635
- s(:call, s(:call, nil, :var), :nil?)),
727
+ s(:not, s(:call, s(:call, nil, :var), :nil?)),
636
728
  s(:str, "foo"),
637
729
  s(:str, "bar"))
638
730
 
@@ -653,20 +745,151 @@ module TestRubyParser
653
745
  def test_parse_while_not_noncanonical
654
746
  rb = "while not var.nil?\n 'foo'\nend"
655
747
  pt = s(:while,
656
- s(:not,
657
- s(:call, s(:call, nil, :var), :nil?)),
748
+ s(:not, s(:call, s(:call, nil, :var), :nil?)),
658
749
  s(:str, "foo"), true)
659
750
 
660
751
  processor.canonicalize_conditions = false
661
752
 
662
753
  assert_parse rb, pt
663
754
  end
755
+ end
756
+
757
+ class TestRuby19Parser < RubyParserTestCase
758
+ include TestRubyParserShared
759
+
760
+ def setup
761
+ super
762
+
763
+ self.processor = Ruby19Parser.new
764
+ end
765
+
766
+ def test_mlhs_back_splat
767
+ rb = "a, b, c, *s = f"
768
+ pt = s(:masgn,
769
+ s(:array,
770
+ s(:lasgn, :a), s(:lasgn, :b), s(:lasgn, :c),
771
+ s(:splat, s(:lasgn, :s))),
772
+ s(:to_ary, s(:call, nil, :f)))
773
+
774
+ assert_parse rb, pt
775
+ end
776
+
777
+ def test_mlhs_back_anonsplat
778
+ rb = "a, b, c, * = f"
779
+ pt = s(:masgn,
780
+ s(:array,
781
+ s(:lasgn, :a), s(:lasgn, :b), s(:lasgn, :c),
782
+ s(:splat)),
783
+ s(:to_ary, s(:call, nil, :f)))
784
+
785
+ assert_parse rb, pt
786
+ end
787
+
788
+ def test_mlhs_mid_splat
789
+ rb = "a, b, c, *s, x, y, z = f"
790
+ pt = s(:masgn,
791
+ s(:array,
792
+ s(:lasgn, :a), s(:lasgn, :b), s(:lasgn, :c),
793
+ s(:splat, s(:lasgn, :s)),
794
+ s(:lasgn, :x), s(:lasgn, :y), s(:lasgn, :z)),
795
+ s(:to_ary, s(:call, nil, :f)))
796
+
797
+ assert_parse rb, pt
798
+ end
799
+
800
+ def test_mlhs_mid_anonsplat
801
+ rb = "a, b, c, *, x, y, z = f"
802
+ pt = s(:masgn,
803
+ s(:array, s(:lasgn, :a), s(:splat), s(:lasgn, :z)),
804
+ s(:to_ary, s(:call, nil, :f)))
805
+ pt = s(:masgn,
806
+ s(:array,
807
+ s(:lasgn, :a), s(:lasgn, :b), s(:lasgn, :c),
808
+ s(:splat),
809
+ s(:lasgn, :x), s(:lasgn, :y), s(:lasgn, :z)),
810
+ s(:to_ary, s(:call, nil, :f)))
811
+
812
+ assert_parse rb, pt
813
+ end
814
+
815
+ def test_mlhs_front_splat
816
+ rb = "*s, x, y, z = f"
817
+ pt = s(:masgn,
818
+ s(:array, s(:splat, s(:lasgn, :s)), s(:lasgn, :z)),
819
+ s(:to_ary, s(:call, nil, :f)))
820
+ pt = s(:masgn,
821
+ s(:array,
822
+ s(:splat, s(:lasgn, :s)),
823
+ s(:lasgn, :x), s(:lasgn, :y), s(:lasgn, :z)),
824
+ s(:to_ary, s(:call, nil, :f)))
825
+
826
+ assert_parse rb, pt
827
+ end
828
+
829
+ def test_mlhs_front_anonsplat
830
+ rb = "*, x, y, z = f"
831
+ pt = s(:masgn,
832
+ s(:array,
833
+ s(:splat),
834
+ s(:lasgn, :x), s(:lasgn, :y), s(:lasgn, :z)),
835
+ s(:to_ary, s(:call, nil, :f)))
836
+
837
+ assert_parse rb, pt
838
+ end
839
+
840
+ def test_expr_not_bang
841
+ rb = "! a b"
842
+ pt = s(:call, s(:call, nil, :a, s(:call, nil, :b)), :"!")
843
+
844
+ assert_parse rb, pt
845
+ end
846
+
847
+ def test_encoding
848
+ rb = '__ENCODING__'
849
+ pt = s(:str, "Unsupported!")
850
+
851
+ assert_parse rb, pt
852
+ end
853
+
854
+ def test_do_colon_19
855
+ rb = "while false : 42 end"
856
+
857
+ assert_parse_error rb, "parse error on value \":\" (tCOLON)"
858
+ end
859
+
860
+ def test_assoc_list_19
861
+ rb = "{1, 2, 3, 4}"
862
+
863
+ assert_parse_error rb, "parse error on value \",\" (tCOMMA)"
864
+ end
865
+
866
+ def test_case_then_colon_19
867
+ rb = <<-EOM
868
+ case x
869
+ when Fixnum : # need the space to not hit new hash arg syntax
870
+ 42
871
+ end
872
+ EOM
873
+
874
+ assert_parse_error rb, "parse error on value \":\" (tCOLON)"
875
+ end
876
+
877
+ def test_parse_def_xxx1
878
+ rb = 'def f(a, *b, c = nil) end'
879
+
880
+ assert_parse_error rb, 'parse error on value "=" (tEQL)'
881
+ end
882
+
883
+ def test_parse_def_xxx2
884
+ rb = 'def f(a = nil, *b, c = nil) end'
885
+
886
+ assert_parse_error rb, 'parse error on value "=" (tEQL)'
887
+ end
664
888
 
665
889
  def test_parse_until_not_canonical
666
890
  rb = "until not var.nil?\n 'foo'\nend"
667
-
668
- pt = s(:while,
669
- s(:call, s(:call, nil, :var), :nil?),
891
+ pt = s(:until,
892
+ s(:call, s(:call, s(:call, nil, :var), :nil?), :"!"),
670
893
  s(:str, "foo"), true)
671
894
 
672
895
  assert_parse rb, pt
@@ -675,49 +898,61 @@ module TestRubyParser
675
898
  def test_parse_until_not_noncanonical
676
899
  rb = "until not var.nil?\n 'foo'\nend"
677
900
  pt = s(:until,
678
- s(:not,
679
- s(:call, s(:call, nil, :var), :nil?)),
901
+ s(:call, s(:call, s(:call, nil, :var), :nil?), :"!"),
680
902
  s(:str, "foo"), true)
681
903
 
682
904
  processor.canonicalize_conditions = false
683
905
 
684
906
  assert_parse rb, pt
685
907
  end
686
- end
687
908
 
688
- class TestRuby18Parser < RubyParserTestCase
689
- include TestRubyParser
690
-
691
- def setup
692
- super
909
+ def test_parse_if_not_canonical
910
+ rb = "if not var.nil? then 'foo' else 'bar'\nend"
911
+ pt = s(:if,
912
+ s(:call, s(:call, s(:call, nil, :var), :nil?), :"!"),
913
+ s(:str, "foo"),
914
+ s(:str, "bar"))
693
915
 
694
- self.processor = Ruby18Parser.new
916
+ assert_parse rb, pt
695
917
  end
696
918
 
697
- def test_flip2_env_lvar
698
- rb = "if a..b then end"
699
- pt = s(:if, s(:flip2, s(:call, nil, :a), s(:call, nil, :b)), nil, nil)
919
+ def test_parse_if_not_noncanonical
920
+ rb = "if not var.nil? then 'foo' else 'bar'\nend"
921
+ pt = s(:if,
922
+ s(:call, s(:call, s(:call, nil, :var), :nil?), :"!"),
923
+ s(:str, "foo"),
924
+ s(:str, "bar"))
925
+
926
+ processor.canonicalize_conditions = false
700
927
 
701
928
  assert_parse rb, pt
929
+ end
702
930
 
703
- top_env = processor.env.env.first
931
+ def test_parse_while_not_canonical
932
+ rb = "while not var.nil?\n 'foo'\nend"
933
+ pt = s(:while,
934
+ s(:call, s(:call, s(:call, nil, :var), :nil?), :"!"),
935
+ s(:str, "foo"), true)
704
936
 
705
- assert_kind_of Hash, top_env
937
+ assert_parse rb, pt
938
+ end
706
939
 
707
- flip = top_env.find { |k,v| k =~ /^flip/ }
940
+ def test_parse_while_not_noncanonical
941
+ rb = "while not var.nil?\n 'foo'\nend"
942
+ pt = s(:while,
943
+ s(:call, s(:call, s(:call, nil, :var), :nil?), :"!"),
944
+ s(:str, "foo"), true)
708
945
 
709
- assert flip
710
- assert_equal :lvar, flip.last
711
- end
712
- end
946
+ processor.canonicalize_conditions = false
713
947
 
714
- class TestRuby19Parser < RubyParserTestCase
715
- include TestRubyParser
948
+ assert_parse rb, pt
949
+ end
716
950
 
717
- def setup
718
- super
951
+ def test_parse_opt_call_args_assocs_comma
952
+ rb = "1[2=>3,]"
953
+ pt = s(:call, s(:lit, 1), :[], s(:lit, 2), s(:lit, 3))
719
954
 
720
- self.processor = Ruby19Parser.new
955
+ assert_parse rb, pt
721
956
  end
722
957
 
723
958
  # HACK: need to figure out the desired structure and get this working